From b474de02ec38e92d1634f656a8e7c089df98e0ba Mon Sep 17 00:00:00 2001 From: "dfo-release[bot]" <336980964+dfo-release[bot]@users.noreply.github.com> Date: Tue, 13 Oct 2026 07:10:28 +0200 Subject: [PATCH 01/39] Seed dev from ONEcampaign/dfo-spec-kit@5d381d8322288dc77411baa70c0dcff323ba6c7f Synced-from: ONEcampaign/dfo-spec-kit@5d381d8322288dc77411baa70c0dcff323ba6c7f From 2116cf208ff6370e1d9ca0637a2e631e88606fe8 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Thu, 15 Oct 2026 10:41:33 +0200 Subject: [PATCH 02/39] docs: point install docs and changelog links at the DFO repo The $id values in the schemas stay as they are. The sync-guard workflow is removed. --- .github/workflows/sync-guard.yml | 45 --------------------- README.md | 22 +++++----- python/descriptions/CHANGELOG.md | 2 +- python/dfo-spec-kit-components/CHANGELOG.md | 2 +- python/frame-grammar/CHANGELOG.md | 2 +- python/provenance-docs/CHANGELOG.md | 2 +- python/spec-kit/CHANGELOG.md | 2 +- 7 files changed, 16 insertions(+), 61 deletions(-) delete mode 100644 .github/workflows/sync-guard.yml diff --git a/.github/workflows/sync-guard.yml b/.github/workflows/sync-guard.yml deleted file mode 100644 index 6635731..0000000 --- a/.github/workflows/sync-guard.yml +++ /dev/null @@ -1,45 +0,0 @@ -# sync-guard: the required check on main in every DevelopmentFinanceObservatory -# repo. It passes only a sync PR whose tree matches its ONEcampaign source -# commit, or a release App image pin. The rules live in -# DevelopmentFinanceObservatory/infra, in .github/actions/sync-guard and -# scripts/sync-guard.sh. -# -# pull_request_target runs this file and the action from the default branch, -# never from the PR, so a PR cannot edit the guard it faces. The job is -# prod-only. In ONEcampaign it skips before the private action is ever -# fetched. -# -# The job posts the sync-guard check run on the PR's head commit with the -# release App's token, and the ruleset accepts sync-guard only from that -# App. The token's secrets live in the sync-guard environment, which only -# main may use, so a workflow a PR adds cannot mint it. -name: sync-guard - -on: - pull_request_target: - types: [opened, synchronize, reopened] - branches: [main] - -permissions: - contents: read - -# A force-push cancels the run for the old head. Each run judges the head -# commit its own event names. -concurrency: - group: sync-guard-${{ github.event.pull_request.number }} - cancel-in-progress: true - -jobs: - sync-guard: - # Named apart from the check run it posts, which is the required one. - name: sync-guard runner - if: github.repository_owner == 'DevelopmentFinanceObservatory' - runs-on: ubuntu-latest - environment: sync-guard - steps: - - uses: DevelopmentFinanceObservatory/infra/.github/actions/sync-guard@main - with: - reader-client-id: ${{ vars.READER_APP_CLIENT_ID }} - reader-private-key: ${{ secrets.READER_APP_PRIVATE_KEY }} - release-client-id: ${{ vars.RELEASE_APP_CLIENT_ID }} - release-private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} diff --git a/README.md b/README.md index b05344a..7bede2f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # dfo-spec-kit -The executable form of the platform's shared contracts. It exists so the consumers of these contracts, the Search API in `dfo-apis`, the harness and Analysis MCP in `dfo-ai`, the website, and the docs, share one source of truth instead of hand-maintained mirrors. This repo is not the spec registry nor the op-spec schema. +The executable form of the platform's shared contracts. It exists so the consumers of these contracts, the Search API in `apis`, the harness and Analysis MCP in `ai`, the website, and the docs, share one source of truth instead of hand-maintained mirrors. This repo is not the spec registry nor the op-spec schema. The target design (repository shape, artifact families, versioning, governance, and delivery sequence) lives in the kit design, maintained outside this repo. This README only orients. That document is authoritative. @@ -23,27 +23,27 @@ The Python distributions live at `python/spec-kit/`, `python/frame-grammar/`, `p Publishing is undecided: no registry workflow exists for any package. Until that's resolved, install a Python package as a git dependency pinned to one commit, e.g. ```bash -uv add "git+https://github.com/ONEcampaign/dfo-spec-kit@#subdirectory=python/spec-kit" -uv add "git+https://github.com/ONEcampaign/dfo-spec-kit@#subdirectory=python/frame-grammar" -uv add "git+https://github.com/ONEcampaign/dfo-spec-kit@#subdirectory=python/dfo-spec-kit-components" -uv add "git+https://github.com/ONEcampaign/dfo-spec-kit@#subdirectory=python/provenance-docs" -uv add "git+https://github.com/ONEcampaign/dfo-spec-kit@#subdirectory=python/descriptions" +uv add "git+https://github.com/DevelopmentFinanceObservatory/spec-kit@#subdirectory=python/spec-kit" +uv add "git+https://github.com/DevelopmentFinanceObservatory/spec-kit@#subdirectory=python/frame-grammar" +uv add "git+https://github.com/DevelopmentFinanceObservatory/spec-kit@#subdirectory=python/dfo-spec-kit-components" +uv add "git+https://github.com/DevelopmentFinanceObservatory/spec-kit@#subdirectory=python/provenance-docs" +uv add "git+https://github.com/DevelopmentFinanceObservatory/spec-kit@#subdirectory=python/descriptions" ``` A package's metadata names its intra-repo dependency by distribution name alone, and no index serves these distributions. uv reads the path source in `[tool.uv.sources]` and resolves the dependency from the same checkout, so `uv add` of `frame-grammar` or `dfo-spec-kit-components` alone installs `dfo-spec-kit` or `dfo-spec-kit-descriptions` at that commit. Every other installer reads the bare name and fails, so name both distributions at the same commit: ```bash pip install \ - "dfo-spec-kit-components @ git+https://github.com/ONEcampaign/dfo-spec-kit@#subdirectory=python/dfo-spec-kit-components" \ - "dfo-spec-kit-descriptions @ git+https://github.com/ONEcampaign/dfo-spec-kit@#subdirectory=python/descriptions" + "dfo-spec-kit-components @ git+https://github.com/DevelopmentFinanceObservatory/spec-kit@#subdirectory=python/dfo-spec-kit-components" \ + "dfo-spec-kit-descriptions @ git+https://github.com/DevelopmentFinanceObservatory/spec-kit@#subdirectory=python/descriptions" ``` -A uv project pins each kit distribution it imports in its own `[tool.uv.sources]`, every entry at the same `rev`, as `dfo-apis` pins `dfo-spec-kit-components` and `dfo-spec-kit-frame-grammar`: +A uv project pins each kit distribution it imports in its own `[tool.uv.sources]`, every entry at the same `rev`, as `apis` pins `dfo-spec-kit-components` and `dfo-spec-kit-frame-grammar`: ```toml [tool.uv.sources] -dfo-spec-kit-components = { git = "https://github.com/ONEcampaign/dfo-spec-kit.git", rev = "", subdirectory = "python/dfo-spec-kit-components" } -dfo-spec-kit-descriptions = { git = "https://github.com/ONEcampaign/dfo-spec-kit.git", rev = "", subdirectory = "python/descriptions" } +dfo-spec-kit-components = { git = "https://github.com/DevelopmentFinanceObservatory/spec-kit.git", rev = "", subdirectory = "python/dfo-spec-kit-components" } +dfo-spec-kit-descriptions = { git = "https://github.com/DevelopmentFinanceObservatory/spec-kit.git", rev = "", subdirectory = "python/descriptions" } ``` ## Layout diff --git a/python/descriptions/CHANGELOG.md b/python/descriptions/CHANGELOG.md index da36b6e..3c6e776 100644 --- a/python/descriptions/CHANGELOG.md +++ b/python/descriptions/CHANGELOG.md @@ -137,4 +137,4 @@ and this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 measure. The card-revision and live-rendering vectors carry the measure, fixed values and drawn values with graph definitions. -[unreleased]: https://github.com/ONEcampaign/dfo-spec-kit/commits/main/python +[unreleased]: https://github.com/DevelopmentFinanceObservatory/spec-kit/commits/main/python diff --git a/python/dfo-spec-kit-components/CHANGELOG.md b/python/dfo-spec-kit-components/CHANGELOG.md index 0dfd9b7..38fdd77 100644 --- a/python/dfo-spec-kit-components/CHANGELOG.md +++ b/python/dfo-spec-kit-components/CHANGELOG.md @@ -179,4 +179,4 @@ and this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `x_axis` and `y_axis`. `schema_version` stays 1; a consuming service's own migration rewrites its stored `bar_chart` payloads to the new key names. -[unreleased]: https://github.com/ONEcampaign/dfo-spec-kit/commits/main/python +[unreleased]: https://github.com/DevelopmentFinanceObservatory/spec-kit/commits/main/python diff --git a/python/frame-grammar/CHANGELOG.md b/python/frame-grammar/CHANGELOG.md index c8fa83d..42815a5 100644 --- a/python/frame-grammar/CHANGELOG.md +++ b/python/frame-grammar/CHANGELOG.md @@ -172,4 +172,4 @@ and this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 slice of 8,192 rows. Bytes, digests, refusal categories and messages are unchanged. -[unreleased]: https://github.com/ONEcampaign/dfo-spec-kit/commits/main/python +[unreleased]: https://github.com/DevelopmentFinanceObservatory/spec-kit/commits/main/python diff --git a/python/provenance-docs/CHANGELOG.md b/python/provenance-docs/CHANGELOG.md index 83f2fbe..bf362fb 100644 --- a/python/provenance-docs/CHANGELOG.md +++ b/python/provenance-docs/CHANGELOG.md @@ -31,4 +31,4 @@ and this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Raise the `markdown-it-py` floor in `pyproject.toml` to the first release that contains that fix. -[unreleased]: https://github.com/ONEcampaign/dfo-spec-kit/commits/main/python +[unreleased]: https://github.com/DevelopmentFinanceObservatory/spec-kit/commits/main/python diff --git a/python/spec-kit/CHANGELOG.md b/python/spec-kit/CHANGELOG.md index a0220df..7b0ec81 100644 --- a/python/spec-kit/CHANGELOG.md +++ b/python/spec-kit/CHANGELOG.md @@ -368,4 +368,4 @@ and this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `invalid_unit_request` rather than passing validation. This deliberately corrects the reference implementation this package was extracted from. -[unreleased]: https://github.com/ONEcampaign/dfo-spec-kit/commits/main/python +[unreleased]: https://github.com/DevelopmentFinanceObservatory/spec-kit/commits/main/python From 45348fa8a6c6b2c49e5209923a8437659d60693e Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Thu, 15 Oct 2026 10:55:02 +0200 Subject: [PATCH 03/39] ci: run spec-kit CI on dev and main --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b604d64..2b64f0d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,12 +3,12 @@ name: CI # A draft pull request runs no jobs. `ready_for_review` is in the types so that # marking it ready starts the run: without it the skipped jobs would stand as # passing required checks on the commit and nothing would have tested it. A push -# to main still runs, as the only test of the merged tree. +# to dev or main still runs, as the only test of the merged tree. on: push: - branches: [main] + branches: [dev, main] pull_request: - branches: [main] + branches: [dev, main] types: [opened, synchronize, reopened, ready_for_review] jobs: From 1622945d2831faefa14c0976a76fa499e438bf49 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Thu, 15 Oct 2026 19:39:50 +0200 Subject: [PATCH 04/39] chore: point schema ids at the public repository Schema $id values now resolve under raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main, the manifest digest for intent.v0.json is recomputed, and the schema and tools READMEs and EXPORTS.md name the public repositories. --- python/descriptions/README.md | 2 +- .../vectors/descriptions-vector.schema.json | 2 +- python/dfo-spec-kit-components/CHANGELOG.md | 2 +- .../dfo_spec_kit_components/catalogue/manifest.json | 2 +- .../catalogue/schemas/intent.v0.json | 2 +- .../src/dfo_frame_grammar/vectors/frame/README.md | 2 +- .../vectors/frame/frame-vector.schema.json | 2 +- .../vectors/provenance-docs-vector.schema.json | 2 +- python/spec-kit/CHANGELOG.md | 7 +++++++ python/spec-kit/EXPORTS.md | 9 +++++---- python/spec-kit/src/dfo_spec_kit/models/__init__.py | 2 +- schemas/registry/README.md | 2 +- schemas/registry/code-registry.schema.json | 2 +- schemas/registry/unit-registry.schema.json | 2 +- schemas/spec/README.md | 2 +- schemas/vectors/README.md | 2 +- schemas/vectors/identity-vector.schema.json | 2 +- schemas/vectors/unit-vector.schema.json | 2 +- tools/README.md | 10 ++++++++-- 19 files changed, 36 insertions(+), 22 deletions(-) diff --git a/python/descriptions/README.md b/python/descriptions/README.md index 885cb8b..201231d 100644 --- a/python/descriptions/README.md +++ b/python/descriptions/README.md @@ -116,7 +116,7 @@ The size bound is on the stored list and `check_steps` checks it where the list ## Operations -`operations.json` lists, for each operation, its kind, whether it takes one input, inputs by role or none, its one fixed policy, the rule for the unit it produces, the coverage it records, and the data gaps it can leave out with what each counts. The analysis operations carry the policy names and exclusion reasons dfo-ai's analysis engine already uses. +`operations.json` lists, for each operation, its kind, whether it takes one input, inputs by role or none, its one fixed policy, the rule for the unit it produces, the coverage it records, and the data gaps it can leave out with what each counts. The analysis operations carry the policy names and exclusion reasons the `ai` repo's analysis engine already uses. | `op` | Kind | Inputs | Policy | Unit | Coverage | Known `left_out` reasons | | ----------------- | --------------- | -------------------------- | ----------------------------------- | ------------------------------------- | ---------- | -------------------------------------------------------------------------------------- | diff --git a/python/descriptions/src/dfo_descriptions/vectors/descriptions-vector.schema.json b/python/descriptions/src/dfo_descriptions/vectors/descriptions-vector.schema.json index da3e5d8..d653193 100644 --- a/python/descriptions/src/dfo_descriptions/vectors/descriptions-vector.schema.json +++ b/python/descriptions/src/dfo_descriptions/vectors/descriptions-vector.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://raw.githubusercontent.com/ONEcampaign/dfo-spec-kit/main/python/descriptions/src/dfo_descriptions/vectors/descriptions-vector.schema.json", + "$id": "https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/python/descriptions/src/dfo_descriptions/vectors/descriptions-vector.schema.json", "title": "Step and description vector record", "description": "One language-neutral conformance fixture: a step list or a description, and whether it is accepted, rejected by its JSON Schema, or rejected by the structure rules with a reason and a step position. See the README beside this schema.", "type": "object", diff --git a/python/dfo-spec-kit-components/CHANGELOG.md b/python/dfo-spec-kit-components/CHANGELOG.md index 38fdd77..6cfd8dc 100644 --- a/python/dfo-spec-kit-components/CHANGELOG.md +++ b/python/dfo-spec-kit-components/CHANGELOG.md @@ -108,7 +108,7 @@ and this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 descriptions suite's card-revision vector. `manifest.json` carries the refreshed digests of the fixture and of `description.schema.json`. -- The catalogue fixtures cite as dfo-apis composes citations: the +- The catalogue fixtures cite as the `apis` repo composes citations: the original sources and the year, then "via the Development Finance Observatory" ("OECD DAC (2026), via the Development Finance Observatory"). The note fixture reads "Development Finance Observatory diff --git a/python/dfo-spec-kit-components/src/dfo_spec_kit_components/catalogue/manifest.json b/python/dfo-spec-kit-components/src/dfo_spec_kit_components/catalogue/manifest.json index 7613b2e..53516b9 100644 --- a/python/dfo-spec-kit-components/src/dfo_spec_kit_components/catalogue/manifest.json +++ b/python/dfo-spec-kit-components/src/dfo_spec_kit_components/catalogue/manifest.json @@ -46,7 +46,7 @@ "schemas/component/stat_card.schema.json": "sha256:24d47ec4c2239553b833c3df2ba0ee4321f8bbf41abe2218a323762848ef1433", "schemas/component/table.schema.json": "sha256:7d7f39d04ff460f417d22b463c0b41146311597356029faac6eea5ea1ae43bc4", "schemas/envelope.schema.json": "sha256:933d59d992f8366395c6b8cded7c748d0f48f09b0a898185cb5d245b71b12c81", - "schemas/intent.v0.json": "sha256:7e080c273bae558535f66ab46964b48e991ae7974ff753429d32ab60529e5602" + "schemas/intent.v0.json": "sha256:397c36caa6950558eb5dccc82dc55bfe2077c70fd6dcca51758053c2f99fcd5d" }, "catalog_version": "2026.10.0", "encoding_classes": { diff --git a/python/dfo-spec-kit-components/src/dfo_spec_kit_components/catalogue/schemas/intent.v0.json b/python/dfo-spec-kit-components/src/dfo_spec_kit_components/catalogue/schemas/intent.v0.json index 2169f83..3bfd92a 100644 --- a/python/dfo-spec-kit-components/src/dfo_spec_kit_components/catalogue/schemas/intent.v0.json +++ b/python/dfo-spec-kit-components/src/dfo_spec_kit_components/catalogue/schemas/intent.v0.json @@ -1,7 +1,7 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "dfo/presentation/intent.v0", - "$comment": "Hand-maintained in this service until dfo-spec-kit's publication pipeline exists; the long-term home is dfo-spec-kit. $id names the grammar release and must match the assembler's release(). Selects are inlined per component, not shared through $defs: a $ref cannot specialize a bound (schema flatteners merge $ref siblings by overwrite), and shapes that differ in a bound are separate shapes. test_intent_schema.py pins the bounds the inlined selects share.", + "$comment": "Hand-maintained in this service until spec-kit's publication pipeline exists; the long-term home is spec-kit. $id names the grammar release and must match the assembler's release(). Selects are inlined per component, not shared through $defs: a $ref cannot specialize a bound (schema flatteners merge $ref siblings by overwrite), and shapes that differ in a bound are separate shapes. test_intent_schema.py pins the bounds the inlined selects share.", "oneOf": [ { "$ref": "#/$defs/line_chart" diff --git a/python/frame-grammar/src/dfo_frame_grammar/vectors/frame/README.md b/python/frame-grammar/src/dfo_frame_grammar/vectors/frame/README.md index 1dfe484..6d3db85 100644 --- a/python/frame-grammar/src/dfo_frame_grammar/vectors/frame/README.md +++ b/python/frame-grammar/src/dfo_frame_grammar/vectors/frame/README.md @@ -1,6 +1,6 @@ # python/frame-grammar/src/dfo_frame_grammar/vectors/frame -This is the frame grammar's golden vector suite: the language-neutral conformance target for `docs/frame-grammar-v1.md`. Where that document and these vectors disagree, **the vectors win**, and the disagreement is a release blocker. `frame-vector.schema.json` (draft 2020-12, `$id` `https://raw.githubusercontent.com/ONEcampaign/dfo-spec-kit/main/python/frame-grammar/src/dfo_frame_grammar/vectors/frame/frame-vector.schema.json`) validates every vector file in this directory. This document defines the frozen record format and the `format_version`. +This is the frame grammar's golden vector suite: the language-neutral conformance target for `docs/frame-grammar-v1.md`. Where that document and these vectors disagree, **the vectors win**, and the disagreement is a release blocker. `frame-vector.schema.json` (draft 2020-12, `$id` `https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/python/frame-grammar/src/dfo_frame_grammar/vectors/frame/frame-vector.schema.json`) validates every vector file in this directory. This document defines the frozen record format and the `format_version`. Every vector's expected output here is captured from this repository's own implementation (see "Adding a vector" below), not from an independent second implementation. This suite proves this implementation's own output has not drifted from a previously recorded value — a regression pin — not that `docs/frame-grammar-v1.md` is independently reproducible by a second implementation that has never read this code. That independent conformance evidence still needs a second implementation, in a different language, to be built and checked against this same suite. diff --git a/python/frame-grammar/src/dfo_frame_grammar/vectors/frame/frame-vector.schema.json b/python/frame-grammar/src/dfo_frame_grammar/vectors/frame/frame-vector.schema.json index d9b4814..2166c30 100644 --- a/python/frame-grammar/src/dfo_frame_grammar/vectors/frame/frame-vector.schema.json +++ b/python/frame-grammar/src/dfo_frame_grammar/vectors/frame/frame-vector.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://raw.githubusercontent.com/ONEcampaign/dfo-spec-kit/main/python/frame-grammar/src/dfo_frame_grammar/vectors/frame/frame-vector.schema.json", + "$id": "https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/python/frame-grammar/src/dfo_frame_grammar/vectors/frame/frame-vector.schema.json", "title": "Frame grammar vector record", "description": "One language-neutral conformance fixture for the frame grammar and content_version minting defined by docs/frame-grammar-v1.md: either a frame's role_keys/rows against its canonical bytes and minted content_version, or a frame_sha256 against its minted token -- or, for a negative vector, the same kind of input against the stable category it is refused under. See the README beside this schema for field semantics, the positive/negative split, the two record kinds, and the frozen failure_category vocabulary.", "type": "object", diff --git a/python/provenance-docs/src/dfo_provenance_docs/vectors/provenance-docs-vector.schema.json b/python/provenance-docs/src/dfo_provenance_docs/vectors/provenance-docs-vector.schema.json index c100d34..4ec0bb0 100644 --- a/python/provenance-docs/src/dfo_provenance_docs/vectors/provenance-docs-vector.schema.json +++ b/python/provenance-docs/src/dfo_provenance_docs/vectors/provenance-docs-vector.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://raw.githubusercontent.com/ONEcampaign/dfo-spec-kit/main/python/provenance-docs/src/dfo_provenance_docs/vectors/provenance-docs-vector.schema.json", + "$id": "https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/python/provenance-docs/src/dfo_provenance_docs/vectors/provenance-docs-vector.schema.json", "title": "Provenance documentation vector record", "description": "One language-neutral conformance fixture for the provenance documentation grammar: a stored graph value, the function it passes through, and either the parsed result or the error reason and line. See the README beside this schema.", "type": "object", diff --git a/python/spec-kit/CHANGELOG.md b/python/spec-kit/CHANGELOG.md index 7b0ec81..8e0e52a 100644 --- a/python/spec-kit/CHANGELOG.md +++ b/python/spec-kit/CHANGELOG.md @@ -58,6 +58,13 @@ and this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- The `$id` of `schemas/registry/code-registry.schema.json`, + `schemas/registry/unit-registry.schema.json`, + `schemas/vectors/identity-vector.schema.json` and + `schemas/vectors/unit-vector.schema.json` now sits under + `https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/`, + with each file's path unchanged. The previous prefix named a private + repository and did not resolve. - Codes `identity_quarantined` (500), `service_unavailable` (503) and `internal_error` (500) map to `datasets.description` at the statuses they have on `datasets.snapshot`. diff --git a/python/spec-kit/EXPORTS.md b/python/spec-kit/EXPORTS.md index 81c0805..1a04281 100644 --- a/python/spec-kit/EXPORTS.md +++ b/python/spec-kit/EXPORTS.md @@ -299,9 +299,10 @@ reason = "bundled-data" # --- dfo_spec_kit.models ----------------------------------------------- # The spec1 identity-core document and the canonical definition wrapping -# it. Extracted from dfo-apis's Search engine; the extraction commit is the -# provenance. Nothing display-shaped belongs here: a symbol carrying a -# graph-read label or a human-facing name is engine surface, not identity. +# it. Extracted from the `apis` repo's Search engine. The extraction +# commit is the provenance. Nothing display-shaped belongs here. A symbol +# carrying a graph-read label or a human-facing name is engine surface, not +# identity. [[export]] name = "BaseIdentity" module = "dfo_spec_kit.models" @@ -417,7 +418,7 @@ boundary, and their absence is a decision rather than an oversight. - **The resubmit edit input.** Its slots are the engine's display shape, which carries graph-read labels and human-facing names. It also has a reshape already planned — see rows C13, C14 and C18 of - `dfo-apis:docs/conformance-search-api-v1.md`. + `docs/conformance-search-api-v1.md` in the `apis` repo. - **The resolved-spec response payload.** One surface produces it, no surface outside that one consumes it, and it reuses the same display-shaped types as the edit input. diff --git a/python/spec-kit/src/dfo_spec_kit/models/__init__.py b/python/spec-kit/src/dfo_spec_kit/models/__init__.py index 96a2706..22b6571 100644 --- a/python/spec-kit/src/dfo_spec_kit/models/__init__.py +++ b/python/spec-kit/src/dfo_spec_kit/models/__init__.py @@ -1,5 +1,5 @@ """Spec models: identity core, canonical doc, resolved spec, edit input. -Extracted from `dfo-apis`'s `src/search/models.py`. Empty until that +Extracted from the `apis` repo's `src/search/models.py`. Empty until that extraction lands. """ diff --git a/schemas/registry/README.md b/schemas/registry/README.md index 657bb98..6a4fb60 100644 --- a/schemas/registry/README.md +++ b/schemas/registry/README.md @@ -2,7 +2,7 @@ The code registry assigns one permanent, language-neutral meaning to every warning and refusal code, so that every consumer of a contract, the engine, the harness, a website, a partner integration, reads the same meaning for the same code. -The registry holds wire codes from Search, Presentation, Datasets, Graph, and Skills, plus the platform-generic codes any contract can render. The platform's `GET /codes/{code}` lookup, mounted on every surface, serves only codes this registry carries. `schemas/registry/code-registry.schema.json` (draft 2020-12, `$id` `https://raw.githubusercontent.com/ONEcampaign/dfo-spec-kit/main/schemas/registry/code-registry.schema.json`) validates `registries/codes.json`. The `$id` sits under the repo's raw-content path because the kit has no schema-hosting service. Should one exist later, the `$id` moves and the old one is retired like any other schema identifier. +The registry holds wire codes from Search, Presentation, Datasets, Graph, and Skills, plus the platform-generic codes any contract can render. The platform's `GET /codes/{code}` lookup, mounted on every surface, serves only codes this registry carries. `schemas/registry/code-registry.schema.json` (draft 2020-12, `$id` `https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/schemas/registry/code-registry.schema.json`) validates `registries/codes.json`. The `$id` sits under the repo's raw-content path because the kit has no schema-hosting service. Should one exist later, the `$id` moves and the old one is retired like any other schema identifier. `registries/codes.json` is canonical. `python/spec-kit/src/dfo_spec_kit/registry/codes.json` is a byte-identical package mirror because `uv_build` only includes files within a package directory. `dfo_spec_kit.registry` loads the mirror through `CodeRegistry`, `CodeEntry`, and `CodeMapping`. `uv run tools/validate_registry.py` fails if the files diverge. diff --git a/schemas/registry/code-registry.schema.json b/schemas/registry/code-registry.schema.json index 6dc381f..5c46e24 100644 --- a/schemas/registry/code-registry.schema.json +++ b/schemas/registry/code-registry.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://raw.githubusercontent.com/ONEcampaign/dfo-spec-kit/main/schemas/registry/code-registry.schema.json", + "$id": "https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/schemas/registry/code-registry.schema.json", "title": "Platform code registry", "description": "Language-neutral registry of permanent warning and refusal codes across every API surface. See schemas/registry/README.md for field semantics, the addition rule, and the endpoint/door/channel vocabulary.", "type": "object", diff --git a/schemas/registry/unit-registry.schema.json b/schemas/registry/unit-registry.schema.json index 86a3020..d4873d8 100644 --- a/schemas/registry/unit-registry.schema.json +++ b/schemas/registry/unit-registry.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://raw.githubusercontent.com/ONEcampaign/dfo-spec-kit/main/schemas/registry/unit-registry.schema.json", + "$id": "https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/schemas/registry/unit-registry.schema.json", "title": "Unit registry", "description": "How unit refs read as typed units, for dfo_spec_kit.units. See registries/README.md for the rules this file declares. tools/validate_unit_registry.py checks sort order, uniqueness, the no-prefix-match rule and the package mirror, which this schema cannot express.", "type": "object", diff --git a/schemas/spec/README.md b/schemas/spec/README.md index 79f7af7..13b4e16 100644 --- a/schemas/spec/README.md +++ b/schemas/spec/README.md @@ -1,3 +1,3 @@ # schemas/spec -Committed JSON Schema exported from the pydantic models in `python/spec-kit/src/dfo_spec_kit/models`. This is the frozen centre of the dataset-spec family. CI fails when the generated schema drifts from the models it is exported from. Empty until the model extraction lands. +This directory holds only this README. It is the reserved location for JSON Schema exported from the pydantic models in `python/spec-kit/src/dfo_spec_kit/models`, which are empty until the model extraction lands. No export script exists, and CI runs no check on this directory. diff --git a/schemas/vectors/README.md b/schemas/vectors/README.md index 67ead2d..269a572 100644 --- a/schemas/vectors/README.md +++ b/schemas/vectors/README.md @@ -1,6 +1,6 @@ # schemas/vectors -The identity vector suite is the language-neutral conformance target for the identity projection and canonicalisation algorithm (`dfo_spec_kit.identity.core`). It is a set of fixtures that any implementation, in any language, must reproduce byte-for-byte and refusal-for-refusal. `schemas/vectors/identity-vector.schema.json` (draft 2020-12, `$id` `https://raw.githubusercontent.com/ONEcampaign/dfo-spec-kit/main/schemas/vectors/identity-vector.schema.json`) validates every file under `vectors/identity/`. The `$id` sits under the repo's own raw-content path for the same reason as the code registry's. The kit has no schema-hosting service yet, and a schema `$id` should stay stable once published, so it only moves the day a real hosting location exists. This document defines the frozen record format and the format_version. `vectors/identity/` carries the authored suite against a floor of at least 25 positive and negative vectors. `tools/validate_vectors.py` (see `tools/README.md`) checks every vector's well-formedness and internal byte/id consistency, and CI runs it on every push and pull request. +The identity vector suite is the language-neutral conformance target for the identity projection and canonicalisation algorithm (`dfo_spec_kit.identity.core`). It is a set of fixtures that any implementation, in any language, must reproduce byte-for-byte and refusal-for-refusal. `schemas/vectors/identity-vector.schema.json` (draft 2020-12, `$id` `https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/schemas/vectors/identity-vector.schema.json`) validates every file under `vectors/identity/`. The `$id` sits under the repo's own raw-content path for the same reason as the code registry's. The kit has no schema-hosting service yet, and a schema `$id` should stay stable once published, so it only moves the day a real hosting location exists. This document defines the frozen record format and the format_version. `vectors/identity/` carries the authored suite against a floor of at least 25 positive and negative vectors. `tools/validate_vectors.py` (see `tools/README.md`) checks every vector's well-formedness and internal byte/id consistency, and CI runs it on every push and pull request. ## Format diff --git a/schemas/vectors/identity-vector.schema.json b/schemas/vectors/identity-vector.schema.json index 4b52da4..2d0fd96 100644 --- a/schemas/vectors/identity-vector.schema.json +++ b/schemas/vectors/identity-vector.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://raw.githubusercontent.com/ONEcampaign/dfo-spec-kit/main/schemas/vectors/identity-vector.schema.json", + "$id": "https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/schemas/vectors/identity-vector.schema.json", "title": "Identity vector record", "description": "One language-neutral conformance fixture for the identity projection and canonicalisation defined by the identity specification: a single input exercised against the identity algorithm, with its expected outcome. An input_bytes vector exercises the algorithm from the strict parse stage onward; an input vector is already-parsed JSON and exercises the algorithm from the schema-validation stage onward. See schemas/vectors/README.md for field semantics, the positive/negative split, and the failure-category vocabulary.", "type": "object", diff --git a/schemas/vectors/unit-vector.schema.json b/schemas/vectors/unit-vector.schema.json index 5199815..ba2ec76 100644 --- a/schemas/vectors/unit-vector.schema.json +++ b/schemas/vectors/unit-vector.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://raw.githubusercontent.com/ONEcampaign/dfo-spec-kit/main/schemas/vectors/unit-vector.schema.json", + "$id": "https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/schemas/vectors/unit-vector.schema.json", "title": "Unit vector record", "description": "One language-neutral conformance fixture for the typed unit (dfo_spec_kit.units): a ref parsed to its typed value, two refs completed under one measurement qualifier and compared, or a ref's unstated prices completed from a measurement qualifier. See schemas/vectors/README.md, section 'Unit vectors'.", "type": "object", diff --git a/tools/README.md b/tools/README.md index 9ccb505..91f0700 100644 --- a/tools/README.md +++ b/tools/README.md @@ -1,6 +1,6 @@ # tools -Codegen and drift-check scripts (e.g. exporting `schemas/` from the pydantic models, checking generated artifacts against their committed source). +Validators for the registries and the conformance vector suites. Each script checks committed JSON against its schema and against the rules the schema cannot express. None of them generates files or imports the package whose vectors it checks. Their tests are in `tools/tests`. `validate_registry.py` validates `registries/codes.json` against `schemas/registry/code-registry.schema.json` (which enforces field shapes, the lower-snake-case code pattern, and the closed endpoint/door/channel vocabulary documented in `schemas/registry/README.md`) and checks what a JSON Schema cannot express on its own: code uniqueness, sort order, and classification/channel consistency. It is a PEP 723 script. Run it with: @@ -20,6 +20,12 @@ uv run tools/validate_unit_registry.py uv run tools/validate_vectors.py ``` +`validate_frame_vectors.py` validates every file under `python/frame-grammar/src/dfo_frame_grammar/vectors/frame/` against `frame-vector.schema.json` beside them, and checks what the schema cannot express: file names match names, names are unique, the suite meets its floor, both classifications are non-empty, vectors over one frame digest share one token and vectors over different digests mint different tokens, and every positive vector's stored bytes, digests and `content_version` are self-consistent. It never imports `dfo_frame_grammar`. `python/frame-grammar/tests/test_vectors.py` drives the real implementation. Also a PEP 723 script: + +```bash +uv run tools/validate_frame_vectors.py +``` + `validate_provenance_docs_vectors.py` validates every vector under `python/provenance-docs/src/dfo_provenance_docs/vectors/` against `provenance-docs-vector.schema.json` beside them, and checks what the schema cannot express: file names match ids, ids are unique, the suite meets its floor, every reason in the schema's vocabulary has a rejection vector, and every function has an accepting vector. It does not import `dfo_provenance_docs`. Also a PEP 723 script: ```bash @@ -38,4 +44,4 @@ uv run tools/validate_descriptions_vectors.py uv run tools/validate_unit_vectors.py ``` -CI runs every validator on every push and pull request against `main` (see `.github/workflows/ci.yml`'s `registry` job). +The `registry` job in `.github/workflows/ci.yml` runs all of them and `pytest tools/tests`. It runs on every pull request into `dev` or `main` and on every push to either branch. A draft pull request runs no jobs until it is marked ready for review. From 20cdb3500c02e2140ae7812c473006c245314543 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Mon, 19 Oct 2026 19:05:00 +0200 Subject: [PATCH 05/39] feat(codes): register the whole_total_available search warning registries/codes.json and its bundled mirror gain whole_total_available, a search.resolve warning on the raw_text, parsed and dataset_resubmit doors. It flags an answer that lists each member of a flow side whose dataset publishes the total of that side's whole population for the answer's years, so a sum of the listed members can differ from the published figure. --- python/spec-kit/CHANGELOG.md | 8 ++++++++ .../src/dfo_spec_kit/registry/codes.json | 20 +++++++++++++++++++ registries/codes.json | 20 +++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/python/spec-kit/CHANGELOG.md b/python/spec-kit/CHANGELOG.md index 7b0ec81..d67d590 100644 --- a/python/spec-kit/CHANGELOG.md +++ b/python/spec-kit/CHANGELOG.md @@ -55,6 +55,14 @@ and this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 that shares its StatVar with other codes of the same source, where the graph does not record what separates them, raises the third, naming the codes that share the variable. The retired `code_ambiguous` is unchanged. +- Code `whole_total_available` in `registries/codes.json` and its bundled + mirror: a `search.resolve` warning on the raw_text, parsed and + dataset_resubmit doors. It flags an answer that lists each member of a flow + side whose dataset publishes the total of that side's whole population for + the answer's years ("Official Donors, Total" in DAC2a and DAC2b, "All + Recipients, Total" in DAC2a from 1984), so a sum of the listed members can + differ from the published figure. Its params name the total (`total`, + `total_label`) and the kinds of party it holds (`whole_of`, comma-joined). ### Changed diff --git a/python/spec-kit/src/dfo_spec_kit/registry/codes.json b/python/spec-kit/src/dfo_spec_kit/registry/codes.json index 42fce0e..88853ef 100644 --- a/python/spec-kit/src/dfo_spec_kit/registry/codes.json +++ b/python/spec-kit/src/dfo_spec_kit/registry/codes.json @@ -5039,6 +5039,26 @@ ], "lifecycle": "active" }, + { + "code": "whole_total_available", + "classification": "warning", + "definition": "The answer lists each member of a flow side whose dataset publishes the total of that side's whole population for the answer's years, so a sum of the listed members can differ from the published figure. The params name the total (total, total_label) and the kinds of party it holds (whole_of, comma-joined).", + "owning_contract": "search", + "owner": "platform", + "introduced_in": "v1", + "mappings": [ + { + "endpoint": "search.resolve", + "doors": [ + "raw_text", + "parsed", + "dataset_resubmit" + ], + "channel": "diagnostics_warning" + } + ], + "lifecycle": "active" + }, { "code": "withheld_by_registry", "classification": "warning", diff --git a/registries/codes.json b/registries/codes.json index 42fce0e..88853ef 100644 --- a/registries/codes.json +++ b/registries/codes.json @@ -5039,6 +5039,26 @@ ], "lifecycle": "active" }, + { + "code": "whole_total_available", + "classification": "warning", + "definition": "The answer lists each member of a flow side whose dataset publishes the total of that side's whole population for the answer's years, so a sum of the listed members can differ from the published figure. The params name the total (total, total_label) and the kinds of party it holds (whole_of, comma-joined).", + "owning_contract": "search", + "owner": "platform", + "introduced_in": "v1", + "mappings": [ + { + "endpoint": "search.resolve", + "doors": [ + "raw_text", + "parsed", + "dataset_resubmit" + ], + "channel": "diagnostics_warning" + } + ], + "lifecycle": "active" + }, { "code": "withheld_by_registry", "classification": "warning", From ba3a9ec112ce679c920f0e0a7cac32499263f574 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Tue, 20 Oct 2026 15:33:08 +0200 Subject: [PATCH 06/39] docs(codes): name whole_total_available's whole_of values as member classes The warning's `whole_of` param lists the member classes the total covers: official, private or residual. --- python/spec-kit/CHANGELOG.md | 3 ++- python/spec-kit/src/dfo_spec_kit/registry/codes.json | 2 +- registries/codes.json | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/python/spec-kit/CHANGELOG.md b/python/spec-kit/CHANGELOG.md index 1e2d70a..7871bb1 100644 --- a/python/spec-kit/CHANGELOG.md +++ b/python/spec-kit/CHANGELOG.md @@ -62,7 +62,8 @@ and this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 the answer's years ("Official Donors, Total" in DAC2a and DAC2b, "All Recipients, Total" in DAC2a from 1984), so a sum of the listed members can differ from the published figure. Its params name the total (`total`, - `total_label`) and the kinds of party it holds (`whole_of`, comma-joined). + `total_label`) and the member classes it covers (`whole_of`: `official`, + `private` or `residual`, comma-joined). ### Changed diff --git a/python/spec-kit/src/dfo_spec_kit/registry/codes.json b/python/spec-kit/src/dfo_spec_kit/registry/codes.json index 88853ef..b087453 100644 --- a/python/spec-kit/src/dfo_spec_kit/registry/codes.json +++ b/python/spec-kit/src/dfo_spec_kit/registry/codes.json @@ -5042,7 +5042,7 @@ { "code": "whole_total_available", "classification": "warning", - "definition": "The answer lists each member of a flow side whose dataset publishes the total of that side's whole population for the answer's years, so a sum of the listed members can differ from the published figure. The params name the total (total, total_label) and the kinds of party it holds (whole_of, comma-joined).", + "definition": "The answer lists each member of a flow side whose dataset publishes the total of that side's whole population for the answer's years, so a sum of the listed members can differ from the published figure. The params name the total (total, total_label) and the member classes it covers (whole_of: official, private or residual, comma-joined).", "owning_contract": "search", "owner": "platform", "introduced_in": "v1", diff --git a/registries/codes.json b/registries/codes.json index 88853ef..b087453 100644 --- a/registries/codes.json +++ b/registries/codes.json @@ -5042,7 +5042,7 @@ { "code": "whole_total_available", "classification": "warning", - "definition": "The answer lists each member of a flow side whose dataset publishes the total of that side's whole population for the answer's years, so a sum of the listed members can differ from the published figure. The params name the total (total, total_label) and the kinds of party it holds (whole_of, comma-joined).", + "definition": "The answer lists each member of a flow side whose dataset publishes the total of that side's whole population for the answer's years, so a sum of the listed members can differ from the published figure. The params name the total (total, total_label) and the member classes it covers (whole_of: official, private or residual, comma-joined).", "owning_contract": "search", "owner": "platform", "introduced_in": "v1", From d22db46d20540238736351e768b48d39a8b0686f Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Tue, 20 Oct 2026 17:39:03 +0200 Subject: [PATCH 07/39] docs(codes): call whole_total_available's whole_of values party classes --- python/spec-kit/CHANGELOG.md | 2 +- python/spec-kit/src/dfo_spec_kit/registry/codes.json | 2 +- registries/codes.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/spec-kit/CHANGELOG.md b/python/spec-kit/CHANGELOG.md index 7871bb1..c7a8ec0 100644 --- a/python/spec-kit/CHANGELOG.md +++ b/python/spec-kit/CHANGELOG.md @@ -62,7 +62,7 @@ and this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 the answer's years ("Official Donors, Total" in DAC2a and DAC2b, "All Recipients, Total" in DAC2a from 1984), so a sum of the listed members can differ from the published figure. Its params name the total (`total`, - `total_label`) and the member classes it covers (`whole_of`: `official`, + `total_label`) and the party classes it covers (`whole_of`: `official`, `private` or `residual`, comma-joined). ### Changed diff --git a/python/spec-kit/src/dfo_spec_kit/registry/codes.json b/python/spec-kit/src/dfo_spec_kit/registry/codes.json index b087453..179d71e 100644 --- a/python/spec-kit/src/dfo_spec_kit/registry/codes.json +++ b/python/spec-kit/src/dfo_spec_kit/registry/codes.json @@ -5042,7 +5042,7 @@ { "code": "whole_total_available", "classification": "warning", - "definition": "The answer lists each member of a flow side whose dataset publishes the total of that side's whole population for the answer's years, so a sum of the listed members can differ from the published figure. The params name the total (total, total_label) and the member classes it covers (whole_of: official, private or residual, comma-joined).", + "definition": "The answer lists each member of a flow side whose dataset publishes the total of that side's whole population for the answer's years, so a sum of the listed members can differ from the published figure. The params name the total (total, total_label) and the party classes it covers (whole_of: official, private or residual, comma-joined).", "owning_contract": "search", "owner": "platform", "introduced_in": "v1", diff --git a/registries/codes.json b/registries/codes.json index b087453..179d71e 100644 --- a/registries/codes.json +++ b/registries/codes.json @@ -5042,7 +5042,7 @@ { "code": "whole_total_available", "classification": "warning", - "definition": "The answer lists each member of a flow side whose dataset publishes the total of that side's whole population for the answer's years, so a sum of the listed members can differ from the published figure. The params name the total (total, total_label) and the member classes it covers (whole_of: official, private or residual, comma-joined).", + "definition": "The answer lists each member of a flow side whose dataset publishes the total of that side's whole population for the answer's years, so a sum of the listed members can differ from the published figure. The params name the total (total, total_label) and the party classes it covers (whole_of: official, private or residual, comma-joined).", "owning_contract": "search", "owner": "platform", "introduced_in": "v1", From cbe2857c0b45d7311445cd578f0695ec4d3ab3d4 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Fri, 23 Oct 2026 13:15:04 +0200 Subject: [PATCH 08/39] feat(registry): map the datasets file selector and versions refusals (#10) * feat(registry): map the datasets file selector and versions refusals `GET /api/datasets/{id}/{content_version}/file` serves under `datasets.files` and refuses `request_invalid` (400), `excel_limit`, `excel_illegal_character`, `parquet_size_bound`, `rollup_not_summable` and `capability_unavailable` (422), and `internal_error` (500). The open `GET /api/datasets/{id}/versions` serves under `datasets.snapshot` and refuses `request_invalid` (400). The registry README names both routes. * fix(registry): map capability_unavailable on datasets.files to 501 The platform resolves one status per code, and every other endpoint answers capability_unavailable with 501. --- .../src/dfo_spec_kit/registry/codes.json | 40 +++++++++++++++++++ registries/codes.json | 40 +++++++++++++++++++ schemas/registry/README.md | 2 +- 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/python/spec-kit/src/dfo_spec_kit/registry/codes.json b/python/spec-kit/src/dfo_spec_kit/registry/codes.json index 179d71e..976cd64 100644 --- a/python/spec-kit/src/dfo_spec_kit/registry/codes.json +++ b/python/spec-kit/src/dfo_spec_kit/registry/codes.json @@ -283,6 +283,11 @@ "endpoint": "datasets.refresh", "channel": "problem_details", "http_status": 501 + }, + { + "endpoint": "datasets.files", + "channel": "problem_details", + "http_status": 501 } ], "lifecycle": "active" @@ -1194,6 +1199,11 @@ "endpoint": "datasets.definition", "channel": "problem_details", "http_status": 422 + }, + { + "endpoint": "datasets.files", + "channel": "problem_details", + "http_status": 422 } ], "lifecycle": "active" @@ -1215,6 +1225,11 @@ "endpoint": "datasets.definition", "channel": "problem_details", "http_status": 422 + }, + { + "endpoint": "datasets.files", + "channel": "problem_details", + "http_status": 422 } ], "lifecycle": "active" @@ -1644,6 +1659,11 @@ "endpoint": "datasets.refresh", "channel": "problem_details", "http_status": 500 + }, + { + "endpoint": "datasets.files", + "channel": "problem_details", + "http_status": 500 } ], "lifecycle": "active" @@ -2594,6 +2614,11 @@ "endpoint": "datasets.refresh", "channel": "problem_details", "http_status": 422 + }, + { + "endpoint": "datasets.files", + "channel": "problem_details", + "http_status": 422 } ], "lifecycle": "active" @@ -3269,6 +3294,16 @@ "endpoint": "datasets.description", "channel": "problem_details", "http_status": 400 + }, + { + "endpoint": "datasets.files", + "channel": "problem_details", + "http_status": 400 + }, + { + "endpoint": "datasets.snapshot", + "channel": "problem_details", + "http_status": 400 } ], "lifecycle": "active" @@ -3584,6 +3619,11 @@ "endpoint": "datasets.refresh", "channel": "problem_details", "http_status": 422 + }, + { + "endpoint": "datasets.files", + "channel": "problem_details", + "http_status": 422 } ], "lifecycle": "active" diff --git a/registries/codes.json b/registries/codes.json index 179d71e..976cd64 100644 --- a/registries/codes.json +++ b/registries/codes.json @@ -283,6 +283,11 @@ "endpoint": "datasets.refresh", "channel": "problem_details", "http_status": 501 + }, + { + "endpoint": "datasets.files", + "channel": "problem_details", + "http_status": 501 } ], "lifecycle": "active" @@ -1194,6 +1199,11 @@ "endpoint": "datasets.definition", "channel": "problem_details", "http_status": 422 + }, + { + "endpoint": "datasets.files", + "channel": "problem_details", + "http_status": 422 } ], "lifecycle": "active" @@ -1215,6 +1225,11 @@ "endpoint": "datasets.definition", "channel": "problem_details", "http_status": 422 + }, + { + "endpoint": "datasets.files", + "channel": "problem_details", + "http_status": 422 } ], "lifecycle": "active" @@ -1644,6 +1659,11 @@ "endpoint": "datasets.refresh", "channel": "problem_details", "http_status": 500 + }, + { + "endpoint": "datasets.files", + "channel": "problem_details", + "http_status": 500 } ], "lifecycle": "active" @@ -2594,6 +2614,11 @@ "endpoint": "datasets.refresh", "channel": "problem_details", "http_status": 422 + }, + { + "endpoint": "datasets.files", + "channel": "problem_details", + "http_status": 422 } ], "lifecycle": "active" @@ -3269,6 +3294,16 @@ "endpoint": "datasets.description", "channel": "problem_details", "http_status": 400 + }, + { + "endpoint": "datasets.files", + "channel": "problem_details", + "http_status": 400 + }, + { + "endpoint": "datasets.snapshot", + "channel": "problem_details", + "http_status": 400 } ], "lifecycle": "active" @@ -3584,6 +3619,11 @@ "endpoint": "datasets.refresh", "channel": "problem_details", "http_status": 422 + }, + { + "endpoint": "datasets.files", + "channel": "problem_details", + "http_status": 422 } ], "lifecycle": "active" diff --git a/schemas/registry/README.md b/schemas/registry/README.md index 6a4fb60..64825ab 100644 --- a/schemas/registry/README.md +++ b/schemas/registry/README.md @@ -59,7 +59,7 @@ Retiring a door is a schema change, reviewed as one: dropping a value from `code - **`endpoint`** lists the Search endpoints `search.resolve` (`POST /api/search/resolve`) and `search.options` (`POST /api/search/options`). - The Datasets endpoints are `datasets.register` (`POST /api/datasets/register`), `datasets.mint` (`POST /api/datasets`), `datasets.definition` (`GET /api/datasets/{id}`), `datasets.options` (`GET /api/datasets/{id}/options`, the write-free preview door), `datasets.members` (`POST /api/datasets/{id}/members`, the write-free member read), `datasets.snapshot` (`GET /api/datasets/{id}/{content_version}`), `datasets.files` (`GET /api/datasets/{id}/{content_version}/files/{digest}`, which answers a stored artifact with a 302 redirect to its download link), `datasets.description` (`GET /api/datasets/{id}/{content_version}/description`, a stored version's description, for a `spec_` id with a `cv_` version or an `ops_` id with an `ocv_` version, and `GET .../description/values`, which pages one dimension's values), `datasets.observations` (`GET /api/datasets/{id}/{content_version}/observations`, a stored version's observations), `datasets.pin` (`POST /api/datasets/{id}/{content_version}/pin`), `datasets.publish` (`POST /api/datasets/frames/publish`, the door an analysis service uses to publish an already-computed frame under its own identity pair), `datasets.recipe` (`PUT` and `GET /api/datasets/frames/{spec_id}/{content_version}/recipe`, the recorded computation behind a published frame, and `GET /api/datasets/recipes/replays/{replay_key}`, the frame stored under a replay key), `datasets.refresh` (`POST /api/datasets/frames/refresh`, which rebuilds a dataset frame's rendering on current data), and `datasets.operations` (`GET /api/datasets/operations/{operation_id}`). + The Datasets endpoints are `datasets.register` (`POST /api/datasets/register`), `datasets.mint` (`POST /api/datasets`), `datasets.definition` (`GET /api/datasets/{id}`), `datasets.options` (`GET /api/datasets/{id}/options`, the write-free preview door), `datasets.members` (`POST /api/datasets/{id}/members`, the write-free member read), `datasets.snapshot` (`GET /api/datasets/{id}/{content_version}`, and `GET /api/datasets/{id}/versions`, which pages a dataset's servable versions), `datasets.files` (`GET /api/datasets/{id}/{content_version}/files/{digest}`, which answers a stored artifact with a 302 redirect to its download link, and `GET /api/datasets/{id}/{content_version}/file`, which selects a stored version's file by format, bundle and layout, renders it when it is missing, and answers the same redirect), `datasets.description` (`GET /api/datasets/{id}/{content_version}/description`, a stored version's description, for a `spec_` id with a `cv_` version or an `ops_` id with an `ocv_` version, and `GET .../description/values`, which pages one dimension's values), `datasets.observations` (`GET /api/datasets/{id}/{content_version}/observations`, a stored version's observations), `datasets.pin` (`POST /api/datasets/{id}/{content_version}/pin`), `datasets.publish` (`POST /api/datasets/frames/publish`, the door an analysis service uses to publish an already-computed frame under its own identity pair), `datasets.recipe` (`PUT` and `GET /api/datasets/frames/{spec_id}/{content_version}/recipe`, the recorded computation behind a published frame, and `GET /api/datasets/recipes/replays/{replay_key}`, the frame stored under a replay key), `datasets.refresh` (`POST /api/datasets/frames/refresh`, which rebuilds a dataset frame's rendering on current data), and `datasets.operations` (`GET /api/datasets/operations/{operation_id}`). The Presentation endpoints are `presentation.write` (`POST /api/presentation/components`, `PATCH /api/presentation/components/{component_id}`) and `presentation.render` (`POST /api/presentation/components/{component_id}/revisions/{revision}/render` and `GET .../render/data`, which draw a stored revision on a named target frame and mint no revision). Search's and Datasets' `schema`, `capabilities`, and `healthz` routes and Presentation's read routes carry no permanent codes. From f85695a657011981e2c5e5b43901d01a2351ce7d Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Tue, 20 Oct 2026 17:32:15 +0200 Subject: [PATCH 09/39] feat(client-contract): add the DFO client contract distribution dfo-spec-kit-client-contract (import dfo_client_contract) holds what the DFO Python and TypeScript clients generate from and what dfo-apis checks its app against: the served OpenAPI document, the strict fields clients act on, the next step for every active refusal code, the scenario and DatasetRef record formats, and rule vectors for the credentials file, key format and cache directory. tools/validate_client_contract.py checks the package data against the code registry and the served document. --- .github/workflows/ci.yml | 6 + README.md | 9 +- .../client-contract/.pre-commit-config.yaml | 121 + python/client-contract/CHANGELOG.md | 17 + python/client-contract/README.md | 140 + python/client-contract/pyproject.toml | 143 + .../src/dfo_client_contract/__init__.py | 42 + .../src/dfo_client_contract/actions.json | 430 + .../dfo_client_contract/actions.schema.json | 58 + .../src/dfo_client_contract/contract.py | 113 + .../dataset-ref.schema.json | 123 + .../src/dfo_client_contract/py.typed | 0 .../refs/ref-answer-member.json | 97 + ...-definition-spec-id-mismatch-rejected.json | 96 + .../refs/ref-frame-layout.json | 96 + .../refs/ref-no-members-rejected.json | 12 + .../refs/ref-one-member.json | 95 + .../refs/ref-repeated-spec-id-rejected.json | 184 + .../refs/ref-server-rendering-rejected.json | 98 + .../src/dfo_client_contract/rules/README.md | 61 + .../dfo_client_contract/rules/cache-dir.json | 109 + .../rules/cache-layout.json | 46 + .../rules/credentials-file.json | 122 + .../rules/credentials-path.json | 94 + .../dfo_client_contract/rules/key-format.json | 62 + .../dfo_client_contract/rules/key-lookup.json | 110 + .../rules/rules.schema.json | 519 + .../dfo_client_contract/scenario.schema.json | 782 + .../scenarios/fetch-spec-known-sentence.json | 924 + .../fetch-spec-known-sentence.parquet | Bin 0 -> 9541 bytes .../scenarios/search-place-ambiguous.json | 219 + .../dfo_client_contract/served/SOURCE.json | 6 + .../dfo_client_contract/served/openapi.json | 20411 ++++++++++++++++ .../dfo_client_contract/strict-fields.json | 133 + .../strict-fields.schema.json | 67 + python/client-contract/tests/__init__.py | 0 python/client-contract/tests/test_contract.py | 45 + .../client-contract/tests/test_isolation.py | 36 + python/client-contract/tests/test_rules.py | 213 + python/client-contract/uv.lock | 567 + python/spec-kit/.pre-commit-config.yaml | 3 +- tools/README.md | 6 + tools/tests/test_validate_client_contract.py | 310 + tools/validate_client_contract.py | 679 + 44 files changed, 27400 insertions(+), 4 deletions(-) create mode 100644 python/client-contract/.pre-commit-config.yaml create mode 100644 python/client-contract/CHANGELOG.md create mode 100644 python/client-contract/README.md create mode 100644 python/client-contract/pyproject.toml create mode 100644 python/client-contract/src/dfo_client_contract/__init__.py create mode 100644 python/client-contract/src/dfo_client_contract/actions.json create mode 100644 python/client-contract/src/dfo_client_contract/actions.schema.json create mode 100644 python/client-contract/src/dfo_client_contract/contract.py create mode 100644 python/client-contract/src/dfo_client_contract/dataset-ref.schema.json create mode 100644 python/client-contract/src/dfo_client_contract/py.typed create mode 100644 python/client-contract/src/dfo_client_contract/refs/ref-answer-member.json create mode 100644 python/client-contract/src/dfo_client_contract/refs/ref-definition-spec-id-mismatch-rejected.json create mode 100644 python/client-contract/src/dfo_client_contract/refs/ref-frame-layout.json create mode 100644 python/client-contract/src/dfo_client_contract/refs/ref-no-members-rejected.json create mode 100644 python/client-contract/src/dfo_client_contract/refs/ref-one-member.json create mode 100644 python/client-contract/src/dfo_client_contract/refs/ref-repeated-spec-id-rejected.json create mode 100644 python/client-contract/src/dfo_client_contract/refs/ref-server-rendering-rejected.json create mode 100644 python/client-contract/src/dfo_client_contract/rules/README.md create mode 100644 python/client-contract/src/dfo_client_contract/rules/cache-dir.json create mode 100644 python/client-contract/src/dfo_client_contract/rules/cache-layout.json create mode 100644 python/client-contract/src/dfo_client_contract/rules/credentials-file.json create mode 100644 python/client-contract/src/dfo_client_contract/rules/credentials-path.json create mode 100644 python/client-contract/src/dfo_client_contract/rules/key-format.json create mode 100644 python/client-contract/src/dfo_client_contract/rules/key-lookup.json create mode 100644 python/client-contract/src/dfo_client_contract/rules/rules.schema.json create mode 100644 python/client-contract/src/dfo_client_contract/scenario.schema.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.parquet create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json create mode 100644 python/client-contract/src/dfo_client_contract/served/SOURCE.json create mode 100644 python/client-contract/src/dfo_client_contract/served/openapi.json create mode 100644 python/client-contract/src/dfo_client_contract/strict-fields.json create mode 100644 python/client-contract/src/dfo_client_contract/strict-fields.schema.json create mode 100644 python/client-contract/tests/__init__.py create mode 100644 python/client-contract/tests/test_contract.py create mode 100644 python/client-contract/tests/test_isolation.py create mode 100644 python/client-contract/tests/test_rules.py create mode 100644 python/client-contract/uv.lock create mode 100644 tools/tests/test_validate_client_contract.py create mode 100644 tools/validate_client_contract.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2b64f0d..cbfe334 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,8 @@ jobs: module: dfo_provenance_docs - package: python/descriptions module: dfo_descriptions + - package: python/client-contract + module: dfo_client_contract defaults: run: working-directory: ${{ matrix.package }} @@ -74,6 +76,7 @@ jobs: python/dfo-spec-kit-components, python/provenance-docs, python/descriptions, + python/client-contract, ] python-version: ["3.12", "3.13"] defaults: @@ -141,3 +144,6 @@ jobs: - name: Validate step and description vectors run: uv run tools/validate_descriptions_vectors.py + + - name: Validate the client contract + run: uv run tools/validate_client_contract.py diff --git a/README.md b/README.md index 7bede2f..38349fd 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,11 @@ The **component-spec family** (the presentation catalogue, composition schema, o ## Status -Five Python distributions exist so far. `python/spec-kit/` (`dfo-spec-kit`, import `dfo_spec_kit`): `identity/` implements the spec1 identity scheme (role-slot projection, JCS canonicalisation, SHA-256 `spec_id` minting), conformance-tested against the vector suite. `units/` reads a unit ref into a typed value (`Money`, `UnpricedMoney`, `Percent`, `Count` or `Other`) from `registries/units.json`, conformance-tested against `vectors/units/`. Money whose ref leaves prices unstated cannot be compared until `complete_prices` applies the StatVar's measurement qualifier, and constant-price money with no base year cannot be compared at all. `models/` has no code yet; model extraction comes next. `python/frame-grammar/` (`dfo-spec-kit-frame-grammar`, import `dfo_frame_grammar`): the frame grammar's executable form -- canonical frame bytes and `content_version` minting for a materialised observation table -- conformance-tested against its own vector suite, and depending on `dfo-spec-kit` for the identity canonicalisation primitives it reuses. `python/dfo-spec-kit-components/` (`dfo-spec-kit-components`, import `dfo_spec_kit_components`): the presentation contract bundle as package data, holding the envelope schema, the per-member component schemas, the write-side intent grammar, and their conformance fixtures. Generated Pydantic models for the catalogue land in this same package once the catalogue freezes. `python/provenance-docs/` (`dfo-spec-kit-provenance-docs`, import `dfo_provenance_docs`): the provenance documentation grammar, which decodes the escaped Markdown documents a Provenance node carries and parses the transformations, changelog, methodology and notes templates, conformance-tested against its own vector suite. `python/descriptions/` (`dfo-spec-kit-descriptions`, import `dfo_descriptions`): the step records and descriptions contract, holding the step schema, the operation list, the description schema and a check of the structure rules a step list must meet beyond its schema, conformance-tested against its own vector suite. +Six Python distributions exist so far. `python/spec-kit/` (`dfo-spec-kit`, import `dfo_spec_kit`): `identity/` implements the spec1 identity scheme (role-slot projection, JCS canonicalisation, SHA-256 `spec_id` minting), conformance-tested against the vector suite. `units/` reads a unit ref into a typed value (`Money`, `UnpricedMoney`, `Percent`, `Count` or `Other`) from `registries/units.json`, conformance-tested against `vectors/units/`. Money whose ref leaves prices unstated cannot be compared until `complete_prices` applies the StatVar's measurement qualifier, and constant-price money with no base year cannot be compared at all. `models/` has no code yet; model extraction comes next. `python/frame-grammar/` (`dfo-spec-kit-frame-grammar`, import `dfo_frame_grammar`): the frame grammar's executable form -- canonical frame bytes and `content_version` minting for a materialised observation table -- conformance-tested against its own vector suite, and depending on `dfo-spec-kit` for the identity canonicalisation primitives it reuses. `python/dfo-spec-kit-components/` (`dfo-spec-kit-components`, import `dfo_spec_kit_components`): the presentation contract bundle as package data, holding the envelope schema, the per-member component schemas, the write-side intent grammar, and their conformance fixtures. Generated Pydantic models for the catalogue land in this same package once the catalogue freezes. `python/provenance-docs/` (`dfo-spec-kit-provenance-docs`, import `dfo_provenance_docs`): the provenance documentation grammar, which decodes the escaped Markdown documents a Provenance node carries and parses the transformations, changelog, methodology and notes templates, conformance-tested against its own vector suite. `python/descriptions/` (`dfo-spec-kit-descriptions`, import `dfo_descriptions`): the step records and descriptions contract, holding the step schema, the operation list, the description schema and a check of the structure rules a step list must meet beyond its schema, conformance-tested against its own vector suite. `python/client-contract/` (`dfo-spec-kit-client-contract`, import `dfo_client_contract`): the contract the DFO Python and TypeScript clients are built to, as package data: the served OpenAPI document of the composed dfo-apis app, the response members the clients act on, the caller's next step for each refusal code, the scenario and `DatasetRef` formats with their records, and the client rules with their vectors. dfo-apis CI checks its app against the same files. -The Python distributions live at `python/spec-kit/`, `python/frame-grammar/`, `python/dfo-spec-kit-components/`, `python/provenance-docs/`, and `python/descriptions/`, each its own installable unit with its own version and dependency surface. A TypeScript package (`ts/`) opens only when the component catalogue freeze lands. +The Python distributions live at `python/spec-kit/`, `python/frame-grammar/`, `python/dfo-spec-kit-components/`, `python/provenance-docs/`, `python/descriptions/`, and `python/client-contract/`, each its own installable unit with its own version and dependency surface. A TypeScript package (`ts/`) opens only when the component catalogue freeze lands. -`dfo-spec-kit-frame-grammar` depends on `dfo-spec-kit` as an intra-repo path source rather than a git dependency, so the two packages develop together in this repo: a change to identity canonicalisation and a change here that depends on it land in the same commit. `dfo-spec-kit-components` depends on `dfo-spec-kit-descriptions` as an intra-repo path source, because the envelope's `description` references `description.schema.json` by its `$id`. A consumer pins both distributions at one revision. Its catalogue bundle is static data plus one accessor function, `bundle_dir()`. `dfo-spec-kit-provenance-docs` also stands alone, depending on `markdown-it-py` only. `dfo-spec-kit-descriptions` depends on `rfc8785` only. +`dfo-spec-kit-frame-grammar` depends on `dfo-spec-kit` as an intra-repo path source rather than a git dependency, so the two packages develop together in this repo: a change to identity canonicalisation and a change here that depends on it land in the same commit. `dfo-spec-kit-components` depends on `dfo-spec-kit-descriptions` as an intra-repo path source, because the envelope's `description` references `description.schema.json` by its `$id`. A consumer pins both distributions at one revision. Its catalogue bundle is static data plus one accessor function, `bundle_dir()`. `dfo-spec-kit-provenance-docs` also stands alone, depending on `markdown-it-py` only. `dfo-spec-kit-descriptions` depends on `rfc8785` only. `dfo-spec-kit-client-contract` depends on the standard library only. Publishing is undecided: no registry workflow exists for any package. Until that's resolved, install a Python package as a git dependency pinned to one commit, e.g. @@ -28,6 +28,7 @@ uv add "git+https://github.com/DevelopmentFinanceObservatory/spec-kit@#subd uv add "git+https://github.com/DevelopmentFinanceObservatory/spec-kit@#subdirectory=python/dfo-spec-kit-components" uv add "git+https://github.com/DevelopmentFinanceObservatory/spec-kit@#subdirectory=python/provenance-docs" uv add "git+https://github.com/DevelopmentFinanceObservatory/spec-kit@#subdirectory=python/descriptions" +uv add "git+https://github.com/DevelopmentFinanceObservatory/spec-kit@#subdirectory=python/client-contract" ``` A package's metadata names its intra-repo dependency by distribution name alone, and no index serves these distributions. uv reads the path source in `[tool.uv.sources]` and resolves the dependency from the same checkout, so `uv add` of `frame-grammar` or `dfo-spec-kit-components` alone installs `dfo-spec-kit` or `dfo-spec-kit-descriptions` at that commit. Every other installer reads the bare name and fails, so name both distributions at the same commit: @@ -68,6 +69,8 @@ dfo-spec-kit/ │ # the provenance documentation grammar and its vector suite as package data ├── python/descriptions/ # the dfo-spec-kit-descriptions package (import dfo_descriptions), │ # the step and description schemas, the operation list and their vector suite as package data +├── python/client-contract/ # the dfo-spec-kit-client-contract package (import dfo_client_contract), +│ # the served OpenAPI document, strict fields, caller actions, scenarios, ref format and client rules as package data ├── policies/ # compatibility policy per artifact family └── tools/ # codegen + drift-check scripts, including the registry and vector validators ``` diff --git a/python/client-contract/.pre-commit-config.yaml b/python/client-contract/.pre-commit-config.yaml new file mode 100644 index 0000000..60bef61 --- /dev/null +++ b/python/client-contract/.pre-commit-config.yaml @@ -0,0 +1,121 @@ +# Pre-commit hooks for Python + data repos +# Install dev deps: uv sync --group dev +# Enable hooks: pre-commit install +# Run all files: pre-commit run --all-files +# Update hooks: pre-commit autoupdate +# Skip once: git commit --no-verify + +repos: + # --------------------------------------------------------------------------- + # Ruff: fast linter + formatter + # --------------------------------------------------------------------------- + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.15.21 + hooks: + - id: ruff-check + args: [--fix] + files: ^python/client-contract/ + - id: ruff-format + files: ^python/client-contract/ + + # --------------------------------------------------------------------------- + # Core hygiene, JSON/YAML/TOML, security + # --------------------------------------------------------------------------- + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + # Whitespace & endings + - id: trailing-whitespace + args: [--markdown-linebreak-ext=md] + - id: end-of-file-fixer + - id: mixed-line-ending + args: [--fix=lf] + + # Conflicts & platform quirks + - id: check-case-conflict + - id: check-merge-conflict + + # Python sanity + - id: debug-statements + - id: check-ast + - id: check-shebang-scripts-are-executable + - id: check-builtin-literals + - id: check-docstring-first + + # Config/data formats + - id: check-json + - id: pretty-format-json + args: [--autofix, --indent=2, --no-sort-keys, --no-ensure-ascii] + exclude: | + (?x)^( + \.idea/.*| + \.vscode/.* + )$ + - id: check-yaml + args: [--allow-multiple-documents] + - id: check-toml + + # Basic secret hygiene + - id: detect-private-key + + # Large files (1MB) with sensible excludes + - id: check-added-large-files + args: [--maxkb=5000] + exclude: | + (?x)^( + .*\.parquet| + .*\.feather| + uv\.lock + )$ + + # --------------------------------------------------------------------------- + # Type checking (uses settings from pyproject.toml) + # --------------------------------------------------------------------------- + - repo: local + hooks: + - id: ty + name: ty type check + language: system + entry: bash -c 'cd python/client-contract && uv run ty check' + types: [python] + files: ^python/client-contract/ + pass_filenames: false + + # --------------------------------------------------------------------------- + # Spelling (docs + code comments) + # --------------------------------------------------------------------------- + - repo: https://github.com/codespell-project/codespell + rev: v2.4.3 + hooks: + - id: codespell + args: [--write-changes] + # The contract files are data: served bodies, keys and codes read as + # misspellings, and --write-changes would rewrite them. + exclude: | + (?x)^( + .*\.lock| + .*\.parquet| + .*\.feather| + .*/dfo_client_contract/.*\.json + )$ + + # --------------------------------------------------------------------------- + # GitHub Actions linting + # --------------------------------------------------------------------------- + - repo: https://github.com/rhysd/actionlint + rev: v1.7.12 + hooks: + - id: actionlint + + # --------------------------------------------------------------------------- + # Markdown formatting (GFM + front matter) + # --------------------------------------------------------------------------- + - repo: https://github.com/hukkin/mdformat + rev: 1.0.0 + hooks: + - id: mdformat + additional_dependencies: + - mdformat-gfm>=1.0.0 + - mdformat-frontmatter>=2.1.0 + # Example: limit to docs if desired + # files: ^(README\.md|docs/|.*/README\.md)$ diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md new file mode 100644 index 0000000..b18b85d --- /dev/null +++ b/python/client-contract/CHANGELOG.md @@ -0,0 +1,17 @@ +# Changelog + +All notable changes to the `dfo-spec-kit-client-contract` Python package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added + +- Package scaffolding (uv, ruff, ty, pytest). +- `served/openapi.json`, the composed dfo-apis app's OpenAPI document, and `served/SOURCE.json`, naming dfo-apis commit `8408f1f95c622223f8fa6e9ba55826ee8e22a852`. +- `strict-fields.json` and its schema: 25 members that stay required and non-nullable, and the answer kinds, part statuses and operation statuses the clients branch on. +- `actions.json` and its schema: the caller's next step for each of the 101 active refusal codes on `problem_details` or `no_data_reason`, with the gap kind of each no_data reason. +- `scenario.schema.json`, the scenario record, and two recorded scenarios: a place that matches two countries, and a fetch of a spec whose sentence the client holds, with its Parquet body. +- `dataset-ref.schema.json`, the frozen `DatasetRef` format, with accepted and rejected examples. +- The client rules and their vectors: the credentials path and file format, the key lookup order, the key format check, and the cache directory and layout. + +[unreleased]: https://github.com/DevelopmentFinanceObservatory/spec-kit/commits/main/python diff --git a/python/client-contract/README.md b/python/client-contract/README.md new file mode 100644 index 0000000..f94ab90 --- /dev/null +++ b/python/client-contract/README.md @@ -0,0 +1,140 @@ +# dfo-spec-kit-client-contract (Python) + +This package holds the contract the DFO clients are built to: the Python client `development-finance` and the TypeScript client `@developmentfinance/client`. The clients generate their wire types, strict checks and error maps from these files and replay the scenarios. dfo-apis CI checks its app against the same files, so a server change that breaks a client fails there first. The files below are normative; where this README and the files disagree, the files win and the disagreement is a bug. See the [repo README](../../README.md) for how this package fits with the rest of `dfo-spec-kit`. + +The import name is `dfo_client_contract`. It depends on the standard library only. + +## Installation + +This package uses [uv](https://docs.astral.sh/uv/) for dependency management. + +```bash +uv sync +``` + +## Development + +```bash +# Run tests +uv run pytest + +# Lint +uv run ruff check . + +# Format +uv run ruff format . + +# Type check +uv run ty check src/dfo_client_contract +``` + +## Contents + +`src/dfo_client_contract/` ships with the package. Each schema's `$id` is its path under `https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/python/client-contract/src/dfo_client_contract/`, as the kit's other schemas are, because the kit has no schema-hosting service. + +| File | Holds | +| --------------------------- | ------------------------------------------------------------------------------------- | +| `served/openapi.json` | The composed dfo-apis app's OpenAPI document, which both clients generate types from | +| `served/SOURCE.json` | The dfo-apis repository and commit `served/openapi.json` was captured from | +| `strict-fields.json` | The response members the clients act on | +| `strict-fields.schema.json` | The shape of `strict-fields.json` | +| `actions.json` | The caller's next step for each refusal code, and the gap kind of each no_data reason | +| `actions.schema.json` | The shape of `actions.json` | +| `scenario.schema.json` | One scenario record | +| `scenarios/` | The scenario records, and the binary response bodies they name | +| `dataset-ref.schema.json` | The frozen `DatasetRef` format | +| `refs/` | Accepted and rejected `DatasetRef` examples | +| `rules/` | The client rules, one vector file each, with `rules.schema.json` and the rules' text | + +| Function | Returns | +| ----------------- | ----------------------------------------------------------- | +| `openapi()` | `served/openapi.json`, parsed | +| `served_source()` | `served/SOURCE.json`, parsed | +| `strict_fields()` | `strict-fields.json`, parsed | +| `actions()` | `actions.json`, parsed | +| `scenarios()` | Every scenario record; raises `RuntimeError` when none load | +| `ref_examples()` | Every `DatasetRef` example; raises `RuntimeError` when none | +| `rule(name)` | The vector file for one of `RULES` | +| `contract_dir()` | The installed contract directory | +| `*_schema()` | Each schema, parsed | + +## Served document + +`served/openapi.json` is `app.openapi()` of the composed dfo-apis app, every surface mounted. `served/SOURCE.json` names the commit it came from as `{format_version, repository, commit, captured_from}`. It names the closed runtime models, `Manifest`, `ArtifactEntryModel`, every Search part model and `ProblemDetails` among them, which the per-surface schema routes leave open. Both clients generate wire types from it and parse tolerantly regardless of its `additionalProperties: false`: an unknown member or enum value passes through. + +## Strict fields + +`strict-fields.json` lists the members a client cannot act without. Each pointer names one property of one component schema, `/components/schemas//properties/`. A `required` entry stays in its schema's `required` list and admits no null, so a client raises `ContractError` when one is missing or null. An `enums` entry keeps every listed value, the values a client branches on: the answer kinds, the part statuses and the operation statuses. A client still accepts a value no entry lists. + +The required members are each part's `status` and its payload (`spec`, `candidates`, `no_data`, `unsupported`), `Resolution.parts`, `CandidateSet.specs`, `NoData.reason`, `Unsupported.code`, `Spec.spec_id` and `definition`, `SpecDefinition.spec_id`, the manifest's `definition`, `definition.spec_id`, `content_version` and `artifacts`, each artifact's `artifact_digest`, `rendering` and `url`, and the operation resource's `operation`, `operation_id` and `status`. The operation's `poll` is nullable in the served document, so a client builds the poll path from `operation_id`. + +## Actions + +`actions.json` has one row per active refusal code in `registries/codes.json` that reaches a problem document (`problem_details`) or a no_data part's `reason` (`no_data_reason`), sorted by code. `action` is the caller's next step, and each client maps it to one error class. + +| `action` | Error class | The caller | +| --------------------- | ------------------------- | ------------------------------------------------ | +| `fix_request` | `InvalidRequestError` | Changes the request | +| `check_id` | `NotFoundError` | Checks the spec, version, operation or other id | +| `choose` | `IncompleteAnswerError` | Chooses among the gap's options | +| `ask_data_question` | `IncompleteAnswerError` | Asks the question another way | +| `take_newest_version` | `VersionUnavailableError` | Takes the newest version | +| `log_in` | `AuthenticationError` | Logs in | +| `request_scope` | `PermissionDeniedError` | Asks for the permission the call needs | +| `wait` | `RateLimitError` | Waits, then retries | +| `wait_for_reset` | `QuotaExceededError` | Waits for the quota to reset | +| `report` | `ServerError` | Reports the trace id, after the client's retries | +| `upgrade` | `ContractError` | Upgrades the client | + +A code that maps to `no_data_reason` also carries `gap_kind`, the kind of gap a no_data part with that reason becomes: `choice`, `no_data`, `not_understood` or `unsupported`. `choose` goes with `choice` and only with it. `choose` and `ask_data_question` name a next step inside an answer, so a code that also reaches a problem document takes another action. A client maps an unknown code on its HTTP status, and a no_data reason with no row becomes a `no_data` gap. + +An answer's gaps follow from its parts. A candidates part is a `choice` gap, its options the candidates. A no_data part is a gap of its reason's `gap_kind`, its options the no_data `options`, and of kind `timed_out` instead when the answer's `diagnostics.timed_out` is true. An unsupported part is an `unsupported` gap. A part whose status a client does not know is an `unknown` gap. + +## Scenarios + +A scenario is one client-level call, the HTTP exchanges it makes, and the outcome each step reaches. Each record is one file, `scenarios/.json`, validated by `scenario.schema.json`. + +| Member | Holds | +| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `format_version` | `1` | +| `name` | The kebab-case name, equal to the file name's stem | +| `description` | One or two sentences on what the scenario proves | +| `origin` | `recorded`, with the `base_url`, the deployed `dfo_commit` and `recorded_at`; or `synthetic`, with the recorded scenario it is `derived_from` and a one-line `edit` | +| `call` | The steps, in order: `search`; `choose`; `fetch` of the previous answer, of a `spec` with `window`, `entities` and `facets`, or of a `ref`; `mint`; `result` | +| `exchanges` | The requests the call makes, in order, each with the response to give | +| `expect` | One outcome per step: an `answer`, a `dataset`, an `operation` or an `error` | + +A step that acts on an earlier result follows one: `choose` and a `fetch` with no target follow `search` or `choose`, and `result` follows `mint`. A `spec` in a step holds `spec_id`, the server's unmodified `definition`, and the `sentence` when the client knows it. + +An exchange's request names its target in one of three ways. `path` is a path the client composes under the base URL, such as `/search/resolve`. `origin_path` is a root-relative URL the server returned, such as an artifact's `url`, which resolves against the base URL's origin and never against its path. `url` is an absolute URL outside the API, such as the signed storage URL a files route redirects to, which the client fetches with a bare request carrying no client header and no key. `json` holds the request body members that must match; a recorded scenario lists every member the client sent. The response gives `status`, the `headers` a client reads, and a `json` body or a `body_file`, a binary body in `scenarios/` whose name starts with the scenario's name. + +An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column. An error outcome gives the error `class` and the problem's `code`, or null when no problem document carries the error. + +A recorded scenario's request and response bodies validate against their route's schemas in `served/openapi.json`, with one allowance: a required member whose schema admits null may be absent, because the server leaves null members out of the bodies it serves. + +A client replays a scenario by serving the exchanges in order: + +- A request matches the next exchange on its method and target, and on each listed `json` member, compared as parsed JSON values. +- A request with no exchange left, or one that matches none, fails the scenario, and so does an exchange the call never makes. +- `path` resolves against the base URL the replay gives the client, and `origin_path` against that base URL's origin, so a replay can run under any base URL form. +- Sleeps are not replayed: the replay injects the client's clock and sleep, and each wait the client asks for advances the clock at once. +- A recorded signed storage URL keeps its scheme, host and path, and its query reads `X-Goog-Signature=redacted`. + +## DatasetRef + +`dataset-ref.schema.json` is the frozen format a client writes for `data.ref` and reads back in any language: `format_version: 1` and one or more `members`, each `{parts, sentence, spec: {spec_id, definition}, content_version, artifact: {digest, rendering}}`. `parts` holds the variable text of each answer part the member answers, in query order, and is empty for a spec fetched outside an answer. `rendering` is the selector a client matches an artifact on, `{format, bundle}` with `layout: "frame"` for the frame layout, never the server's rendering object. Beyond the schema, each member's `definition.spec_id` equals its `spec.spec_id`, and members hold distinct `spec_id`s. `refs/` holds accepted examples and rejected ones, each `{format_version, name, description, ref}` with `expect: "accept"` or `error`, `{by: "schema"}` or `{by: "rule", reason}`, the reason `definition_spec_id_mismatch` or `repeated_spec_id`. + +## Rules + +`rules/README.md` states the rules every client implements the same way: the credentials path and file format, the key lookup order, the key format check, and the cache directory and layout. Each rule's vectors are in `rules/.json`. + +## Validation + +```bash +# Validate the contract against its schemas, the served document and the code registry, +# without importing this package +uv run ../../tools/validate_client_contract.py + +# Replay the rule vectors through a reference implementation of each rule +uv run pytest tests/test_rules.py +``` diff --git a/python/client-contract/pyproject.toml b/python/client-contract/pyproject.toml new file mode 100644 index 0000000..d613df2 --- /dev/null +++ b/python/client-contract/pyproject.toml @@ -0,0 +1,143 @@ +[project] +name = "dfo-spec-kit-client-contract" +version = "0.1.0" +description = "The DFO client contract: the served OpenAPI document, the strict fields, the caller actions per refusal code, the scenario and DatasetRef formats, the client rules and their vectors, shipped as package data." +authors = [ + { name = "ONE Campaign" } +] +readme = "README.md" +requires-python = ">=3.12" +dependencies = [] + +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", +] + +[build-system] +requires = ["uv_build>=0.11.29,<0.12"] +build-backend = "uv_build" + +[tool.uv.build-backend] +# The distribution name (dfo-spec-kit-client-contract) does not match the +# import name (dfo_client_contract) uv_build would otherwise infer it from, so +# it is pinned explicitly. +module-name = ["dfo_client_contract"] +# uv_build ships every non-.py file under the module root by default; this +# pins the contract files explicitly. +source-include = [ + "src/dfo_client_contract/*.json", + "src/dfo_client_contract/served/*.json", + "src/dfo_client_contract/scenarios/*", + "src/dfo_client_contract/refs/*.json", + "src/dfo_client_contract/rules/*", +] + +[dependency-groups] +dev = [ + "pytest>=9.1.0", + "pytest-cov>=7.1.0", + "ty>=0.0.59", + "ruff>=0.15.0", + "pre-commit>=4.6.0", + "jsonschema>=4.23", + "referencing>=0.36", +] + +[tool.ruff] +# Deliberate: kit standard is 88, not 100. +line-length = 88 +target-version = "py312" +extend-include = ["*.ipynb"] + +exclude = [ + ".git", + ".venv", + "venv", + "__pycache__", + "build", + "dist", + "*.egg-info", + ".pytest_cache", + "htmlcov", +] + +[tool.ruff.lint] +select = [ + "E", "W", "F", # pycodestyle, pyflakes + "I", # isort + "N", # pep8-naming + "UP", # pyupgrade + "B", # bugbear + "C4", # comprehensions + "SIM", # simplify + "PL", # pylint + "RUF", # ruff-specific + "ERA", # eradicate (commented-out code) + "PERF", # perflint + "ANN", # flake8-annotations (require type hints on public APIs) +] + +ignore = [ + "E501", # Line length (formatter handles) + "PLR0913", # Too many arguments + "PLR0912", # Too many branches + "PLR0914", # Too many locals + "PLR0915", # Too many statements + "PLR2004", # Magic values + "ANN401", # Allow `Any` in typed signatures +] + +# Allow autofix for all enabled rules +fixable = ["ALL"] +unfixable = [] + +[tool.ruff.lint.per-file-ignores] +# Tests don't need annotations or pylint-complexity gates. +"tests/**/*.py" = ["ANN", "PLR2004"] +# Notebooks: don't require annotations; allow REPL-style patterns. +"**/*.ipynb" = ["ANN", "F401", "F811", "E402"] + +[tool.ruff.lint.pydocstyle] +convention = "google" + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" +skip-magic-trailing-comma = false +line-ending = "auto" + +[tool.ty.environment] +python-version = "3.12" + +[tool.ty.src] +include = ["src/dfo_client_contract"] + +[tool.pytest.ini_options] +testpaths = ["tests"] +python_files = ["test_*.py"] +addopts = "-v --cov=src/dfo_client_contract --cov-report=term --cov-report=xml" + +[tool.coverage.run] +source = ["src"] +branch = true +omit = [ + "*/tests/*", + "*/__pycache__/*", +] + +[tool.coverage.report] +exclude_lines = [ + "pragma: no cover", + "def __repr__", + "def __str__", + "raise AssertionError", + "raise NotImplementedError", + "if __name__ == .__main__.:", + "if TYPE_CHECKING:", +] +show_missing = true +precision = 2 diff --git a/python/client-contract/src/dfo_client_contract/__init__.py b/python/client-contract/src/dfo_client_contract/__init__.py new file mode 100644 index 0000000..676df89 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/__init__.py @@ -0,0 +1,42 @@ +"""The DFO client contract. + +Ships, as package data, what the DFO Python and TypeScript clients generate +from and replay: the served OpenAPI document, the strict fields, the caller +action for each refusal code, the scenario and DatasetRef formats with their +records, and the client rules with their vectors. Every accessor reads the +installed files through `importlib.resources`. +""" + +from dfo_client_contract.contract import ( + RULES, + actions, + actions_schema, + contract_dir, + dataset_ref_schema, + openapi, + ref_examples, + rule, + rules_schema, + scenario_schema, + scenarios, + served_source, + strict_fields, + strict_fields_schema, +) + +__all__ = [ + "RULES", + "actions", + "actions_schema", + "contract_dir", + "dataset_ref_schema", + "openapi", + "ref_examples", + "rule", + "rules_schema", + "scenario_schema", + "scenarios", + "served_source", + "strict_fields", + "strict_fields_schema", +] diff --git a/python/client-contract/src/dfo_client_contract/actions.json b/python/client-contract/src/dfo_client_contract/actions.json new file mode 100644 index 0000000..e8c8ba3 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/actions.json @@ -0,0 +1,430 @@ +{ + "format_version": 1, + "codes": [ + { + "code": "artifact_expired", + "action": "take_newest_version" + }, + { + "code": "artifact_not_found", + "action": "check_id" + }, + { + "code": "binding_invalid", + "action": "fix_request" + }, + { + "code": "binding_mismatch", + "action": "ask_data_question", + "gap_kind": "no_data" + }, + { + "code": "capability_unavailable", + "action": "fix_request" + }, + { + "code": "children_anchor_ambiguous", + "action": "fix_request" + }, + { + "code": "children_anchor_required", + "action": "fix_request" + }, + { + "code": "code_not_found", + "action": "check_id" + }, + { + "code": "collection_probe_ceiling", + "action": "fix_request" + }, + { + "code": "column_not_droppable", + "action": "fix_request" + }, + { + "code": "column_unknown", + "action": "fix_request" + }, + { + "code": "constraint_violation", + "action": "fix_request" + }, + { + "code": "default_facet_undefined", + "action": "fix_request" + }, + { + "code": "definition_not_reproducible", + "action": "fix_request" + }, + { + "code": "denominator_not_available", + "action": "ask_data_question", + "gap_kind": "no_data" + }, + { + "code": "directional_children_unsupported", + "action": "fix_request" + }, + { + "code": "door_not_implemented", + "action": "upgrade" + }, + { + "code": "edit_conflict", + "action": "fix_request" + }, + { + "code": "entities_unbound", + "action": "fix_request" + }, + { + "code": "entity_ambiguous", + "action": "choose", + "gap_kind": "choice" + }, + { + "code": "entity_not_resolved", + "action": "ask_data_question", + "gap_kind": "not_understood" + }, + { + "code": "entity_role_not_admitted", + "action": "ask_data_question", + "gap_kind": "unsupported" + }, + { + "code": "entity_set_too_large", + "action": "ask_data_question", + "gap_kind": "unsupported" + }, + { + "code": "exact_binding_unsupported", + "action": "fix_request" + }, + { + "code": "excel_illegal_character", + "action": "fix_request" + }, + { + "code": "excel_limit", + "action": "fix_request" + }, + { + "code": "excluded_by_registry", + "action": "fix_request" + }, + { + "code": "facet_binding_unsupported", + "action": "fix_request" + }, + { + "code": "facet_not_available", + "action": "fix_request", + "gap_kind": "no_data" + }, + { + "code": "facet_probe_ceiling", + "action": "fix_request" + }, + { + "code": "frame_not_refreshable", + "action": "fix_request" + }, + { + "code": "frame_unavailable", + "action": "check_id" + }, + { + "code": "identity_collision", + "action": "report" + }, + { + "code": "identity_quarantined", + "action": "report" + }, + { + "code": "internal_error", + "action": "report" + }, + { + "code": "invalid_role_ref", + "action": "fix_request" + }, + { + "code": "member_not_resolvable", + "action": "fix_request" + }, + { + "code": "members_not_held", + "action": "report" + }, + { + "code": "method_not_allowed", + "action": "fix_request" + }, + { + "code": "mixed_peers_anchor_types", + "action": "fix_request" + }, + { + "code": "no_matching_slice", + "action": "ask_data_question", + "gap_kind": "no_data" + }, + { + "code": "no_observations", + "action": "ask_data_question", + "gap_kind": "no_data" + }, + { + "code": "node_not_held", + "action": "check_id" + }, + { + "code": "not_found", + "action": "check_id" + }, + { + "code": "observations_unavailable", + "action": "fix_request" + }, + { + "code": "open_role_unavailable", + "action": "fix_request" + }, + { + "code": "operation_failed", + "action": "report" + }, + { + "code": "operation_not_found", + "action": "check_id" + }, + { + "code": "option_target_invalid", + "action": "fix_request" + }, + { + "code": "over_ceiling", + "action": "fix_request" + }, + { + "code": "parquet_size_bound", + "action": "fix_request" + }, + { + "code": "pin_not_permitted", + "action": "request_scope" + }, + { + "code": "pivot_not_homogeneous", + "action": "fix_request" + }, + { + "code": "pivot_not_unique", + "action": "fix_request" + }, + { + "code": "pivot_over_cell_cap", + "action": "fix_request" + }, + { + "code": "pivot_over_column_cap", + "action": "fix_request" + }, + { + "code": "population_empty", + "action": "fix_request" + }, + { + "code": "provider_ambiguous", + "action": "fix_request" + }, + { + "code": "publish_conflict", + "action": "fix_request" + }, + { + "code": "publish_not_permitted", + "action": "request_scope" + }, + { + "code": "qualifier_not_bound", + "action": "ask_data_question", + "gap_kind": "not_understood" + }, + { + "code": "query_too_long", + "action": "fix_request" + }, + { + "code": "rate_coverage_gap", + "action": "fix_request", + "gap_kind": "no_data" + }, + { + "code": "recipe_not_declared", + "action": "fix_request" + }, + { + "code": "recipe_not_found", + "action": "check_id" + }, + { + "code": "refresh_not_permitted", + "action": "request_scope" + }, + { + "code": "release_mismatch", + "action": "upgrade" + }, + { + "code": "render_target_mismatch", + "action": "fix_request" + }, + { + "code": "rendering_not_recorded", + "action": "fix_request" + }, + { + "code": "request_invalid", + "action": "fix_request" + }, + { + "code": "resolution_ambiguous", + "action": "fix_request" + }, + { + "code": "resource_exhausted", + "action": "fix_request" + }, + { + "code": "role_incompatible", + "action": "fix_request", + "gap_kind": "unsupported" + }, + { + "code": "role_not_resolved", + "action": "choose", + "gap_kind": "choice" + }, + { + "code": "role_signature_incompatible", + "action": "fix_request", + "gap_kind": "unsupported" + }, + { + "code": "rollup_not_summable", + "action": "fix_request" + }, + { + "code": "schema_invalid", + "action": "fix_request" + }, + { + "code": "scope_too_broad", + "action": "fix_request" + }, + { + "code": "service_unavailable", + "action": "report" + }, + { + "code": "shape_mismatch", + "action": "fix_request" + }, + { + "code": "skill_not_found", + "action": "check_id" + }, + { + "code": "skill_resource_not_found", + "action": "check_id" + }, + { + "code": "snapshot_not_found", + "action": "check_id" + }, + { + "code": "snapshot_revoked", + "action": "take_newest_version" + }, + { + "code": "source_ambiguous", + "action": "choose", + "gap_kind": "choice" + }, + { + "code": "source_code_ambiguous", + "action": "choose", + "gap_kind": "choice" + }, + { + "code": "source_code_not_held", + "action": "ask_data_question", + "gap_kind": "no_data" + }, + { + "code": "source_code_shares_variable", + "action": "ask_data_question", + "gap_kind": "unsupported" + }, + { + "code": "source_not_resolved", + "action": "ask_data_question", + "gap_kind": "not_understood" + }, + { + "code": "spec_id_mismatch", + "action": "fix_request" + }, + { + "code": "spec_not_exportable", + "action": "fix_request" + }, + { + "code": "spec_not_found", + "action": "check_id" + }, + { + "code": "timeout", + "action": "report" + }, + { + "code": "unit_not_resolved", + "action": "ask_data_question", + "gap_kind": "not_understood" + }, + { + "code": "unsupported_children_anchor_type", + "action": "fix_request" + }, + { + "code": "unsupported_peers_anchor_type", + "action": "fix_request" + }, + { + "code": "unsupported_schema_version", + "action": "upgrade" + }, + { + "code": "upstream_error", + "action": "report" + }, + { + "code": "upstream_version_changed", + "action": "report" + }, + { + "code": "variable_not_resolved", + "action": "ask_data_question", + "gap_kind": "not_understood" + }, + { + "code": "write_refused", + "action": "request_scope" + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/actions.schema.json b/python/client-contract/src/dfo_client_contract/actions.schema.json new file mode 100644 index 0000000..70c6fa2 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/actions.schema.json @@ -0,0 +1,58 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/python/client-contract/src/dfo_client_contract/actions.schema.json", + "title": "Caller actions", + "description": "The next step a client caller takes for each active refusal code that reaches a problem document or a no_data reason, sorted by code. A code with a no_data_reason mapping also names the gap kind a no_data part with that reason becomes.", + "type": "object", + "additionalProperties": false, + "required": [ + "format_version", + "codes" + ], + "properties": { + "format_version": { + "const": 1 + }, + "codes": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "code", + "action" + ], + "properties": { + "code": { + "type": "string", + "pattern": "^[a-z][a-z0-9]*(_[a-z0-9]+)*$" + }, + "action": { + "enum": [ + "fix_request", + "check_id", + "choose", + "ask_data_question", + "take_newest_version", + "log_in", + "request_scope", + "wait", + "wait_for_reset", + "report", + "upgrade" + ] + }, + "gap_kind": { + "enum": [ + "choice", + "no_data", + "not_understood", + "unsupported" + ] + } + } + } + } + } +} diff --git a/python/client-contract/src/dfo_client_contract/contract.py b/python/client-contract/src/dfo_client_contract/contract.py new file mode 100644 index 0000000..212c594 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/contract.py @@ -0,0 +1,113 @@ +"""The packaged contract files, read from package data.""" + +from __future__ import annotations + +import json +from importlib import resources +from pathlib import Path +from typing import Any + +# The rules under `rules/`, each a file of vectors named after the rule. +RULES = ( + "key-format", + "credentials-path", + "credentials-file", + "key-lookup", + "cache-dir", + "cache-layout", +) + + +def contract_dir() -> Path: + """The installed contract directory. + + Resolves through `importlib.resources`, so it works from a repo checkout + and from an installed wheel. A scenario's binary body file sits in its + `scenarios/` directory. + """ + return Path(str(resources.files("dfo_client_contract"))) + + +def _load(relative: str) -> Any: + return json.loads((contract_dir() / relative).read_text(encoding="utf-8")) + + +def _records(directory: str) -> list[dict[str, Any]]: + paths = sorted((contract_dir() / directory).glob("*.json")) + if not paths: + raise RuntimeError(f"no records found under dfo_client_contract/{directory}") + return [json.loads(path.read_text(encoding="utf-8")) for path in paths] + + +def openapi() -> dict[str, Any]: + """`served/openapi.json`: the composed dfo-apis app's OpenAPI document.""" + return _load("served/openapi.json") + + +def served_source() -> dict[str, Any]: + """`served/SOURCE.json`: the dfo-apis commit `openapi()` was captured from.""" + return _load("served/SOURCE.json") + + +def strict_fields() -> dict[str, Any]: + """`strict-fields.json`: the response members the clients act on.""" + return _load("strict-fields.json") + + +def strict_fields_schema() -> dict[str, Any]: + """`strict-fields.schema.json`: the shape of `strict-fields.json`.""" + return _load("strict-fields.schema.json") + + +def actions() -> dict[str, Any]: + """`actions.json`: the caller's next step for each refusal code.""" + return _load("actions.json") + + +def actions_schema() -> dict[str, Any]: + """`actions.schema.json`: the shape of `actions.json`.""" + return _load("actions.schema.json") + + +def scenario_schema() -> dict[str, Any]: + """`scenario.schema.json`: the shape of one scenario record.""" + return _load("scenario.schema.json") + + +def dataset_ref_schema() -> dict[str, Any]: + """`dataset-ref.schema.json`: the frozen DatasetRef format.""" + return _load("dataset-ref.schema.json") + + +def rules_schema() -> dict[str, Any]: + """`rules/rules.schema.json`: the shape of every rule file.""" + return _load("rules/rules.schema.json") + + +def scenarios() -> list[dict[str, Any]]: + """Every scenario record, sorted by file name. + + Raises: + RuntimeError: No scenario record is installed. + """ + return _records("scenarios") + + +def ref_examples() -> list[dict[str, Any]]: + """Every DatasetRef example, sorted by file name. + + Raises: + RuntimeError: No example is installed. + """ + return _records("refs") + + +def rule(name: str) -> dict[str, Any]: + """The vector file for rule `name`, one of `RULES`. + + Raises: + ValueError: `name` is not in `RULES`. + """ + if name not in RULES: + raise ValueError(f"unknown rule {name!r}; expected one of {RULES}") + return _load(f"rules/{name}.json") diff --git a/python/client-contract/src/dfo_client_contract/dataset-ref.schema.json b/python/client-contract/src/dfo_client_contract/dataset-ref.schema.json new file mode 100644 index 0000000..b9d7e0b --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/dataset-ref.schema.json @@ -0,0 +1,123 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/python/client-contract/src/dfo_client_contract/dataset-ref.schema.json", + "title": "DatasetRef", + "description": "The frozen reference to the exact versions a dataset holds. Every DFO client writes and reads this format, so a ref saved by one language loads in another.", + "type": "object", + "additionalProperties": false, + "required": [ + "format_version", + "members" + ], + "properties": { + "format_version": { + "const": 1 + }, + "members": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/member" + } + } + }, + "$defs": { + "member": { + "type": "object", + "additionalProperties": false, + "required": [ + "parts", + "sentence", + "spec", + "content_version", + "artifact" + ], + "properties": { + "parts": { + "description": "The variable text of each answer part this member answers, in query order. Empty for a spec fetched outside an answer.", + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + }, + "sentence": { + "description": "Search's rendered sentence for the built identity.", + "type": "string", + "minLength": 1 + }, + "spec": { + "type": "object", + "additionalProperties": false, + "required": [ + "spec_id", + "definition" + ], + "properties": { + "spec_id": { + "$ref": "#/$defs/spec_id" + }, + "definition": { + "description": "The server's definition for spec_id, unmodified.", + "type": "object", + "required": [ + "spec_id" + ], + "properties": { + "spec_id": { + "$ref": "#/$defs/spec_id" + } + } + } + } + }, + "content_version": { + "type": "string", + "pattern": "^cv_[0-9a-f]{32}$" + }, + "artifact": { + "type": "object", + "additionalProperties": false, + "required": [ + "digest", + "rendering" + ], + "properties": { + "digest": { + "type": "string", + "pattern": "^sha256:[0-9a-f]{64}$" + }, + "rendering": { + "description": "The selector a client matches an artifact's rendering on. Never the server's rendering object.", + "type": "object", + "additionalProperties": false, + "required": [ + "format", + "bundle" + ], + "properties": { + "format": { + "enum": [ + "csv", + "xlsx", + "parquet" + ] + }, + "bundle": { + "type": "boolean" + }, + "layout": { + "const": "frame" + } + } + } + } + } + } + }, + "spec_id": { + "type": "string", + "pattern": "^spec_[0-9a-f]{32}$" + } + } +} diff --git a/python/client-contract/src/dfo_client_contract/py.typed b/python/client-contract/src/dfo_client_contract/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-answer-member.json b/python/client-contract/src/dfo_client_contract/refs/ref-answer-member.json new file mode 100644 index 0000000..7ca8187 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/refs/ref-answer-member.json @@ -0,0 +1,97 @@ +{ + "format_version": 1, + "name": "ref-answer-member", + "description": "A member built from an answer names the part it answers.", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [ + "ODA disbursements for basic health care" + ], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "artifact": { + "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "format": "parquet", + "bundle": false + } + } + } + ] + }, + "expect": "accept" +} diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-definition-spec-id-mismatch-rejected.json b/python/client-contract/src/dfo_client_contract/refs/ref-definition-spec-id-mismatch-rejected.json new file mode 100644 index 0000000..efe42b8 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/refs/ref-definition-spec-id-mismatch-rejected.json @@ -0,0 +1,96 @@ +{ + "format_version": 1, + "name": "ref-definition-spec-id-mismatch-rejected", + "description": "A member's definition is the definition for its own spec_id.", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "artifact": { + "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "format": "parquet", + "bundle": false + } + } + } + ] + }, + "error": { + "by": "rule", + "reason": "definition_spec_id_mismatch" + } +} diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-frame-layout.json b/python/client-contract/src/dfo_client_contract/refs/ref-frame-layout.json new file mode 100644 index 0000000..eb52150 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/refs/ref-frame-layout.json @@ -0,0 +1,96 @@ +{ + "format_version": 1, + "name": "ref-frame-layout", + "description": "A member fetched with layout frame names the frame layout in its rendering.", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "artifact": { + "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "format": "parquet", + "bundle": false, + "layout": "frame" + } + } + } + ] + }, + "expect": "accept" +} diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-no-members-rejected.json b/python/client-contract/src/dfo_client_contract/refs/ref-no-members-rejected.json new file mode 100644 index 0000000..ac72242 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/refs/ref-no-members-rejected.json @@ -0,0 +1,12 @@ +{ + "format_version": 1, + "name": "ref-no-members-rejected", + "description": "A ref holds at least one member.", + "ref": { + "format_version": 1, + "members": [] + }, + "error": { + "by": "schema" + } +} diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-one-member.json b/python/client-contract/src/dfo_client_contract/refs/ref-one-member.json new file mode 100644 index 0000000..544cd44 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/refs/ref-one-member.json @@ -0,0 +1,95 @@ +{ + "format_version": 1, + "name": "ref-one-member", + "description": "A ref to one bare long Parquet version, the member of fetch-spec-known-sentence.", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "artifact": { + "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "format": "parquet", + "bundle": false + } + } + } + ] + }, + "expect": "accept" +} diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-repeated-spec-id-rejected.json b/python/client-contract/src/dfo_client_contract/refs/ref-repeated-spec-id-rejected.json new file mode 100644 index 0000000..7c4df56 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/refs/ref-repeated-spec-id-rejected.json @@ -0,0 +1,184 @@ +{ + "format_version": 1, + "name": "ref-repeated-spec-id-rejected", + "description": "Each member holds a distinct spec_id.", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "artifact": { + "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "format": "parquet", + "bundle": false + } + } + }, + { + "parts": [ + "ODA disbursements for basic health care" + ], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "artifact": { + "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "format": "parquet", + "bundle": false + } + } + } + ] + }, + "error": { + "by": "rule", + "reason": "repeated_spec_id" + } +} diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-server-rendering-rejected.json b/python/client-contract/src/dfo_client_contract/refs/ref-server-rendering-rejected.json new file mode 100644 index 0000000..5ba2ee1 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/refs/ref-server-rendering-rejected.json @@ -0,0 +1,98 @@ +{ + "format_version": 1, + "name": "ref-server-rendering-rejected", + "description": "The server's rendering object, with its integer layout, is not the selector a ref stores.", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "artifact": { + "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + } + } + } + ] + }, + "error": { + "by": "schema" + } +} diff --git a/python/client-contract/src/dfo_client_contract/rules/README.md b/python/client-contract/src/dfo_client_contract/rules/README.md new file mode 100644 index 0000000..f70b359 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/rules/README.md @@ -0,0 +1,61 @@ +# Client rules + +Every DFO client implements these rules the same way, so a key, a credentials file and a cache directory work across languages. Each rule's vectors are in `.json`, validated by `rules.schema.json`. In a vector, `env` lists the environment variables set, and an empty value counts as unset everywhere below. + +## Credentials path (`credentials-path`) + +The credentials file is the first of: + +1. `$DFO_CREDENTIALS_FILE`, as given; +1. on Linux and macOS, `$XDG_CONFIG_HOME/dfo/credentials.toml`, else `~/.config/dfo/credentials.toml`; +1. on Windows, `%APPDATA%\dfo\credentials.toml`, else `\AppData\Roaming\dfo\credentials.toml`. + +Windows ignores `XDG_CONFIG_HOME`. + +## Credentials file (`credentials-file`) + +The file is UTF-8 text in a subset of TOML, so any TOML reader reads the same profiles. Lines split on `\n`, and a line drops a final `\r` and its surrounding spaces and tabs. A line is then one of: + +- empty, or a comment starting with `#`; +- a table header `[name]`, which opens the profile `name`; +- an entry `name = "value"`, with spaces or tabs allowed around `=`, which sets `name` in the open profile. + +A name is one or more of `A-Z`, `a-z`, `0-9`, `_` and `-`. A value holds no `"`, no `\` and no control character, so it needs no escape. A profile keeps every entry it holds; a client reads `key`. The first broken line refuses the file with its 1-based line number and a reason: `outside_table` for an entry before any header, `duplicate_table` for a header seen before, `duplicate_key` for a name its profile already holds, and `invalid_line` for anything else, a trailing comment included. Only the Python CLI writes the file, readable by its owner only. + +## Key lookup (`key-lookup`) + +A client resolves its key when it is built, and again after a 401. The first source found wins: + +1. the `api_key` argument: a key, or `false` to force anonymous use; +1. `DFO_API_KEY`; +1. the credentials file at the credentials path, profile `$DFO_PROFILE`, else `default`; +1. inside Colab, a notebook secret named `DFO_API_KEY`; +1. otherwise, anonymous. + +A missing file goes on to the next source, and so does a missing `default` profile. A file that fails to parse raises `credentials_file_invalid`, a profile named by `DFO_PROFILE` that the file lacks raises `profile_not_found`, and a chosen profile with no `key` raises `profile_without_key`. The file is read only when no earlier source wins. The argument may also be a callable or a key object, called or unwrapped when the client resolves the key; vectors pass strings, and the Colab source has none. + +## Key format (`key-format`) + +A secret key is `dfo_k_`, then a base62 body, then a 6-character checksum; `dfo_p_` marks a browser-safe key. Base62 is `0-9A-Za-z` in that order. The checksum is the CRC32 (ISO-HDLC, as zlib computes it) of the body's ASCII bytes, written in base62 and left-padded with `0` to six characters. Issued keys have a 32-character body, 44 characters in all, but the check ignores length: the last six characters after the prefix are the checksum and the rest is the body. + +The check runs in order and reports the first failure: `unknown_prefix` when the key starts with neither prefix, `not_base62` when a character after the prefix is outside base62, and `checksum_mismatch` when the body is empty or its checksum differs. A failure warns and the client sends the key anyway, so a change of key format forces no upgrade. + +## Cache directory (`cache-dir`) + +The cache root is the first of, as readerkit's `resolve_cache_dir(app="dfo", ...)` resolves it: + +1. the `cache_dir` argument; +1. `DFO_CACHE_DIR`; +1. `BBLOCKS_CACHE_DIR`; +1. the platform cache directory for `readerkit`: on Linux `$XDG_CACHE_HOME/readerkit`, else `~/.cache/readerkit`; on macOS `~/Library/Caches/readerkit`; on Windows `\readerkit\Cache`, which the vectors give as `LOCALAPPDATA`. + +A leading `~` expands to the home directory. The cache directory is `/v1/dfo/cache1`: `v1` is readerkit's own layout version, `dfo` the app, and `cache1` the client cache's layout version, shared by every client and every client release. + +## Cache layout (`cache-layout`) + +Inside the cache directory: + +- a downloaded artifact is `files/sha256/`, keyed by its digest; +- a manifest is `manifests///.json`, where `` is the format, then `-bundle` for a bundle, then `-frame` for the frame layout: `parquet`, `parquet-frame`, `csv-bundle`. + +A client writes an entry to a temporary name in the same directory and renames it into place, so a reader never sees a partial entry, and concurrent writers of one entry write identical bytes. A read re-hashes an artifact, and a mismatch counts as a miss. diff --git a/python/client-contract/src/dfo_client_contract/rules/cache-dir.json b/python/client-contract/src/dfo_client_contract/rules/cache-dir.json new file mode 100644 index 0000000..dfb3de9 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/rules/cache-dir.json @@ -0,0 +1,109 @@ +{ + "format_version": 1, + "rule": "cache-dir", + "vectors": [ + { + "name": "argument-wins", + "platform": "linux", + "home": "/home/ana", + "cache_dir": "/data/cache", + "env": { + "DFO_CACHE_DIR": "/env/dfo", + "BBLOCKS_CACHE_DIR": "/env/bblocks" + }, + "root": "/data/cache", + "directory": "/data/cache/v1/dfo/cache1" + }, + { + "name": "argument-with-home-expands", + "platform": "macos", + "home": "/Users/ana", + "cache_dir": "~/dfo-cache", + "env": {}, + "root": "/Users/ana/dfo-cache", + "directory": "/Users/ana/dfo-cache/v1/dfo/cache1" + }, + { + "name": "dfo-variable", + "platform": "linux", + "home": "/home/ana", + "env": { + "DFO_CACHE_DIR": "/env/dfo", + "BBLOCKS_CACHE_DIR": "/env/bblocks" + }, + "root": "/env/dfo", + "directory": "/env/dfo/v1/dfo/cache1" + }, + { + "name": "family-variable", + "platform": "linux", + "home": "/home/ana", + "env": { + "BBLOCKS_CACHE_DIR": "/env/bblocks" + }, + "root": "/env/bblocks", + "directory": "/env/bblocks/v1/dfo/cache1" + }, + { + "name": "empty-variables-count-as-unset", + "platform": "linux", + "home": "/home/ana", + "env": { + "DFO_CACHE_DIR": "", + "BBLOCKS_CACHE_DIR": "", + "XDG_CACHE_HOME": "" + }, + "root": "/home/ana/.cache/readerkit", + "directory": "/home/ana/.cache/readerkit/v1/dfo/cache1" + }, + { + "name": "xdg-cache-home-on-linux", + "platform": "linux", + "home": "/home/ana", + "env": { + "XDG_CACHE_HOME": "/home/ana/.xdg-cache" + }, + "root": "/home/ana/.xdg-cache/readerkit", + "directory": "/home/ana/.xdg-cache/readerkit/v1/dfo/cache1" + }, + { + "name": "platform-default-on-linux", + "platform": "linux", + "home": "/home/ana", + "env": {}, + "root": "/home/ana/.cache/readerkit", + "directory": "/home/ana/.cache/readerkit/v1/dfo/cache1" + }, + { + "name": "platform-default-on-macos", + "platform": "macos", + "home": "/Users/ana", + "env": { + "XDG_CACHE_HOME": "/Users/ana/.xdg-cache" + }, + "root": "/Users/ana/Library/Caches/readerkit", + "directory": "/Users/ana/Library/Caches/readerkit/v1/dfo/cache1" + }, + { + "name": "platform-default-on-windows", + "platform": "windows", + "home": "C:\\Users\\ana", + "env": { + "LOCALAPPDATA": "C:\\Users\\ana\\AppData\\Local" + }, + "root": "C:\\Users\\ana\\AppData\\Local\\readerkit\\Cache", + "directory": "C:\\Users\\ana\\AppData\\Local\\readerkit\\Cache\\v1\\dfo\\cache1" + }, + { + "name": "dfo-variable-on-windows", + "platform": "windows", + "home": "C:\\Users\\ana", + "env": { + "DFO_CACHE_DIR": "D:\\cache", + "LOCALAPPDATA": "C:\\Users\\ana\\AppData\\Local" + }, + "root": "D:\\cache", + "directory": "D:\\cache\\v1\\dfo\\cache1" + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/rules/cache-layout.json b/python/client-contract/src/dfo_client_contract/rules/cache-layout.json new file mode 100644 index 0000000..9a63b8a --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/rules/cache-layout.json @@ -0,0 +1,46 @@ +{ + "format_version": 1, + "rule": "cache-layout", + "vectors": [ + { + "name": "file-by-digest", + "entry": "file", + "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "path": "files/sha256/e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + { + "name": "manifest-long-parquet", + "entry": "manifest", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "rendering": { + "format": "parquet", + "bundle": false + }, + "path": "manifests/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/parquet.json" + }, + { + "name": "manifest-frame-parquet", + "entry": "manifest", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "rendering": { + "format": "parquet", + "bundle": false, + "layout": "frame" + }, + "path": "manifests/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/parquet-frame.json" + }, + { + "name": "manifest-csv-bundle", + "entry": "manifest", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "rendering": { + "format": "csv", + "bundle": true + }, + "path": "manifests/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/csv-bundle.json" + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/rules/credentials-file.json b/python/client-contract/src/dfo_client_contract/rules/credentials-file.json new file mode 100644 index 0000000..8cdad68 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/rules/credentials-file.json @@ -0,0 +1,122 @@ +{ + "format_version": 1, + "rule": "credentials-file", + "vectors": [ + { + "name": "one-profile", + "text": "[default]\nkey = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\"\n", + "profiles": { + "default": { + "key": "dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe" + } + } + }, + { + "name": "two-profiles-comments-and-blank-lines", + "text": "# written by dfo auth login\n\n[default]\nkey = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\"\n\n[ci]\nkey=\"dfo_k_Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2Rr1Qq0Pp448bfc\"\n", + "profiles": { + "default": { + "key": "dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe" + }, + "ci": { + "key": "dfo_k_Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2Rr1Qq0Pp448bfc" + } + } + }, + { + "name": "whitespace-and-crlf", + "text": " [default] \r\n\tkey = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\" \r\n", + "profiles": { + "default": { + "key": "dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe" + } + } + }, + { + "name": "other-keys-are-kept", + "text": "[default]\nkey = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\"\nlabel = \"laptop\"\n", + "profiles": { + "default": { + "key": "dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe", + "label": "laptop" + } + } + }, + { + "name": "empty-file", + "text": "", + "profiles": {} + }, + { + "name": "empty-table", + "text": "[default]\n", + "profiles": { + "default": {} + } + }, + { + "name": "entry-before-any-table", + "text": "key = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\"\n", + "error": { + "reason": "outside_table", + "line": 1 + } + }, + { + "name": "duplicate-table", + "text": "[default]\nkey = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\"\n[default]\nkey = \"dfo_k_Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2Rr1Qq0Pp448bfc\"\n", + "error": { + "reason": "duplicate_table", + "line": 3 + } + }, + { + "name": "duplicate-key", + "text": "[default]\nkey = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\"\nkey = \"dfo_k_Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2Rr1Qq0Pp448bfc\"\n", + "error": { + "reason": "duplicate_key", + "line": 3 + } + }, + { + "name": "single-quoted-value", + "text": "[default]\nkey = 'dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe'\n", + "error": { + "reason": "invalid_line", + "line": 2 + } + }, + { + "name": "escape-in-value", + "text": "[default]\nkey = \"dfo\\\\k\"\n", + "error": { + "reason": "invalid_line", + "line": 2 + } + }, + { + "name": "trailing-comment", + "text": "[default]\nkey = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\" # laptop\n", + "error": { + "reason": "invalid_line", + "line": 2 + } + }, + { + "name": "dotted-table", + "text": "[dfo.default]\nkey = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\"\n", + "error": { + "reason": "invalid_line", + "line": 1 + } + }, + { + "name": "unquoted-value", + "text": "[default]\nkey = dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\n", + "error": { + "reason": "invalid_line", + "line": 2 + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/rules/credentials-path.json b/python/client-contract/src/dfo_client_contract/rules/credentials-path.json new file mode 100644 index 0000000..612b049 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/rules/credentials-path.json @@ -0,0 +1,94 @@ +{ + "format_version": 1, + "rule": "credentials-path", + "vectors": [ + { + "name": "explicit-file-wins", + "platform": "linux", + "home": "/home/ana", + "env": { + "DFO_CREDENTIALS_FILE": "/etc/dfo/ci.toml", + "XDG_CONFIG_HOME": "/home/ana/.xdg" + }, + "path": "/etc/dfo/ci.toml" + }, + { + "name": "explicit-file-wins-on-windows", + "platform": "windows", + "home": "C:\\Users\\ana", + "env": { + "DFO_CREDENTIALS_FILE": "D:\\keys\\dfo.toml", + "APPDATA": "C:\\Users\\ana\\AppData\\Roaming" + }, + "path": "D:\\keys\\dfo.toml" + }, + { + "name": "xdg-config-home-on-linux", + "platform": "linux", + "home": "/home/ana", + "env": { + "XDG_CONFIG_HOME": "/home/ana/.xdg" + }, + "path": "/home/ana/.xdg/dfo/credentials.toml" + }, + { + "name": "xdg-config-home-on-macos", + "platform": "macos", + "home": "/Users/ana", + "env": { + "XDG_CONFIG_HOME": "/Users/ana/.xdg" + }, + "path": "/Users/ana/.xdg/dfo/credentials.toml" + }, + { + "name": "default-on-linux", + "platform": "linux", + "home": "/home/ana", + "env": {}, + "path": "/home/ana/.config/dfo/credentials.toml" + }, + { + "name": "default-on-macos", + "platform": "macos", + "home": "/Users/ana", + "env": {}, + "path": "/Users/ana/.config/dfo/credentials.toml" + }, + { + "name": "empty-values-count-as-unset", + "platform": "linux", + "home": "/home/ana", + "env": { + "DFO_CREDENTIALS_FILE": "", + "XDG_CONFIG_HOME": "" + }, + "path": "/home/ana/.config/dfo/credentials.toml" + }, + { + "name": "appdata-on-windows", + "platform": "windows", + "home": "C:\\Users\\ana", + "env": { + "APPDATA": "C:\\Users\\ana\\AppData\\Roaming" + }, + "path": "C:\\Users\\ana\\AppData\\Roaming\\dfo\\credentials.toml" + }, + { + "name": "windows-ignores-xdg", + "platform": "windows", + "home": "C:\\Users\\ana", + "env": { + "APPDATA": "C:\\Users\\ana\\AppData\\Roaming", + "XDG_CONFIG_HOME": "C:\\xdg" + }, + "path": "C:\\Users\\ana\\AppData\\Roaming\\dfo\\credentials.toml" + }, + { + "name": "windows-without-appdata", + "platform": "windows", + "home": "C:\\Users\\ana", + "env": {}, + "path": "C:\\Users\\ana\\AppData\\Roaming\\dfo\\credentials.toml" + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/rules/key-format.json b/python/client-contract/src/dfo_client_contract/rules/key-format.json new file mode 100644 index 0000000..a2a793a --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/rules/key-format.json @@ -0,0 +1,62 @@ +{ + "format_version": 1, + "rule": "key-format", + "vectors": [ + { + "name": "secret-key-passes", + "key": "dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe", + "verdict": "pass" + }, + { + "name": "publishable-key-passes", + "key": "dfo_p_Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2Rr1Qq0Pp448bfc", + "verdict": "pass" + }, + { + "name": "checksum-with-leading-zero-passes", + "key": "dfo_k_padTest00000000000000000000000020xpmWN", + "verdict": "pass" + }, + { + "name": "longer-body-passes", + "key": "dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0UeXY2EMnsV", + "verdict": "pass" + }, + { + "name": "unknown-prefix-warns", + "key": "dfo_x_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe", + "verdict": "warn", + "reason": "unknown_prefix" + }, + { + "name": "other-vendor-key-warns", + "key": "sk-4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue", + "verdict": "warn", + "reason": "unknown_prefix" + }, + { + "name": "non-base62-character-warns", + "key": "dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0U-2wanxe", + "verdict": "warn", + "reason": "not_base62" + }, + { + "name": "checksum-mismatch-warns", + "key": "dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue448bfc", + "verdict": "warn", + "reason": "checksum_mismatch" + }, + { + "name": "swapped-body-characters-warn", + "key": "dfo_k_f48Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe", + "verdict": "warn", + "reason": "checksum_mismatch" + }, + { + "name": "too-short-for-a-checksum-warns", + "key": "dfo_k_abc123", + "verdict": "warn", + "reason": "checksum_mismatch" + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/rules/key-lookup.json b/python/client-contract/src/dfo_client_contract/rules/key-lookup.json new file mode 100644 index 0000000..2f5d4c0 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/rules/key-lookup.json @@ -0,0 +1,110 @@ +{ + "format_version": 1, + "rule": "key-lookup", + "vectors": [ + { + "name": "argument-wins", + "api_key": "dfo_k_argument", + "env": { + "DFO_API_KEY": "dfo_k_environment" + }, + "file": "[default]\nkey = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\"\n\n[ci]\nkey = \"dfo_k_Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2Rr1Qq0Pp448bfc\"\n", + "source": "argument", + "key": "dfo_k_argument" + }, + { + "name": "false-forces-anonymous", + "api_key": false, + "env": { + "DFO_API_KEY": "dfo_k_environment" + }, + "file": "[default]\nkey = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\"\n\n[ci]\nkey = \"dfo_k_Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2Rr1Qq0Pp448bfc\"\n", + "source": "anonymous", + "key": null + }, + { + "name": "environment-beats-file", + "env": { + "DFO_API_KEY": "dfo_k_environment" + }, + "file": "[default]\nkey = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\"\n\n[ci]\nkey = \"dfo_k_Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2Rr1Qq0Pp448bfc\"\n", + "source": "environment", + "key": "dfo_k_environment" + }, + { + "name": "default-profile", + "env": {}, + "file": "[default]\nkey = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\"\n\n[ci]\nkey = \"dfo_k_Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2Rr1Qq0Pp448bfc\"\n", + "source": "credentials_file", + "key": "dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe" + }, + { + "name": "named-profile", + "env": { + "DFO_PROFILE": "ci" + }, + "file": "[default]\nkey = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\"\n\n[ci]\nkey = \"dfo_k_Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2Rr1Qq0Pp448bfc\"\n", + "source": "credentials_file", + "key": "dfo_k_Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2Rr1Qq0Pp448bfc" + }, + { + "name": "empty-environment-counts-as-unset", + "env": { + "DFO_API_KEY": "", + "DFO_PROFILE": "" + }, + "file": "[default]\nkey = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\"\n\n[ci]\nkey = \"dfo_k_Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2Rr1Qq0Pp448bfc\"\n", + "source": "credentials_file", + "key": "dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe" + }, + { + "name": "no-file-is-anonymous", + "env": {}, + "file": null, + "source": "anonymous", + "key": null + }, + { + "name": "default-profile-absent-is-anonymous", + "env": {}, + "file": "[ci]\nkey = \"dfo_k_Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2Rr1Qq0Pp448bfc\"\n", + "source": "anonymous", + "key": null + }, + { + "name": "named-profile-absent-raises", + "env": { + "DFO_PROFILE": "prod" + }, + "file": "[default]\nkey = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\"\n\n[ci]\nkey = \"dfo_k_Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2Rr1Qq0Pp448bfc\"\n", + "error": { + "reason": "profile_not_found" + } + }, + { + "name": "profile-without-key-raises", + "env": {}, + "file": "[default]\nlabel = \"laptop\"\n", + "error": { + "reason": "profile_without_key" + } + }, + { + "name": "invalid-file-raises", + "env": {}, + "file": "key = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\"\n", + "error": { + "reason": "credentials_file_invalid" + } + }, + { + "name": "invalid-file-is-not-read-when-the-environment-wins", + "env": { + "DFO_API_KEY": "dfo_k_environment" + }, + "file": "key = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\"\n", + "source": "environment", + "key": "dfo_k_environment" + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/rules/rules.schema.json b/python/client-contract/src/dfo_client_contract/rules/rules.schema.json new file mode 100644 index 0000000..e6e956c --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/rules/rules.schema.json @@ -0,0 +1,519 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/python/client-contract/src/dfo_client_contract/rules/rules.schema.json", + "title": "Client rule vectors", + "description": "One file per rule, each holding the vectors a client's implementation of that rule must reproduce. rules/README.md states each rule.", + "type": "object", + "oneOf": [ + { + "$ref": "#/$defs/key_format" + }, + { + "$ref": "#/$defs/credentials_path" + }, + { + "$ref": "#/$defs/credentials_file" + }, + { + "$ref": "#/$defs/key_lookup" + }, + { + "$ref": "#/$defs/cache_dir" + }, + { + "$ref": "#/$defs/cache_layout" + } + ], + "$defs": { + "one_line": { + "description": "Text without a newline. Python's `re.search` lets an anchored pattern's `$` match before a final newline, so every pattern here anchored with `$` refers to this as well.", + "not": { + "pattern": "\\n" + } + }, + "name": { + "type": "string", + "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$", + "$ref": "#/$defs/one_line" + }, + "platform": { + "enum": [ + "linux", + "macos", + "windows" + ] + }, + "env": { + "description": "The environment variables set for the vector. A variable not listed is unset.", + "type": "object", + "propertyNames": { + "pattern": "^[A-Z][A-Z0-9_]*$", + "$ref": "#/$defs/one_line" + }, + "additionalProperties": { + "type": "string" + } + }, + "path": { + "type": "string", + "minLength": 1 + }, + "rendering": { + "type": "object", + "additionalProperties": false, + "required": [ + "format", + "bundle" + ], + "properties": { + "format": { + "enum": [ + "csv", + "xlsx", + "parquet" + ] + }, + "bundle": { + "type": "boolean" + }, + "layout": { + "const": "frame" + } + } + }, + "file_error": { + "enum": [ + "outside_table", + "duplicate_table", + "duplicate_key", + "invalid_line" + ] + }, + "suite": { + "type": "object", + "required": [ + "format_version", + "rule", + "vectors" + ], + "properties": { + "format_version": { + "const": 1 + }, + "vectors": { + "type": "array", + "minItems": 1 + } + } + }, + "key_format": { + "$ref": "#/$defs/suite", + "additionalProperties": false, + "properties": { + "format_version": true, + "rule": { + "const": "key-format" + }, + "vectors": { + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "name", + "key", + "verdict" + ], + "properties": { + "name": { + "$ref": "#/$defs/name" + }, + "key": { + "type": "string", + "minLength": 1 + }, + "verdict": { + "enum": [ + "pass", + "warn" + ] + }, + "reason": { + "enum": [ + "unknown_prefix", + "not_base62", + "checksum_mismatch" + ] + } + }, + "if": { + "properties": { + "verdict": { + "const": "warn" + } + } + }, + "then": { + "required": [ + "reason" + ] + }, + "else": { + "not": { + "required": [ + "reason" + ] + } + } + } + } + } + }, + "credentials_path": { + "$ref": "#/$defs/suite", + "additionalProperties": false, + "properties": { + "format_version": true, + "rule": { + "const": "credentials-path" + }, + "vectors": { + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "name", + "platform", + "home", + "env", + "path" + ], + "properties": { + "name": { + "$ref": "#/$defs/name" + }, + "platform": { + "$ref": "#/$defs/platform" + }, + "home": { + "$ref": "#/$defs/path" + }, + "env": { + "$ref": "#/$defs/env" + }, + "path": { + "$ref": "#/$defs/path" + } + } + } + } + } + }, + "credentials_file": { + "$ref": "#/$defs/suite", + "additionalProperties": false, + "properties": { + "format_version": true, + "rule": { + "const": "credentials-file" + }, + "vectors": { + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "name", + "text" + ], + "oneOf": [ + { + "required": [ + "profiles" + ] + }, + { + "required": [ + "error" + ] + } + ], + "properties": { + "name": { + "$ref": "#/$defs/name" + }, + "text": { + "type": "string" + }, + "profiles": { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "error": { + "type": "object", + "additionalProperties": false, + "required": [ + "reason", + "line" + ], + "properties": { + "reason": { + "$ref": "#/$defs/file_error" + }, + "line": { + "type": "integer", + "minimum": 1 + } + } + } + } + } + } + } + }, + "key_lookup": { + "$ref": "#/$defs/suite", + "additionalProperties": false, + "properties": { + "format_version": true, + "rule": { + "const": "key-lookup" + }, + "vectors": { + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "name", + "env", + "file" + ], + "oneOf": [ + { + "required": [ + "source", + "key" + ] + }, + { + "required": [ + "error" + ] + } + ], + "properties": { + "name": { + "$ref": "#/$defs/name" + }, + "api_key": { + "description": "The api_key argument: a key string, or false to force anonymous use. Absent when the caller passes none.", + "oneOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "const": false + } + ] + }, + "env": { + "$ref": "#/$defs/env" + }, + "file": { + "description": "The text of the credentials file at the credentials path, or null when no file exists there.", + "type": [ + "string", + "null" + ] + }, + "source": { + "enum": [ + "argument", + "environment", + "credentials_file", + "anonymous" + ] + }, + "key": { + "type": [ + "string", + "null" + ] + }, + "error": { + "type": "object", + "additionalProperties": false, + "required": [ + "reason" + ], + "properties": { + "reason": { + "enum": [ + "profile_not_found", + "profile_without_key", + "credentials_file_invalid" + ] + } + } + } + } + } + } + } + }, + "cache_dir": { + "$ref": "#/$defs/suite", + "additionalProperties": false, + "properties": { + "format_version": true, + "rule": { + "const": "cache-dir" + }, + "vectors": { + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "name", + "platform", + "home", + "env", + "root", + "directory" + ], + "properties": { + "name": { + "$ref": "#/$defs/name" + }, + "platform": { + "$ref": "#/$defs/platform" + }, + "home": { + "$ref": "#/$defs/path" + }, + "cache_dir": { + "$ref": "#/$defs/path" + }, + "env": { + "$ref": "#/$defs/env" + }, + "root": { + "$ref": "#/$defs/path" + }, + "directory": { + "$ref": "#/$defs/path" + } + } + } + } + } + }, + "cache_layout": { + "$ref": "#/$defs/suite", + "additionalProperties": false, + "properties": { + "format_version": true, + "rule": { + "const": "cache-layout" + }, + "vectors": { + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "name", + "entry", + "path" + ], + "oneOf": [ + { + "properties": { + "entry": { + "const": "file" + } + }, + "required": [ + "digest" + ], + "not": { + "anyOf": [ + { + "required": [ + "spec_id" + ] + }, + { + "required": [ + "content_version" + ] + }, + { + "required": [ + "rendering" + ] + } + ] + } + }, + { + "properties": { + "entry": { + "const": "manifest" + } + }, + "required": [ + "spec_id", + "content_version", + "rendering" + ], + "not": { + "required": [ + "digest" + ] + } + } + ], + "properties": { + "name": { + "$ref": "#/$defs/name" + }, + "entry": { + "enum": [ + "file", + "manifest" + ] + }, + "digest": { + "type": "string", + "pattern": "^sha256:[0-9a-f]{64}$", + "$ref": "#/$defs/one_line" + }, + "spec_id": { + "type": "string", + "pattern": "^spec_[0-9a-f]{32}$", + "$ref": "#/$defs/one_line" + }, + "content_version": { + "type": "string", + "pattern": "^cv_[0-9a-f]{32}$", + "$ref": "#/$defs/one_line" + }, + "rendering": { + "$ref": "#/$defs/rendering" + }, + "path": { + "type": "string", + "pattern": "^[a-z]+(/[A-Za-z0-9_.-]+)+$", + "$ref": "#/$defs/one_line" + } + } + } + } + } + } + } +} diff --git a/python/client-contract/src/dfo_client_contract/scenario.schema.json b/python/client-contract/src/dfo_client_contract/scenario.schema.json new file mode 100644 index 0000000..3c530f4 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenario.schema.json @@ -0,0 +1,782 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/python/client-contract/src/dfo_client_contract/scenario.schema.json", + "title": "Client scenario", + "description": "One client-level call, the HTTP exchanges it makes in order, and the outcome each step reaches. Every DFO client replays every scenario.", + "type": "object", + "additionalProperties": false, + "required": [ + "format_version", + "name", + "description", + "origin", + "call", + "exchanges", + "expect" + ], + "properties": { + "format_version": { + "const": 1 + }, + "name": { + "$ref": "#/$defs/name" + }, + "description": { + "type": "string", + "minLength": 1 + }, + "origin": { + "oneOf": [ + { + "$ref": "#/$defs/recorded" + }, + { + "$ref": "#/$defs/synthetic" + } + ] + }, + "call": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/step" + } + }, + "exchanges": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/exchange" + } + }, + "expect": { + "description": "One outcome per step of call, in the same order.", + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/outcome" + } + } + }, + "$defs": { + "one_line": { + "description": "Text without a newline. Python's `re.search` lets an anchored pattern's `$` match before a final newline, so every pattern here anchored with `$` refers to this as well.", + "not": { + "pattern": "\\n" + } + }, + "name": { + "type": "string", + "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$", + "$ref": "#/$defs/one_line" + }, + "spec_id": { + "type": "string", + "pattern": "^spec_[0-9a-f]{32}$", + "$ref": "#/$defs/one_line" + }, + "content_version": { + "type": "string", + "pattern": "^cv_[0-9a-f]{32}$", + "$ref": "#/$defs/one_line" + }, + "recorded": { + "type": "object", + "additionalProperties": false, + "required": [ + "kind", + "base_url", + "dfo_commit", + "recorded_at" + ], + "properties": { + "kind": { + "const": "recorded" + }, + "base_url": { + "description": "The base URL the client was given. A request path resolves against it, and an origin path against its origin.", + "type": "string", + "pattern": "^https?://[^/?#]+(/[^?#]*)?$", + "$ref": "#/$defs/one_line" + }, + "dfo_commit": { + "type": "string", + "pattern": "^[0-9a-f]{40}$", + "$ref": "#/$defs/one_line" + }, + "recorded_at": { + "type": "string", + "format": "date-time" + } + } + }, + "synthetic": { + "type": "object", + "additionalProperties": false, + "required": [ + "kind", + "derived_from", + "edit" + ], + "properties": { + "kind": { + "const": "synthetic" + }, + "derived_from": { + "$ref": "#/$defs/name" + }, + "edit": { + "type": "string", + "minLength": 1, + "$ref": "#/$defs/one_line" + } + } + }, + "spec": { + "description": "A Spec as a client holds it: the server's spec_id and unmodified definition, and the sentence when the client knows it.", + "type": "object", + "additionalProperties": false, + "required": [ + "spec_id", + "definition" + ], + "properties": { + "spec_id": { + "$ref": "#/$defs/spec_id" + }, + "definition": { + "type": "object" + }, + "sentence": { + "type": "string", + "minLength": 1 + } + } + }, + "window": { + "oneOf": [ + { + "enum": [ + "all", + "latest" + ] + }, + { + "type": "array", + "prefixItems": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "minItems": 2, + "maxItems": 2 + } + ] + }, + "narrowing": { + "type": "object", + "properties": { + "window": { + "$ref": "#/$defs/window" + }, + "entities": { + "type": "object", + "additionalProperties": { + "type": "array", + "minItems": 1, + "items": { + "type": "string", + "minLength": 1 + } + } + }, + "facets": { + "type": "object" + } + } + }, + "layout": { + "enum": [ + "long", + "frame" + ] + }, + "step": { + "oneOf": [ + { + "$ref": "#/$defs/search_step" + }, + { + "$ref": "#/$defs/choose_step" + }, + { + "$ref": "#/$defs/fetch_answer_step" + }, + { + "$ref": "#/$defs/fetch_spec_step" + }, + { + "$ref": "#/$defs/fetch_ref_step" + }, + { + "$ref": "#/$defs/mint_step" + }, + { + "$ref": "#/$defs/result_step" + } + ] + }, + "search_step": { + "type": "object", + "additionalProperties": false, + "required": [ + "op", + "question" + ], + "properties": { + "op": { + "const": "search" + }, + "question": { + "type": "string", + "minLength": 1 + }, + "timeout": { + "type": "number", + "exclusiveMinimum": 0 + } + } + }, + "choose_step": { + "description": "A choice on the answer the previous step produced. part names the part by index or variable text, and may be left out when one part awaits a choice. option names the option by index or label.", + "type": "object", + "additionalProperties": false, + "required": [ + "op", + "option" + ], + "properties": { + "op": { + "const": "choose" + }, + "part": { + "oneOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string", + "minLength": 1 + } + ] + }, + "option": { + "oneOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string", + "minLength": 1 + } + ] + } + } + }, + "fetch_answer_step": { + "description": "A fetch of the answer the previous step produced.", + "type": "object", + "additionalProperties": false, + "required": [ + "op" + ], + "properties": { + "op": { + "const": "fetch" + }, + "layout": { + "$ref": "#/$defs/layout" + }, + "partial": { + "type": "boolean" + }, + "strict": { + "type": "boolean" + }, + "timeout": { + "type": "number", + "exclusiveMinimum": 0 + } + } + }, + "fetch_spec_step": { + "type": "object", + "additionalProperties": false, + "required": [ + "op", + "spec" + ], + "$ref": "#/$defs/narrowing", + "properties": { + "op": { + "const": "fetch" + }, + "spec": { + "$ref": "#/$defs/spec" + }, + "layout": { + "$ref": "#/$defs/layout" + }, + "strict": { + "type": "boolean" + }, + "timeout": { + "type": "number", + "exclusiveMinimum": 0 + }, + "window": true, + "entities": true, + "facets": true + } + }, + "fetch_ref_step": { + "description": "A fetch of the exact versions a ref names. A ref takes no narrowing.", + "type": "object", + "additionalProperties": false, + "required": [ + "op", + "ref" + ], + "properties": { + "op": { + "const": "fetch" + }, + "ref": { + "$ref": "dataset-ref.schema.json" + }, + "timeout": { + "type": "number", + "exclusiveMinimum": 0 + } + } + }, + "mint_step": { + "type": "object", + "additionalProperties": false, + "required": [ + "op", + "spec" + ], + "$ref": "#/$defs/narrowing", + "properties": { + "op": { + "const": "mint" + }, + "spec": { + "$ref": "#/$defs/spec" + }, + "layout": { + "$ref": "#/$defs/layout" + }, + "window": true, + "entities": true, + "facets": true + } + }, + "result_step": { + "description": "Waiting for the operation the previous mint step started, and taking its dataset.", + "type": "object", + "additionalProperties": false, + "required": [ + "op" + ], + "properties": { + "op": { + "const": "result" + }, + "timeout": { + "type": "number", + "exclusiveMinimum": 0 + } + } + }, + "exchange": { + "type": "object", + "additionalProperties": false, + "required": [ + "request", + "response" + ], + "properties": { + "request": { + "$ref": "#/$defs/request" + }, + "response": { + "$ref": "#/$defs/response" + } + } + }, + "request": { + "description": "Exactly one of path, a path the client composes under the base URL; origin_path, a root-relative URL the server returned, resolved against the base URL's origin; or url, an absolute URL outside the API, such as a signed storage URL.", + "type": "object", + "additionalProperties": false, + "required": [ + "method" + ], + "oneOf": [ + { + "required": [ + "path" + ] + }, + { + "required": [ + "origin_path" + ] + }, + { + "required": [ + "url" + ] + } + ], + "properties": { + "method": { + "enum": [ + "GET", + "POST", + "PUT", + "PATCH", + "DELETE" + ] + }, + "path": { + "type": "string", + "pattern": "^/[^?#]*(\\?[^#]*)?$", + "$ref": "#/$defs/one_line" + }, + "origin_path": { + "type": "string", + "pattern": "^/[^?#]*(\\?[^#]*)?$", + "$ref": "#/$defs/one_line" + }, + "url": { + "type": "string", + "pattern": "^https?://[^/?#]+", + "$ref": "#/$defs/one_line" + }, + "json": { + "description": "The members of the JSON request body that must match, compared as parsed JSON values. A recorded scenario lists every member the client sent.", + "type": "object" + } + } + }, + "response": { + "type": "object", + "additionalProperties": false, + "required": [ + "status" + ], + "not": { + "required": [ + "json", + "body_file" + ] + }, + "properties": { + "status": { + "type": "integer", + "minimum": 100, + "maximum": 599 + }, + "headers": { + "description": "The response headers a client reads, by lower-case name.", + "type": "object", + "propertyNames": { + "pattern": "^[a-z0-9-]+$", + "$ref": "#/$defs/one_line" + }, + "additionalProperties": { + "type": "string" + } + }, + "json": { + "description": "The JSON response body." + }, + "body_file": { + "description": "A binary response body, in a file beside the record whose name starts with the scenario's name.", + "type": "string", + "pattern": "^[a-z0-9]+(-[a-z0-9]+)*\\.[a-z0-9]+$", + "$ref": "#/$defs/one_line" + } + } + }, + "gap_kind": { + "enum": [ + "choice", + "no_data", + "not_understood", + "unsupported", + "timed_out", + "unknown" + ] + }, + "outcome": { + "oneOf": [ + { + "type": "object", + "additionalProperties": false, + "required": [ + "answer" + ], + "properties": { + "answer": { + "$ref": "#/$defs/answer" + } + } + }, + { + "type": "object", + "additionalProperties": false, + "required": [ + "dataset" + ], + "properties": { + "dataset": { + "$ref": "#/$defs/dataset" + } + } + }, + { + "type": "object", + "additionalProperties": false, + "required": [ + "operation" + ], + "properties": { + "operation": { + "$ref": "#/$defs/operation" + } + } + }, + { + "type": "object", + "additionalProperties": false, + "required": [ + "error" + ], + "properties": { + "error": { + "$ref": "#/$defs/error" + } + } + } + ] + }, + "answer": { + "type": "object", + "additionalProperties": false, + "required": [ + "kind", + "complete", + "gaps" + ], + "properties": { + "kind": { + "enum": [ + "resolution", + "catalogue", + "declined" + ] + }, + "status": { + "type": "string", + "minLength": 1 + }, + "sentence": { + "type": [ + "string", + "null" + ] + }, + "complete": { + "type": "boolean" + }, + "specs": { + "description": "The distinct spec_ids of the answer's definite parts, in part order.", + "type": "array", + "items": { + "$ref": "#/$defs/spec_id" + } + }, + "gaps": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "part", + "kind", + "options" + ], + "properties": { + "part": { + "type": "integer", + "minimum": 0 + }, + "kind": { + "$ref": "#/$defs/gap_kind" + }, + "options": { + "type": "integer", + "minimum": 0 + } + } + } + } + } + }, + "dataset": { + "type": "object", + "additionalProperties": false, + "required": [ + "rows", + "columns", + "complete", + "members", + "missing" + ], + "properties": { + "rows": { + "type": "integer", + "minimum": 0 + }, + "columns": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + }, + "complete": { + "type": "boolean" + }, + "members": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "parts", + "spec_id", + "content_version", + "sentence" + ], + "properties": { + "parts": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + }, + "spec_id": { + "$ref": "#/$defs/spec_id" + }, + "content_version": { + "$ref": "#/$defs/content_version" + }, + "sentence": { + "type": "string", + "minLength": 1 + } + } + } + }, + "missing": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "part", + "kind" + ], + "properties": { + "part": { + "type": "integer", + "minimum": 0 + }, + "kind": { + "$ref": "#/$defs/gap_kind" + } + } + } + } + } + }, + "operation": { + "type": "object", + "additionalProperties": false, + "required": [ + "operation_id", + "status" + ], + "properties": { + "operation_id": { + "type": "string", + "pattern": "^op_[0-9a-f]{64}$", + "$ref": "#/$defs/one_line" + }, + "status": { + "enum": [ + "pending", + "running", + "done", + "failed" + ] + } + } + }, + "error": { + "type": "object", + "additionalProperties": false, + "required": [ + "class", + "code" + ], + "properties": { + "class": { + "enum": [ + "InvalidRequestError", + "NotFoundError", + "IncompleteAnswerError", + "DeclinedError", + "VersionUnavailableError", + "AuthenticationError", + "PermissionDeniedError", + "RateLimitError", + "QuotaExceededError", + "ServerError", + "ContractError", + "NetworkError", + "DfoTimeoutError" + ] + }, + "code": { + "description": "The problem document's code, or null for an error no problem document carries.", + "type": [ + "string", + "null" + ] + } + } + } + } +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json new file mode 100644 index 0000000..aaa1cd1 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json @@ -0,0 +1,924 @@ +{ + "format_version": 1, + "name": "fetch-spec-known-sentence", + "description": "Fetching a spec whose sentence the client holds builds bare Parquet, follows the files route's redirect with a bare request, and returns one member with that sentence and no Search call.", + "origin": { + "kind": "recorded", + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "recorded_at": "2026-10-20T15:12:19Z" + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "prepared_at": "2026-10-20T13:59:17Z", + "coverage": { + "rows": 4, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 4 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T13:18:18Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "served_from": "head", + "confirmed_at": "2026-10-20T15:12:19.419215+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal, which hold none at the observation period the other members serve in the requested years." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9541, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T13:59:18.050980+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + { + "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", + "rendering": { + "statistics": "series" + }, + "bytes": 5741, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T13:59:18.050980+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" + } + ], + "series_count": 1, + "output_options": { + "capability_version": "dset_1e6cd9546fac19e9", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 4 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "fetch-spec-known-sentence.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 4, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "crsCooperationModality", + "crsCooperationModality_label", + "crsPurpose", + "crsPurpose_label", + "crsTypeOfFinance", + "crsTypeOfFinance_label", + "crsTypeOfFlow", + "crsTypeOfFlow_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + ], + "missing": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.parquet b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.parquet new file mode 100644 index 0000000000000000000000000000000000000000..e9df5e79ccfa45682c8d8e2b716ce5cb25a955d4 GIT binary patch literal 9541 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 literal 0 HcmV?d00001 diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json b/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json new file mode 100644 index 0000000..3f6904e --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json @@ -0,0 +1,219 @@ +{ + "format_version": 1, + "name": "search-place-ambiguous", + "description": "A question naming a place that matches two countries answers with one no_data part whose entity_ambiguous reason makes a choice gap. This build carries no options, so the gap offers none.", + "origin": { + "kind": "recorded", + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "recorded_at": "2026-10-20T15:12:21Z" + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Congo", + "normalized_query": "ODA disbursements from Germany to Congo", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "trace_id": "3ad2cd38008340ea9db5dcf58365f38d", + "warnings": [], + "timing_ms": { + "total": 1413, + "by_step": { + "coverage": 0, + "extract": 1367 + } + }, + "llm_usage": { + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 1, + "by_step": { + "recall": 1 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "no_data" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "no_data", + "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 0 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/served/SOURCE.json b/python/client-contract/src/dfo_client_contract/served/SOURCE.json new file mode 100644 index 0000000..9a4786c --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/served/SOURCE.json @@ -0,0 +1,6 @@ +{ + "format_version": 1, + "repository": "DevelopmentFinanceObservatory/apis", + "commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "captured_from": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/openapi.json" +} diff --git a/python/client-contract/src/dfo_client_contract/served/openapi.json b/python/client-contract/src/dfo_client_contract/served/openapi.json new file mode 100644 index 0000000..5ef64e0 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/served/openapi.json @@ -0,0 +1,20411 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "DFO APIs", + "version": "1.0" + }, + "paths": { + "/api/search/resolve": { + "post": { + "summary": "Resolve Endpoint", + "operationId": "resolve_endpoint_api_search_resolve_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/search__models__request__ResolveRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "A buffered ResolveResponse JSON document or, with Accept: text/event-stream, progressive Server-Sent Events. Successful streams emit a complete response event and end with done; pipeline failures end with error and emit neither response nor done.", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/Resolution" + }, + { + "$ref": "#/components/schemas/CatalogueAnswer" + }, + { + "$ref": "#/components/schemas/DeclinedAnswer" + } + ], + "title": "Response Resolve Endpoint Api Search Resolve Post", + "discriminator": { + "propertyName": "kind", + "mapping": { + "resolution": "#/components/schemas/Resolution", + "catalogue": "#/components/schemas/CatalogueAnswer", + "declined": "#/components/schemas/DeclinedAnswer" + } + } + } + }, + "text/event-stream": { + "schema": { + "type": "string", + "format": "event-stream", + "description": "Progressive Server-Sent Events frames. On successful streams, the response event contains the complete ResolveResponse body." + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/search/options": { + "post": { + "summary": "Options Endpoint", + "description": "The options door: on-demand candidate enumeration for one resolved\nentity role (origin, destination, or observationAbout) of a posted\nidentity, queried independently of the /resolve pipeline and fetched\nlazily when a user opens an editor.\n\nComposes engine.options.resolve.resolve_options_target (derive the\nposted identity's own StatVar population, typed anchors and\nrole-target validity, server-side, with no resubmit or materialise\npipeline) with engine.options.surface.compute_options (compute the\nper-role option surface), then assembles the envelope here --\nsee those two modules' own docstrings for the full design, including\nthe option_target_invalid (422) role check that runs inside\nresolution. Every EngineInputError either half raises propagates\nuncaught to classify_search_exception above, the same RFC 9457\nproblem body every other door's refusal returns -- no bespoke\nhandling here.\n\nresolve_options_target always runs, hit or miss on the response\ncache below: it is what runs validate_edited_identity and the role/\nanchor refusals, and none of those may be skipped just because an\nidentical target was already answered once. Only build_options_\nresponse's own compute -- the graph/SDMX work -- is what a cache hit\nskips; see options.options_response_cache's own module docstring for\nthe key and the warning-free-result caching rule.", + "operationId": "options_endpoint_api_search_options_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OptionsRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OptionsResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/search/healthz": { + "get": { + "summary": "Healthz", + "operationId": "healthz_api_search_healthz_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HealthResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/search/schema": { + "get": { + "summary": "Schema", + "operationId": "schema_api_search_schema_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1 + }, + "request": { + "type": "object", + "description": "JSON Schema for request" + }, + "response": { + "type": "object", + "description": "JSON Schema for response" + }, + "capabilities": { + "type": "string" + } + }, + "type": "object", + "required": [ + "schema_version", + "request", + "response", + "capabilities" + ] + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/search/capabilities": { + "get": { + "summary": "Capabilities", + "operationId": "capabilities_api_search_capabilities_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/search__engine__capabilities__Capabilities" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/search/catalogue": { + "get": { + "summary": "Catalogue Endpoint", + "description": "What DFO holds and example sentences to ask of it, from the published\nsearch catalogue. `place` scopes the counts to one country and offers the\nexamples whose StatVar has data there, filled with its name.", + "operationId": "catalogue_endpoint_api_search_catalogue_get", + "parameters": [ + { + "name": "place", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "pattern": "^country/\\S+$" + }, + { + "type": "null" + } + ], + "description": "a country dcid; scopes the counts and examples to that country", + "title": "Place" + }, + "description": "a country dcid; scopes the counts and examples to that country" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CatalogueResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/healthz": { + "get": { + "summary": "Healthz", + "operationId": "healthz_api_datasets_healthz_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HealthResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/schema": { + "get": { + "summary": "Schema", + "operationId": "schema_api_datasets_schema_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1 + }, + "mint_request": { + "type": "object", + "description": "JSON Schema for mint_request" + }, + "register_request": { + "type": "object", + "description": "JSON Schema for register_request" + }, + "register_response": { + "type": "object", + "description": "JSON Schema for register_response" + }, + "manifest": { + "type": "object", + "description": "JSON Schema for manifest" + }, + "definition_options_request": { + "type": "object", + "description": "JSON Schema for definition_options_request" + }, + "options_envelope": { + "type": "object", + "description": "JSON Schema for options_envelope" + }, + "definition_members_request": { + "type": "object", + "description": "JSON Schema for definition_members_request" + }, + "members_envelope": { + "type": "object", + "description": "JSON Schema for members_envelope" + }, + "pin_request": { + "type": "object", + "description": "JSON Schema for pin_request" + }, + "pin_response": { + "type": "object", + "description": "JSON Schema for pin_response" + }, + "operation_resource": { + "type": "object", + "description": "JSON Schema for operation_resource" + }, + "description": { + "type": "object", + "description": "JSON Schema for description" + }, + "description_values_page": { + "type": "object", + "description": "JSON Schema for description_values_page" + }, + "problem_details_extensions": { + "type": "object", + "description": "JSON Schema for problem_details_extensions" + }, + "capabilities": { + "type": "string" + } + }, + "type": "object", + "required": [ + "schema_version", + "mint_request", + "register_request", + "register_response", + "manifest", + "definition_options_request", + "options_envelope", + "definition_members_request", + "members_envelope", + "pin_request", + "pin_response", + "operation_resource", + "description", + "description_values_page", + "problem_details_extensions", + "capabilities" + ] + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/capabilities": { + "get": { + "summary": "Capabilities", + "operationId": "capabilities_api_datasets_capabilities_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/datasets_api__capabilities__Capabilities" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/operations/{operation_id}": { + "get": { + "summary": "Get Operation", + "operationId": "get_operation_api_datasets_operations__operation_id__get", + "parameters": [ + { + "name": "operation_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Operation Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OperationResource" + } + } + } + }, + "404": { + "description": "Operation not found", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "500": { + "description": "The operation ran and did not complete successfully", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/register": { + "post": { + "summary": "Register Endpoint", + "operationId": "register_endpoint_api_datasets_register_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RegisterRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DefinitionResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets": { + "post": { + "summary": "Mint Endpoint", + "operationId": "mint_endpoint_api_datasets_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MintRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Manifest" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/{id}": { + "get": { + "summary": "Get Definition", + "operationId": "get_definition_api_datasets__id__get", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Manifest" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/{id}/options": { + "get": { + "summary": "Get Definition Options", + "description": "The definition's current version with no rendering, reported as\n`output_options`: what the data honours. A rebuild records the version and advances\nthe head as a GET does. Any query key refuses `request_invalid` with an\n`/options/` pointer, the same `QueryOptionsInvalid` this door's `get_definition`\nraises for a query key outside its own namespace, through the same\n`query_options.pointer_for_key` mapping.", + "operationId": "get_definition_options_api_datasets__id__options_get", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OptionsEnvelope" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + }, + "post": { + "summary": "Post Definition Options", + "description": "The GET route's envelope for a spec id whose canonical `definition` the body\ncarries, registered or not. An unregistered definition is admitted as a mint admits a\nsidecar, registered, and served as the GET route serves a registered one, so the\nmint that follows is a head hit. Query keys refuse as on the GET route.", + "operationId": "post_definition_options_api_datasets__id__options_post", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DefinitionOptionsRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OptionsEnvelope" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/{id}/members": { + "post": { + "summary": "Post Definition Members", + "description": "The members a mint of the spec serves, resolved without materialising a frame:\neach member's ref, label, declared roles and constraints, their count, and the\nfamily's count and digest. The body may carry the spec's canonical `definition`,\nwhich an unregistered id needs; it is admitted as a mint admits a sidecar and nothing\nis registered. Refusals are the mint's member refusals. Query keys refuse as on the\noptions route.", + "operationId": "post_definition_members_api_datasets__id__members_post", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/DefinitionMembersRequest" + }, + { + "type": "null" + } + ], + "title": "Body" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MembersEnvelope" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/frames/refresh": { + "post": { + "summary": "Refresh Frame", + "description": "Whether the named dataset frame is still its rendering's current frame. Answers\n`current`, `moved` with the current frame, or `pending` with the queued rebuild.", + "operationId": "refresh_frame_api_datasets_frames_refresh_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RefreshFrameRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/FrameCurrent" + }, + { + "$ref": "#/components/schemas/FrameMoved" + }, + { + "$ref": "#/components/schemas/FramePending" + } + ], + "title": "Response Refresh Frame Api Datasets Frames Refresh Post", + "discriminator": { + "propertyName": "status", + "mapping": { + "current": "#/components/schemas/FrameCurrent", + "moved": "#/components/schemas/FrameMoved", + "pending": "#/components/schemas/FramePending" + } + } + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/frames/{spec_id}/{content_version}/recipe": { + "put": { + "summary": "Put Recipe", + "operationId": "put_recipe_api_datasets_frames__spec_id___content_version__recipe_put", + "parameters": [ + { + "name": "spec_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "pattern": "^ops_[0-9a-f]{6,64}$", + "title": "Spec Id" + } + }, + { + "name": "content_version", + "in": "path", + "required": true, + "schema": { + "type": "string", + "pattern": "^ocv_[0-9a-f]{6,64}$", + "title": "Content Version" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Recipe" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecipeWriteResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + }, + "get": { + "summary": "Get Recipe", + "operationId": "get_recipe_api_datasets_frames__spec_id___content_version__recipe_get", + "parameters": [ + { + "name": "spec_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "pattern": "^ops_[0-9a-f]{6,64}$", + "title": "Spec Id" + } + }, + { + "name": "content_version", + "in": "path", + "required": true, + "schema": { + "type": "string", + "pattern": "^ocv_[0-9a-f]{6,64}$", + "title": "Content Version" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Recipe" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/recipes/replays/{replay_key}": { + "get": { + "summary": "Get Replay", + "operationId": "get_replay_api_datasets_recipes_replays__replay_key__get", + "parameters": [ + { + "name": "replay_key", + "in": "path", + "required": true, + "schema": { + "type": "string", + "pattern": "^rpk_[0-9a-f]{32}$", + "title": "Replay Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReplayedFrameResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/{id}/versions": { + "get": { + "summary": "Get Versions", + "operationId": "get_versions_api_datasets__id__versions_get", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DatasetVersionsResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/{id}/{content_version}": { + "get": { + "summary": "Get Snapshot", + "operationId": "get_snapshot_api_datasets__id___content_version__get", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + }, + { + "name": "content_version", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Content Version" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Manifest" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/{id}/{content_version}/description": { + "get": { + "summary": "Get Description", + "operationId": "get_description_api_datasets__id___content_version__description_get", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + }, + { + "name": "content_version", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Content Version" + } + } + ], + "responses": { + "200": { + "description": "the version's description", + "content": { + "application/json": { + "schema": { + "type": "object", + "description": "A version's description, in the schema https://developmentfinance.org/descriptions/schema/v1/description.schema.json", + "properties": { + "describes": {}, + "title": {}, + "about": {}, + "sources": {}, + "freshness": {}, + "steps": {}, + "cite": {}, + "caveats": {}, + "gaps": {}, + "built_from": {} + } + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/{id}/{content_version}/description/values": { + "get": { + "summary": "Get Description Values", + "operationId": "get_description_values_api_datasets__id___content_version__description_values_get", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + }, + { + "name": "content_version", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Content Version" + } + }, + { + "name": "property", + "in": "query", + "required": true, + "schema": { + "type": "string", + "title": "Property" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 100, + "title": "Limit" + } + }, + { + "name": "cursor", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Cursor" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DescriptionValuesPage" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/{id}/{content_version}/files/{digest}": { + "get": { + "summary": "Get File", + "operationId": "get_file_api_datasets__id___content_version__files__digest__get", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + }, + { + "name": "content_version", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Content Version" + } + }, + { + "name": "digest", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Digest" + } + } + ], + "responses": { + "302": { + "description": "a redirect to the artifact's bytes", + "headers": { + "Location": { + "description": "a GET URL signed for at most five minutes", + "schema": { + "type": "string" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/{id}/{content_version}/observations": { + "get": { + "summary": "Get Observations", + "operationId": "get_observations_api_datasets__id___content_version__observations_get", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + }, + { + "name": "content_version", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Content Version" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SpecObservations" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/{id}/{content_version}/pin": { + "post": { + "summary": "Post Pin", + "operationId": "post_pin_api_datasets__id___content_version__pin_post", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + }, + { + "name": "content_version", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Content Version" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PinRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PinResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/datasets/frames/publish": { + "post": { + "summary": "Post Publish", + "description": "Publish a validated body under the permit the route class took for this request.", + "operationId": "post_publish_api_datasets_frames_publish_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublishFrameRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublishFrameResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/graph/healthz": { + "get": { + "summary": "Healthz", + "operationId": "healthz_api_graph_healthz_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HealthResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/graph/capabilities": { + "get": { + "summary": "Capabilities", + "operationId": "capabilities_api_graph_capabilities_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/graph_api__capabilities__Capabilities" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/graph/schema": { + "get": { + "summary": "Schema", + "operationId": "schema_api_graph_schema_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GraphSchema" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/graph/resolve": { + "post": { + "summary": "Resolve Endpoint", + "operationId": "resolve_endpoint_api_graph_resolve_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/graph_api__resolve_models__ResolveRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResolveResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/graph/documentation/{dcid}": { + "get": { + "summary": "Sources Endpoint", + "operationId": "sources_endpoint_api_graph_documentation__dcid__get", + "parameters": [ + { + "name": "dcid", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Dcid" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SourceDocumentation" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/graph/sources": { + "get": { + "summary": "Sources Catalogue Endpoint", + "operationId": "sources_catalogue_endpoint_api_graph_sources_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SourceCatalogue" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/graph/node/{dcid}/members": { + "get": { + "summary": "Members Endpoint", + "operationId": "members_endpoint_api_graph_node__dcid__members_get", + "parameters": [ + { + "name": "dcid", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Dcid" + } + }, + { + "name": "relation", + "in": "query", + "required": true, + "schema": { + "enum": [ + "codes", + "children", + "datasets", + "variables", + "members", + "countries", + "facets" + ], + "type": "string", + "title": "Relation" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 200, + "title": "Limit" + } + }, + { + "name": "cursor", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Cursor" + } + }, + { + "name": "projection", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/Projection" + }, + { + "type": "null" + } + ], + "title": "Projection" + } + }, + { + "name": "as_of", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + { + "name": "source", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source" + } + }, + { + "name": "unit", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Unit" + } + }, + { + "name": "measurement_method", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Measurement Method" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MembersPage" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/graph/roots": { + "get": { + "summary": "Roots Endpoint", + "operationId": "roots_endpoint_api_graph_roots_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Roots" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/graph/node/{dcid}": { + "get": { + "summary": "Node Endpoint", + "operationId": "node_endpoint_api_graph_node__dcid__get", + "parameters": [ + { + "name": "dcid", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Dcid" + } + }, + { + "name": "as_of", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/StatVarNode" + }, + { + "$ref": "#/components/schemas/CodeSystemNode" + }, + { + "$ref": "#/components/schemas/CodeNode" + }, + { + "$ref": "#/components/schemas/GroupNode" + }, + { + "$ref": "#/components/schemas/CountryNode" + }, + { + "$ref": "#/components/schemas/ContinentNode" + }, + { + "$ref": "#/components/schemas/SubregionNode" + }, + { + "$ref": "#/components/schemas/ContinentalUnionNode" + }, + { + "$ref": "#/components/schemas/PlaceOtherNode" + }, + { + "$ref": "#/components/schemas/OrganisationNode" + }, + { + "$ref": "#/components/schemas/AggregateNode" + }, + { + "$ref": "#/components/schemas/UnitNode" + }, + { + "$ref": "#/components/schemas/SourceNode" + }, + { + "$ref": "#/components/schemas/DatasetNode" + }, + { + "$ref": "#/components/schemas/ProvenanceNode" + }, + { + "$ref": "#/components/schemas/OtherNode" + } + ], + "discriminator": { + "propertyName": "kind", + "mapping": { + "stat_var": "#/components/schemas/StatVarNode", + "code_system": "#/components/schemas/CodeSystemNode", + "code": "#/components/schemas/CodeNode", + "group": "#/components/schemas/GroupNode", + "country": "#/components/schemas/CountryNode", + "continent": "#/components/schemas/ContinentNode", + "subregion": "#/components/schemas/SubregionNode", + "continental_union": "#/components/schemas/ContinentalUnionNode", + "place_other": "#/components/schemas/PlaceOtherNode", + "organisation": "#/components/schemas/OrganisationNode", + "aggregate": "#/components/schemas/AggregateNode", + "unit": "#/components/schemas/UnitNode", + "source": "#/components/schemas/SourceNode", + "dataset": "#/components/schemas/DatasetNode", + "provenance": "#/components/schemas/ProvenanceNode", + "other": "#/components/schemas/OtherNode" + } + }, + "title": "Response Node Endpoint Api Graph Node Dcid Get" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/graph/nodes": { + "post": { + "summary": "Nodes Endpoint", + "operationId": "nodes_endpoint_api_graph_nodes_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NodesRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NodesResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/presentation/healthz": { + "get": { + "summary": "Healthz", + "operationId": "healthz_api_presentation_healthz_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HealthResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/presentation/capabilities": { + "get": { + "summary": "Capabilities", + "operationId": "capabilities_api_presentation_capabilities_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CapabilitiesResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/presentation/components": { + "post": { + "summary": "Create Component", + "operationId": "create_component_api_presentation_components_post", + "parameters": [ + { + "name": "x-dfo-write-token", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Dfo-Write-Token" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateComponentBody" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateReplyResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/presentation/components/{component_id}": { + "patch": { + "summary": "Revise Component", + "operationId": "revise_component_api_presentation_components__component_id__patch", + "parameters": [ + { + "name": "component_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Component Id" + } + }, + { + "name": "x-dfo-write-token", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Dfo-Write-Token" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ComponentBody" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WriteReplyResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + }, + "get": { + "summary": "Read Component", + "operationId": "read_component_api_presentation_components__component_id__get", + "parameters": [ + { + "name": "component_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Component Id" + } + }, + { + "name": "revision", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "integer", + "minimum": 1 + }, + { + "type": "null" + } + ], + "title": "Revision" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ComponentReadResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/presentation/components/{component_id}/revisions/{revision}/data": { + "get": { + "summary": "Read Component Data", + "operationId": "read_component_data_api_presentation_components__component_id__revisions__revision__data_get", + "parameters": [ + { + "name": "component_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Component Id" + } + }, + { + "name": "revision", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "minimum": 1, + "title": "Revision" + } + }, + { + "name": "format", + "in": "query", + "required": false, + "schema": { + "enum": [ + "csv", + "xlsx", + "parquet" + ], + "type": "string", + "default": "csv", + "title": "Format" + } + }, + { + "name": "bundle", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "default": true, + "title": "Bundle" + } + } + ], + "responses": { + "200": { + "description": "The rows behind every value the revision shows. `bundle=true` serves a zip holding the file under `data/` with `data/codes.csv`, `datapackage.json`, `CITATION.cff`, `README.md`, and `SOURCES.md`.", + "content": { + "application/zip": {}, + "text/csv": {}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": {}, + "application/vnd.apache.parquet": {} + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/presentation/components/{component_id}/revisions/{revision}/render": { + "post": { + "summary": "Render Component Revision", + "description": "Draw one stored revision on the frame the body names. Appends no revision.", + "operationId": "render_component_revision_api_presentation_components__component_id__revisions__revision__render_post", + "parameters": [ + { + "name": "component_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Component Id" + } + }, + { + "name": "revision", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "minimum": 1, + "title": "Revision" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RenderBody" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ComponentReadResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/presentation/components/{component_id}/revisions/{revision}/render/data": { + "get": { + "summary": "Read Rendered Component Data", + "description": "The data export of one stored revision drawn on the frame the query names.", + "operationId": "read_rendered_component_data_api_presentation_components__component_id__revisions__revision__render_data_get", + "parameters": [ + { + "name": "component_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Component Id" + } + }, + { + "name": "revision", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "minimum": 1, + "title": "Revision" + } + }, + { + "name": "spec_id", + "in": "query", + "required": true, + "schema": { + "type": "string", + "title": "Spec Id" + } + }, + { + "name": "content_version", + "in": "query", + "required": true, + "schema": { + "type": "string", + "title": "Content Version" + } + }, + { + "name": "format", + "in": "query", + "required": false, + "schema": { + "enum": [ + "csv", + "xlsx", + "parquet" + ], + "type": "string", + "default": "csv", + "title": "Format" + } + }, + { + "name": "bundle", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "default": true, + "title": "Bundle" + } + } + ], + "responses": { + "200": { + "description": "The rows behind every value the revision shows when drawn on the named frame, as the component data route serves a stored revision's.", + "content": { + "application/zip": {}, + "text/csv": {}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": {}, + "application/vnd.apache.parquet": {} + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/presentation/frames/{spec_id}/{content_version}": { + "get": { + "summary": "Get Frame", + "operationId": "get_frame_api_presentation_frames__spec_id___content_version__get", + "parameters": [ + { + "name": "spec_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Spec Id" + } + }, + { + "name": "content_version", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Content Version" + } + }, + { + "name": "dimension", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Dimension" + } + }, + { + "name": "query", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Query" + } + } + ], + "responses": { + "200": { + "description": "Neither `dimension` nor `query` given returns the frame's structural view. `dimension` alone returns that one dimension's full value list. `query` alone returns every dimension filtered to values matching the query. `dimension` and `query` together return that one dimension's values filtered to the query.", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/FrameStructuralViewResponse" + }, + { + "$ref": "#/components/schemas/FrameDimensionValuesResponse" + }, + { + "$ref": "#/components/schemas/FrameFilteredViewResponse" + } + ], + "title": "Response 200 Get Frame Api Presentation Frames Spec Id Content Version Get" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/presentation/release": { + "get": { + "summary": "Get Release", + "operationId": "get_release_api_presentation_release_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseDocumentResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/skills/healthz": { + "get": { + "summary": "Healthz", + "operationId": "healthz_api_skills_healthz_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HealthResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/skills": { + "get": { + "summary": "List Endpoint", + "operationId": "list_endpoint_api_skills_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SkillListResponse" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/skills/{skill_id}": { + "get": { + "summary": "Fetch Endpoint", + "operationId": "fetch_endpoint_api_skills__skill_id__get", + "parameters": [ + { + "name": "skill_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Skill Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SkillBody" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/skills/{skill_id}/resources/{path}": { + "get": { + "summary": "Resource Endpoint", + "operationId": "resource_endpoint_api_skills__skill_id__resources__path__get", + "parameters": [ + { + "name": "skill_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Skill Id" + } + }, + { + "name": "path", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Path" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SkillResourceContent" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/codes/{code}": { + "get": { + "summary": "Code Registry Entry", + "operationId": "code_registry_entry_codes__code__get", + "parameters": [ + { + "name": "code", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Code" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CodeRegistryEntry" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "AggregateNode": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the node's dcid" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "the node's name; for a Provenance, its parent Dataset's name where it has one. Null, and named in gaps, when the graph gives none" + }, + "types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Types", + "description": "the node's typeOf values, as the graph holds them" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "the node's prose in the graph; null when it has none" + }, + "links": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "codes", + "children", + "members", + "countries", + "datasets", + "variables", + "facets" + ] + }, + "type": "object", + "title": "Links", + "description": "each list relation the node has, mapped to its route; empty when none" + }, + "gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Gaps", + "description": "the member path of every value this door cannot know" + }, + "built_from": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "code_index", + "origin_catalogue", + "coverage_index", + "membership" + ] + }, + "type": "object", + "title": "Built From", + "description": "the build of each table the response read" + }, + "kind": { + "type": "string", + "const": "aggregate", + "title": "Kind", + "default": "aggregate" + }, + "aggregate": { + "$ref": "#/components/schemas/PartyBlock" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "types", + "description", + "links", + "gaps", + "built_from", + "kind", + "aggregate" + ], + "title": "AggregateNode" + }, + "AidCounts": { + "properties": { + "donors": { + "type": "integer", + "title": "Donors", + "description": "distinct donors: countries and organisations, leaving out the parties that total other donors (DAC countries, the G7)" + }, + "recipients": { + "type": "integer", + "title": "Recipients", + "description": "distinct recipients: countries, organisations and the residuals no country holds (Africa, unallocated by country), leaving out the parties that total other recipients (Africa, Total)" + }, + "years": { + "anyOf": [ + { + "$ref": "#/components/schemas/YearRange" + }, + { + "type": "null" + } + ], + "description": "the years with aid data; null when none" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "donors", + "recipients", + "years" + ], + "title": "AidCounts", + "description": "Counts over the coverage index's rows of the declared datasets." + }, + "AmbiguousEntityCandidate": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the candidate's own dcid" + }, + "label": { + "type": "string", + "title": "Label", + "description": "the candidate's display name" + }, + "kind": { + "type": "string", + "title": "Kind", + "description": "the candidate's entity kind: country, continent, subregion, continental_union, organisation, aggregate, place_other, or other" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref", + "label", + "kind" + ], + "title": "AmbiguousEntityCandidate", + "description": "One graph node an ambiguous query wording could name -- one entry of\nan AmbiguousEntityGroup's own `candidates`. Mirrors engine.region.result.\nAmbiguousEntityCandidate field-for-field, with `label` in place of that\ndataclass's `name` (this contract's own vocabulary for a display\nstring, matching ResolvedEntity.label)." + }, + "AmbiguousEntityGroup": { + "properties": { + "text": { + "type": "string", + "title": "Text", + "description": "the ambiguous query wording; equals some restatement.entities[i].text on the same part" + }, + "candidates": { + "items": { + "$ref": "#/components/schemas/AmbiguousEntityCandidate" + }, + "type": "array", + "title": "Candidates", + "description": "the graph candidates this wording could name -- 2+ from a real Ambiguous resolution, by construction of the resolver's own Ambiguous outcome (2+ candidates graph-confirm and none can be preferred); not constrained to a minimum here since region.AmbiguousEntity, this field's own engine-side source, carries no such constraint of its own" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "candidates" + ], + "title": "AmbiguousEntityGroup", + "description": "One query wording Ambiguous resolved to more than one graph\ncandidate, paired with the candidates it could name -- one entry of\nNoData.ambiguous_entities." + }, + "AmbiguousSourceCandidate": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the source's reference, which a client posts back as a SourceMention's ref" + }, + "label": { + "type": "string", + "title": "Label", + "description": "the source's display name in the origin catalogue" + }, + "kind": { + "type": "string", + "enum": [ + "provenance", + "dataset", + "source" + ], + "title": "Kind", + "description": "what the reference names: a provenance, a catalogue Dataset, or a publishing Source" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref", + "label", + "kind" + ], + "title": "AmbiguousSourceCandidate", + "description": "One reading of an ambiguous source wording -- one entry of an\nAmbiguousSourceGroup's own `candidates`." + }, + "AmbiguousSourceGroup": { + "properties": { + "text": { + "type": "string", + "title": "Text", + "description": "the ambiguous wording; equals some restatement.sources[i].text on the part, or its restatement.source_code for source_code_ambiguous" + }, + "candidates": { + "items": { + "$ref": "#/components/schemas/AmbiguousSourceCandidate" + }, + "type": "array", + "title": "Candidates", + "description": "the admitted sources this wording names, two or more: provenances first, then datasets and sources" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "candidates" + ], + "title": "AmbiguousSourceGroup", + "description": "One source wording that names two or more unrelated admitted sources, paired with\nthe sources it could name -- one entry of NoData.ambiguous_sources." + }, + "AppliedDefaultModel": { + "properties": { + "pointer": { + "type": "string", + "title": "Pointer", + "description": "a JSON Pointer to the intent field this default fills" + }, + "detail": { + "type": "string", + "title": "Detail", + "description": "what the component chose and how to narrow it, in plain language" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "pointer", + "detail" + ], + "title": "AppliedDefaultModel", + "description": "One `fact_summary.defaults[]` entry: a choice the component made where its intent\nleft one open. An entity-mode bar_chart whose select lists no values draws every value\nof its one varying dimension, largest first." + }, + "ArtifactEntryModel": { + "properties": { + "artifact_digest": { + "type": "string", + "title": "Artifact Digest" + }, + "rendering": { + "additionalProperties": true, + "type": "object", + "title": "Rendering", + "description": "the rendering that produced the bytes: the request options of a requested file, {\"statistics\": \"series\"} for the series statistics, or {\"format\": \"frame\"} for the version's canonical frame, a Parquet file of the frame as minted" + }, + "bytes": { + "type": "integer", + "title": "Bytes" + }, + "media_type": { + "type": "string", + "title": "Media Type" + }, + "created_at": { + "type": "string", + "title": "Created At" + }, + "tier": { + "type": "string", + "title": "Tier" + }, + "url": { + "type": "string", + "title": "Url", + "description": "the artifact's stable download link, `/api/datasets/{id}/{content_version}/files/{artifact_digest}`, relative to the API host. It never expires: each request checks the version and answers 302 to a signed URL valid for five minutes, or refuses snapshot_revoked once the version is taken down" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "artifact_digest", + "rendering", + "bytes", + "media_type", + "created_at", + "tier", + "url" + ], + "title": "ArtifactEntryModel" + }, + "Authority": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "version": { + "type": "string", + "title": "Version" + } + }, + "type": "object", + "required": [ + "name", + "version" + ], + "title": "GraphMembershipAuthority", + "description": "Where a membership's rows come from, with the data version that reproduces them." + }, + "Availability": { + "properties": { + "scope": { + "type": "string", + "const": "dfo", + "title": "Scope", + "default": "dfo" + }, + "summary": { + "$ref": "#/components/schemas/AvailabilitySummary" + }, + "default": { + "anyOf": [ + { + "$ref": "#/components/schemas/AvailabilityDefault" + }, + { + "type": "null" + } + ], + "description": "null when no facet dispatches a request naming nothing" + }, + "sources": { + "items": { + "$ref": "#/components/schemas/SourceAvailability" + }, + "type": "array", + "title": "Sources" + }, + "more_sources": { + "type": "integer", + "title": "More Sources", + "description": "the sources past the first ten" + } + }, + "type": "object", + "required": [ + "scope", + "summary", + "default", + "sources", + "more_sources" + ], + "title": "GraphAvailability", + "description": "Where DFO holds observations of a variable. `sources: []` means it verifiably holds\nnone." + }, + "AvailabilityDefault": { + "properties": { + "facets": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Facets", + "description": "the facet ids the request is served, in order" + }, + "source": { + "anyOf": [ + { + "$ref": "#/components/schemas/AvailabilitySource" + }, + { + "type": "null" + } + ] + }, + "unit": { + "anyOf": [ + { + "$ref": "#/components/schemas/NodeRef" + }, + { + "type": "null" + } + ] + }, + "measurement_method": { + "anyOf": [ + { + "$ref": "#/components/schemas/NodeRef" + }, + { + "type": "null" + } + ] + }, + "observation_period": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Observation Period" + }, + "first_year": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "First Year" + }, + "last_year": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Year" + }, + "places": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Places", + "description": "null for a role-bearing variable" + }, + "without_data": { + "type": "integer", + "title": "Without Data", + "description": "the places, or parties, holding the variable that the default leaves without data" + } + }, + "type": "object", + "required": [ + "facets", + "source", + "unit", + "measurement_method", + "observation_period", + "first_year", + "last_year", + "places", + "without_data" + ], + "title": "GraphAvailabilityDefault", + "description": "What a data request naming no place, years or facet receives." + }, + "AvailabilitySource": { + "properties": { + "ref": { + "type": "string", + "title": "Ref" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label" + }, + "documentation": { + "type": "string", + "title": "Documentation", + "description": "the path of the provenance's source document" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "documentation" + ], + "title": "GraphAvailabilitySource", + "description": "A source that holds the variable: its provenance, labelled with the catalogue's name." + }, + "AvailabilitySummary": { + "properties": { + "places": { + "anyOf": [ + { + "additionalProperties": { + "type": "integer" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Places", + "description": "the places covered by kind; null for a role-bearing variable, and while the places' kinds are unread (a transient gap)" + }, + "entities": { + "anyOf": [ + { + "additionalProperties": { + "$ref": "#/components/schemas/EntityCounts" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Entities", + "description": "the entities covered per graph role; null for any other variable" + }, + "first_year": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "First Year" + }, + "last_year": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Year" + }, + "sources": { + "type": "integer", + "title": "Sources" + }, + "facets": { + "type": "integer", + "title": "Facets" + } + }, + "type": "object", + "required": [ + "places", + "entities", + "first_year", + "last_year", + "sources", + "facets" + ], + "title": "GraphAvailabilitySummary", + "description": "The variable across every source." + }, + "BaseIdentity": { + "properties": { + "identity_version": { + "type": "string", + "const": "spec1", + "title": "Identity Version", + "description": "the identity domain separator this Spec was hashed under", + "default": "spec1" + }, + "shape": { + "oneOf": [ + { + "$ref": "#/components/schemas/IdentityShapeSchema" + }, + { + "$ref": "#/components/schemas/IdentityShapePin" + } + ], + "title": "Shape", + "description": "the shape this Spec was hashed under", + "discriminator": { + "propertyName": "kind", + "mapping": { + "stat_var": "#/components/schemas/IdentityShapePin", + "statvar_schema": "#/components/schemas/IdentityShapeSchema" + } + } + }, + "slots": { + "items": { + "$ref": "#/components/schemas/IdentitySlot" + }, + "type": "array", + "maxItems": 64, + "title": "Slots", + "description": "the what/how slots that feed identity -- where/when/source are excluded" + }, + "entities": { + "additionalProperties": { + "items": { + "type": "string", + "maxLength": 1024 + }, + "type": "array", + "maxItems": 1024, + "minItems": 1 + }, + "type": "object", + "maxProperties": 16, + "title": "Entities", + "description": "the bound entities, keyed by role (observationAbout/origin/destination); {} when none were bound -- always present, never omitted. A role that appears carries at least one dcid: the identity core refuses a role with zero members, so an empty list must not be expressible here" + }, + "requested_window": { + "oneOf": [ + { + "$ref": "#/components/schemas/IdentityWindowAll" + }, + { + "$ref": "#/components/schemas/IdentityWindowLatest" + }, + { + "$ref": "#/components/schemas/IdentityWindowRange" + } + ], + "title": "Requested Window", + "description": "the requested date window this Spec was hashed under; always present -- {\"kind\": \"all\"} means no date was requested at all", + "discriminator": { + "propertyName": "kind", + "mapping": { + "all": "#/components/schemas/IdentityWindowAll", + "latest": "#/components/schemas/IdentityWindowLatest", + "range": "#/components/schemas/IdentityWindowRange" + } + } + }, + "facets": { + "anyOf": [ + { + "additionalProperties": { + "oneOf": [ + { + "$ref": "#/components/schemas/IdentityBindingValue" + }, + { + "$ref": "#/components/schemas/IdentityBindingSet" + }, + { + "$ref": "#/components/schemas/IdentityFacetValueRequest" + }, + { + "$ref": "#/components/schemas/IdentityFacetValueAbsent" + } + ] + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Facets", + "description": "sparse facet bindings (provenance/measurementMethod/unit); omitted entirely when no facet axis is bound, never an empty object. A facet axis that appears is bound -- value, set, or (unit axis only) the request form -- never unbound: the identity core refuses an unbound facet binding state, since a sparse map omits what is not bound rather than carrying it as unbound" + }, + "open_roles": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/RoleAxis" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Open Roles", + "description": "the flow axes asked for member by member (every creditor, every donor), sorted and de-duplicated; omitted when none is. A role absent from both entities and open_roles asks for the total over that role. An open role is never also an entities key, and a pinned shape (kind='stat_var') carries none" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "shape", + "slots", + "requested_window" + ], + "title": "BaseIdentity", + "description": "The spec1 identity-core projection document for one Spec: exactly what\ngets hashed to produce its spec_id, serialised once and echoed back\nverbatim -- never re-derived by a second, parallel implementation.\n\nEvery Spec carries one, on `Spec.definition.identity` (see\n`SpecDefinition`). A dataset_resubmit identity entry posts a prior Spec's own\n`definition.identity` byte-for-byte as its edited `identity`. Directional\nentities live directly in `identity.entities.origin` and\n`identity.entities.destination`. StatVar members are graph state, derived from the\nidentity, and no member here.\n\nThe document is hashed whole. `\"spec_\"` plus the first 32 hex digits of\nthe SHA-256 of its RFC 8785 serialisation, with null members omitted, is\nthe Spec's spec_id." + }, + "Binding": { + "properties": { + "provenance": { + "type": "string", + "title": "Provenance" + }, + "measurementMethod": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Measurementmethod" + }, + "unit": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Unit" + } + }, + "type": "object", + "required": [ + "provenance", + "measurementMethod", + "unit" + ], + "title": "GraphAvailabilityBinding", + "description": "The `scope.facets` values that request a series from Datasets, in its leading unit." + }, + "BindingSet": { + "properties": { + "kind": { + "type": "string", + "const": "set", + "title": "Kind", + "description": "binding kind discriminator", + "default": "set" + }, + "values": { + "items": { + "$ref": "#/components/schemas/SlotValue" + }, + "type": "array", + "minItems": 2, + "title": "Values", + "description": "two or more members, all in scope (a union)" + }, + "set_ref": { + "anyOf": [ + { + "$ref": "#/components/schemas/GraphRef" + }, + { + "type": "null" + } + ], + "description": "the group the set was drawn from, when one exists" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "values" + ], + "title": "BindingSet", + "description": "A slot bound to two or more taxonomy members, all in scope." + }, + "BindingUnbound": { + "properties": { + "kind": { + "type": "string", + "const": "unbound", + "title": "Kind", + "description": "explicit whole slot in scope, NOT null/missing", + "default": "unbound" + } + }, + "additionalProperties": false, + "type": "object", + "title": "BindingUnbound", + "description": "A slot explicitly open to the whole slot in scope, NOT null or missing." + }, + "BindingValue": { + "properties": { + "kind": { + "type": "string", + "const": "value", + "title": "Kind", + "description": "binding kind discriminator", + "default": "value" + }, + "value": { + "$ref": "#/components/schemas/SlotValue", + "description": "exactly one taxonomy member" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "value" + ], + "title": "BindingValue", + "description": "A slot bound to exactly one taxonomy member." + }, + "BreadthDim": { + "properties": { + "label": { + "type": "string", + "title": "Label", + "description": "the dimension, e.g. providers, years, methods, sources" + }, + "count": { + "type": "integer", + "title": "Count", + "description": "e.g. 36, 22, 3" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "label", + "count" + ], + "title": "BreadthDim", + "description": "One breadth dimension with its cardinality." + }, + "BundleOptionModel": { + "properties": { + "state": { + "type": "string", + "title": "State" + }, + "reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "state" + ], + "title": "BundleOptionModel" + }, + "CandidateSet": { + "properties": { + "ordering": { + "type": "string", + "enum": [ + "broadest_first", + "intent_rank" + ], + "title": "Ordering", + "description": "how `specs` below is ordered -- see the two orderings described above" + }, + "max_candidates": { + "type": "integer", + "title": "Max Candidates", + "description": "the maximum number of candidates applied" + }, + "specs": { + "items": { + "$ref": "#/components/schemas/Spec", + "description": "the resolved Spec answering this part. Several parts sharing one five-tuple shape carry the identical spec verbatim (the same spec_id); a part that shares the spec without minting it carries a part-scoped binding_folded warning" + }, + "type": "array", + "minItems": 2, + "title": "Specs", + "description": "2 <= len <= max_candidates; full Specs, ordered per `ordering` above" + }, + "truncated": { + "type": "boolean", + "title": "Truncated", + "description": "false when every eligible, semantically distinct candidate shape found for this query is present in specs; true when the engine's own candidate budget dropped an eligible shape before it could be considered, or max_candidates itself cut the ordered list short" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ordering", + "max_candidates", + "specs", + "truncated" + ], + "title": "CandidateSet", + "description": "A set of 2..N competing Specs, presented in the order named by ``ordering``.\n\n``ordering=\"intent_rank\"``: the order the status rule offers the readings in. A first\nanswer always uses it. The elected reading comes first, then its rivals in menu order,\neach stating why it is offered (``ResolvedSpec.basis``). Where the elected reading holds\nno data and several siblings differing from it only on the measurement qualifier do,\nthose siblings are the set, in menu order, without it. Where a place named without a\ndirection holds data under both, the elected reading under each direction is offered.\n\n``ordering=\"broadest_first\"``: a posted candidates entry that names it\n(``ResubmitCandidatesEntry``) keeps its posted order and states this ordering back. No\nfirst answer uses it.\n\nEach candidate carries its own heading and byline inside its own\n``resolved.rendered_sentence``/``resolved.sentence_plan``. There is no separate parallel sentence array, and a\ncandidate's Spec is a returned Spec like any other. The part's own\nsentence opens with how many readings there are and states, for each\nshown candidate, the source and span that set it apart." + }, + "CandidatesPart": { + "properties": { + "variable_text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Variable Text", + "description": "the variable text this part answers, in the order asked. This part's position in Resolution.parts equals the same variable_index every SSE event keyed by variable_index uses (ShapeEvent, StepEvent, SentenceEvent). Every dataset_resubmit entry kind (identity, candidates, placeholder, and parsed through its nested ParsedPart) requires its own posted variable_text, so this field is always the posted text echoed back onto the rebuilt part, never null. Null only when the whole posted query was empty or whitespace-only (raw_text door), which refuses variable_not_resolved before extraction runs and so has no text to name." + }, + "separate": { + "type": "boolean", + "title": "Separate", + "description": "true when this part was asked beside the others to be compared with them. A client resubmitting an identity, candidate set, or placeholder posts this flag on that entry to preserve the comparison. False, the default, is omitted", + "default": false + }, + "warnings": { + "items": { + "$ref": "#/components/schemas/Warning" + }, + "type": "array", + "title": "Warnings", + "description": "this part's own run-health signals. A part folded into an earlier part's spec (see DefinitePart.spec) carries binding_folded alone. The merged spec's own resolved warnings live only on the first part that carries it. An unfolded part carries the warnings raised while resolving this part, plus observations_omitted on a candidates part when response_options.include_observations was set." + }, + "timing_ms": { + "anyOf": [ + { + "$ref": "#/components/schemas/Timing" + }, + { + "type": "null" + } + ], + "description": "this part's own latency breakdown, where by_step names only the phases this part ran and total sums them, leaving out the shape_* stages nested inside shape. Excludes the shared, once-per-request steps (e.g. extract), which diagnostics.timing_ms.by_step carries once for the whole request; distinct too from diagnostics.timing_ms.total, the whole request's wall-clock elapsed time." + }, + "rendered_sentence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Rendered Sentence", + "description": "a human-readable string. For candidates, a header naming how many readings there are ('3 readings.'), then each shown candidate's heading and a byline led by the source and span that set it apart; for no_data, a heading in the same claim form naming the entity, measure, and counterpart that were checked. Either ends with the text of this part's departures, in order. For a definite part this stays null or omitted: the confirmation sentence (heading and byline) lives at spec.resolved.rendered_sentence, and its departures reach the envelope's composed sentence." + }, + "sentence_plan": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/SentenceToken" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Sentence Plan", + "description": "the ordered token form of rendered_sentence, present whenever it is. For a definite part this stays null or omitted. spec.resolved.sentence_plan carries the confirmation sentence's own plan instead." + }, + "restatement": { + "anyOf": [ + { + "$ref": "#/components/schemas/ParsedPart" + }, + { + "type": "null" + } + ], + "description": "the ParsedPart that reproduces this part's own resolution inputs -- the same entities, resolved time window, unit text, and source text the engine actually used to resolve this one leg -- so a client holding this part alone can copy it straight into a fresh ParsedInput.parts entry and re-resolve it faithfully, without flattening it into the whole query's variable_text the way variable_text alone would. Canonical, not verbatim: for a raw_text part, time_text is the equivalent phrase this door's own time grammar recognises (e.g. '2015 to 2020'), not the user's original words, since the engine's date extraction keeps only the structured window and discards the phrasing. Null whenever this part has no faithful echo to give. On a dataset_resubmit entry's identity/candidates/placeholder kinds, which post an identity or stub rather than a phrase and have no per-part resolution inputs to echo -- a dataset_resubmit parsed entry, genuinely re-resolved from its own posted ParsedPart, carries a real one like any parsed-door part. Also null when this leg's entity was bound to a directional role axis (origin/destination) and no door-supplied role named that axis, since an echo without the axis would resubmit the request with that entity reversed. Also null when one of this leg's own inputs does not fit ParsedPart's own field caps, since a truncated echo would misrepresent what was actually resolved." + }, + "operations": { + "items": { + "$ref": "#/components/schemas/Operation" + }, + "type": "array", + "title": "Operations", + "description": "the operations the question asks for over this part's data, in query order; the engine echoes them onto the part it resolves. Empty when the question asks for none" + }, + "departures": { + "items": { + "$ref": "#/components/schemas/Departure" + }, + "type": "array", + "title": "Departures", + "description": "every way this part's answer differs from what its request asked, ordered by how much each changes the number: closest_match, measure_not_applied, operation_not_applied, breakdown_not_applied, entity_unavailable, year_unavailable, modelled_values, group_read_as_members, direction_discarded, direction_inferred, scope_limited. [] when the answer is what was asked. A client that renders its own sentence reads them here; each one's text also closes the sentence that carries this part (see Departure.text). A warning on the same part reports run health and stays separate" + }, + "status": { + "type": "string", + "const": "candidates", + "title": "Status", + "description": "this part's variable was genuinely ambiguous" + }, + "candidates": { + "$ref": "#/components/schemas/CandidateSet", + "description": "2..N competing Specs" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "status", + "candidates" + ], + "title": "CandidatesPart", + "description": "This part's variable was genuinely ambiguous; two or more distinct specs compete." + }, + "CanonicalDefinition": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "description": "the wire version this definition was written under" + }, + "spec_id": { + "type": "string", + "title": "Spec Id", + "description": "the caller-supplied spec_id this definition must hash to" + }, + "identity": { + "additionalProperties": true, + "type": "object", + "title": "Identity", + "description": "the identity-core document, shaped as search.models.identity.BaseIdentity and published at GET /api/search/schema" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "schema_version", + "spec_id", + "identity" + ], + "title": "CanonicalDefinition", + "description": "One canonical definition, exactly as the contract shapes it: the wire\nversion it was written under, its own spec_id (required -- the register\ndoor always verifies a supplied id, never mints one for a definition),\nand its identity-core document." + }, + "CapabilitiesResponse": { + "properties": { + "capability_version": { + "type": "string", + "title": "Capability Version", + "description": "a content hash over every capability-bearing field of the release this deployment serves" + }, + "catalog_version": { + "type": "string", + "title": "Catalog Version", + "description": "the catalogue release this deployment serves" + }, + "build": { + "type": "string", + "title": "Build", + "description": "the commit sha the image was built from, the same value the x-dfo-commit response header carries" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "capability_version", + "catalog_version", + "build" + ], + "title": "CapabilitiesResponse", + "description": "`GET /api/presentation/capabilities`'s body. It carries this\nsurface's own hashed `capability_version` beside the unhashed\n`catalog_version`." + }, + "CapabilityDefaultPolicy": { + "properties": { + "name": { + "type": "string", + "title": "Name", + "description": "the declared default policy's name" + }, + "live": { + "type": "boolean", + "title": "Live", + "description": "whether this deployment honours the declared default" + }, + "default": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Default", + "description": "the current default value, when this policy is a boolean toggle" + } + }, + "type": "object", + "required": [ + "name", + "live" + ], + "title": "CapabilityDefaultPolicy", + "description": "One declared default policy: whether it is live, and its current\ndefault value when it is a simple boolean toggle." + }, + "CapabilityFormat": { + "properties": { + "name": { + "type": "string", + "title": "Name", + "description": "csv, xlsx, or parquet" + }, + "live": { + "type": "boolean", + "title": "Live", + "description": "whether this deployment can render this format" + } + }, + "type": "object", + "required": [ + "name", + "live" + ], + "title": "CapabilityFormat", + "description": "One output rendering's liveness in this deployment." + }, + "CapabilityKind": { + "properties": { + "name": { + "type": "string", + "title": "Name", + "description": "spec_id or statvar_set" + }, + "live": { + "type": "boolean", + "title": "Live", + "description": "whether this deployment's mint door dispatches this kind" + } + }, + "type": "object", + "required": [ + "name", + "live" + ], + "title": "CapabilityKind", + "description": "One mint-request `kind`'s liveness in this deployment." + }, + "CatalogueAnswer": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "description": "contract schema version; exactly 1 for v1. Required on every response.", + "default": 1 + }, + "query_echo": { + "$ref": "#/components/schemas/QueryEcho", + "description": "what the response was understood to be answering" + }, + "diagnostics": { + "$ref": "#/components/schemas/Diagnostics", + "description": "run health, warnings, timing, build stamp" + }, + "kind": { + "type": "string", + "const": "catalogue", + "title": "Kind", + "description": "discriminator for a response to a question about what DFO holds", + "default": "catalogue" + }, + "scope": { + "$ref": "#/components/schemas/Scope-Output", + "description": "the place the question named, when it named a country" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query_echo", + "diagnostics", + "scope" + ], + "title": "CatalogueAnswer", + "description": "A resolve response to a question that asks what DFO holds and names\nneither an indicator nor a subject, such as \"what data do you have?\". It\ncarries the country the question named, when the resolver confirms one." + }, + "CatalogueExampleSentence": { + "properties": { + "text": { + "type": "string", + "title": "Text", + "description": "the template filled with the place's name" + }, + "template": { + "type": "string", + "title": "Template", + "description": "the sentence with a {place} slot" + }, + "stat_var": { + "type": "string", + "title": "Stat Var", + "description": "the StatVar the sentence resolves to" + }, + "place": { + "type": "string", + "title": "Place", + "description": "the country dcid the sentence is filled with" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "template", + "stat_var", + "place" + ], + "title": "CatalogueExampleSentence", + "description": "An example sentence a client offers and runs as a query." + }, + "CatalogueResponse": { + "properties": { + "catalogue_version": { + "type": "string", + "title": "Catalogue Version", + "description": "the published build this body comes from" + }, + "counts": { + "anyOf": [ + { + "$ref": "#/components/schemas/Counts" + }, + { + "$ref": "#/components/schemas/PlaceCounts" + } + ], + "title": "Counts", + "description": "global counts, or the counts at the requested place" + }, + "examples": { + "items": { + "$ref": "#/components/schemas/CatalogueExampleSentence" + }, + "type": "array", + "title": "Examples" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "catalogue_version", + "counts", + "examples" + ], + "title": "CatalogueResponse", + "description": "What DFO holds and example sentences to ask of it." + }, + "Cause": { + "description": "The `cause` extension: why a refusal fired, beneath its own top-level\n`code` -- present only on a refusal that carries one (`recipe_not_declared`,\n`rate_coverage_gap`, `operation_failed`). On `operation_failed`, `code` is\nthe failed operation's refusal code. Mirrors `alternatives`/`truncated`'s\nown extension style: `entities` names what the cause concerns (entity or\n`entity@year` keys), capped, with `truncated` set when the cap cut items\nshort.", + "properties": { + "code": { + "description": "the cause code: a sub-cause such as nominal_undeclared, recipe_undeclared, or rate_missing, or on operation_failed the failed operation's own refusal code", + "title": "Code", + "type": "string" + }, + "entities": { + "description": "the entity or entity@year keys this cause concerns, in the order given, capped at 10; empty for a cause that names no entity", + "items": { + "type": "string" + }, + "maxItems": 10, + "title": "Entities", + "type": "array" + }, + "truncated": { + "default": false, + "description": "true when the entities cap cut items short", + "title": "Truncated", + "type": "boolean" + } + }, + "required": [ + "code" + ], + "title": "Cause", + "type": "object" + }, + "ChangeEntry": { + "properties": { + "kind": { + "type": "string", + "enum": [ + "added", + "changed", + "deprecated", + "removed", + "fixed", + "security" + ], + "title": "Kind", + "description": "the Keep a Changelog group the change sits under" + }, + "note": { + "type": "string", + "title": "Note", + "description": "the change, as CommonMark" + } + }, + "type": "object", + "required": [ + "kind", + "note" + ], + "title": "ChangeEntry", + "description": "One change in a release." + }, + "ChangeModel": { + "properties": { + "kind": { + "type": "string", + "title": "Kind", + "description": "the Keep a Changelog group, lowercase: added, changed, deprecated, removed, fixed or security" + }, + "note": { + "type": "string", + "title": "Note", + "description": "the change, as CommonMark" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind", + "note" + ], + "title": "ChangeModel", + "description": "One change in a release of a source's DFO pipeline." + }, + "ChangedFieldModel": { + "properties": { + "field": { + "type": "string", + "title": "Field", + "description": "the intent field this entry reports" + }, + "prior": { + "anyOf": [ + {}, + { + "type": "null" + } + ], + "title": "Prior", + "description": "the field's value before the write, for a disclosed scalar" + }, + "new": { + "anyOf": [ + {}, + { + "type": "null" + } + ], + "title": "New", + "description": "the field's value after the write, for a disclosed scalar" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "field" + ], + "title": "ChangedFieldModel", + "description": "One entry of `changed[]`. `prior` and `new` are present only for a\nscalar field the write set changed. An array or object field carries\n`field` alone." + }, + "Choice": { + "properties": { + "chosen": { + "$ref": "#/components/schemas/StepRef" + }, + "others": { + "items": { + "$ref": "#/components/schemas/StepRef" + }, + "type": "array", + "maxItems": 32, + "title": "Others" + }, + "ranking": { + "items": { + "type": "string", + "pattern": "^[a-z][a-z0-9_]{0,63}$" + }, + "type": "array", + "maxItems": 8, + "minItems": 1, + "title": "Ranking" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "chosen", + "others", + "ranking" + ], + "title": "Choice", + "description": "A choice of source at mint: the source chosen, the others it was chosen over, and the\nranking it applied, in order." + }, + "CitationModel": { + "properties": { + "text": { + "type": "string", + "title": "Text" + }, + "sources": { + "items": { + "$ref": "#/components/schemas/CitationSource" + }, + "type": "array", + "title": "Sources" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "sources" + ], + "title": "CitationModel" + }, + "CitationSource": { + "properties": { + "ref": { + "type": "string", + "title": "Ref" + }, + "label": { + "type": "string", + "title": "Label" + }, + "processing_level": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Processing Level" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "license_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License Type" + }, + "license_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License Url" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Url" + }, + "source": { + "anyOf": [ + { + "$ref": "#/components/schemas/CitedSourceNode" + }, + { + "type": "null" + } + ] + }, + "data_commons": { + "anyOf": [ + { + "$ref": "#/components/schemas/CitedDataCommons" + }, + { + "type": "null" + } + ] + }, + "documentation": { + "anyOf": [ + { + "$ref": "#/components/schemas/CitedDocumentation" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref", + "label" + ], + "title": "CitationSource", + "description": "One cited source, named through\n`materialise.provenance_doc.read_source_citations`. `label`, `url`,\n`source`, `data_commons`, the licence fields and `documentation` come\nfrom the origin catalogue where it lists `ref`, and from the graph\notherwise: `license` is the licence's label, `license_type` its\n`licenseType` dcid and `license_url` its terms page. `license`, `license_type`,\n`license_url` and `url` are `None` where neither the catalogue nor the graph declares one. `source`\nand `data_commons` are `None` for a ref the catalogue does not list.\n`documentation` is the source's documentation at first mint, `None` when\nnothing documents the source or its graph read failed. A mint\nleaves a stored citation as it is. A bundle render fills every field but\n`ref`, `label` and `processing_level` that is `None` from a live read for\nthat render only (`datasets_api.manifest.healed_citation`), and every set\nfield wins." + }, + "CitedDataCommons": { + "properties": { + "id": { + "type": "string", + "enum": [ + "dfo", + "base", + "un_system" + ], + "title": "Id" + }, + "label": { + "type": "string", + "title": "Label" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "label" + ], + "title": "CitedDataCommons", + "description": "The Data Commons that serves a cited provenance." + }, + "CitedDocumentation": { + "properties": { + "publisher": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Publisher", + "description": "the publishing organisation" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "what the source holds" + }, + "source_data_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Data Url", + "description": "where the raw data downloads from" + }, + "attribution": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Attribution", + "description": "the citation text the publisher asks for, verbatim" + }, + "update_cadence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Update Cadence", + "description": "how often the source updates, as display text such as 'Quarterly'; an unrecognised ISO 8601 duration passes through as stored" + }, + "last_update": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Update", + "description": "the date of the DFO's last refresh of the source" + }, + "years_covered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Years Covered", + "description": "YYYY or YYYY-YYYY" + }, + "granularity": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Granularity", + "description": "such as 'Annual, by provider and recipient'" + }, + "currencies": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Currencies", + "description": "sorted ISO 4217 codes of the source's currencies" + }, + "transformation_log": { + "items": { + "$ref": "#/components/schemas/TransformationStepModel" + }, + "type": "array", + "title": "Transformation Log" + }, + "version_history": { + "items": { + "$ref": "#/components/schemas/ReleaseModel" + }, + "type": "array", + "title": "Version History", + "description": "the DFO pipeline's releases, newest first" + } + }, + "additionalProperties": false, + "type": "object", + "title": "CitedDocumentation", + "description": "A cited source's documentation at first mint, read by\n`materialise.provenance_doc.read_provenance_doc`, the reader behind\n`GET /api/graph/documentation/{ref}`. Each member is `None` or empty where the graph\ndocuments nothing." + }, + "CitedSourceNode": { + "properties": { + "ref": { + "type": "string", + "title": "Ref" + }, + "label": { + "type": "string", + "title": "Label" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref", + "label" + ], + "title": "CitedSourceNode", + "description": "The Data Commons `Source` node behind a cited provenance. On the UN\nSystem Data Commons it is the agency provenance itself." + }, + "CodeBlock": { + "properties": { + "code_system": { + "anyOf": [ + { + "$ref": "#/components/schemas/NodeRef" + }, + { + "type": "null" + } + ], + "description": "the system's graph node, such as `CRSPurposeCodeEnum`" + }, + "property": { + "type": "string", + "title": "Property", + "description": "the constraint property the code is a value of" + }, + "code": { + "type": "string", + "title": "Code" + }, + "parent": { + "anyOf": [ + { + "$ref": "#/components/schemas/NodeRef" + }, + { + "type": "null" + } + ], + "description": "the code it specialises; null for a root" + }, + "synonyms": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Synonyms" + } + }, + "type": "object", + "required": [ + "code_system", + "property", + "code", + "parent", + "synonyms" + ], + "title": "GraphCodeBlock", + "description": "A code's detail block." + }, + "CodeItem": { + "properties": { + "ref": { + "type": "string", + "title": "Ref" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label" + }, + "code": { + "type": "string", + "title": "Code" + }, + "parent": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parent", + "description": "the parent code's dcid; null for a top-level code" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "code", + "parent" + ], + "title": "GraphCodeItem", + "description": "A code in a `codes` or `children` list, with its code and its parent's dcid." + }, + "CodeMappingEntry": { + "properties": { + "endpoint": { + "type": "string", + "title": "Endpoint" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "doors": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Doors" + }, + "http_status": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Http Status" + } + }, + "type": "object", + "required": [ + "endpoint", + "channel", + "doors", + "http_status" + ], + "title": "CodeMappingEntry", + "description": "One endpoint/channel combination a registered code is permitted on.\nMirrors `dfo_spec_kit.registry.CodeMapping`'s fields. `doors` and\n`http_status` are null when the registry entry omits them." + }, + "CodeNode": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the node's dcid" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "the node's name; for a Provenance, its parent Dataset's name where it has one. Null, and named in gaps, when the graph gives none" + }, + "types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Types", + "description": "the node's typeOf values, as the graph holds them" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "the node's prose in the graph; null when it has none" + }, + "links": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "codes", + "children", + "members", + "countries", + "datasets", + "variables", + "facets" + ] + }, + "type": "object", + "title": "Links", + "description": "each list relation the node has, mapped to its route; empty when none" + }, + "gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Gaps", + "description": "the member path of every value this door cannot know" + }, + "built_from": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "code_index", + "origin_catalogue", + "coverage_index", + "membership" + ] + }, + "type": "object", + "title": "Built From", + "description": "the build of each table the response read" + }, + "kind": { + "type": "string", + "const": "code", + "title": "Kind", + "default": "code" + }, + "code": { + "$ref": "#/components/schemas/CodeBlock" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "types", + "description", + "links", + "gaps", + "built_from", + "kind", + "code" + ], + "title": "CodeNode" + }, + "CodeRegistryEntry": { + "properties": { + "code": { + "type": "string", + "title": "Code" + }, + "classification": { + "anyOf": [ + { + "type": "string", + "enum": [ + "refusal", + "warning" + ] + }, + { + "type": "null" + } + ], + "title": "Classification" + }, + "definition": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Definition" + }, + "lifecycle": { + "anyOf": [ + { + "type": "string", + "enum": [ + "active", + "retired" + ] + }, + { + "type": "null" + } + ], + "title": "Lifecycle" + }, + "mappings": { + "items": { + "$ref": "#/components/schemas/CodeMappingEntry" + }, + "type": "array", + "title": "Mappings" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Title" + }, + "detail": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Detail" + } + }, + "type": "object", + "required": [ + "code", + "classification", + "definition", + "lifecycle", + "mappings", + "title", + "detail" + ], + "title": "CodeRegistryEntry", + "description": "The wire shape of a successful `GET /codes/{code}` lookup, not the\n`ProblemDetails`/`Envelope` shape that carries `capability_version`,\n`trace_id`, and `type`. `dfo_platform.version` hashes this shape by\ncalling `registry_entry_body` through the `codes` module attribute, so\nany change here moves `PLATFORM_CAPABILITY_VERSION`.\n\n`classification`, `definition`, `lifecycle` and `mappings` come from\n`dfo_spec_kit.registry.REGISTRY`. `title` and `detail` come from the\nmerged refusal catalogue. Either source can lack the code. `title` and\n`detail` are null for a code the merged catalogue does not carry (a\nwarning, or a no-data reason), while `classification`, `definition` and\n`lifecycle` are null and `mappings` is empty for a code absent from the\nregistry. A client sees a missing source as null fields on a present\ncode, not as a vanished key set." + }, + "CodeSystemBlock": { + "properties": { + "property": { + "type": "string", + "title": "Property", + "description": "the constraint property the system governs" + }, + "plain_name": { + "type": "string", + "title": "Plain Name", + "description": "the property's plain name, such as `sector`" + }, + "declarations": { + "$ref": "#/components/schemas/CodeSystemDeclarations" + }, + "code_count": { + "type": "integer", + "title": "Code Count", + "description": "how many codes the code index holds for the system" + } + }, + "type": "object", + "required": [ + "property", + "plain_name", + "declarations", + "code_count" + ], + "title": "GraphCodeSystemBlock", + "description": "A code system's detail block." + }, + "CodeSystemDeclarations": { + "properties": { + "hierarchical": { + "type": "boolean", + "title": "Hierarchical", + "description": "whether its codes nest through specializationOf" + }, + "disjoint_from_children": { + "type": "boolean", + "title": "Disjoint From Children", + "description": "whether a parent code's records sit apart from its children's, so a parent's total is its own records plus its descendants' (CRS purposes); false where a parent row already totals its children (DAC1 aid types)" + }, + "summable": { + "type": "boolean", + "title": "Summable", + "description": "whether sibling values can rebuild a parent total" + }, + "absent_reading": { + "type": "string", + "enum": [ + "not_declared", + "aggregate" + ], + "title": "Absent Reading", + "description": "how a variable that does not declare the property reads" + } + }, + "type": "object", + "required": [ + "hierarchical", + "disjoint_from_children", + "summable", + "absent_reading" + ], + "title": "GraphCodeSystemDeclarations", + "description": "The rules a code system declares (`code_index.types.CodeSystemDeclaration`)." + }, + "CodeSystemNode": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the node's dcid" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "the node's name; for a Provenance, its parent Dataset's name where it has one. Null, and named in gaps, when the graph gives none" + }, + "types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Types", + "description": "the node's typeOf values, as the graph holds them" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "the node's prose in the graph; null when it has none" + }, + "links": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "codes", + "children", + "members", + "countries", + "datasets", + "variables", + "facets" + ] + }, + "type": "object", + "title": "Links", + "description": "each list relation the node has, mapped to its route; empty when none" + }, + "gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Gaps", + "description": "the member path of every value this door cannot know" + }, + "built_from": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "code_index", + "origin_catalogue", + "coverage_index", + "membership" + ] + }, + "type": "object", + "title": "Built From", + "description": "the build of each table the response read" + }, + "kind": { + "type": "string", + "const": "code_system", + "title": "Kind", + "default": "code_system" + }, + "code_system": { + "$ref": "#/components/schemas/CodeSystemBlock" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "types", + "description", + "links", + "gaps", + "built_from", + "kind", + "code_system" + ], + "title": "CodeSystemNode" + }, + "ColumnOptionModel": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "kind": { + "type": "string", + "title": "Kind" + }, + "droppable": { + "type": "boolean", + "title": "Droppable" + }, + "distinct": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Distinct" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name", + "kind", + "droppable", + "distinct" + ], + "title": "ColumnOptionModel", + "description": "One frame column, verbatim from `materialise.profile.ColumnProfile`." + }, + "ComponentBody": { + "properties": { + "intent": { + "additionalProperties": true, + "type": "object", + "title": "Intent" + }, + "composition_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Composition Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "intent" + ], + "title": "ComponentBody", + "description": "The create and revise routes' shared request body. `extra=\"forbid\"`\nis what refuses a body carrying `session`/`caller`. An undeclared\nfield fails pydantic validation, which\n`presentation_api.refusals.request_validation_spec` classifies as\n`request_invalid` with no door-level code needed, `retryable` false. A\nrevise's `composition_id` is passed straight through to\n`write_component`, which refuses it (composition membership is\ncreate-only); this model does not distinguish the two routes." + }, + "ComponentReadResponse": { + "properties": { + "component_id": { + "type": "string", + "title": "Component Id", + "description": "the read component's own id" + }, + "revision": { + "type": "integer", + "title": "Revision", + "description": "the revision this read reports" + }, + "catalog_version": { + "type": "string", + "title": "Catalog Version", + "description": "the catalogue release this revision minted under" + }, + "composition_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Composition Id", + "description": "the composition this component belongs to, null outside one" + }, + "composition_revision": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Composition Revision", + "description": "the composition's current head revision, null outside one" + }, + "stored_intent": { + "additionalProperties": true, + "type": "object", + "title": "Stored Intent", + "description": "this revision's own stored intent, exactly as minted" + }, + "fact_summary": { + "$ref": "#/components/schemas/FactSummaryModel", + "description": "the closed, token-capped fact summary this revision reports" + }, + "resolved_payload": { + "additionalProperties": true, + "type": "object", + "title": "Resolved Payload", + "description": "the revision's stored resolved payload, verbatim: the catalogue envelope {schema_version, catalog_version, component_id, revision, provenance, component}, validated against the catalogue release's envelope schema (dfo-spec-kit envelope.schema.json) when minted. GET /api/presentation/release serves the pinned release's envelope_schema and the component_schemas its component field $refs by $id; every payload this door serves carries that pinned catalog_version." + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "component_id", + "revision", + "catalog_version", + "composition_id", + "composition_revision", + "stored_intent", + "fact_summary", + "resolved_payload" + ], + "title": "ComponentReadResponse", + "description": "`GET /api/presentation/components/{component_id}`'s 200 body." + }, + "ComposedUnit": { + "properties": { + "numerator": { + "anyOf": [ + { + "$ref": "#/components/schemas/SimpleUnit" + }, + { + "$ref": "#/components/schemas/VariableSide" + } + ], + "title": "Numerator" + }, + "denominator": { + "anyOf": [ + { + "$ref": "#/components/schemas/SimpleUnit" + }, + { + "$ref": "#/components/schemas/VariableSide" + } + ], + "title": "Denominator" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "numerator", + "denominator" + ], + "title": "ComposedUnit", + "description": "A quotient's unit: the numerator's unit per the denominator's. Either side may be a\nvariable." + }, + "ComposedUnitModel": { + "properties": { + "numerator": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/ConvertedUnitModel" + }, + { + "$ref": "#/components/schemas/CountedStatVarModel" + } + ], + "title": "Numerator", + "description": "the unit of the measure divided" + }, + "denominator": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/ConvertedUnitModel" + }, + { + "$ref": "#/components/schemas/CountedStatVarModel" + } + ], + "title": "Denominator", + "description": "the unit of the measure divided by" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "numerator", + "denominator" + ], + "title": "ComposedUnitModel", + "description": "The unit of a quotient of two measures, read ` per `.\n\nEach side is a unit's graph name (its ref when the graph has none), a converted unit, or\nthe StatVar a unit-less side counts." + }, + "Constraint": { + "properties": { + "property": { + "$ref": "#/components/schemas/NodeRef" + }, + "value": { + "$ref": "#/components/schemas/NodeRef" + } + }, + "type": "object", + "required": [ + "property", + "value" + ], + "title": "GraphDefinitionConstraint", + "description": "One constraint: the property and the value the variable fixes it at." + }, + "ContinentNode": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the node's dcid" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "the node's name; for a Provenance, its parent Dataset's name where it has one. Null, and named in gaps, when the graph gives none" + }, + "types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Types", + "description": "the node's typeOf values, as the graph holds them" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "the node's prose in the graph; null when it has none" + }, + "links": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "codes", + "children", + "members", + "countries", + "datasets", + "variables", + "facets" + ] + }, + "type": "object", + "title": "Links", + "description": "each list relation the node has, mapped to its route; empty when none" + }, + "gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Gaps", + "description": "the member path of every value this door cannot know" + }, + "built_from": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "code_index", + "origin_catalogue", + "coverage_index", + "membership" + ] + }, + "type": "object", + "title": "Built From", + "description": "the build of each table the response read" + }, + "kind": { + "type": "string", + "const": "continent", + "title": "Kind", + "default": "continent" + }, + "continent": { + "$ref": "#/components/schemas/PlaceBlock" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "types", + "description", + "links", + "gaps", + "built_from", + "kind", + "continent" + ], + "title": "ContinentNode" + }, + "ContinentalUnionNode": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the node's dcid" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "the node's name; for a Provenance, its parent Dataset's name where it has one. Null, and named in gaps, when the graph gives none" + }, + "types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Types", + "description": "the node's typeOf values, as the graph holds them" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "the node's prose in the graph; null when it has none" + }, + "links": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "codes", + "children", + "members", + "countries", + "datasets", + "variables", + "facets" + ] + }, + "type": "object", + "title": "Links", + "description": "each list relation the node has, mapped to its route; empty when none" + }, + "gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Gaps", + "description": "the member path of every value this door cannot know" + }, + "built_from": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "code_index", + "origin_catalogue", + "coverage_index", + "membership" + ] + }, + "type": "object", + "title": "Built From", + "description": "the build of each table the response read" + }, + "kind": { + "type": "string", + "const": "continental_union", + "title": "Kind", + "default": "continental_union" + }, + "continental_union": { + "$ref": "#/components/schemas/PlaceBlock" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "types", + "description", + "links", + "gaps", + "built_from", + "kind", + "continental_union" + ], + "title": "ContinentalUnionNode" + }, + "ConversionCurrency": { + "properties": { + "code": { + "type": "string", + "title": "Code", + "description": "the ISO 4217 code a unit request names the currency by" + }, + "noun": { + "type": "string", + "title": "Noun", + "description": "the plural English noun the sentence's unit token names the currency by ('euros', 'Guatemalan quetzales')" + }, + "current_years": { + "anyOf": [ + { + "$ref": "#/components/schemas/TimeWindow" + }, + { + "type": "null" + } + ], + "description": "the first and last years a current-price request in this currency shows, the longest run of consecutive years, inside the years the answer serves (download.window), in which the recipe's exchange-rate table holds a rate for this currency and for the native currency of every facet the answer serves. It equals download.window when the conversion keeps every served year. With no download.window, the run the tables hold. Null when no year converts" + }, + "constant_years": { + "anyOf": [ + { + "$ref": "#/components/schemas/TimeWindow" + }, + { + "type": "null" + } + ], + "description": "the first and last years a constant-price request in this currency shows, at any base year from base_year_min to base_year_max, the longest run of consecutive years, read as current_years is, in which the exchange-rate table holds a rate for the native currency of every facet the answer serves and the deflator table a value for at least one entity the answer serves on the recipe's deflator role, bound or open. The conversion leaves out an entity's rows in the years its deflator lacks, and the answer names them (deflator_missing_omitted). Null when no year converts or no base year exists" + }, + "base_year_min": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Base Year Min", + "description": "the first base year a constant-price request in this currency converts at. With base_year_max it spans the run of consecutive years, ending at the latest, in which the deflator table holds an actual value, the exchange-rate table a rate for the currency, and the deflator table a value for at least one entity the answer serves on the recipe's deflator role. The conversion leaves out every row of an entity whose deflator lacks the base year, and the answer names it (deflator_missing_omitted). Null when no such year exists" + }, + "base_year_max": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Base Year Max", + "description": "the last base year a constant-price request in this currency converts at" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "code", + "noun", + "current_years", + "constant_years", + "base_year_min", + "base_year_max" + ], + "title": "ConversionCurrency", + "description": "One currency a unit request can convert this answer to, with the years each price\nbasis converts. A request whose tables leave out some of the years the answer serves\nshows the years stated here, and departs `year_unavailable` naming the table." + }, + "ConvertedUnitModel": { + "properties": { + "currency": { + "type": "string", + "title": "Currency", + "description": "the ISO 4217 code of the currency the values are in" + }, + "prices": { + "type": "string", + "enum": [ + "current", + "constant" + ], + "title": "Prices", + "description": "the price basis of the values" + }, + "base_year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Base Year", + "description": "the base year of constant prices, absent for current prices" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "currency", + "prices" + ], + "title": "ConvertedUnitModel", + "description": "A converted unit, as the frame's `unit` cell states it." + }, + "CountedStatVarModel": { + "properties": { + "stat_var": { + "type": "string", + "title": "Stat Var", + "description": "the StatVar's `dcid:`-prefixed ref, as the frame holds it" + }, + "label": { + "type": "string", + "title": "Label", + "description": "the StatVar's graph name, or its ref without `dcid:` when the graph has none" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "stat_var", + "label" + ], + "title": "CountedStatVarModel", + "description": "One side of a composed unit whose measure declares no unit, named by its StatVar." + }, + "CountryNode": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the node's dcid" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "the node's name; for a Provenance, its parent Dataset's name where it has one. Null, and named in gaps, when the graph gives none" + }, + "types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Types", + "description": "the node's typeOf values, as the graph holds them" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "the node's prose in the graph; null when it has none" + }, + "links": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "codes", + "children", + "members", + "countries", + "datasets", + "variables", + "facets" + ] + }, + "type": "object", + "title": "Links", + "description": "each list relation the node has, mapped to its route; empty when none" + }, + "gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Gaps", + "description": "the member path of every value this door cannot know" + }, + "built_from": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "code_index", + "origin_catalogue", + "coverage_index", + "membership" + ] + }, + "type": "object", + "title": "Built From", + "description": "the build of each table the response read" + }, + "kind": { + "type": "string", + "const": "country", + "title": "Kind", + "default": "country" + }, + "country": { + "$ref": "#/components/schemas/PlaceBlock" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "types", + "description", + "links", + "gaps", + "built_from", + "kind", + "country" + ], + "title": "CountryNode" + }, + "Counts": { + "properties": { + "indicators": { + "type": "integer", + "title": "Indicators", + "description": "distinct StatVars search can serve: base, DFO and coverage variables" + }, + "datasets": { + "type": "integer", + "title": "Datasets", + "description": "distinct source-index entries of the admitted provenances" + }, + "publishers": { + "type": "integer", + "title": "Publishers", + "description": "distinct sources of the admitted provenances" + }, + "countries": { + "type": "integer", + "title": "Countries", + "description": "countries with base data in the origin catalogue or coverage rows" + }, + "aid": { + "$ref": "#/components/schemas/AidCounts" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "indicators", + "datasets", + "publishers", + "countries", + "aid" + ], + "title": "Counts", + "description": "What DFO holds, counted from one origin catalogue build and one\ncoverage index build." + }, + "CoverageBare": { + "properties": { + "kind": { + "type": "string", + "const": "bare", + "title": "Kind", + "description": "coverage kind discriminator", + "default": "bare" + }, + "has_data": { + "type": "boolean", + "title": "Has Data", + "description": "whether the region has any observations" + }, + "window": { + "anyOf": [ + { + "$ref": "#/components/schemas/TimeWindow" + }, + { + "type": "null" + } + ], + "description": "the date window, when known" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "has_data" + ], + "title": "CoverageBare", + "description": "Observation footprint with no count or dimensions; an honest could-not-count." + }, + "CoverageBreadth": { + "properties": { + "kind": { + "type": "string", + "const": "breadth", + "title": "Kind", + "description": "coverage kind discriminator", + "default": "breadth" + }, + "has_data": { + "type": "boolean", + "title": "Has Data", + "description": "whether the region has any observations" + }, + "dimensions": { + "items": { + "$ref": "#/components/schemas/BreadthDim" + }, + "type": "array", + "minItems": 1, + "title": "Dimensions", + "description": "non-empty on breadth; structured dimension counts" + }, + "window": { + "anyOf": [ + { + "$ref": "#/components/schemas/TimeWindow" + }, + { + "type": "null" + } + ], + "description": "the date window this breadth applies to" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "has_data", + "dimensions" + ], + "title": "CoverageBreadth", + "description": "Observation footprint expressed as structured breadth dimensions." + }, + "CoverageDimension": { + "properties": { + "label": { + "type": "string", + "title": "Label" + }, + "count": { + "type": "integer", + "title": "Count" + }, + "axis": { + "anyOf": [ + { + "$ref": "#/components/schemas/RoleAxis" + }, + { + "type": "null" + } + ] + }, + "noun": { + "anyOf": [ + { + "$ref": "#/components/schemas/DimensionNoun" + }, + { + "type": "null" + } + ], + "description": "what the members this dimension counts are called, by the frame's flow family: provider and recipient for aid, creditor and debtor for debt. Absent for a dimension on no flow axis, such as `years`, and on a version stored without it" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "label", + "count" + ], + "title": "CoverageDimension", + "description": "One coverage dimension. `axis` is `axis_for_role(label)`: the flow axis of a dimension\nlabelled by a declared role, and `None` for `years` and unmapped roles. Validation derives\nit, so a stored body written without it carries it once loaded. `noun` is set at the mint\nfrom the version's flow family (`dfo_platform.roles.role_wording`), which the label and\naxis do not fix, so a body stored without it carries none (`year_coverage_counted`): a\n`None` noun is left out of every dump." + }, + "CoverageExact": { + "properties": { + "kind": { + "type": "string", + "const": "exact", + "title": "Kind", + "description": "coverage kind discriminator", + "default": "exact" + }, + "has_data": { + "type": "boolean", + "title": "Has Data", + "description": "whether the exact observation_count has observations in the resolved window, or in full history when window is absent" + }, + "observation_count": { + "type": "integer", + "title": "Observation Count", + "description": "exact distinct (date, facet) observation pairs for resolved stat_vars and entities in the resolved window, or full history when window is absent" + }, + "evidence": { + "type": "string", + "enum": [ + "facet_metadata", + "observed" + ], + "title": "Evidence", + "description": "provenance of observation_count. 'facet_metadata': the count comes from the graph's facet index and no observation series was delivered for this spec in this payload. 'observed': a preview series was delivered for this spec in this payload, and observation_count is still the facet-index count, now backed by fetchable data. A streaming response's `response` event ships before any observation fetch, so it always carries 'facet_metadata'; its trailing `observations` event carries the series. dfo-apis wire field outside the spec-kit contract.", + "default": "facet_metadata" + }, + "dimensions": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/BreadthDim" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Dimensions", + "description": "optional per-facet breadth dimensions; the observations dimension is window-narrowed to agree with observation_count when window is set, lifetime otherwise" + }, + "window": { + "anyOf": [ + { + "$ref": "#/components/schemas/TimeWindow" + }, + { + "type": "null" + } + ], + "description": "the date window this count applies to" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "has_data", + "observation_count" + ], + "title": "CoverageExact", + "description": "Observation footprint with an exact count for its resolved window." + }, + "CoverageModel": { + "properties": { + "rows": { + "type": "integer", + "title": "Rows" + }, + "dimensions": { + "items": { + "$ref": "#/components/schemas/CoverageDimension" + }, + "type": "array", + "title": "Dimensions" + }, + "window": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Window" + }, + "recent_years": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/YearCoverage" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Recent Years", + "description": "three calendar years, newest first, each with the counts the coverage index held of the series the frame's run read when the version was minted. They end at the newest year a counted series held up to the year the index was built in, so a year after the frame's can hold data the frame leaves out. Stated for a latest window and for a named year at or after the year a latest window serves, and absent for an earlier named year" + }, + "elected_year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Elected Year", + "description": "the year a latest window served when the version was minted. It is the frame's year under a latest window. A frame of a named year after it holds a year a latest window passes over" + }, + "fullest_year": { + "anyOf": [ + { + "$ref": "#/components/schemas/YearCoverage" + }, + { + "type": "null" + } + ], + "description": "the year holding the most series of the ten calendar years ending at the newest of `recent_years`, stated when it is earlier than those three and the frame's year holds under the share of its series a latest window's year must hold" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "rows", + "dimensions" + ], + "title": "CoverageModel", + "description": "A frame's row and dimension counts and its applied window.\n\n`recent_years`, `elected_year` and `fullest_year` set the frame's one year beside the\nyears around it (`datasets_api.manifest.year_coverage`). They are counted once, when\nthe version is minted, and stored with it, all three or none, so every read of the\nversion states the same ones. A `None` member is left out of every dump." + }, + "CreateComponentBody": { + "properties": { + "intent": { + "additionalProperties": true, + "type": "object", + "title": "Intent" + }, + "composition_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Composition Id" + }, + "write_token": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Write Token", + "description": "a cmw_ token this client minted for the new component: \"cmw_\" + secrets.token_urlsafe(16) or an equivalent CSPRNG, 22 url-safe base64 characters after the prefix. It becomes the component's write token and keys the create: a retry with the same write_token, intent and composition_id returns the first create's reply, and a different request with it is refused as request_invalid. Mint a new one for each create. Not allowed with composition_id \"new\"." + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "intent" + ], + "title": "CreateComponentBody", + "description": "The create route's body. `write_token` is checked by `write_component`, which refuses a\nmalformed token, or one sent with `composition_id` \"new\", as `request_invalid`." + }, + "CreateReplyResponse": { + "properties": { + "component_id": { + "type": "string", + "title": "Component Id", + "description": "the newly minted component's own id" + }, + "revision": { + "type": "integer", + "title": "Revision", + "description": "the first revision a create mints, always 1" + }, + "catalog_version": { + "type": "string", + "title": "Catalog Version", + "description": "the catalogue release this revision minted under" + }, + "composition_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Composition Id", + "description": "the composition this component belongs to, null outside one" + }, + "composition_revision": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Composition Revision", + "description": "the composition's current head revision, null outside one" + }, + "changed": { + "items": { + "$ref": "#/components/schemas/ChangedFieldModel" + }, + "type": "array", + "title": "Changed", + "description": "always empty, since a create carries no prior intent to compare against" + }, + "fact_summary": { + "$ref": "#/components/schemas/FactSummaryModel", + "description": "the closed, token-capped fact summary this revision reports" + }, + "resolved_payload": { + "additionalProperties": true, + "type": "object", + "title": "Resolved Payload", + "description": "the revision's stored resolved payload, verbatim: the catalogue envelope {schema_version, catalog_version, component_id, revision, provenance, component}, validated against the catalogue release's envelope schema (dfo-spec-kit envelope.schema.json) when minted. GET /api/presentation/release serves the pinned release's envelope_schema and the component_schemas its component field $refs by $id; every payload this door serves carries that pinned catalog_version." + }, + "affordance": { + "type": "string", + "title": "Affordance", + "description": "this door's own line naming the revise and read routes for this component" + }, + "write_token": { + "type": "string", + "title": "Write Token", + "description": "the cmw_ token that grants revising this component, sent back as the x-dfo-write-token header. A server-minted token appears only in this reply; a token the create sent as write_token is echoed, and a replayed create returns it again." + }, + "composition_write_token": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Composition Write Token", + "description": "the cpw_ token that grants creating components into the composition this create started with composition_id \"new\", sent back as the x-dfo-write-token header. Present only on that create." + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "component_id", + "revision", + "catalog_version", + "composition_id", + "composition_revision", + "changed", + "fact_summary", + "resolved_payload", + "affordance", + "write_token" + ], + "title": "CreateReplyResponse", + "description": "`POST /api/presentation/components`'s 201 body. It carries\n`WriteReplyResponse`'s fields plus this door's own `affordance` line\nnaming the freshly minted component's revise and read routes." + }, + "DataBuilds": { + "properties": { + "graph_generation": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Graph Generation", + "description": "the graph generation token: the graph service's Cloud Run revisions last read, joined with +; null while unknown" + }, + "origin_catalogue": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Origin Catalogue", + "description": "build id of the origin catalogue this request is bound to" + }, + "coverage_index": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Coverage Index", + "description": "build id of the series coverage index; null when none is loaded" + }, + "code_index": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Code Index", + "description": "content hash of the packaged code index export" + } + }, + "type": "object", + "title": "GraphDataBuilds", + "description": "The data builds this process serves, each null where it is unknown or absent." + }, + "DatasetEntry": { + "properties": { + "ref": { + "type": "string", + "title": "Ref" + }, + "label": { + "type": "string", + "title": "Label" + }, + "provenances": { + "items": { + "$ref": "#/components/schemas/ProvenanceEntry" + }, + "type": "array", + "title": "Provenances" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "its sole Provenance's description, as `details.description`; null when it has several" + }, + "license_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License Type", + "description": "licence label every Provenance agrees on, as `license.type`; null when they disagree or one has none" + }, + "update_cadence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Update Cadence", + "description": "release cadence label every Provenance agrees on, as `license.update_cadence`; null when they disagree or one has none" + }, + "years_covered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Years Covered", + "description": "`YYYY` or `YYYY-YYYY` span of its Provenances' observation dates, as `scope_and_units.years_covered`; null when either end is unknown" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Url", + "description": "the publication's page, as `details.source_url`: the Dataset's url, else its sole Provenance's" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "provenances", + "description", + "license_type", + "update_cadence", + "years_covered", + "source_url" + ], + "title": "DatasetEntry", + "description": "A Dataset and the admitted provenances that belong to it. A provenance with\nno Dataset forms its own entry, keyed by the provenance, so `ref` and `label`\nare the provenance's and `provenances` holds that one provenance.\n\nThe card facts (`description`, `license_type`, `update_cadence`,\n`years_covered`, `source_url`) equal the same members of\n`GET /api/graph/documentation/{ref}` for the graph the loaded catalogue\nbuild read. They are null on UN System Data Commons entries." + }, + "DatasetNode": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the node's dcid" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "the node's name; for a Provenance, its parent Dataset's name where it has one. Null, and named in gaps, when the graph gives none" + }, + "types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Types", + "description": "the node's typeOf values, as the graph holds them" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "the node's prose in the graph; null when it has none" + }, + "links": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "codes", + "children", + "members", + "countries", + "datasets", + "variables", + "facets" + ] + }, + "type": "object", + "title": "Links", + "description": "each list relation the node has, mapped to its route; empty when none" + }, + "gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Gaps", + "description": "the member path of every value this door cannot know" + }, + "built_from": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "code_index", + "origin_catalogue", + "coverage_index", + "membership" + ] + }, + "type": "object", + "title": "Built From", + "description": "the build of each table the response read" + }, + "kind": { + "type": "string", + "const": "dataset", + "title": "Kind", + "default": "dataset" + }, + "dataset": { + "$ref": "#/components/schemas/SourceBlock" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "types", + "description", + "links", + "gaps", + "built_from", + "kind", + "dataset" + ], + "title": "DatasetNode" + }, + "DatasetResubmitInput": { + "properties": { + "kind": { + "type": "string", + "const": "dataset_resubmit", + "title": "Kind", + "description": "discriminator for dataset-level re-resolution across every part", + "default": "dataset_resubmit" + }, + "entries": { + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ResubmitIdentityEntry" + }, + { + "$ref": "#/components/schemas/ResubmitCandidatesEntry" + }, + { + "$ref": "#/components/schemas/ResubmitPlaceholderEntry" + }, + { + "$ref": "#/components/schemas/ResubmitParsedEntry" + } + ], + "discriminator": { + "propertyName": "entry_kind", + "mapping": { + "candidates": "#/components/schemas/ResubmitCandidatesEntry", + "identity": "#/components/schemas/ResubmitIdentityEntry", + "parsed": "#/components/schemas/ResubmitParsedEntry", + "placeholder": "#/components/schemas/ResubmitPlaceholderEntry" + } + } + }, + "type": "array", + "maxItems": 6, + "minItems": 1, + "title": "Entries", + "description": "one entry per response part, in response part order; a single-entry request whose entry is an identity re-resolves exactly that one part" + }, + "raw_query": { + "anyOf": [ + { + "type": "string", + "maxLength": 2000, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Raw Query", + "description": "original query text, for echo only; does not affect resolution" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "entries" + ], + "title": "DatasetResubmitInput", + "description": "Re-resolve every part of a multi-variable result in one request, so an\nedit to one part cannot leave the other parts' composed sentence or fold\nstale (see `envelope.make_response` / `conjoin.combine_regions`, the\ncombiner every entry kind here is routed through).\n\n`entries` supplies one entry per response part, in response part order;\neach entry edits against its own base, never a dataset-level one. There\nis no spec registry, so every entry carries its full identity and this\ndoor reads no server-side state." + }, + "DatasetVersion": { + "properties": { + "content_version": { + "type": "string", + "title": "Content Version" + }, + "base_content_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Base Content Version", + "description": "the raw version a derived version (a full groupby collapse, a party-totals cut, or both) was rendered from; null on every other version" + }, + "rendering": { + "type": "string", + "enum": [ + "plain", + "groupby", + "without_party_totals", + "not_recorded" + ], + "title": "Rendering", + "description": "plain: a raw version, which is also what a groupby sum or a party-totals cut that left the frame unchanged is stored under. groupby: a collapse, summed by `groupby`, of the frame or of its party-totals cut when `without_party_totals` is true. without_party_totals: the frame without its party totals, unsummed. not_recorded: a derived version with no linked file recording its options" + }, + "groupby": { + "anyOf": [ + { + "$ref": "#/components/schemas/GroupbyOptions" + }, + { + "type": "null" + } + ], + "description": "the groupby a collapse was summed by, as its file's rendering records it; null unless `rendering` is groupby" + }, + "without_party_totals": { + "type": "boolean", + "title": "Without Party Totals", + "description": "true when the derived version's frame leaves out the group totals of its open party roles, as its file's rendering records it; absent when false", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "content_version", + "base_content_version", + "rendering", + "groupby" + ], + "title": "DatasetVersion" + }, + "DatasetVersionsResponse": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "default": 1 + }, + "spec_id": { + "type": "string", + "title": "Spec Id" + }, + "versions": { + "items": { + "$ref": "#/components/schemas/DatasetVersion" + }, + "type": "array", + "title": "Versions", + "description": "stored versions, newest first" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "spec_id", + "versions" + ], + "title": "DatasetVersionsResponse" + }, + "DateRange": { + "properties": { + "start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Start", + "description": "first served date, e.g. '2012'" + }, + "end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "End", + "description": "last served date, e.g. '2022'" + } + }, + "additionalProperties": false, + "type": "object", + "title": "DateRange", + "description": "The first and last dates of the points an answer serves for a StatVar." + }, + "DeclinedAnswer": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "description": "contract schema version; exactly 1 for v1. Required on every response.", + "default": 1 + }, + "query_echo": { + "$ref": "#/components/schemas/QueryEcho", + "description": "what the response was understood to be answering" + }, + "diagnostics": { + "$ref": "#/components/schemas/Diagnostics", + "description": "run health, warnings, timing, build stamp" + }, + "kind": { + "type": "string", + "const": "declined", + "title": "Kind", + "description": "discriminator for a response to a question search does not answer", + "default": "declined" + }, + "reason": { + "type": "string", + "enum": [ + "out_of_scope", + "requires_analysis" + ], + "title": "Reason", + "description": "why search declined: 'out_of_scope' when no part of the question asks for a published statistic about a place, a population or a financial flow; 'requires_analysis' when the subject is in scope but the question asks for an argument and names no data to show" + }, + "scope": { + "$ref": "#/components/schemas/Scope-Output", + "description": "the place the question named, when it named a country" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query_echo", + "diagnostics", + "reason", + "scope" + ], + "title": "DeclinedAnswer", + "description": "A resolve response to a question search does not answer." + }, + "DefinitePart": { + "properties": { + "variable_text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Variable Text", + "description": "the variable text this part answers, in the order asked. This part's position in Resolution.parts equals the same variable_index every SSE event keyed by variable_index uses (ShapeEvent, StepEvent, SentenceEvent). Every dataset_resubmit entry kind (identity, candidates, placeholder, and parsed through its nested ParsedPart) requires its own posted variable_text, so this field is always the posted text echoed back onto the rebuilt part, never null. Null only when the whole posted query was empty or whitespace-only (raw_text door), which refuses variable_not_resolved before extraction runs and so has no text to name." + }, + "separate": { + "type": "boolean", + "title": "Separate", + "description": "true when this part was asked beside the others to be compared with them. A client resubmitting an identity, candidate set, or placeholder posts this flag on that entry to preserve the comparison. False, the default, is omitted", + "default": false + }, + "warnings": { + "items": { + "$ref": "#/components/schemas/Warning" + }, + "type": "array", + "title": "Warnings", + "description": "this part's own run-health signals. A part folded into an earlier part's spec (see DefinitePart.spec) carries binding_folded alone. The merged spec's own resolved warnings live only on the first part that carries it. An unfolded part carries the warnings raised while resolving this part, plus observations_omitted on a candidates part when response_options.include_observations was set." + }, + "timing_ms": { + "anyOf": [ + { + "$ref": "#/components/schemas/Timing" + }, + { + "type": "null" + } + ], + "description": "this part's own latency breakdown, where by_step names only the phases this part ran and total sums them, leaving out the shape_* stages nested inside shape. Excludes the shared, once-per-request steps (e.g. extract), which diagnostics.timing_ms.by_step carries once for the whole request; distinct too from diagnostics.timing_ms.total, the whole request's wall-clock elapsed time." + }, + "rendered_sentence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Rendered Sentence", + "description": "a human-readable string. For candidates, a header naming how many readings there are ('3 readings.'), then each shown candidate's heading and a byline led by the source and span that set it apart; for no_data, a heading in the same claim form naming the entity, measure, and counterpart that were checked. Either ends with the text of this part's departures, in order. For a definite part this stays null or omitted: the confirmation sentence (heading and byline) lives at spec.resolved.rendered_sentence, and its departures reach the envelope's composed sentence." + }, + "sentence_plan": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/SentenceToken" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Sentence Plan", + "description": "the ordered token form of rendered_sentence, present whenever it is. For a definite part this stays null or omitted. spec.resolved.sentence_plan carries the confirmation sentence's own plan instead." + }, + "restatement": { + "anyOf": [ + { + "$ref": "#/components/schemas/ParsedPart" + }, + { + "type": "null" + } + ], + "description": "the ParsedPart that reproduces this part's own resolution inputs -- the same entities, resolved time window, unit text, and source text the engine actually used to resolve this one leg -- so a client holding this part alone can copy it straight into a fresh ParsedInput.parts entry and re-resolve it faithfully, without flattening it into the whole query's variable_text the way variable_text alone would. Canonical, not verbatim: for a raw_text part, time_text is the equivalent phrase this door's own time grammar recognises (e.g. '2015 to 2020'), not the user's original words, since the engine's date extraction keeps only the structured window and discards the phrasing. Null whenever this part has no faithful echo to give. On a dataset_resubmit entry's identity/candidates/placeholder kinds, which post an identity or stub rather than a phrase and have no per-part resolution inputs to echo -- a dataset_resubmit parsed entry, genuinely re-resolved from its own posted ParsedPart, carries a real one like any parsed-door part. Also null when this leg's entity was bound to a directional role axis (origin/destination) and no door-supplied role named that axis, since an echo without the axis would resubmit the request with that entity reversed. Also null when one of this leg's own inputs does not fit ParsedPart's own field caps, since a truncated echo would misrepresent what was actually resolved." + }, + "operations": { + "items": { + "$ref": "#/components/schemas/Operation" + }, + "type": "array", + "title": "Operations", + "description": "the operations the question asks for over this part's data, in query order; the engine echoes them onto the part it resolves. Empty when the question asks for none" + }, + "departures": { + "items": { + "$ref": "#/components/schemas/Departure" + }, + "type": "array", + "title": "Departures", + "description": "every way this part's answer differs from what its request asked, ordered by how much each changes the number: closest_match, measure_not_applied, operation_not_applied, breakdown_not_applied, entity_unavailable, year_unavailable, modelled_values, group_read_as_members, direction_discarded, direction_inferred, scope_limited. [] when the answer is what was asked. A client that renders its own sentence reads them here; each one's text also closes the sentence that carries this part (see Departure.text). A warning on the same part reports run health and stays separate" + }, + "status": { + "type": "string", + "const": "definite", + "title": "Status", + "description": "one answer was resolved" + }, + "spec": { + "$ref": "#/components/schemas/Spec", + "description": "the resolved Spec answering this part. Several parts sharing one five-tuple shape carry the identical spec verbatim (the same spec_id); a part that shares the spec without minting it carries a part-scoped binding_folded warning" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "status", + "spec" + ], + "title": "DefinitePart", + "description": "One unambiguous answer was resolved for this part." + }, + "DefinitionMembersRequest": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "default": 1 + }, + "definition": { + "anyOf": [ + { + "$ref": "#/components/schemas/CanonicalDefinition" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "title": "DefinitionMembersRequest", + "description": "Body of `POST /api/datasets/{id}/members`. It may carry the canonical `definition` a\nsearch response gives for `id`, so the route answers before any mint registers it.\n\nA registered id needs no `definition`. A supplied one is admitted as a mint admits a\n`spec_id` sidecar: `definition.spec_id` must equal the path id, and the identity must hash\nto it. Nothing is written." + }, + "DefinitionModel": { + "properties": { + "schema_version": { + "type": "integer", + "title": "Schema Version" + }, + "spec_id": { + "type": "string", + "title": "Spec Id" + }, + "identity": { + "additionalProperties": true, + "type": "object", + "title": "Identity", + "description": "the identity-core document, shaped as search.models.identity.BaseIdentity and published at GET /api/search/schema" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "schema_version", + "spec_id", + "identity" + ], + "title": "DefinitionModel" + }, + "DefinitionOptionsRequest": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "default": 1 + }, + "definition": { + "$ref": "#/components/schemas/CanonicalDefinition" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "definition" + ], + "title": "DefinitionOptionsRequest", + "description": "Body of `POST /api/datasets/{id}/options`. It carries the canonical `definition` a search\nresponse gives for `id`, so the options route answers for an id no mint has registered.\n\nThe route admits and registers the definition as a `spec_id` mint registers its sidecar.\n`definition.spec_id` must equal the path id, and the identity must hash to it." + }, + "DefinitionResponse": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "default": 1 + }, + "definition": { + "$ref": "#/components/schemas/CanonicalDefinition" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "schema_version", + "definition" + ], + "title": "DefinitionResponse", + "description": "The register door's response: the verified\nidentity, echoed back whole." + }, + "DefinitionText": { + "properties": { + "of": { + "$ref": "#/components/schemas/NodeRef", + "description": "the part the text defines" + }, + "text": { + "type": "string", + "title": "Text" + } + }, + "type": "object", + "required": [ + "of", + "text" + ], + "title": "GraphDefinitionText", + "description": "The graph's prose for one part of a definition." + }, + "Departure": { + "properties": { + "code": { + "type": "string", + "enum": [ + "closest_match", + "measure_not_applied", + "operation_not_applied", + "breakdown_not_applied", + "entity_unavailable", + "year_unavailable", + "modelled_values", + "group_read_as_members", + "direction_discarded", + "direction_inferred", + "scope_limited" + ], + "title": "Code", + "description": "what kind of departure this is. 'closest_match': the answer shows the nearest measure the graph holds, not the one asked; a client draws a muted 'Closest match:' lead before the heading, and on a candidates part, whose readings stand in for a measure with no data, once before the first reading. 'measure_not_applied': a named measure qualifier was not applied. 'operation_not_applied': an operation the request named (a share, a ranking) was not run, so the amounts behind it are shown. 'breakdown_not_applied': a breakdown the request named was not applied, so the total is shown. 'entity_unavailable': an entity the request named holds no values in the series the answer reads, one departure per role; for a role the request named as a group, asked is the request's words for the group and the text counts the members without values; the text names any source holding values there that Search does not read. 'year_unavailable': a named year or range falls outside the years served. 'modelled_values': the served values are modelled or estimated. 'group_read_as_members': a named group was read as its member entities; on a flow role the text names the amounts the group's published total counts that no member holds, and, for a group whose published total is not its members' sum, says the source publishes its own figure for the group. 'direction_discarded': a flow direction the request's own words named was not applied. 'direction_inferred': a place the request named without a direction is read on the one direction that holds data, which over names. 'scope_limited': a no_data answer's check covered only values the engine chose, which the request did not name; its text names only what the check covered ('This check covered only ODA.')" + }, + "binding_ref": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Binding Ref", + "description": "the identity binding whose edit clears this departure ('when:' for a year, 'how:' for a measure value, 'where:' or 'origin:' for a role's entities, 'unit:' for the price basis); null for a departure no binding edit clears, such as an operation the engine does not run. A client links the departure to the sentence token carrying the same binding_ref when the plan has one; a candidates or no_data plan, and a how slot the heading leaves silent, may carry no such token" + }, + "asked": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Asked", + "description": "what the request named, in its own wording; null when it named nothing" + }, + "shown": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Shown", + "description": "what the answer shows instead, as the heading states it; null when nothing" + }, + "text": { + "type": "string", + "minLength": 1, + "title": "Text", + "description": "the departure as one or two short sentences for people: 'You asked for 2030. The data ends in 2024, so this shows 1973 to 2024.' On a no_data part no text claims the part shows anything. The envelope's composed sentence carries the same text as a segment='departure' token after its part's heading and byline, and so does the rendered_sentence of a part that is not definite" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "code", + "text" + ], + "title": "Departure", + "description": "One way this part's answer differs from what its request asked, stated\nfor people in `text` and for code in `code`, `asked`, and `shown`.\n\nDepartures live on the part (`_PartBase.departures`).\n`spec.resolved.rendered_sentence` states what the answer is, and a\ndeparture states how that differs from the request that produced it." + }, + "DeploymentFacetPolicy": { + "properties": { + "policy": { + "type": "string", + "title": "Policy", + "description": "the deployment default policy's own id" + }, + "version": { + "type": "string", + "title": "Version", + "description": "the policy id's own version" + } + }, + "type": "object", + "required": [ + "policy", + "version" + ], + "title": "DeploymentFacetPolicy", + "description": "This deployment's own default-facet policy: what an unbound facet\naxis falls back to once `default_facet_policies_live` (a graph-declared,\nper-StatVar policy) is `false`. See `docs/datasets-facet-policy.md`." + }, + "DescribedProperty": { + "properties": { + "ref": { + "type": "string", + "title": "Ref" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref", + "label" + ], + "title": "DescribedProperty", + "description": "The open dimension a values page lists, and its label (`null` where none is known)." + }, + "DescribedValue": { + "properties": { + "ref": { + "type": "string", + "title": "Ref" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label" + }, + "variables": { + "type": "integer", + "minimum": 0.0, + "title": "Variables" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref", + "label", + "variables" + ], + "title": "DescribedValue", + "description": "One value of an open dimension, its label (`null` where none is known), and how many of\nthe version's variables with data hold it." + }, + "DescriptionValuesPage": { + "$id": "https://schemas.dfo.one.org/datasets/v1/description-values-page.json", + "properties": { + "property": { + "$ref": "#/components/schemas/DescribedProperty" + }, + "items": { + "items": { + "$ref": "#/components/schemas/DescribedValue" + }, + "type": "array", + "title": "Items" + }, + "next_cursor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Next Cursor" + }, + "complete": { + "type": "boolean", + "title": "Complete" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "property", + "items", + "next_cursor", + "complete" + ], + "title": "DescriptionValuesPage", + "description": "One page of `GET /api/datasets/{id}/{content_version}/description/values`: the values\nthe version's record holds for one open dimension, most variables first, ties ordered by\ndcid. `next_cursor` continues the list after the page's last value and is `null` on its\nlast page, where `complete` is true." + }, + "DiagnosticModel": { + "properties": { + "code": { + "type": "string", + "title": "Code" + }, + "severity": { + "type": "string", + "title": "Severity" + }, + "message": { + "type": "string", + "title": "Message" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "code", + "severity", + "message" + ], + "title": "DiagnosticModel", + "description": "One manifest diagnostic: a fact about how this response was produced that a developer\nreads and a dataset's description leaves out, since it states nothing about the data.\n`processing_level_undeclared` and `origin_catalogue_stale` are the codes it carries." + }, + "Diagnostics": { + "properties": { + "engine_build": { + "type": "string", + "title": "Engine Build", + "description": "the commit sha the image was built from, the same value the x-dfo-commit response header carries; distinct from schema_version" + }, + "trace_id": { + "type": "string", + "title": "Trace Id", + "description": "this request's trace_id, shared verbatim with every RFC 9457 problem-details body and the SSE stream's `done` event" + }, + "warnings": { + "items": { + "$ref": "#/components/schemas/Warning" + }, + "type": "array", + "title": "Warnings", + "description": "degraded-mode, applied-signal, partial-graph signals" + }, + "timing_ms": { + "anyOf": [ + { + "$ref": "#/components/schemas/Timing" + }, + { + "type": "null" + } + ], + "description": "latency breakdown" + }, + "llm_usage": { + "anyOf": [ + { + "additionalProperties": { + "type": "integer" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Llm Usage", + "description": "per-request LLM token counts {input_tokens, output_tokens, cached_tokens}" + }, + "timed_out": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Timed Out", + "description": "True when the pipeline's soft deadline truncated this result to a partial response; False when it ran to completion. None on the SSE response event (whose `done` event carries the authoritative flag instead) -- only resolve_async's buffered ResolveResponse populates this, since a buffered caller has no `done` event of its own to read." + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "engine_build", + "trace_id", + "warnings" + ], + "title": "Diagnostics", + "description": "Run health, warnings, timing, and build stamp." + }, + "DimensionNoun": { + "properties": { + "singular": { + "type": "string", + "title": "Singular" + }, + "plural": { + "type": "string", + "title": "Plural" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "singular", + "plural" + ], + "title": "DimensionNoun", + "description": "What one member of a flow dimension is called, and several of them." + }, + "DocumentErrorEntry": { + "properties": { + "member": { + "type": "string", + "enum": [ + "transformation_log", + "version_history", + "methodology.description", + "data_notes" + ], + "title": "Member", + "description": "the wire path the document fills" + }, + "line": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Line", + "description": "1-based line in the decoded document where the problem starts, or null" + }, + "reason": { + "type": "string", + "enum": [ + "undecodable", + "empty_document", + "content_outside_section", + "unexpected_heading_level", + "heading_not_plain_text", + "empty_heading", + "empty_section", + "disallowed_block", + "raw_html", + "hard_break", + "invalid_release_heading", + "missing_release_title", + "release_dates_not_descending", + "duplicate_release_date", + "unknown_change_kind", + "duplicate_change_kind", + "not_single_bullet_list", + "list_item_not_single_paragraph", + "document_too_large", + "nesting_too_deep", + "conflicting_values" + ], + "title": "Reason", + "description": "the template rule the document breaks" + } + }, + "type": "object", + "required": [ + "member", + "line", + "reason" + ], + "title": "DocumentErrorEntry", + "description": "A Markdown document the source carries that this door could not serve.\nThe member it fills is empty and named in `gaps`." + }, + "DownloadFacts": { + "properties": { + "rows": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Rows", + "description": "the rows the definition's series serve: one per series and date, totals included. A long-layout CSV or XLSX keeps the rows where a role the Datasets options document lists in long_layout_totals holds a total out of its main table, so that table can hold fewer. Null when it could understate: a served member the coverage artifact does not hold" + }, + "rows_exact": { + "type": "boolean", + "title": "Rows Exact", + "description": "true when rows equals the mint's coverage.rows. Under a unit request rows counts only the rows the conversion keeps: at constant prices each entity's rows in the years its deflator holds, none when it lacks the base year. False when rows is an upper bound: a unit request whose conversion cannot be read from the loaded conversion tables (none loaded, served facets under several recipes or in a unit that is no currency, or no single deflator role), or a series whose facets carry no complete date list. False when rows is null" + }, + "series": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Series", + "description": "the series in the file: distinct (StatVar, entities) with a point, the mint's series_count. Null when rows is null" + }, + "window": { + "anyOf": [ + { + "$ref": "#/components/schemas/TimeWindow" + }, + { + "type": "null" + } + ], + "description": "the first and last years of the file's points; null when rows is null" + }, + "licence": { + "anyOf": [ + { + "$ref": "#/components/schemas/DownloadLicence" + }, + { + "type": "null" + } + ], + "description": "the licence of the one provenance the answer serves, from the origin catalogue; null when it serves several, or the catalogue names no single licence for it" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "rows_exact" + ], + "title": "DownloadFacts", + "description": "What a Datasets mint of this Spec's definition writes in its default file (no\ngrouping), known before the first download. Rows and series count what the answer's\nread plan serves over the identity's whole window: every year for no window, the\nrange for a range, and each series' latest year for `latest`." + }, + "DownloadLicence": { + "properties": { + "label": { + "type": "string", + "title": "Label", + "description": "the licence's name: the `name` of the licenseType node the provenances of the provenance's source-index entry agree on" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "label" + ], + "title": "DownloadLicence", + "description": "The licence of the provenance a Spec's file cites. Its terms page is on the\nprovenance's source page." + }, + "EnrichmentCoverageCountsModel": { + "properties": { + "entities": { + "type": "integer", + "title": "Entities" + }, + "covered": { + "type": "integer", + "title": "Covered" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "entities", + "covered" + ], + "title": "EnrichmentCoverageCountsModel" + }, + "EnrichmentOptionModel": { + "properties": { + "column": { + "type": "string", + "title": "Column" + }, + "field": { + "type": "string", + "title": "Field" + }, + "token": { + "type": "string", + "title": "Token" + }, + "state": { + "type": "string", + "title": "State" + }, + "reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reason" + }, + "coverage": { + "$ref": "#/components/schemas/EnrichmentCoverageCountsModel" + }, + "missing": { + "items": { + "$ref": "#/components/schemas/MissingEntityModel" + }, + "type": "array", + "title": "Missing" + }, + "truncated": { + "type": "boolean", + "title": "Truncated", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "column", + "field", + "token", + "state", + "coverage" + ], + "title": "EnrichmentOptionModel", + "description": "One `(entity column, field)` enrichment this deployment enables,\nwith `token` naming the exact `{column}_{field}` the `columns` option\naccepts to request it." + }, + "EntityCounts": { + "properties": { + "parties": { + "type": "integer", + "title": "Parties", + "description": "entities with figures of their own" + }, + "totals": { + "type": "integer", + "title": "Totals", + "description": "entities that hold other entities' figures" + }, + "residual": { + "type": "integer", + "title": "Residual", + "description": "entities holding figures no other entity does" + }, + "unclassified": { + "type": "integer", + "title": "Unclassified", + "description": "entities the code index does not list" + } + }, + "type": "object", + "required": [ + "parties", + "totals", + "residual", + "unclassified" + ], + "title": "GraphAvailabilityEntityCounts", + "description": "The distinct entities in one role, split by their kind in the code index." + }, + "EntityCoverage": { + "properties": { + "entity": { + "$ref": "#/components/schemas/StepRef" + }, + "periods": { + "type": "integer", + "minimum": 0.0, + "title": "Periods" + }, + "of": { + "type": "integer", + "minimum": 0.0, + "title": "Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "entity", + "periods", + "of" + ], + "title": "EntityCoverage", + "description": "How many of the window's periods one ranked entity holds." + }, + "EntityGroup": { + "properties": { + "ref": { + "anyOf": [ + { + "type": "string", + "maxLength": 1024 + }, + { + "type": "null" + } + ], + "title": "Ref", + "description": "the group's own graph node, when the graph holds one; null otherwise" + }, + "label": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Label", + "description": "the group's name as the request gave it, plain text" + }, + "entity_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 1024 + }, + { + "type": "null" + } + ], + "title": "Entity Type", + "description": "the graph type of the group's own node, e.g. Continent, UNGeoRegion, ContinentalUnion; null when the graph holds no node for the group" + }, + "total": { + "anyOf": [ + { + "type": "string", + "maxLength": 1024 + }, + { + "type": "null" + } + ], + "title": "Total", + "description": "the party the dataset publishes as the group's total, which the role binds in place of the members (DACAfrica for Africa); null when the role binds the members" + }, + "group_id": { + "anyOf": [ + { + "type": "string", + "maxLength": 1024 + }, + { + "type": "null" + } + ], + "title": "Group Id", + "description": "the membership registry's id for a group the graph holds no node for, e.g. groups/OECD.DAC.Region.Asia; null when ref is set or the group is no registry group" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "label" + ], + "title": "EntityGroup", + "description": "A named group whose members fill one entity role, as the request named it\n(\"EU member states\"). The members themselves are the role's dcids in\n`BaseIdentity.entities`. This records only that they were asked for as one\ngroup, so the heading can say \"the 27 EU member states\" after any edit that\nkeeps the role's members. A group the graph holds no node for, read from the\nmembership registry (\"Asia (DAC)\"), names the registry's id for it in\n`group_id`, so a resubmit restores it and the total its dataset publishes for it.\nA group whose `ref` is a continent or subregion\nthat the membership policy holds or omits (`MembershipPolicy.holds_region`)\nreads as its countries (\"the 54 countries in Africa\"), whatever its graph\ntype. `entity_type` is informational, and the reading keys on `ref`. When\nthe role binds the total its dataset publishes\nfor the group (\"Africa (DAC)\") in place of the members, `total` names that\nparty and the role's one dcid is it. A Spec serves its groups on\n`ResolvedSpec.entity_groups`, and a resubmit posts them beside the identity\n(`ResubmitIdentityEntry.entity_groups`, `ResubmitCandidate.entity_groups`)." + }, + "EntityOptions": { + "properties": { + "entity_ref": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Entity Ref", + "description": "dcid of the currently-bound directional entity; joins to an entry in SentenceToken.entity_refs. None means this role axis is open -- no entity is bound on it, and `options` is this axis's own candidate member set rather than a set the current binding could be swapped among. An open role axis omits this key entirely on both the buffered body and the SSE entity_options event, rather than emitting null -- the opposite of SlotOption.coverage's own explicit-null convention on that same SSE channel" + }, + "role": { + "$ref": "#/components/schemas/RoleAxis", + "description": "the flow axis these candidates apply to; present even when entity_ref is omitted so a selected candidate can be posted under the same identity.entities role" + }, + "options": { + "items": { + "$ref": "#/components/schemas/SlotOption" + }, + "type": "array", + "title": "Options", + "description": "candidate entities, reusing SlotOption for shape parity with slot_options" + }, + "truncated": { + "type": "boolean", + "title": "Truncated", + "description": "true when options is capped or deliberately count-only, so it is not the complete known candidate set; false when every known candidate is listed" + }, + "source": { + "type": "string", + "enum": [ + "observed", + "seed" + ], + "title": "Source", + "description": "'seed' for a hand-curated candidate set; 'observed' for candidates already confirmed while resolving this flow axis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "role", + "options", + "truncated", + "source" + ], + "title": "EntityOptions", + "description": "Candidates for one directional entity axis.\n\nParallel to SlotOptions, but for a directional *entity* (an observation\nendpoint) rather than a constraint-property value. A role-bearing flow may\nexpose either its origin or destination axis here when that axis was left\nopen. The entry's ``role`` is the routing key a client uses to promote a\nselected candidate into ``identity.entities`` on a dataset_resubmit entry." + }, + "EntityRef": { + "properties": { + "ref": { + "type": "string", + "title": "Ref" + }, + "label": { + "type": "string", + "title": "Label" + }, + "kind": { + "anyOf": [ + { + "type": "string", + "enum": [ + "country", + "continent", + "subregion", + "continental_union", + "place_other", + "aggregate", + "organisation", + "group", + "stat_var", + "code_system", + "code", + "unit", + "source", + "dataset", + "provenance", + "other" + ] + }, + { + "type": "null" + } + ], + "title": "Kind" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "kind" + ], + "title": "GraphResolveEntity", + "description": "A reference with its kind. `kind` is `null` only for a `not_held` entity, which the\ngraph holds no node to classify." + }, + "Exclusion": { + "properties": { + "ref": { + "type": "string", + "title": "Ref" + }, + "reason": { + "type": "string", + "enum": [ + "superseded_by_dfo", + "superseded_by_un_system" + ], + "title": "Reason", + "description": "superseded_by_dfo: an upstream copy of a dataset DFO imports. superseded_by_un_system: a UN System Data Commons agency's series replace it" + } + }, + "type": "object", + "required": [ + "ref", + "reason" + ], + "title": "Exclusion", + "description": "A provenance a base source holds that this deployment does not admit, because\nanother Data Commons supersedes it." + }, + "Expansion": { + "properties": { + "added": { + "items": { + "$ref": "#/components/schemas/GraphRef" + }, + "type": "array", + "minItems": 1, + "title": "Added", + "description": "descendant codes admitted beyond the slot's own bound value(s), in the code index's descendant-walk order. Never empty -- a slot whose expansion added nothing carries no Expansion at all (Slot.expansion is None), rather than one with added=[]" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "added" + ], + "title": "Expansion", + "description": "Codes a hierarchical value/set binding resolved to beyond its own bound\nvalue(s): the descendant codes admitted by walking the code index's\n`specializationOf` closure for a dimension the index declares\n`hierarchical` (code_index.query.CodeIndex.descendants).\n\nAdditive only. Never a substitute for `binding`, and never fed into spec\nidentity -- `BindingValue`/`BindingSet` are the sole identity-bearing wire\nform (see Slot.expansion's own docstring for why: identity is minted from\n`BindingSet.values`, built from the query's own drafted values, before\nresolution ever widens them). `added` never repeats a dcid already in the\nbinding's own value(s); it holds only what expansion contributed on top." + }, + "FacetItem": { + "properties": { + "ref": { + "type": "string", + "title": "Ref" + }, + "label": { + "type": "null", + "title": "Label" + }, + "source": { + "$ref": "#/components/schemas/AvailabilitySource" + }, + "unit": { + "anyOf": [ + { + "$ref": "#/components/schemas/NodeRef" + }, + { + "type": "null" + } + ] + }, + "measurement_method": { + "anyOf": [ + { + "$ref": "#/components/schemas/NodeRef" + }, + { + "type": "null" + } + ] + }, + "observation_period": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Observation Period" + }, + "scaling": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scaling" + }, + "first_year": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "First Year" + }, + "last_year": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Year" + }, + "observations": { + "type": "integer", + "title": "Observations" + }, + "places": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Places", + "description": "null for a role-bearing variable" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "source", + "unit", + "measurement_method", + "observation_period", + "scaling", + "first_year", + "last_year", + "observations", + "places" + ], + "title": "GraphFacetItem", + "description": "One facet of a variable, as the `facets` list relation serves it. `ref` is the facet id,\nwhich hashes the facet's metadata." + }, + "FacetNationalCurrencyBinding": { + "properties": { + "national_currency": { + "$ref": "#/components/schemas/UnitCurrencyRole" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "national_currency" + ], + "title": "FacetNationalCurrencyBinding", + "description": "The unit axis bound to each entity's own currency: at each entity `role`\nbinds, the facets whose unit is the one currency the graph's\n`nationalCurrencyOf` names for it, served as published and never converted.\nThe conversion request naming the same role (`UnitCurrencyRole`) converts\neach row into that currency instead." + }, + "FacetOptions": { + "properties": { + "axis": { + "type": "string", + "title": "Axis", + "description": "the facet axis this option set belongs to (see FacetAxis)" + }, + "options": { + "items": { + "$ref": "#/components/schemas/SlotOption" + }, + "type": "array", + "title": "Options", + "description": "candidate values seen on the resolved candidates' own unfiltered observation facets, ranked by in-window observation-point count descending then ref ascending; a dcid the graph can't label falls back to the dcid itself as its own label rather than being dropped -- every value here already came off a confirmed observation facet, unlike a curated seed candidate. On the measurementMethod and unit axes, an option with no value.ref stands for the facets that declare no value on the axis, as Data Commons omits the member; it is listed only beside a declared value, ranks last among equal counts, and is pinned by posting identity.facets. as {state: 'value', ref: null}" + }, + "truncated": { + "type": "boolean", + "title": "Truncated", + "description": "true when options is bounded by SEARCH_MAX_OPTIONS rather than the full distinct set observed" + }, + "source": { + "type": "string", + "enum": [ + "observed", + "seed" + ], + "title": "Source", + "description": "always 'observed' -- a facet axis has no curated seed taxonomy" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "axis", + "options", + "truncated", + "source" + ], + "title": "FacetOptions", + "description": "The candidate set one facet axis (see ResolvedFacet) was chosen from:\nevery distinct value seen on the resolved candidates' own observation\nfacets, so a client can offer \"what else could I ask for\" alongside the\nserved answer.\n\nParallel to SlotOptions/EntityOptions, reusing SlotOption for shape\nparity. Unlike either, source is always \"observed\" -- a facet axis has\nno curated seed taxonomy -- and no option here ever carries a populated\nSlotOption.coverage: there is no separate confirm step for a facet\noption, the observed count already ranks the list." + }, + "FacetRefBinding": { + "properties": { + "ref": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Ref" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref" + ], + "title": "FacetRefBinding", + "description": "A facet axis bound to a specific ref. Every axis accepts this form;\nthe unit axis alone also accepts `FacetUnitRequestBinding`, the\nconversion-request form (`currency`/`prices`/`base_year`), and\n`FacetNationalCurrencyBinding`. A null `ref` binds the facets that declare\nno value on the axis, and only `NULL_REF_FACET_AXES` accept it." + }, + "FactSummaryModel": { + "properties": { + "changed": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Changed", + "description": "the patch's own changed field names, empty for a create or a no-op write" + }, + "series": { + "items": { + "$ref": "#/components/schemas/FactSummarySeriesEntry" + }, + "type": "array", + "title": "Series", + "description": "every visible series this revision resolves, capped" + }, + "series_cut": { + "type": "integer", + "title": "Series Cut", + "description": "how many series the series cap and the token cap together dropped from this summary" + }, + "window": { + "anyOf": [ + { + "$ref": "#/components/schemas/WindowModel" + }, + { + "type": "null" + } + ], + "description": "this component's own [start, end] period window, null where its type defines none" + }, + "unit": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/ConvertedUnitModel" + }, + { + "$ref": "#/components/schemas/ComposedUnitModel" + }, + { + "type": "null" + } + ], + "title": "Unit", + "description": "this component's own unit, the value its resolved payload carries: a unit's graph name (its ref when the graph has none), a converted unit, or a composed unit. A line_chart or bar_chart reports its first series' unit and a table the unit every row shares. Null where the type defines none, the rows declare none, or a table's rows differ." + }, + "change": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Change", + "description": "the stat_card's derived comparison between its two basis periods, null for every other member and for a stat_card whose intent carries no change" + }, + "source_refs": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Source Refs", + "description": "every distinct raw provenance ref a source_card's frame carries. It is null for every other member." + }, + "defaults": { + "items": { + "$ref": "#/components/schemas/AppliedDefaultModel" + }, + "type": "array", + "title": "Defaults", + "description": "the choices this component made where its intent left one open, empty when it made none" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "changed", + "series", + "series_cut", + "window", + "unit", + "change", + "source_refs", + "defaults" + ], + "title": "FactSummaryModel", + "description": "The closed, token-capped fact summary a revision reports." + }, + "FactSummarySeriesEntry": { + "properties": { + "id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Id", + "description": "this series' own id, null when none could be assigned" + }, + "label": { + "type": "string", + "title": "Label", + "description": "this series' own display label" + }, + "coordinates": { + "additionalProperties": true, + "type": "object", + "title": "Coordinates", + "description": "this series' own dimension coordinates" + }, + "point_count": { + "type": "integer", + "title": "Point Count", + "description": "how many of this series' points carry an observed value" + }, + "first_value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "First Value", + "description": "this series' earliest observed value, formatted, null when it has none" + }, + "last_value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Value", + "description": "this series' latest observed value, formatted, null when it has none" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "label", + "coordinates", + "point_count", + "first_value", + "last_value" + ], + "title": "FactSummarySeriesEntry", + "description": "One `fact_summary.series[]` entry. It reports one visible series'\nidentity, point count and formatted boundary values." + }, + "FlowAccount": { + "type": "string", + "const": "provider" + }, + "FormatOptionModel": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "state": { + "type": "string", + "title": "State" + }, + "reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name", + "state" + ], + "title": "FormatOptionModel" + }, + "FrameCurrent": { + "properties": { + "status": { + "type": "string", + "const": "current", + "title": "Status", + "default": "current" + }, + "frame": { + "$ref": "#/components/schemas/FramePair", + "description": "the named frame, which is its rendering's current one" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "frame" + ], + "title": "FrameCurrent" + }, + "FrameDimensionMatch": { + "properties": { + "name": { + "type": "string", + "title": "Name", + "description": "this dimension's own column name" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Values", + "description": "this dimension's own values matching the query" + }, + "matched_count": { + "type": "integer", + "title": "Matched Count", + "description": "how many of this dimension's values matched the query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name", + "values", + "matched_count" + ], + "title": "FrameDimensionMatch", + "description": "One dimension of a frame's query-filtered view (`?query=` given,\n`dimension` absent). Its values are filtered to those matching the\nquery." + }, + "FrameDimensionSummary": { + "properties": { + "name": { + "type": "string", + "title": "Name", + "description": "this dimension's own column name" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Values", + "description": "this dimension's own values, capped" + }, + "total_count": { + "type": "integer", + "title": "Total Count", + "description": "this dimension's own value count before capping" + }, + "truncated": { + "type": "boolean", + "title": "Truncated", + "description": "whether this dimension's values list was capped" + }, + "plural": { + "type": "boolean", + "title": "Plural", + "description": "whether this frame's series hold more than one value of this dimension, a null counting as one; the estimates continuing a series hold its method, so they leave measurementMethod not plural" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name", + "values", + "total_count", + "truncated", + "plural" + ], + "title": "FrameDimensionSummary", + "description": "One dimension of a frame's structural view (`GET .../frames/{...}`\nwith neither `dimension` nor `query` given). Its values are capped to\nthe per-dimension listing cap." + }, + "FrameDimensionValuesResponse": { + "properties": { + "dimension": { + "type": "string", + "title": "Dimension", + "description": "the dimension this response reports" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Values", + "description": "every value this dimension carries, uncapped, or only the values matching `query` when it is given" + }, + "total_count": { + "type": "integer", + "title": "Total Count", + "description": "how many values this dimension carries, or how many match `query` when it is given" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "dimension", + "values", + "total_count" + ], + "title": "FrameDimensionValuesResponse", + "description": "`GET /api/presentation/frames/{spec_id}/{content_version}?dimension=`'s\nbody. It reports one dimension's full value list, read fresh and\nuncapped. Given alongside `?query=`, `values` and `total_count`\ndescribe only the values matching the query." + }, + "FrameFilteredViewResponse": { + "properties": { + "dimensions": { + "items": { + "$ref": "#/components/schemas/FrameDimensionMatch" + }, + "type": "array", + "title": "Dimensions", + "description": "every dimension this frame declares, filtered" + }, + "period_grain": { + "type": "string", + "title": "Period Grain", + "description": "this frame's own period grain" + }, + "coverage": { + "anyOf": [ + { + "prefixItems": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array", + "maxItems": 2, + "minItems": 2 + }, + { + "type": "null" + } + ], + "title": "Coverage", + "description": "this frame's own [start, end] period coverage, null if it has none" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "dimensions", + "period_grain", + "coverage" + ], + "title": "FrameFilteredViewResponse", + "description": "`GET /api/presentation/frames/{spec_id}/{content_version}?query=`'s\nbody (`dimension` absent). It reports every dimension this frame\ndeclares, filtered to values matching the query, counts kept." + }, + "FrameMoved": { + "properties": { + "status": { + "type": "string", + "const": "moved", + "title": "Status", + "default": "moved" + }, + "frame": { + "$ref": "#/components/schemas/FramePair", + "description": "the current frame of the named frame's rendering" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "frame" + ], + "title": "FrameMoved" + }, + "FramePair": { + "properties": { + "spec_id": { + "type": "string", + "title": "Spec Id" + }, + "content_version": { + "type": "string", + "title": "Content Version" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "spec_id", + "content_version" + ], + "title": "FramePair" + }, + "FramePending": { + "properties": { + "status": { + "type": "string", + "const": "pending", + "title": "Status", + "default": "pending" + }, + "operation_id": { + "type": "string", + "title": "Operation Id", + "description": "the queued rebuild, pollable on the operations route" + }, + "retry_after_s": { + "type": "number", + "title": "Retry After S", + "description": "seconds to wait before calling again" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "operation_id", + "retry_after_s" + ], + "title": "FramePending" + }, + "FrameStructuralViewResponse": { + "properties": { + "dimensions": { + "items": { + "$ref": "#/components/schemas/FrameDimensionSummary" + }, + "type": "array", + "title": "Dimensions", + "description": "every dimension this frame declares" + }, + "period_grain": { + "type": "string", + "title": "Period Grain", + "description": "this frame's own period grain" + }, + "coverage": { + "anyOf": [ + { + "prefixItems": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array", + "maxItems": 2, + "minItems": 2 + }, + { + "type": "null" + } + ], + "title": "Coverage", + "description": "this frame's own [start, end] period coverage, null if it has none" + }, + "series_count": { + "type": "integer", + "title": "Series Count", + "description": "how many distinct series this frame resolves" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "dimensions", + "period_grain", + "coverage", + "series_count" + ], + "title": "FrameStructuralViewResponse", + "description": "`GET /api/presentation/frames/{spec_id}/{content_version}`'s body\nwith neither `dimension` nor `query` given. It reports the frame's own\nstructural view, every dimension capped." + }, + "Freshness": { + "properties": { + "release_frequency": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Release Frequency" + }, + "release_frequency_label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Release Frequency Label" + }, + "refresh_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Refresh Type" + } + }, + "type": "object", + "required": [ + "release_frequency", + "release_frequency_label", + "refresh_type" + ], + "title": "Freshness", + "description": "A source's own refresh cadence, read from DCP provenance arcs that imports populate\nunevenly: `dc/base/WHO_COVID19` carries both `sourceReleaseFrequency` and\n`automaticRefreshType`, `dc/base/BIS_CentralBankPolicyRate` only the second, and\n`dc/base/WHO_GHO` neither. Nullability is the contract.\n\n`release_frequency` is the raw `sourceReleaseFrequency` ISO 8601 duration (`P1M`);\n`release_frequency_label` is `materialise.cadence.cadence_label`'s display label for it\n(`Monthly`), or the raw token when that module does not recognise it.\n\n`refresh_type` is `automaticRefreshType`'s value: how this deployment refreshes the\nsource, such as `GCPCloudRunAutomaticRefresh`, or the sentinel `NoAutomaticRefresh`." + }, + "FrontMatterValue": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "$ref": "#/components/schemas/FrontMatterValue" + }, + "type": "array" + }, + { + "additionalProperties": { + "$ref": "#/components/schemas/FrontMatterValue" + }, + "type": "object" + } + ] + }, + "GraphRef": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the graph identifier" + }, + "label": { + "type": "string", + "title": "Label", + "description": "plain-language display name, read from the graph" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref", + "label" + ], + "title": "GraphRef", + "description": "Every graph identifier in the contract." + }, + "GraphSchema": { + "properties": { + "schemas": { + "additionalProperties": { + "additionalProperties": true, + "type": "object" + }, + "type": "object", + "title": "Schemas", + "description": "JSON Schema of each served request and response body, keyed by name" + }, + "capabilities": { + "type": "string", + "title": "Capabilities", + "description": "path of this surface's capability document" + } + }, + "type": "object", + "required": [ + "schemas", + "capabilities" + ], + "title": "GraphSchema", + "description": "The full `GET /api/graph/schema` document." + }, + "GroupNode": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the node's dcid" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "the node's name; for a Provenance, its parent Dataset's name where it has one. Null, and named in gaps, when the graph gives none" + }, + "types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Types", + "description": "the node's typeOf values, as the graph holds them" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "the node's prose in the graph; null when it has none" + }, + "links": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "codes", + "children", + "members", + "countries", + "datasets", + "variables", + "facets" + ] + }, + "type": "object", + "title": "Links", + "description": "each list relation the node has, mapped to its route; empty when none" + }, + "gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Gaps", + "description": "the member path of every value this door cannot know" + }, + "built_from": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "code_index", + "origin_catalogue", + "coverage_index", + "membership" + ] + }, + "type": "object", + "title": "Built From", + "description": "the build of each table the response read" + }, + "kind": { + "type": "string", + "const": "group", + "title": "Kind", + "default": "group" + }, + "group": { + "$ref": "#/components/schemas/MembershipBlock" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "types", + "description", + "links", + "gaps", + "built_from", + "kind", + "group" + ], + "title": "GroupNode" + }, + "GroupbyOptions": { + "properties": { + "by": { + "items": { + "type": "string", + "minLength": 1 + }, + "type": "array", + "minItems": 1, + "uniqueItems": true, + "title": "By" + }, + "op": { + "type": "string", + "const": "sum", + "title": "Op" + }, + "levels": { + "anyOf": [ + { + "additionalProperties": { + "type": "integer", + "maximum": 99.0, + "minimum": 0.0 + }, + "type": "object", + "minProperties": 1 + }, + { + "type": "null" + } + ], + "title": "Levels", + "description": "code system -> depth: roll each kept code up to its ancestor at that depth (0 = root codes); a code shallower than the depth stays as itself, under its own label" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "by", + "op" + ], + "title": "GroupbyOptions", + "description": "`options.groupby`: a safe roll-up that keeps exactly the axes named\nin `by`, one row per distinct combination of their values. Every other\ngraph-declared summable axis a frame decoded is summed away, `stat_var`\nincluded. `by` names what a caller wants to see, the opposite of\n`groupby_sum`'s own \"collapse this axis\" reading. `sum` is the only op\nthis closed reshape list allows.\n\nEvery `by` entry names a code system some deployment declaration marks\nsummable, a role/entity column (`materialise.roles.KNOWN_ROLE_NAMES`),\n`stat_var`, or a column every frame carries regardless of shape; any\nother name refuses `rollup_not_summable`\n(`datasets_api.groupby.refuse_unknown_by_axes`). A declared axis this\nframe's StatVars do not decode is left out of the collapse set\n(`datasets_api.groupby.collapse_axes`).\n\n`levels` rolls a kept hierarchical axis up to one depth of its parent\nchain before the sum: each code becomes its ancestor at that depth, and\ndepth 0 is the root codes. Each key must also appear in `by`, and must\nbe one of the capabilities document's `groupby_level_axes`\n(`datasets_api.render.check_options_supported`)." + }, + "GroupbyOptionsModel": { + "properties": { + "state": { + "type": "string", + "title": "State" + }, + "reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reason" + }, + "axes": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Axes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "state" + ], + "title": "GroupbyOptionsModel", + "description": "`axes` names the axes a `groupby.by` request may keep: every other\ndeclared-summable axis a frame decoded is collapsed into it. Empty\nwhile `state` is `unavailable`." + }, + "Headline": { + "properties": { + "year": { + "type": "integer", + "title": "Year", + "description": "the year the counts are for. For a latest window it is the elected year: of the three calendar years ending at the newest year a variable's series hold, at or before the year the coverage artifact was built, the newest one that at least half as many series hold as the fullest of the three, and with several variables the newest year any of them elects. For a named window it is the latest year any served series has an observation inside the window" + }, + "year_named": { + "type": "boolean", + "title": "Year Named", + "description": "whether the request itself named a year or a range of years, rather than defaulting to one, independent of whether those years include the shown `year`" + }, + "named_window": { + "anyOf": [ + { + "$ref": "#/components/schemas/TimeWindow" + }, + { + "type": "null" + } + ], + "description": "the year or years the request named: equal bounds for one year, an absent bound for an open range; null when no year was named. The counts are for `year` alone, whatever this window holds" + }, + "observations": { + "type": "integer", + "title": "Observations", + "description": "exact observation count across served series in year" + }, + "series": { + "type": "integer", + "title": "Series", + "description": "exact series count with an observation in year" + }, + "role_counts": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Role Counts", + "description": "distinct dcid count per role active in year, keyed by the graph's own role property dcid (e.g. financingProvider, financingRecipient) -- never by a donor/recipient label, so the wire stays aligned with Data Commons' own names" + }, + "recent_years": { + "items": { + "$ref": "#/components/schemas/HeadlineYear" + }, + "type": "array", + "minItems": 1, + "title": "Recent Years", + "description": "the counts for three calendar years, newest first, so a newest year with far fewer series than the years before it reads as incomplete. For a latest window they are raw counts over every series the answer holds, ending at the newest year any of them holds at or before the year the coverage artifact was built, or at the newest year any holds when none holds a year that early; `year` is one of the three: the newest year a variable heads, which is the year it elected or, for a variable that elects none, such as one of monthly data, its newest year at or before the build year. When no variable holds a year that early, each heads its newest year. `observations`, `series` and `role_counts` count only the variables heading it. For a named window they end at `year`, the first entry repeats `observations`, `series` and `role_counts`, and the earlier years count whether or not `named_window` reaches them. A year with no data is kept with zero counts. The list stops at the first year the coverage artifact represents, so it can hold fewer than three entries" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "year", + "year_named", + "observations", + "series", + "role_counts", + "recent_years" + ], + "title": "Headline", + "description": "The exact, one-year summary of a role-bearing answer's own served\npopulation: the year `CoverageIndex.headline` (series_coverage) heads the\nanswer with, whether that year was the one the question named, the exact\nobservation and series count in that year alone, and how many distinct dcids\neach role carries in it. `series_coverage.index.Headline`'s own docstring is\nthe source of truth for why `observations` and `series` are always equal\nunder this schema.\n\nThe counts are those of the year the answer's read plan serves. Under a `latest`\nwindow that is the year its variables elect (`CoverageIndex.elected_years`), which\nthe preview and a mint of the Spec serve too. Under a named window it is the latest\nyear with data in that window, so a question naming 2015 to 2020 counts the latest\nof those years with data. `named_window` carries the years it named.\n\nAttached to every role-bearing answer (named-destination confirmed and\nopen-axis discovered alike), never to a non-role-bearing one: coverage\nonly exists for role-bearing series (series_coverage.schema's own scope\nnote), and computing this is a free in-memory bitmask operation, not a\nnetwork read, so there is no population-size reason to withhold it from\na narrow answer the way the per-series preview stays capped at 20\nregardless of how broad the answer is." + }, + "HeadlineYear": { + "properties": { + "year": { + "type": "integer", + "title": "Year", + "description": "the calendar year these counts are for" + }, + "observations": { + "type": "integer", + "title": "Observations", + "description": "exact observation count across served series in year" + }, + "series": { + "type": "integer", + "title": "Series", + "description": "exact series count with an observation in year" + }, + "role_counts": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Role Counts", + "description": "distinct dcid count per role active in year, keyed by the graph's own role property dcid; a role with no dcid in the year is absent" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "year", + "observations", + "series", + "role_counts" + ], + "title": "HeadlineYear", + "description": "The exact counts for one calendar year of a role-bearing answer's served\npopulation: observations and series with an observation in it, and how many\ndistinct dcids each role carries. A year with no data counts zero." + }, + "HealthResponse": { + "properties": { + "status": { + "type": "string", + "const": "ok", + "title": "Status", + "description": "always \"ok\" for a 200 response" + }, + "build": { + "type": "string", + "title": "Build", + "description": "the commit sha the image was built from, the same value the x-dfo-commit response header carries, \"unknown\" on a checkout run with no DFO_BUILD_COMMIT set" + }, + "capability_version": { + "type": "string", + "title": "Capability Version", + "description": "this surface's own capability_version token" + } + }, + "type": "object", + "required": [ + "status", + "build", + "capability_version" + ], + "title": "HealthResponse", + "description": "`GET /healthz`'s own response body, shared across every surface." + }, + "IdentityBindingExact": { + "properties": { + "state": { + "type": "string", + "const": "exact", + "title": "State", + "default": "exact" + }, + "ref": { + "type": "string", + "maxLength": 1024, + "title": "Ref", + "description": "the bound dcid, denoting that code alone" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref" + ], + "title": "IdentityBindingExact", + "description": "A single bound dcid, denoting that code alone -- never its subtree,\neven where the code is a hierarchical (non-leaf) code (see\n`docs/identity-v1.md` in `spec-kit` for the denotation rule: `value`\ndenotes a hierarchical code's whole subtree, `exact` denotes the code\nalone). Slot-only: `_build_facet_binding` refuses `exact` on a facet.\nNo engine `Binding` arm maps onto this state and no minting site\nproduces it -- see `IdentityBinding`'s own docstring." + }, + "IdentityBindingSet": { + "properties": { + "state": { + "type": "string", + "const": "set", + "title": "State", + "default": "set" + }, + "refs": { + "items": { + "type": "string", + "maxLength": 1024 + }, + "type": "array", + "maxItems": 1024, + "minItems": 1, + "title": "Refs", + "description": "the bound dcids (dfo_spec_kit sorts and de-duplicates)" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "refs" + ], + "title": "IdentityBindingSet", + "description": "A bound dcid set, in the identity core's own binding wire shape." + }, + "IdentityBindingUnbound": { + "properties": { + "state": { + "type": "string", + "const": "unbound", + "title": "State", + "default": "unbound" + } + }, + "additionalProperties": false, + "type": "object", + "title": "IdentityBindingUnbound", + "description": "An unbound slot/facet binding." + }, + "IdentityBindingValue": { + "properties": { + "state": { + "type": "string", + "const": "value", + "title": "State", + "default": "value" + }, + "ref": { + "type": "string", + "maxLength": 1024, + "title": "Ref", + "description": "the bound dcid" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref" + ], + "title": "IdentityBindingValue", + "description": "A single bound dcid, in the identity core's own binding wire shape." + }, + "IdentityCurrencyRole": { + "properties": { + "role": { + "type": "string", + "enum": [ + "observationAbout", + "origin", + "destination" + ], + "title": "Role", + "description": "the entity role whose bound entity's currency this request means" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "role" + ], + "title": "IdentityCurrencyRole", + "description": "The role-shaped form of a unit request's `currency`: the currency of\nthe entity bound to this spec role, resolved per row. Field-for-field mirror\nof the identity core's own `_CURRENCY_ROLE_KEYS`/`_CURRENCY_ROLES`\n(`dfo_spec_kit.identity`'s `_build_currency`, the object arm)." + }, + "IdentityFacetValueAbsent": { + "properties": { + "state": { + "type": "string", + "const": "value", + "title": "State", + "default": "value" + }, + "ref": { + "type": "null", + "title": "Ref", + "description": "null: the facet declares no value on this axis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref" + ], + "title": "IdentityFacetValueAbsent", + "description": "A measurementMethod or unit facet bound to no declared value:\n`{\"state\": \"value\", \"ref\": null}` asks for the facets that declare no value\non the axis, the ones Data Commons serves without that member. An unbound\naxis admits every facet; this binding admits only those without a value.\nMirrors the identity core's null facet ref (`docs/identity-v1.md` in\n`spec-kit`). `ref` serialises as `null` even under `exclude_none`, since\nthe identity core refuses a value binding with neither `ref` nor `request`." + }, + "IdentityFacetValueRequest": { + "properties": { + "state": { + "type": "string", + "const": "value", + "title": "State", + "default": "value" + }, + "request": { + "$ref": "#/components/schemas/IdentityUnitRequest", + "description": "the completed unit-conversion request" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request" + ], + "title": "IdentityFacetValueRequest", + "description": "A unit-axis facet bound via the request form: \"serve whatever facet\nhonours this completed currency/prices/base_year request\" rather than a\nliteral graph ref. `state` reuses the value-state spelling since this is\nstill a single-valued binding to the identity core -- `request` is what\ndistinguishes it from `IdentityBindingValue`'s `ref` form (see\n`_facet_binding_tag`, this union's discriminator)." + }, + "IdentityShapeDenominatorRef": { + "properties": { + "ref": { + "type": "string", + "maxLength": 1024, + "title": "Ref", + "description": "the resolved denominator StatVar's dcid" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref" + ], + "title": "IdentityShapeDenominatorRef", + "description": "The described arm's `measurement_denominator`, resolved to a dcid." + }, + "IdentityShapeDenominatorUnresolved": { + "properties": { + "unresolved": { + "type": "boolean", + "const": true, + "title": "Unresolved", + "description": "always the literal true -- the arc exists but names no dcid", + "default": true + } + }, + "additionalProperties": false, + "type": "object", + "title": "IdentityShapeDenominatorUnresolved", + "description": "The described arm's `measurement_denominator`, present on the graph but\nnever resolved to a dcid (e.g. a dcid-less ProvisionalNode) -- distinct\nfrom the member being absent entirely, which means no denominator arc\nexists at all." + }, + "IdentityShapePin": { + "properties": { + "kind": { + "type": "string", + "const": "stat_var", + "title": "Kind", + "default": "stat_var" + }, + "id": { + "type": "string", + "maxLength": 1024, + "title": "Id", + "description": "the pinned StatVar's dcid" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id" + ], + "title": "IdentityShapePin", + "description": "The pinned-ask arm of the identity core's `shape` union\n(`kind: \"stat_var\"`): a single StatVar dcid, minted by Datasets'\nstatvar_set. See `BaseIdentity`'s cross-member validator -- when this arm\nis chosen, `slots` must be empty." + }, + "IdentityShapeSchema": { + "properties": { + "kind": { + "type": "string", + "const": "statvar_schema", + "title": "Kind", + "default": "statvar_schema" + }, + "population_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 1024 + }, + { + "type": "null" + } + ], + "title": "Population Type", + "description": "the graph populationType dcid" + }, + "measured_property": { + "anyOf": [ + { + "type": "string", + "maxLength": 1024 + }, + { + "type": "null" + } + ], + "title": "Measured Property", + "description": "the graph measuredProperty dcid" + }, + "stat_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 1024 + }, + { + "type": "null" + } + ], + "title": "Stat Type", + "description": "the graph statType dcid, e.g. measuredValue" + }, + "measurement_qualifier": { + "anyOf": [ + { + "type": "string", + "maxLength": 1024 + }, + { + "type": "null" + } + ], + "title": "Measurement Qualifier", + "description": "the graph measurementQualifier dcid, present only when the measured property is qualified" + }, + "measurement_denominator": { + "anyOf": [ + { + "oneOf": [ + { + "$ref": "#/components/schemas/IdentityShapeDenominatorRef" + }, + { + "$ref": "#/components/schemas/IdentityShapeDenominatorUnresolved" + } + ] + }, + { + "type": "null" + } + ], + "title": "Measurement Denominator", + "description": "the graph measurementDenominator, present only on a ratio or per-capita measure: {'ref': dcid} when resolved, {'unresolved': true} when the arc exists but names no dcid" + } + }, + "additionalProperties": false, + "type": "object", + "title": "IdentityShapeSchema", + "description": "The described-ask arm of the identity core's `shape` union\n(`kind: \"statvar_schema\"`): up to five sparse schema members mapping 1:1\nonto Search's FiveTuple (see `engine.shape.identity_shape_for`, the\nadapter that builds this from a ShapeDraft's or a grounded wire Shape's\nfive-tuple dcids). Minted by Search for every standard and family shape.\n\nEvery member is optional and sparse -- an absent member contributes no\nbytes, the same sparse rule the facets map follows -- but an arm\ndescribing nothing is invalid: at least one member must be present (see\n`_at_least_one_schema_member`)." + }, + "IdentitySlot": { + "properties": { + "property": { + "type": "string", + "maxLength": 1024, + "title": "Property", + "description": "the constraint property dcid" + }, + "binding": { + "oneOf": [ + { + "$ref": "#/components/schemas/IdentityBindingValue" + }, + { + "$ref": "#/components/schemas/IdentityBindingSet" + }, + { + "$ref": "#/components/schemas/IdentityBindingUnbound" + }, + { + "$ref": "#/components/schemas/IdentityBindingExact" + } + ], + "title": "Binding", + "description": "this slot's bound state", + "discriminator": { + "propertyName": "state", + "mapping": { + "exact": "#/components/schemas/IdentityBindingExact", + "set": "#/components/schemas/IdentityBindingSet", + "unbound": "#/components/schemas/IdentityBindingUnbound", + "value": "#/components/schemas/IdentityBindingValue" + } + } + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "property", + "binding" + ], + "title": "IdentitySlot", + "description": "One what/how slot's identity contribution: property dcid + binding state.\n\nNever a where/when/source slot: `where` is carried by entity roles instead,\n`when` is carried by `requested_window` instead, and `source` is carried by\n`facets.provenance` instead -- all three would otherwise hash resolved\ngraph state rather than what was actually asked. Every IdentitySlot here\ncarries a real constraint property by construction of the shape grammar." + }, + "IdentityUnitRequest": { + "properties": { + "currency": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Z]{3}$" + }, + { + "$ref": "#/components/schemas/IdentityCurrencyRole" + } + ], + "title": "Currency", + "description": "the requested currency, upper-case ISO 4217 (e.g. 'USD'), or a role object" + }, + "prices": { + "type": "string", + "enum": [ + "current", + "constant" + ], + "title": "Prices", + "description": "'current' (nominal) prices, or 'constant' (real, base_year-anchored) prices" + }, + "base_year": { + "anyOf": [ + { + "type": "integer", + "maximum": 9007199254740991.0, + "minimum": -9007199254740991.0 + }, + { + "type": "null" + } + ], + "title": "Base Year", + "description": "required exactly when prices=='constant'; absent when prices=='current'" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "currency", + "prices" + ], + "title": "IdentityUnitRequest", + "description": "A completed unit-conversion request, in the identity core's own wire\nshape (`dfo_spec_kit.identity`'s `_build_unit_request`) -- legal only\ninside a unit-axis facet binding's `request` member\n(`IdentityFacetValueRequest`; see `BaseIdentity`'s model validator, which\nrefuses this form on any other axis).\n\nField-for-field mirror of the identity core's own `_UNIT_REQUEST_KEYS`\nschema: `currency` is upper-case ISO 4217 or a role object naming\nthe spec role whose bound entity's currency to use (see\n`IdentityCurrency`; the identity core NFC-normalises a string spelling\nbut does not case-fold, so a lower-case currency refuses here rather\nthan silently normalising to a different meaning at hash time), `prices`\nis current (nominal) or constant (real, anchored to\n`base_year`), and `base_year` is present exactly when `prices==\"constant\"`\n-- both directions enforced below, matching the identity core's own\n`invalid_unit_request` pair of checks. `base_year` is `StrictInt`,\nmatching `_require_integral_number`'s own exclusion of `bool` (a Python\n`int` subclass) and of numeric strings -- a lax `int` field would coerce\nJSON `true` to `1` and `\"2023\"` to `2023`, hashing a malformed request\nunder an unintended base year instead of refusing it. Under simultaneous\nviolations\n(e.g. a lower-case currency together with a missing base_year) the two\nlayers can report a different invariant first: this model's per-field\n`currency` pattern validates ahead of `_base_year_matches_prices` (a\n`mode=\"after\"` validator, which never runs once a field has already\nfailed), while the identity core checks `prices`-vs-`base_year` before\nthe currency regex. Same HTTP status/code either way -- message content\nonly." + }, + "IdentityWindowAll": { + "properties": { + "kind": { + "type": "string", + "const": "all", + "title": "Kind", + "default": "all" + } + }, + "additionalProperties": false, + "type": "object", + "title": "IdentityWindowAll", + "description": "No date signal was requested at all." + }, + "IdentityWindowLatest": { + "properties": { + "kind": { + "type": "string", + "const": "latest", + "title": "Kind", + "default": "latest" + } + }, + "additionalProperties": false, + "type": "object", + "title": "IdentityWindowLatest", + "description": "An explicit latest-ask: re-resolve to whatever year is CURRENTLY latest." + }, + "IdentityWindowRange": { + "properties": { + "kind": { + "type": "string", + "const": "range", + "title": "Kind", + "default": "range" + }, + "start_year": { + "anyOf": [ + { + "type": "integer", + "maximum": 9007199254740991.0, + "minimum": -9007199254740991.0 + }, + { + "type": "null" + } + ], + "title": "Start Year", + "description": "absent means open-ended start" + }, + "end_year": { + "anyOf": [ + { + "type": "integer", + "maximum": 9007199254740991.0, + "minimum": -9007199254740991.0 + }, + { + "type": "null" + } + ], + "title": "End Year", + "description": "absent means open-ended end" + } + }, + "additionalProperties": false, + "type": "object", + "title": "IdentityWindowRange", + "description": "A concrete requested date range; at least one bound is always present." + }, + "JsonValue": {}, + "LeftOut": { + "properties": { + "reason": { + "type": "string", + "pattern": "^[a-z][a-z0-9_]{0,63}$", + "title": "Reason" + }, + "count": { + "type": "integer", + "minimum": 0.0, + "title": "Count" + }, + "of": { + "type": "string", + "enum": [ + "entities", + "periods", + "entity_periods", + "pooled_entities" + ], + "title": "Of" + }, + "role": { + "type": "string", + "pattern": "^[a-z][A-Za-z0-9]{0,63}$", + "title": "Role" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "reason", + "count", + "of" + ], + "title": "LeftOut", + "description": "One data gap: why some data was left out, how many, and of what. The caller's own\nselection is a parameter and never appears here.\n\nA `pooled_entities` count is of the distinct parties of one pooled role, named in `role`,\nacross all the step's inputs. Those parties are never among the entities the step kept.\nOnly that `of` takes a `role`, and it requires one." + }, + "Manifest": { + "properties": { + "schema_version": { + "type": "integer", + "title": "Schema Version", + "default": 1 + }, + "definition": { + "$ref": "#/components/schemas/DefinitionModel" + }, + "content_version": { + "type": "string", + "title": "Content Version" + }, + "prepared_at": { + "type": "string", + "format": "date-time", + "title": "Prepared At" + }, + "coverage": { + "$ref": "#/components/schemas/CoverageModel" + }, + "citation": { + "$ref": "#/components/schemas/CitationModel" + }, + "trace": { + "additionalProperties": true, + "type": "object", + "title": "Trace" + }, + "warnings": { + "items": { + "$ref": "#/components/schemas/WarningModel" + }, + "type": "array", + "title": "Warnings" + }, + "diagnostics": { + "items": { + "$ref": "#/components/schemas/DiagnosticModel" + }, + "type": "array", + "title": "Diagnostics", + "description": "facts about how this response was produced, for developers: a citation whose sources declare no processing level, and an origin catalogue past its staleness limit. A version stores none; each response states its own" + }, + "artifacts": { + "items": { + "$ref": "#/components/schemas/ArtifactEntryModel" + }, + "type": "array", + "title": "Artifacts", + "description": "every servable artifact for this rendering, in a fixed order: every data artifact first, the series-statistics/1 artifact (rendering.statistics == 'series') last, if present. A caller selecting the data artifact should check rendering rather than take the first entry, but the order itself is a stable contract, not an accident of storage" + }, + "series_count": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Series Count" + }, + "output_options": { + "anyOf": [ + { + "$ref": "#/components/schemas/OutputOptionsModel" + }, + { + "type": "null" + } + ] + }, + "series_coverage_stamp": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Series Coverage Stamp", + "description": "the series_coverage artifact stamp this request's sync-admission estimate was computed against, kept as lineage only. content_version is a pure function of the frame and does not fold this in. Not the same coverage as the 'coverage' field above (materialise.window.Coverage's row/dimension/window report)" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "definition", + "content_version", + "prepared_at", + "coverage", + "citation", + "trace", + "artifacts" + ], + "title": "Manifest", + "description": "`trace` stays a plain dict, since `materialise.trace.ManifestTrace.to_dict()`\nis already this field's exact wire shape.\n\n`series_count` is the number of distinct series this definition\nresolves, as the version's description counts them (`statistics.SeriesFigures.series`): a\nseries and the estimates continuing it count once, though the statistics artifact holds a\nrow for each method. `None` means a version record minted before this field existed, whose old\ninline `statistics` no fact carries. The per-series detail itself lives in the\n`series-statistics/1` Parquet artifact every door that returns a\n`Manifest` lists in `artifacts` whenever `series_count` is not `None`\n(`datasets_api.render.render_and_store_series_statistics`), never\ninline on this model.\n\n`output_options` is `None` on a version record minted before the field\nexisted, the same convention `series_count` uses.\n\n`prepared_at` is when this version was first prepared, written once at its\nfirst mint and stored with it, so every re-mint and re-render reads the same\ninstant." + }, + "Matched": { + "properties": { + "text": { + "type": "string", + "title": "Text" + }, + "as": { + "type": "string", + "enum": [ + "name", + "alias", + "code" + ], + "title": "As" + } + }, + "type": "object", + "required": [ + "text", + "as" + ], + "title": "GraphResolveMatched", + "description": "The listed text the input matched, and whether it is the entity's name, an alias, or a\ncode. A phrase naming a group's members (\"EU countries\") matches as `alias`." + }, + "Measure": { + "properties": { + "label": { + "type": "string", + "title": "Label", + "description": "the measure's noun phrase, such as `net disbursements`" + } + }, + "type": "object", + "required": [ + "label" + ], + "title": "GraphDefinitionMeasure", + "description": "What the variable counts or sums, as the code index names it." + }, + "MeasureAxisValue": { + "properties": { + "axis": { + "type": "string", + "title": "Axis", + "description": "the declared measure-axis identifier (code_index.types.MeasureAxis.axis), e.g. 'measuredProperty' or a constraint-property dcid such as 'financialFlowType'" + }, + "value": { + "$ref": "#/components/schemas/GraphRef", + "description": "the value's dcid and the measure index's label for it, e.g. Gross" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "axis", + "value" + ], + "title": "MeasureAxisValue", + "description": "One measure axis and the value a measure partition holds on it (see\nResolvedSpec.measure_axis_values)." + }, + "MemberItem": { + "properties": { + "ref": { + "type": "string", + "title": "Ref" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label" + } + }, + "type": "object", + "required": [ + "ref", + "label" + ], + "title": "GraphMemberItem", + "description": "One item of a list: its dcid and the owner's label for it, `null` where the owner holds\nno name." + }, + "MembersEnvelope": { + "$id": "https://schemas.dfo.one.org/datasets/v1/members-envelope.json", + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "default": 1 + }, + "spec_id": { + "type": "string", + "pattern": "^spec_", + "title": "Spec Id" + }, + "members": { + "items": { + "$ref": "#/components/schemas/ServedMember" + }, + "type": "array", + "title": "Members" + }, + "served_count": { + "type": "integer", + "title": "Served Count" + }, + "family_member_count": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Family Member Count" + }, + "family_member_digest": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Family Member Digest" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "schema_version", + "spec_id", + "members", + "served_count", + "family_member_count", + "family_member_digest" + ], + "title": "MembersEnvelope", + "description": "`POST /api/datasets/{id}/members`'s response: the members a mint of the spec serves,\nresolved without materialising a frame.\n\n`members` lists them sorted by `ref`, and `served_count` counts them.\n`family_member_count` and `family_member_digest` state the whole population the identity\nadmits, before a broader member's dominated members are dropped, as a mint's\n`trace.family_member_count` and `trace.family_member_digest` state it; both are `null`\nwhen member resolution cannot state that population." + }, + "MembersPage": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the node whose list this is" + }, + "relation": { + "type": "string", + "enum": [ + "codes", + "children", + "datasets", + "variables", + "members", + "countries", + "facets" + ], + "title": "Relation" + }, + "projection": { + "anyOf": [ + { + "$ref": "#/components/schemas/Projection" + }, + { + "type": "null" + } + ], + "description": "the membership projection listed; null for a relation that takes none" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of", + "description": "the date membership was read at; null for today" + }, + "items": { + "items": { + "anyOf": [ + { + "$ref": "#/components/schemas/CodeItem" + }, + { + "$ref": "#/components/schemas/FacetItem" + }, + { + "$ref": "#/components/schemas/MemberItem" + } + ] + }, + "type": "array", + "title": "Items" + }, + "next_cursor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Next Cursor", + "description": "the cursor for the next page; null when this page ends the list" + }, + "complete": { + "type": "boolean", + "title": "Complete", + "description": "whether the walk reached the end of a list the owner holds in full" + }, + "total": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Total", + "description": "the list's length; null where the list is partial" + }, + "gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Gaps", + "description": "the code of each way the list is partial" + }, + "built_from": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "code_index", + "origin_catalogue", + "coverage_index", + "membership" + ] + }, + "type": "object", + "title": "Built From", + "description": "the build of each table the list read" + } + }, + "type": "object", + "required": [ + "ref", + "relation", + "projection", + "as_of", + "items", + "next_cursor", + "complete", + "total", + "gaps", + "built_from" + ], + "title": "GraphMembersPage", + "description": "One page of `GET /api/graph/node/{dcid}/members`." + }, + "MembershipBlock": { + "properties": { + "authority": { + "$ref": "#/components/schemas/Authority" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of", + "description": "the date the read asked for; null for today" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date", + "description": "the latest membership change on or before the date; null for an undated membership" + }, + "projections": { + "items": { + "$ref": "#/components/schemas/ProjectionCount" + }, + "type": "array", + "title": "Projections" + } + }, + "type": "object", + "required": [ + "authority", + "as_of", + "effective_date", + "projections" + ], + "title": "GraphMembershipBlock", + "description": "A group's or region's membership under its declared authority." + }, + "Methodology": { + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "how the publisher collects and compiles the data, as CommonMark" + } + }, + "type": "object", + "required": [ + "description" + ], + "title": "Methodology" + }, + "MintOptions": { + "properties": { + "format": { + "type": "string", + "enum": [ + "csv", + "xlsx", + "parquet" + ], + "title": "Format", + "default": "csv" + }, + "bundle": { + "type": "boolean", + "title": "Bundle", + "default": true + }, + "groupby": { + "anyOf": [ + { + "$ref": "#/components/schemas/GroupbyOptions" + }, + { + "type": "null" + } + ] + }, + "pivot": { + "anyOf": [ + { + "$ref": "#/components/schemas/PivotOptions" + }, + { + "type": "null" + } + ] + }, + "columns": { + "anyOf": [ + { + "items": { + "type": "string", + "minLength": 1 + }, + "type": "array" + }, + { + "type": "null" + } + ], + "uniqueItems": true, + "title": "Columns" + }, + "without_party_totals": { + "type": "boolean", + "title": "Without Party Totals", + "default": false + }, + "layout": { + "anyOf": [ + { + "type": "string", + "const": "frame" + }, + { + "type": "null" + } + ], + "title": "Layout" + } + }, + "additionalProperties": false, + "type": "object", + "title": "MintOptions", + "description": "Rendering-only, never hashed into identity. `format`/`bundle`/`pivot`/\n`columns`/`groupby`/`without_party_totals` are this deployment's live rendering surface. A\n`groupby.by` entry names a code system some deployment declaration\nmarks summable, a role/entity column, `stat_var`, or a column every\nframe carries regardless of shape; any other name refuses\n`rollup_not_summable` (`datasets_api.groupby.refuse_unknown_by_axes`).\nA declared axis this frame did not decode is simply absent from the\ncollapse-set computation, not an error (see\n`datasets_api.groupby.collapse_axes`); an unsafe collapse refuses\n`rollup_not_summable` too, naming the axis and precondition\n(`materialise.reshape.groupby_sum`,\n`datasets_api.groupby.refuse_stat_var_collision`,\n`datasets_api.groupby.refuse_decode_gaps`). A `columns` entry naming a\nrecognised-but-disabled enrichment field refuses `capability_unavailable`.\n`columns` selects the table and decoded columns it names. A list that names\nonly enrichment fields selects nothing: every default column stays,\ndecoded columns included, and the enrichments are added. A list that mixes\na table column with an enrichment selects. Without a pivot, a list that\nnames no decoded column keeps all of them, `status` is accepted and left\nout, `_label` is written by default (a list naming it keeps\n``), and the written order follows the long layout\n(`materialise.projection`) whatever order the list names.\n\n`layout: \"frame\"` writes a bare parquet file in the frame layout instead\nof the long layout: the frame's grammar columns as reshaped, with\ndecoded axes as `stat_var_`, `status` kept, and a converted\nunit as its JCS request text. `columns` then selects over those columns,\nas it does for pivot output. It refuses with `bundle: true`, a `pivot`,\nor a format other than parquet.\n\n`without_party_totals: true` leaves out the rows whose party, on a flow party role the\nserved identity binds no entity on, the code index declares a group total\n(`datasets_api.party_totals`). It runs on the frame before any reshape, so a `groupby`\nsums members alone. A cut that leaves rows out mints a version of its own, as a `groupby`\ncollapse does; one that leaves nothing out serves the frame's own version." + }, + "MintRequest": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "default": 1 + }, + "input": { + "oneOf": [ + { + "$ref": "#/components/schemas/SpecIdInput" + }, + { + "$ref": "#/components/schemas/StatVarSetInput" + } + ], + "title": "Input", + "discriminator": { + "propertyName": "kind", + "mapping": { + "spec_id": "#/components/schemas/SpecIdInput", + "statvar_set": "#/components/schemas/StatVarSetInput" + } + } + }, + "options": { + "$ref": "#/components/schemas/MintOptions" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "input" + ], + "title": "MintRequest", + "description": "Body of `POST /api/datasets`: one `input` and the render `options`." + }, + "MissingEntityModel": { + "properties": { + "ref": { + "type": "string", + "title": "Ref" + }, + "label": { + "type": "string", + "title": "Label" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref", + "label" + ], + "title": "MissingEntityModel" + }, + "NationalCurrency": { + "properties": { + "currencies": { + "type": "integer", + "title": "Currencies" + }, + "places": { + "type": "integer", + "title": "Places" + } + }, + "type": "object", + "required": [ + "currencies", + "places" + ], + "title": "GraphAvailabilityNationalCurrency", + "description": "The units that are each covered place's own currency." + }, + "NearestRealSpec": { + "properties": { + "spec_id": { + "type": "string", + "title": "Spec Id", + "description": "deterministic hash of (shape + canonical slot bindings); permalink-safe, dedup key, golden-comparison handle, cache key" + }, + "definition": { + "$ref": "#/components/schemas/SpecDefinition", + "description": "the canonical definition this Spec was resolved from: {schema_version, identity}, the same shape Unsupported.definition uses. definition.identity is the identity-core projection this spec_id was minted from, serialised once and never re-derived; hashing it reproduces spec_id by construction. Post definition.identity back byte-for-byte as ResubmitIdentityPayload.identity to edit this Spec. Directional entities remain nested in identity.entities." + }, + "resolved": { + "$ref": "#/components/schemas/ResolvedSpec", + "description": "the engine's report of what it did with the ask: stat_vars, entities, coverage, trace, and every other display/diagnostic field. Never hashed; see ResolvedSpec" + }, + "relaxation": { + "$ref": "#/components/schemas/Relaxation", + "description": "the definition part this suggestion relaxed, and the value(s) it dropped" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "spec_id", + "definition", + "resolved", + "relaxation" + ], + "title": "NearestRealSpec", + "description": "A nearest_real suggestion: a full Spec found by relaxing one constraint\nbinding and re-confirming the result against the live graph.\n\nGraph-re-confirmed only, never fabricated. See relaxation for which\nbinding was dropped to find it." + }, + "NoData": { + "properties": { + "reason": { + "type": "string", + "enum": [ + "source_not_resolved", + "source_ambiguous", + "source_code_not_held", + "source_code_ambiguous", + "source_code_shares_variable", + "entity_not_resolved", + "entity_ambiguous", + "entity_set_too_large", + "entity_role_not_admitted", + "variable_not_resolved", + "role_not_resolved", + "unit_not_resolved", + "rate_coverage_gap", + "no_matching_slice", + "binding_mismatch", + "denominator_not_available", + "no_observations", + "facet_not_available", + "role_incompatible", + "role_signature_incompatible", + "qualifier_not_bound" + ], + "title": "Reason", + "description": "why nothing could be returned, in contract resolution order. \"entity_not_resolved\" means a named entity could not be resolved to a graph node; \"entity_ambiguous\" means a named entity matched more than one graph candidate and none could be preferred over the others, distinct from \"entity_not_resolved\", where no node matched at all; \"entity_role_not_admitted\" means a named entity resolved to exactly one graph node, but no role any candidate shape declares admits that node's graph type -- the entity is real, just not the kind of thing this query's data is reported for; \"entity_set_too_large\" means every named entity resolved, but the places the request names, counting the members of each group or region among them and summed over the roles they sit on, exceed what the engine binds in one request -- distinct from every other entity_* reason, where one entity, not the size of the set, is what failed; \"variable_not_resolved\" means no StatVar matched the variable text (e.g. an absent posted stat_var_dcid or entity, or no measure match at all); \"role_not_resolved\" means the query names a role the engine could not resolve; \"unit_not_resolved\" means the unit binder could not classify a token in the requested unit phrase against its lexicons; \"no_matching_slice\" means the measure matched fine, but the requested combination has no corresponding data series -- the constructed/derived variable does not exist in the graph at all. Covers an identity resubmit refine edit with no confirmable sibling StatVar for the edited slice, and a dev-finance scheme x purpose x recipient combination that was never published as a series, on raw-text and resubmit alike; \"binding_mismatch\" means the variable resolved and graph-confirmed StatVars exist, but none satisfies the requested slot bindings, either because a resolved value on a bound property mismatched or because the StatVar's value on a bound property is present but could not be read (an unresolvable dcid); distinct from \"no_matching_slice\" (the combination was never published at all) and \"variable_not_resolved\" (no StatVar matched at all); \"denominator_not_available\" means the query asks for a normalised form (per person, per area, a rate or a share) or names a denominator, and the matched series is not in that form or divides by another base; \"no_observations\" means a StatVar WAS confirmed to exist but has no observation at the resolved entity (it exists, but not data here); \"facet_not_available\" means observations exist at the entity, none under the requested facet values; \"role_incompatible\" means the role is real, and the StatVar does not declare it; \"role_signature_incompatible\" means the resolved StatVars carry incompatible role signatures and no partition into candidates was possible; \"source_code_not_held\" means no variable held under the part's source_code by a source search serves can answer the part: no served source holds the code, the part's sources exclude every source that does, or the code's variables cannot answer the part as asked; \"source_code_ambiguous\" means two of the part's sources hold its source_code; \"source_code_shares_variable\" means the source_code's variables answer other codes of its source too, so search cannot serve the code alone; \"qualifier_not_bound\" means the variable resolved to a series family, but a narrowing term the request's text named bound no constraint slot: no code system in the packaged index carries it, or its registered rows landed in no binding" + }, + "cause": { + "anyOf": [ + { + "$ref": "#/components/schemas/Cause" + }, + { + "type": "null" + } + ], + "description": "why this refusal fired, present only for reason=rate_coverage_gap (the structured door's same-named ProblemDetails extension); omitted on every other reason" + }, + "category": { + "type": "string", + "enum": [ + "unresolved", + "absent" + ], + "title": "Category", + "description": "derived from reason, never independently settable: \"entity_not_resolved\", \"entity_ambiguous\", \"entity_set_too_large\", \"entity_role_not_admitted\", \"variable_not_resolved\", \"role_not_resolved\", \"source_not_resolved\", \"source_ambiguous\", \"source_code_not_held\", \"source_code_ambiguous\", \"source_code_shares_variable\", and \"unit_not_resolved\" are \"unresolved\" (the request could not be read into the graph); every other code is \"absent\" (the read request names a place holding nothing)", + "default": "absent" + }, + "message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Message", + "description": "the plain-language sentence for reason, naming the query terms it concerns where the reason has them (the indicator, place, or category wording), so a client can show a person the reason beside its code. Every no_data part the engine returns sets it. Clients must not parse it" + }, + "nearest_real": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/NearestRealSpec" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Nearest Real", + "description": "optional; up to two real, grounded specs found by relaxing one constraint at a time and re-confirming against the live graph. Each carries its own relaxation naming the definition part relaxed and the value(s) it dropped. Shaped by response_options and banded by confidence like any returned spec. Distinct from flagged_match (the elected variable itself) and alternate_match (a different variable). nearest_real varies the SAME variable's own constraints, never the variable." + }, + "gate": { + "anyOf": [ + { + "type": "string", + "enum": [ + "no_member_has_data_at_place", + "no_member_asserts_bound_properties", + "only_alternate_has_data" + ] + }, + { + "type": "null" + } + ], + "title": "Gate", + "description": "optional; the failed quality gate's code from the platform registry, one of the three registry gate codes (no_member_has_data_at_place, no_member_asserts_bound_properties, only_alternate_has_data). The single home for the code regardless of which near-match field carries the Spec: present exactly when flagged_match or alternate_match is present, except a role_incompatible refusal before or during materialise whose flagged_match records the confirmed elected identity without a gate (role incompatibility prevents an availability verdict), a qualifier_not_bound refusal, whose flagged_match records the graph-confirmed elected spec without a gate because the qualifier guard refuses before an availability verdict exists, or a denominator_not_available refusal, whose flagged_match records the elected spec the form or denominator check refused. Absent on every other no_data outcome. At most one of flagged_match and alternate_match is present at a time." + }, + "flagged_match": { + "anyOf": [ + { + "$ref": "#/components/schemas/Spec" + }, + { + "type": "null" + } + ], + "description": "optional; the elected variable's own Spec, present whenever gate fired and a groundable identity exists for the elected shape, or for a role_incompatible, qualifier_not_bound or denominator_not_available refusal that records its graph-confirmed identity without a gate: role incompatibility prevents an availability verdict, the qualifier guard refuses before one exists, and the denominator check refuses the series for its form, not its data. See gate for which check failed. available_at_place is False and confidence is low on gate=no_member_has_data_at_place; both stay at their not-assessed default (None) on gate=no_member_asserts_bound_properties, since there is no resolved place to be unavailable at. Absent on gate=only_alternate_has_data, where no groundable Spec for the elected shape exists; alternate_match carries the substitute the engine found instead. Distinct from nearest_real, up to two constraint-RELAXED specs that DO have data nearby. flagged_match is the elected variable itself, unavailable as the request asked for it." + }, + "alternate_match": { + "anyOf": [ + { + "$ref": "#/components/schemas/Spec" + }, + { + "type": "null" + } + ], + "description": "optional; a categorically different, data-bearing variable the request did not elect, present exactly when gate == 'only_alternate_has_data'. elected_count still counts the variable the request actually asked for; alternate_match is the one substitute the engine found nearby with observations of its own. Distinct from flagged_match (the elected variable itself, present on the other two gates) and from nearest_real (up to two constraint-relaxed variants of the SAME variable). alternate_match always names a different variable." + }, + "elected_count": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Elected Count", + "description": "optional; how many StatVars the request actually elected. Present whenever the elected shape's variable identity was graph-confirmed, whatever no_data reason or gate the outcome ultimately carries. None when the outcome stops short of a graph-confirmed identity altogether (variable_not_resolved, role_not_resolved, role_signature_incompatible, and binding_mismatch all resolve no StatVar to count). Counts the SAME variable as flagged_match whenever flagged_match is present. On gate=only_alternate_has_data, where flagged_match is absent, elected_count still counts the variable the request elected, distinct from alternate_match's different variable." + }, + "entity_terms": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Entity Terms", + "description": "the query entity text responsible for an entity-resolution outcome, in query order: every entity the engine could not resolve for entity_not_resolved, every ambiguous wording for entity_ambiguous, or every resolved-but-unadmitted entity for entity_role_not_admitted. Empty for every other no_data reason. This structured list is the client-facing source of those terms; rendered_sentence may quote the same wording for people, but clients must not parse it." + }, + "ambiguous_entities": { + "items": { + "$ref": "#/components/schemas/AmbiguousEntityGroup" + }, + "type": "array", + "title": "Ambiguous Entities", + "description": "every ambiguous wording responsible for an entity_ambiguous outcome, in query order, each paired with the graph candidates it could name. Empty for every other no_data reason. Invariant: every group's `text` equals some restatement.entities[i].text on the same part. Additive to entity_terms, which carries the same wordings as bare strings; rendered_sentence is unaffected by this field and quotes the same wordings and candidate names for people, but clients must not parse it." + }, + "source_terms": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Source Terms", + "description": "the source wordings responsible for a source-resolution outcome, in query order: every included wording that matched no admitted source for source_not_resolved, every ambiguous wording for source_ambiguous, and the part's source_code for source_code_not_held, source_code_ambiguous and source_code_shares_variable. Empty for every other no_data reason. rendered_sentence may quote the same wording for people, but clients must not parse it." + }, + "ambiguous_sources": { + "items": { + "$ref": "#/components/schemas/AmbiguousSourceGroup" + }, + "type": "array", + "title": "Ambiguous Sources", + "description": "every ambiguous source wording responsible for a source_ambiguous outcome, in query order, each paired with the admitted sources it could name, and for source_code_ambiguous the part's source_code paired with the provenances holding it. Empty for every other no_data reason. A client posts the chosen candidate's ref on that mention of data_query, or for a source code as a new mention in its sources, and posts the part back." + }, + "unit_alternatives": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/UnitAlternative" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Unit Alternatives", + "description": "the currencies a unit_not_resolved outcome offers, in the binder's order: the candidate ISO codes for an ambiguous currency name with no declared alias (XOF, XAF and CHF for 'francs'), or the role shapes for a role-relative currency phrase beside entities on two roles. Absent on every other outcome, and on a unit_not_resolved outcome the binder offers no candidates for" + }, + "unbound_qualifiers": { + "items": { + "$ref": "#/components/schemas/ResolvedQualifier" + }, + "type": "array", + "title": "Unbound Qualifiers", + "description": "the ResolvedQualifier entries responsible for a qualifier_not_bound outcome, in query order: every entry from flagged_match.resolved.trace.query_qualifiers whose disposition is not \"bound\" (\"unbound\": a named code row exists but no final binding covers it; \"no_vocabulary\": the text names no code at all), then, for a part naming or leaving out sources, each source it could not bind, an \"unbound\" entry under the source's label whose named holds the source's references. Empty for every other no_data reason. This structured list is the client-facing source of which terms went unrecognised, alongside each one's own disposition; rendered_sentence may quote the same wording for people, but clients must not parse it." + }, + "denominator": { + "anyOf": [ + { + "$ref": "#/components/schemas/NoDataDenominator" + }, + { + "type": "null" + } + ], + "description": "the denominator the question named and the one the flagged match divides by, set on every denominator_not_available refusal the engine returns after electing a series; null for every other no_data reason. A client can offer the flagged match, or fetch its nearest_real level and the denominator asked and divide them" + }, + "data_query": { + "anyOf": [ + { + "$ref": "#/components/schemas/ParsedInput" + }, + { + "type": "null" + } + ], + "description": "the parsed form of this part, one part long, set when reason is entity_ambiguous, source_ambiguous or source_code_ambiguous: its variable text, entities with role_text, time, unit, sources, and operations. On entity_ambiguous every entity that resolved to one graph node is pinned to its dcid and each ambiguous wording left unpinned. A named group stays unpinned too, so it resolves to the same members again. On source_ambiguous every source mention that resolved carries its ref and each ambiguous wording carries none. On source_code_ambiguous it carries the code and the part's mentions. A client pins the candidate the user picks from ambiguous_entities or ambiguous_sources and posts the part back, through the parsed door or as a dataset_resubmit parsed entry. It is set when the part has no restatement too: an entity whose direction the question leaves unnamed carries no role_text. Null for every other no_data reason, and when the part's inputs exceed the ParsedPart bounds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "reason" + ], + "title": "NoData", + "description": "Outcome when no grounded result can be returned." + }, + "NoDataDenominator": { + "properties": { + "asked": { + "anyOf": [ + { + "$ref": "#/components/schemas/GraphRef" + }, + { + "type": "null" + } + ], + "description": "the denominator the question named, as the search read it from the bases the candidate series divide by; null when the question named none, or named one that no candidate series divides by" + }, + "found": { + "anyOf": [ + { + "$ref": "#/components/schemas/GraphRef" + }, + { + "type": "null" + } + ], + "description": "the denominator the flagged match divides by; null when it states none (a level such as an amount in US dollars, or a series whose name alone gives its base)" + } + }, + "additionalProperties": false, + "type": "object", + "title": "NoDataDenominator", + "description": "The denominators a denominator_not_available refusal compared: the one the question\nnamed and the one its flagged match divides by -- NoData.denominator." + }, + "NoDataPart": { + "properties": { + "variable_text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Variable Text", + "description": "the variable text this part answers, in the order asked. This part's position in Resolution.parts equals the same variable_index every SSE event keyed by variable_index uses (ShapeEvent, StepEvent, SentenceEvent). Every dataset_resubmit entry kind (identity, candidates, placeholder, and parsed through its nested ParsedPart) requires its own posted variable_text, so this field is always the posted text echoed back onto the rebuilt part, never null. Null only when the whole posted query was empty or whitespace-only (raw_text door), which refuses variable_not_resolved before extraction runs and so has no text to name." + }, + "separate": { + "type": "boolean", + "title": "Separate", + "description": "true when this part was asked beside the others to be compared with them. A client resubmitting an identity, candidate set, or placeholder posts this flag on that entry to preserve the comparison. False, the default, is omitted", + "default": false + }, + "warnings": { + "items": { + "$ref": "#/components/schemas/Warning" + }, + "type": "array", + "title": "Warnings", + "description": "this part's own run-health signals. A part folded into an earlier part's spec (see DefinitePart.spec) carries binding_folded alone. The merged spec's own resolved warnings live only on the first part that carries it. An unfolded part carries the warnings raised while resolving this part, plus observations_omitted on a candidates part when response_options.include_observations was set." + }, + "timing_ms": { + "anyOf": [ + { + "$ref": "#/components/schemas/Timing" + }, + { + "type": "null" + } + ], + "description": "this part's own latency breakdown, where by_step names only the phases this part ran and total sums them, leaving out the shape_* stages nested inside shape. Excludes the shared, once-per-request steps (e.g. extract), which diagnostics.timing_ms.by_step carries once for the whole request; distinct too from diagnostics.timing_ms.total, the whole request's wall-clock elapsed time." + }, + "rendered_sentence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Rendered Sentence", + "description": "a human-readable string. For candidates, a header naming how many readings there are ('3 readings.'), then each shown candidate's heading and a byline led by the source and span that set it apart; for no_data, a heading in the same claim form naming the entity, measure, and counterpart that were checked. Either ends with the text of this part's departures, in order. For a definite part this stays null or omitted: the confirmation sentence (heading and byline) lives at spec.resolved.rendered_sentence, and its departures reach the envelope's composed sentence." + }, + "sentence_plan": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/SentenceToken" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Sentence Plan", + "description": "the ordered token form of rendered_sentence, present whenever it is. For a definite part this stays null or omitted. spec.resolved.sentence_plan carries the confirmation sentence's own plan instead." + }, + "restatement": { + "anyOf": [ + { + "$ref": "#/components/schemas/ParsedPart" + }, + { + "type": "null" + } + ], + "description": "the ParsedPart that reproduces this part's own resolution inputs -- the same entities, resolved time window, unit text, and source text the engine actually used to resolve this one leg -- so a client holding this part alone can copy it straight into a fresh ParsedInput.parts entry and re-resolve it faithfully, without flattening it into the whole query's variable_text the way variable_text alone would. Canonical, not verbatim: for a raw_text part, time_text is the equivalent phrase this door's own time grammar recognises (e.g. '2015 to 2020'), not the user's original words, since the engine's date extraction keeps only the structured window and discards the phrasing. Null whenever this part has no faithful echo to give. On a dataset_resubmit entry's identity/candidates/placeholder kinds, which post an identity or stub rather than a phrase and have no per-part resolution inputs to echo -- a dataset_resubmit parsed entry, genuinely re-resolved from its own posted ParsedPart, carries a real one like any parsed-door part. Also null when this leg's entity was bound to a directional role axis (origin/destination) and no door-supplied role named that axis, since an echo without the axis would resubmit the request with that entity reversed. Also null when one of this leg's own inputs does not fit ParsedPart's own field caps, since a truncated echo would misrepresent what was actually resolved." + }, + "operations": { + "items": { + "$ref": "#/components/schemas/Operation" + }, + "type": "array", + "title": "Operations", + "description": "the operations the question asks for over this part's data, in query order; the engine echoes them onto the part it resolves. Empty when the question asks for none" + }, + "departures": { + "items": { + "$ref": "#/components/schemas/Departure" + }, + "type": "array", + "title": "Departures", + "description": "every way this part's answer differs from what its request asked, ordered by how much each changes the number: closest_match, measure_not_applied, operation_not_applied, breakdown_not_applied, entity_unavailable, year_unavailable, modelled_values, group_read_as_members, direction_discarded, direction_inferred, scope_limited. [] when the answer is what was asked. A client that renders its own sentence reads them here; each one's text also closes the sentence that carries this part (see Departure.text). A warning on the same part reports run health and stays separate" + }, + "status": { + "type": "string", + "const": "no_data", + "title": "Status", + "description": "nothing to return" + }, + "no_data": { + "$ref": "#/components/schemas/NoData", + "description": "the reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "status", + "no_data" + ], + "title": "NoDataPart", + "description": "Nothing could be returned for this part." + }, + "NodeRef": { + "properties": { + "ref": { + "type": "string", + "title": "Ref" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label" + } + }, + "type": "object", + "required": [ + "ref", + "label" + ], + "title": "GraphNodeRef", + "description": "A graph reference. `label` is `null` when the target is not held, carries no `name`, or\ncarries only a `name` equal to its own dcid." + }, + "NodesRequest": { + "properties": { + "dcids": { + "items": { + "type": "string", + "maxLength": 512, + "pattern": "^[A-Za-z0-9_.\\-]+(?:/[A-Za-z0-9_.\\-]+)*$" + }, + "type": "array", + "maxItems": 50, + "minItems": 1, + "title": "Dcids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "dcids" + ], + "title": "GraphNodesRequest", + "description": "`dcids`: 1 to `NODES_MAX_DCIDS` node dcids read as one batch, in one DCP-read\nexecutor job. Each dcid matches the GET route's `{dcid}` path syntax and its 512-character\nceiling." + }, + "NodesResponse": { + "properties": { + "nodes": { + "items": { + "anyOf": [ + { + "oneOf": [ + { + "$ref": "#/components/schemas/StatVarNode" + }, + { + "$ref": "#/components/schemas/CodeSystemNode" + }, + { + "$ref": "#/components/schemas/CodeNode" + }, + { + "$ref": "#/components/schemas/GroupNode" + }, + { + "$ref": "#/components/schemas/CountryNode" + }, + { + "$ref": "#/components/schemas/ContinentNode" + }, + { + "$ref": "#/components/schemas/SubregionNode" + }, + { + "$ref": "#/components/schemas/ContinentalUnionNode" + }, + { + "$ref": "#/components/schemas/PlaceOtherNode" + }, + { + "$ref": "#/components/schemas/OrganisationNode" + }, + { + "$ref": "#/components/schemas/AggregateNode" + }, + { + "$ref": "#/components/schemas/UnitNode" + }, + { + "$ref": "#/components/schemas/SourceNode" + }, + { + "$ref": "#/components/schemas/DatasetNode" + }, + { + "$ref": "#/components/schemas/ProvenanceNode" + }, + { + "$ref": "#/components/schemas/OtherNode" + } + ], + "discriminator": { + "propertyName": "kind", + "mapping": { + "aggregate": "#/components/schemas/AggregateNode", + "code": "#/components/schemas/CodeNode", + "code_system": "#/components/schemas/CodeSystemNode", + "continent": "#/components/schemas/ContinentNode", + "continental_union": "#/components/schemas/ContinentalUnionNode", + "country": "#/components/schemas/CountryNode", + "dataset": "#/components/schemas/DatasetNode", + "group": "#/components/schemas/GroupNode", + "organisation": "#/components/schemas/OrganisationNode", + "other": "#/components/schemas/OtherNode", + "place_other": "#/components/schemas/PlaceOtherNode", + "provenance": "#/components/schemas/ProvenanceNode", + "source": "#/components/schemas/SourceNode", + "stat_var": "#/components/schemas/StatVarNode", + "subregion": "#/components/schemas/SubregionNode", + "unit": "#/components/schemas/UnitNode" + } + } + }, + { + "$ref": "#/components/schemas/NotHeldEntry" + } + ] + }, + "type": "array", + "title": "Nodes" + } + }, + "type": "object", + "required": [ + "nodes" + ], + "title": "NodesResponse", + "description": "`nodes` is index-aligned with the request's `dcids`: a repeated dcid repeats its\nentry. Each entry is the body `GET /api/graph/node/{dcid}` returns for that dcid, or a\n`not_held` entry where that route answers 404." + }, + "NotHeldEntry": { + "properties": { + "ref": { + "type": "string", + "title": "Ref" + }, + "status": { + "type": "string", + "const": "not_held", + "title": "Status", + "default": "not_held" + } + }, + "type": "object", + "required": [ + "ref", + "status" + ], + "title": "GraphNotHeldEntry", + "description": "A batch entry for a dcid where `GET /api/graph/node/{dcid}` answers 404\n`node_not_held`." + }, + "ObservationPoint": { + "additionalProperties": true, + "type": "object" + }, + "ObservationSeries": { + "properties": { + "stat_var": { + "$ref": "#/components/schemas/SeriesStatVarRef", + "description": "the StatVar these points observe" + }, + "entities": { + "items": { + "$ref": "#/components/schemas/SeriesEntityRef" + }, + "type": "array", + "title": "Entities", + "description": "the role tuple this series observes -- one entry for a standard single-role series (role='observationAbout'), two for a dev-finance bilateral series (role='origin' and role='destination')" + }, + "axes": { + "items": { + "$ref": "#/components/schemas/SeriesAxisRef" + }, + "type": "array", + "title": "Axes", + "description": "one entry per constraint the StatVar declares with a resolved value, ordered by property dcid; empty for a StatVar with no constraints. A client names each property from the Spec's slots" + }, + "points": { + "items": { + "$ref": "#/components/schemas/ObservationPoint" + }, + "type": "array", + "title": "Points", + "description": "chronological observation points from the series' lead observation facet (see SpecObservations), plus the points of the same source's estimates continuing the series past the lead's last period when it has any -- the `modelled_values` departure marks those -- filtered to the spec's requested window when one exists; the full in-window series when SpecObservations.truncated is false, else at most the latest points (bounded by the server's preview-points setting and its per-series row limit)" + }, + "total_obs": { + "type": "integer", + "title": "Total Obs", + "description": "this series' SELECTED facet's in-window point count (before truncation) -- a per-series figure alongside SpecObservations.total_obs's aggregate across every series. For a scope-defaulted bulk latest-only series (no requested window), this is the coverage probe's all-time obs_count for that entity's selected facet -- the in-window count too, since no window narrows it" + }, + "source_refs": { + "items": { + "$ref": "#/components/schemas/ProvenanceRef" + }, + "type": "array", + "title": "Source Refs", + "description": "provenance of the lead observation facet these points were read from (the facet selected for this series -- see SpecObservations)" + }, + "facet": { + "additionalProperties": { + "$ref": "#/components/schemas/SeriesFacetRef" + }, + "type": "object", + "title": "Facet", + "description": "this series' lead observation facet, per axis (provenance/measurementMethod/unit); the estimates continuing the series keep the lead's entry; sparse -- an axis the facet carries no value for is absent, never a null placeholder. provenance here always agrees with source_refs, since both derive from the same lead facet" + }, + "conversion": { + "anyOf": [ + { + "$ref": "#/components/schemas/ObservationSeriesConversion" + }, + { + "type": "null" + } + ], + "description": "what recipe and tables converted this series' points to the requested currency; absent on a series served in its native facet" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "stat_var", + "entities", + "points", + "total_obs" + ], + "title": "ObservationSeries", + "description": "One (stat_var, role tuple) pair's observation points, in chronological order." + }, + "ObservationSeriesConversion": { + "properties": { + "recipe_id": { + "type": "string", + "title": "Recipe Id", + "description": "the ConversionRecipe.recipe_id that produced these points" + }, + "table_provenance": { + "$ref": "#/components/schemas/SeriesFacetRef", + "description": "the Provenance node both the exchange-rate and (when present) deflator tables loaded under" + }, + "exchange_rate_table_version": { + "type": "string", + "title": "Exchange Rate Table Version", + "description": "the exchange-rate table's own version" + }, + "deflator_table_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Deflator Table Version", + "description": "the deflator table's own version; absent for a current-prices conversion" + }, + "fallback_count": { + "type": "integer", + "title": "Fallback Count", + "description": "rows whose deflator-role entity was substituted with the recipe's fallback entity" + }, + "fallback_examples": { + "items": { + "$ref": "#/components/schemas/SeriesConversionFallbackExample" + }, + "type": "array", + "title": "Fallback Examples", + "description": "a capped, sorted sample of the substituted (entity, fallback_entity) pairs" + }, + "projected_count": { + "type": "integer", + "title": "Projected Count", + "description": "rows whose rate/deflator term was sourced from a projected table row" + }, + "projected_examples": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Projected Examples", + "description": "a capped, sorted sample of the affected 'entity@year' keys" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recipe_id", + "table_provenance", + "exchange_rate_table_version", + "fallback_count", + "projected_count" + ], + "title": "ObservationSeriesConversion", + "description": "What produced a converted series' points: the recipe and table\nversions, and the fallback/projected markers a caller reads off them.\nModelled on materialise.convert.ConversionRecord, whose own docstring\nthis field's members mirror. Omits ConversionRecord.native_currency:\na caller trusting or reproducing the number needs what recipe and\ntables produced it, not what currency it started from -- facet.unit\nalready names the currency the points are actually in." + }, + "ObservationsOmission": { + "properties": { + "reason": { + "type": "string", + "enum": [ + "observations_timed_out", + "observations_no_matching_source", + "observations_windowed_scope_unsupported", + "observations_converted_scope_unsupported", + "observations_no_dispatchable_facet", + "observations_bulk_fetch_failed", + "observations_probe_failed", + "observations_preview_too_large", + "observations_nothing_to_probe", + "observations_clients_unavailable", + "observations_no_points" + ], + "title": "Reason", + "description": "machine-readable cause, equal to the accompanying Warning's code when one fires" + }, + "message": { + "type": "string", + "title": "Message", + "description": "human-readable explanation, safe to render directly" + }, + "pairs": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Pairs", + "description": "observations_preview_too_large only: the count that was too large" + }, + "cap": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Cap", + "description": "observations_preview_too_large only: the ceiling it exceeded" + }, + "dispatched": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Dispatched", + "description": "observations_no_points/observations_probe_failed/observations_no_matching_source/observations_timed_out: pairs actually dispatched" + }, + "empty": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Empty", + "description": "observations_no_points only: dispatched pairs that carried no data on their own facet" + }, + "hard_failed": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Hard Failed", + "description": "observations_no_points (always 0) and observations_probe_failed: dispatched pairs whose fetch itself failed" + }, + "facet_rejected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Facet Rejected", + "description": "observations_no_points (always 0) and observations_no_matching_source: dispatched pairs a bound facet_filter rejected" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "reason", + "message" + ], + "title": "ObservationsOmission", + "description": "Why a SpecObservations payload carries no series, made unconditional:\nevery _fetch_observations call that reaches a \"nothing to show\" outcome\nsets this field instead of leaving the whole payload absent, so a client\nis never left guessing which of at least a dozen distinct causes\nproduced an empty preview.\n\nreason is a warning code from search.engine.region.codes (see\nObservationsOmissionReason's own docstring for the closed vocabulary and\nwhy it is duplicated here rather than imported) -- the SAME code the\naccompanying Warning carries when one is also emitted, so a client reads\none vocabulary rather than two. Not every reason accompanies a Warning:\na genuinely uninteresting omission (nothing was ever there to probe)\ncarries no diagnostic Warning of its own, but always carries this field.\n\nThe converse also holds, and the pairing is not exhaustive: a reason\narriving as a bare Warning with `omitted` absent means partial coverage,\nnot absence -- a fetch that delivered some series would never set this\nfield, but can warn (`observations_probe_failed` on a partially hard-\nfailed fetch, and `observations_timed_out` on one some of whose pairs\ncrossed the deadline).\n\nWhenever `omitted` is set, SpecObservations.series is `[]`, total_obs is\n`0`, and truncated is `false`, so a client reading `series ?? []` and\nignoring `omitted` sees an ordinary empty result, with no schema_version\nbump needed to stay compatible.\n\npairs/cap: populated only for reason==\"observations_preview_too_large\" --\nthe (stat_var, role_tuple) pair (or pair x elected-combination\ndispatch-item, or distinct-stat_var) count that was compared against the\nceiling it crossed, and that ceiling itself. Lets a client render \"this\nselection has {pairs} series, above the {cap} the preview fetches\"\nwithout re-deriving either number.\n\ndispatched: how many (stat_var, role_tuple) pairs this call actually\ndispatched. Populated for reason==\"observations_no_points\",\n\"observations_probe_failed\", \"observations_no_matching_source\", and\n\"observations_timed_out\" -- every reason a dispatch actually happened\nfor; None for a reason reached before dispatch (e.g.\n\"observations_nothing_to_probe\").\n\nempty: dispatched pairs that carried no data on their own facet.\nPopulated only for reason==\"observations_no_points\".\n\nhard_failed: dispatched pairs whose fetch itself failed. Populated for\nreason==\"observations_no_points\" (always 0 there -- a nonzero count\nmeans reason is \"observations_probe_failed\" instead) and for\n\"observations_probe_failed\" itself (the nonzero count that produced\nthat reason); None elsewhere.\n\nfacet_rejected: dispatched pairs a bound facet_filter (or currency\nconversion) rejected. Populated for reason==\"observations_no_points\"\n(always 0 there -- a nonzero count means reason is\n\"observations_no_matching_source\" instead) and for\n\"observations_no_matching_source\" itself; None elsewhere.\n\nEvery field left None where the branch that produced this omission has\nno meaningful count for it." + }, + "OpenAxisValueCount": { + "properties": { + "value": { + "$ref": "#/components/schemas/GraphRef", + "description": "the declared value" + }, + "count": { + "type": "integer", + "title": "Count", + "description": "how many distinct served members declare this value" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "value", + "count" + ], + "title": "OpenAxisValueCount", + "description": "One declared value on an open constraint axis and how many served members\ndeclare it (see OpenConstraintAxisFact.values)." + }, + "OpenConstraintAxisFact": { + "properties": { + "property": { + "type": "string", + "title": "Property", + "description": "the constraint property dcid this fact is about" + }, + "varies": { + "type": "boolean", + "title": "Varies", + "description": "False when every served member that declares a value for this axis declares the same one (including when none of them declare one at all, since declaring nothing is itself an agreeing value here, the same rule resolved.alternative_measures' own observed-partition read applies); True when they differ" + }, + "value": { + "anyOf": [ + { + "$ref": "#/components/schemas/GraphRef" + }, + { + "type": "null" + } + ], + "description": "the single value every served member that declares one for this axis agrees on; present only when varies is False and at least one member declares a value, absent when varies is True or every member declares nothing" + }, + "distinct_count": { + "type": "integer", + "title": "Distinct Count", + "description": "how many distinct declared values the served members actually exhibit for this axis, not counting a member that declares nothing. 0 when every member declares nothing, 1 when varies is False and value is set. Counted over the served members' own declarations, independent of this response's observation window: a query's applied when-slot narrows which observation points are returned, not which constraint values a member declares, so this count is never scoped to that window the way an observation-count field on this contract is" + }, + "undeclared_count": { + "type": "integer", + "title": "Undeclared Count", + "description": "how many served members declare no value at all for this axis. A member whose arc names the axis but never resolved to a dcid counts here too, the same as a member that never asserted the axis at all" + }, + "values": { + "items": { + "$ref": "#/components/schemas/OpenAxisValueCount" + }, + "type": "array", + "title": "Values", + "description": "every declared value with the number of served members declaring it, highest count first, then by dcid. Each served StatVar counts once, also after a merge of answers that serve it more than once, so the counts plus undeclared_count sum to the distinct served members. Labels as for value" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "property", + "varies", + "distinct_count", + "undeclared_count" + ], + "title": "OpenConstraintAxisFact", + "description": "One constraint axis the query left open, and what this Spec's own\nserved StatVar members exhibit on it (see ResolvedSpec.open_axis_facts):\nwhether they agree on a single declared value or differ, what that\nagreed value is when one exists, how many distinct values the axis\nactually served, and how many declare none at all." + }, + "Operation": { + "properties": { + "verb": { + "type": "string", + "enum": [ + "rank", + "aggregate", + "growth", + "share_of", + "explain", + "forecast", + "report" + ], + "title": "Verb", + "description": "what the question asks to compute: rank, aggregate, growth, share_of, explain, forecast, or report" + }, + "phrase": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Phrase", + "description": "the query wording that asks for the operation, e.g. 'top 5 donors'; one line with no control characters or line separators, and not blank" + }, + "over": { + "anyOf": [ + { + "type": "string", + "enum": [ + "place", + "origin", + "destination", + "category", + "year" + ] + }, + { + "type": "null" + } + ], + "title": "Over", + "description": "the axis the operation runs across (place, origin, destination, category, or year); null when the verb names none, as explain does. The part leaves this axis open, so its data covers every value the operation needs" + }, + "target_year": { + "anyOf": [ + { + "type": "integer", + "maximum": 2200.0, + "minimum": 1000.0 + }, + { + "type": "null" + } + ], + "title": "Target Year", + "description": "the year a forecast projects to, e.g. 2050 for 'forecast aid to Ethiopia to 2050'; set only on a forecast, a four-digit year up to 2200. The raw_text door sets it only to a year after the current one, and leaves it null when the question names none; a posted value is taken as given within the bound, whatever today's date. It is kept apart from the part's time_text, the years whose data the part fetches, and does not affect resolution" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "verb", + "phrase" + ], + "title": "Operation", + "description": "One computation the question asks for over a part's data, which search\ndoes not perform: the part answers with the data the operation needs, and\nthe operation rides on the part for a client to perform or hand on." + }, + "OperationEnvelope": { + "properties": { + "operation_id": { + "type": "string", + "pattern": "^op_", + "title": "Operation Id" + }, + "status": { + "type": "string", + "enum": [ + "pending", + "running", + "done", + "failed" + ], + "title": "Status" + }, + "poll": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Poll" + }, + "retry_after_ms": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Retry After Ms", + "description": "present only on the initial 202 submit response; absent on a pending/running poll -- a caller polling with no backoff strategy of its own gets no ongoing pacing guidance from this field past the first response" + }, + "progress": { + "anyOf": [ + { + "$ref": "#/components/schemas/OperationProgress" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "operation_id", + "status" + ], + "title": "OperationEnvelope" + }, + "OperationProgress": { + "properties": { + "rows_written": { + "type": "integer", + "title": "Rows Written" + }, + "estimate_rows": { + "type": "integer", + "title": "Estimate Rows" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "rows_written", + "estimate_rows" + ], + "title": "OperationProgress", + "description": "`rows_written` against `estimate_rows`, read live off\n`datasets.operation` at poll time (`datasets_api.operation_store\n.Operation`). Present on a `pending`/`running` operation's own\nenvelope; omitted from the `202` submit envelope (nothing has run\nyet) and from a terminal (`done`/`failed`) operation's own envelope,\nwhose outcome the sibling `manifest` field, or the poll route's own\n`operation_failed` refusal, already carries in full." + }, + "OperationResource": { + "$id": "https://schemas.dfo.one.org/datasets/v1/operation-resource.json", + "properties": { + "operation": { + "$ref": "#/components/schemas/OperationEnvelope" + }, + "manifest": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Manifest" + }, + "error": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Error" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "operation" + ], + "title": "OperationResource", + "description": "`GET /api/datasets/operations/{operation_id}`'s poll response. The\ncapability document reports `operation_envelope_active: true`, and this\nis the shape the route returns for a known operation id in `pending`,\n`running`, or `done` state. A `failed` operation raises the platform's\nordinary refusal path instead (`operation_failed`), and an unknown or\nunauthorized-`done` id answers 404 `operation_not_found` -- neither\nreturns this shape.\n\n`manifest` is set only once `operation.status == \"done\"`: the same\nmanifest a synchronous mint returns, read at poll time\n(`datasets_api.doors.meta`'s operations route reuses `datasets_api\n.doors.snapshot.read_snapshot_manifest` against the operation's own\nstored `subject_id`/`content_version`). `error` models a `failed`\noperation's outcome inline with this resource's own shape, but the\ndoor never populates it: a `failed` operation raises the platform's\nordinary refusal path instead (`operation_failed`, a bare RFC 9457\nbody, the same pattern `operation_not_found` already uses on this\nroute -- see the registry's own `datasets.operations` mapping), so a\npoll never reaches this model at all once the underlying operation\nhas failed. `error` stays declared for schema completeness -- this is\na contract-stable, immutable-`$id` shape -- but no code path fills it." + }, + "OptionsEnvelope": { + "properties": { + "schema_version": { + "type": "integer", + "title": "Schema Version", + "default": 1 + }, + "definition": { + "$ref": "#/components/schemas/DefinitionModel" + }, + "content_version": { + "type": "string", + "title": "Content Version" + }, + "coverage": { + "$ref": "#/components/schemas/CoverageModel" + }, + "output_options": { + "anyOf": [ + { + "$ref": "#/components/schemas/OutputOptionsModel" + }, + { + "type": "null" + } + ] + }, + "warnings": { + "items": { + "$ref": "#/components/schemas/WarningModel" + }, + "type": "array", + "title": "Warnings" + }, + "trace": { + "additionalProperties": true, + "type": "object", + "title": "Trace" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "definition", + "content_version", + "coverage", + "trace" + ], + "title": "OptionsEnvelope", + "description": "`GET /api/datasets/{id}/options`'s response. It is the projection\nof a materialising door's manifest onto the fields this route's callers\nneed (content_version, coverage, output_options, warnings, trace). The\nroute serves with no rendering (`doors.definition._serve_spec_options`),\nso no reshape runs and `warnings` here excludes reshape-level warnings\nsuch as `enrichment_unavailable`." + }, + "OptionsFor": { + "properties": { + "role": { + "type": "string", + "title": "Role", + "description": "the resolved entity role to enumerate candidates for (e.g. 'origin', 'destination', 'observationAbout' -- the vocabulary is derived per family, not frozen here). Deliberately a plain str, NEVER a Literal or enum: the target is checked only AFTER the posted identity resolves to StatVars, refusing option_target_invalid (422) for a role the resolved family does not carry. A Literal/enum would instead refuse an unrecognised role at the pydantic validation layer as request_invalid (400), before resolution ever runs -- do not tighten this to an enum." + }, + "scope": { + "anyOf": [ + { + "type": "string", + "enum": [ + "peers", + "children" + ] + }, + { + "type": "null" + } + ], + "title": "Scope", + "description": "which candidate universe to enumerate for a role whose options are derived from the graph rather than a curated list; absent means 'peers'. 'peers' enumerates entities sharing the bound entity's own type; 'children' enumerates entities contained in it. Roles backed by a curated candidate list ignore this member, having only one universe to draw from. Naming a role alone cannot distinguish the two readings -- peers of a country and the regions within it are both 'options for observationAbout' -- and only the peers reading is recoverable from the identity, so without this member the contained-in reading is unreachable rather than merely unrequested." + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "role" + ], + "title": "OptionsFor", + "description": "Which resolved entity role the options door enumerates candidates for.\n\nWrapped in its own object (rather than a bare string field) so the wire\nbody reads `\"for\": {\"role\": \"destination\"}`, matching the contract's\nenvelope shape on both the request and the echoed response." + }, + "OptionsRequest": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "description": "contract version the caller targets", + "default": 1 + }, + "identity": { + "$ref": "#/components/schemas/BaseIdentity", + "description": "the identity to resolve and enumerate candidate options for" + }, + "for": { + "$ref": "#/components/schemas/OptionsFor", + "description": "which resolved entity role to enumerate candidate options for" + }, + "include_coverage": { + "type": "boolean", + "title": "Include Coverage", + "description": "when true, the engine probes each returned option for observation coverage (e.g. 'Kenya — 205 obs') and populates SlotOption.coverage; false (the default) never fires the extra probe, so this is opt-in latency, not a hidden cost on the hot path. The only resolution option this door reads -- unlike /resolve's ResolveOptions, this door has no candidate cap or sentence concept, so it carries this one field directly rather than nesting a response_options object with members it would never use.", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "identity", + "for" + ], + "title": "OptionsRequest", + "description": "Request body for the options door (POST /api/search/options): enumerate\nthe candidate set for one resolved entity role of a posted identity.\n\nAn identity block only. The door derives the identity's own StatVar\npopulation server-side (engine.options.population.options_population)\nrather than resolving a Spec through the resubmit path.\n\nvalidate_by_name=False (with validate_by_alias=True, the pydantic default\npairing made explicit here): the published schema declares only the alias\n`for`, and this model is otherwise extra=\"forbid\", so a wire body must be\nrejected for posting the internal Python attribute name `for_` instead --\naccepting both would let a client bypass the declared schema through the\nimplementation-detail spelling. `for_` exists only because `for` is a\nPython reserved word and cannot itself be an attribute name; every\nconstructor call (internal code, tests) builds this model through the\nalias instead, e.g. ``OptionsRequest(identity=..., **{\"for\": OptionsFor(...)})``." + }, + "OptionsResponse": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "description": "contract schema version; exactly 1 for v1", + "default": 1 + }, + "diagnostics": { + "$ref": "#/components/schemas/Diagnostics", + "description": "run health, warnings, timing, build stamp" + }, + "for": { + "$ref": "#/components/schemas/OptionsFor", + "description": "the role this response's options were enumerated for, echoed back from the request" + }, + "options": { + "$ref": "#/components/schemas/OptionsSet", + "description": "the enumerated candidate set" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "diagnostics", + "for", + "options" + ], + "title": "OptionsResponse", + "description": "Response for POST /api/search/options: `{schema_version, diagnostics,\nfor, options}`. Carries no semantic status: the door either refuses\n(through the same shared identity validation a dataset_resubmit identity\nentry runs) or returns options -- possibly an empty\nlist -- with no definite/candidates/no_data three-way to report on top.\n\nOmits graph_revision: no revision concept exists anywhere in src/ --\nnothing tracks the graph the way engine_build tracks the code build -- so\nstamping one here would assert a graph fact this deployment cannot back.\nLeft out deliberately rather than filled with something untrue." + }, + "OptionsSet": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/SlotOption" + }, + "type": "array", + "title": "Items", + "description": "candidate values, deterministically ordered; a dcid that failed to resolve a label is omitted rather than fabricated" + }, + "truncated": { + "type": "boolean", + "title": "Truncated", + "description": "true when items was capped before every candidate could be checked" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items", + "truncated" + ], + "title": "OptionsSet", + "description": "The enumerated candidate set an options-door request returns.\n\nItems reuse SlotOption for shape parity with slot_options/entity_options\n({value, coverage}) rather than a simpler {ref, label, obs_count} shape --\nthe richer coverage form is what the engine already serves. An\nempty list is itself a valid result (e.g. the current recipient's\nvariable truly has no other recipient with data), not an error.\n\nCarries no graph_revision -- see OptionsResponse's docstring for why." + }, + "OrganisationNode": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the node's dcid" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "the node's name; for a Provenance, its parent Dataset's name where it has one. Null, and named in gaps, when the graph gives none" + }, + "types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Types", + "description": "the node's typeOf values, as the graph holds them" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "the node's prose in the graph; null when it has none" + }, + "links": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "codes", + "children", + "members", + "countries", + "datasets", + "variables", + "facets" + ] + }, + "type": "object", + "title": "Links", + "description": "each list relation the node has, mapped to its route; empty when none" + }, + "gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Gaps", + "description": "the member path of every value this door cannot know" + }, + "built_from": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "code_index", + "origin_catalogue", + "coverage_index", + "membership" + ] + }, + "type": "object", + "title": "Built From", + "description": "the build of each table the response read" + }, + "kind": { + "type": "string", + "const": "organisation", + "title": "Kind", + "default": "organisation" + }, + "organisation": { + "$ref": "#/components/schemas/PartyBlock" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "types", + "description", + "links", + "gaps", + "built_from", + "kind", + "organisation" + ], + "title": "OrganisationNode" + }, + "OtherNode": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the node's dcid" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "the node's name; for a Provenance, its parent Dataset's name where it has one. Null, and named in gaps, when the graph gives none" + }, + "types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Types", + "description": "the node's typeOf values, as the graph holds them" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "the node's prose in the graph; null when it has none" + }, + "links": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "codes", + "children", + "members", + "countries", + "datasets", + "variables", + "facets" + ] + }, + "type": "object", + "title": "Links", + "description": "each list relation the node has, mapped to its route; empty when none" + }, + "gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Gaps", + "description": "the member path of every value this door cannot know" + }, + "built_from": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "code_index", + "origin_catalogue", + "coverage_index", + "membership" + ] + }, + "type": "object", + "title": "Built From", + "description": "the build of each table the response read" + }, + "kind": { + "type": "string", + "const": "other", + "title": "Kind", + "default": "other" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "types", + "description", + "links", + "gaps", + "built_from", + "kind" + ], + "title": "OtherNode", + "description": "A node no other kind fits. `types` and `description` carry what the graph holds." + }, + "OutputOptionsModel": { + "properties": { + "capability_version": { + "type": "string", + "title": "Capability Version" + }, + "columns": { + "items": { + "$ref": "#/components/schemas/ColumnOptionModel" + }, + "type": "array", + "title": "Columns" + }, + "formats": { + "items": { + "$ref": "#/components/schemas/FormatOptionModel" + }, + "type": "array", + "title": "Formats" + }, + "bundle": { + "$ref": "#/components/schemas/BundleOptionModel" + }, + "enrichments": { + "items": { + "$ref": "#/components/schemas/EnrichmentOptionModel" + }, + "type": "array", + "title": "Enrichments" + }, + "long_layout_defaults": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Long Layout Defaults", + "description": "the enrichment tokens a long-layout download writes with no columns option, in column order: every role's {role}_label, and {role}_party_kind for every role on a flow axis. Naming one in columns gives the same column once" + }, + "long_layout_totals": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Long Layout Totals", + "description": "the roles whose total rows ({role}_party_kind is total) a long-layout CSV or XLSX download keeps out of its main table. A role is listed when the definition binds it to several entities one of which the code index declares a total, or leaves it open and the code index lists a total on its axis in a dataset the definition read (any dataset, when the read selected none). A role bound to several parties holds no total row and is not listed. A bundle's CSV writes those rows to a second data file, data/-totals.csv; an XLSX writes them on a second sheet, totals. A bare CSV has no README and drops them, so this list names the roles whose totals it drops. Parquet, a pivot and the frame layout keep every row. Empty when no role can hold a total row" + }, + "pivots": { + "items": { + "$ref": "#/components/schemas/PivotOptionModel" + }, + "type": "array", + "title": "Pivots" + }, + "groupby": { + "$ref": "#/components/schemas/GroupbyOptionsModel" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "capability_version", + "columns", + "formats", + "bundle", + "enrichments", + "long_layout_defaults", + "long_layout_totals", + "pivots", + "groupby" + ], + "title": "OutputOptionsModel", + "description": "The reshape options this frame supports, joined from its stored\n`materialise.profile.OutputProfile` and the current capability\ndocument." + }, + "ParsedEntity": { + "properties": { + "text": { + "type": "string", + "maxLength": 128, + "minLength": 1, + "title": "Text", + "description": "the entity's text as the caller identified it" + }, + "role_text": { + "anyOf": [ + { + "type": "string", + "maxLength": 64, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Role Text", + "description": "the caller's free-form role hint for this entity, when available; recognised words (case-insensitive) are 'from'/'to' and synonyms such as donor/provider/funder/source/creditor/lender/exporter for the 'from' side, recipient/beneficiary/debtor/borrower/importer for the 'to' side -- unrecognised text warns role_text_not_recognised and the entity is treated as undirected" + }, + "dcid": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Dcid", + "description": "an optional caller-pinned dcid for this entity, naming exactly which graph node `text` refers to -- the door a client with a candidate's dcid in hand (e.g. from NoData.ambiguous_entities) posts through, instead of relying on name resolution to disambiguate `text` on its own. When present, this entity's name resolution is skipped: the pinned dcid seeds the entry's pre_resolved map directly, still confirmed against the graph. An unconfirmable dcid (absent from the graph, or present but type-less) refuses invalid_role_ref (422). `text` stays required and is not re-derived from the dcid; it is still what a rendered sentence and any further restatement echo back." + }, + "members": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Members", + "description": "true asks for the members of the set `text` names, each as its own series: the countries of a continent or UN subregion, or the members of a group. It has no effect on a single place. Text whose wording names members, such as 'EU member states', reads as true without the flag. With a pinned `dcid` it is honoured for a continent or subregion that the membership policy holds or omits, whatever the node's graph type, and refuses request_invalid for a group's own node, whose members a pin cannot supply. One part names a set once: the same `text` posted with both values refuses request_invalid" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "ParsedEntity", + "description": "One entity mentioned in a parsed part, with an optional caller-supplied role hint." + }, + "ParsedInput": { + "properties": { + "kind": { + "type": "string", + "const": "parsed", + "title": "Kind", + "description": "discriminator for pre-parsed input", + "default": "parsed" + }, + "parts": { + "items": { + "$ref": "#/components/schemas/ParsedPart" + }, + "type": "array", + "maxItems": 6, + "minItems": 1, + "title": "Parts", + "description": "one entry per variable ask; conjunctions pre-split by the caller. Parts that are byte-identical across every field collapse to one before resolution, so the response's own parts list can hold fewer entries than this list." + }, + "raw_query": { + "anyOf": [ + { + "type": "string", + "maxLength": 2000, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Raw Query", + "description": "original query text, for echo only; does not affect resolution" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "parts" + ], + "title": "ParsedInput", + "description": "Pre-parsed input: one or more variable parts supplied directly by the caller,\nskipping natural-language extraction." + }, + "ParsedPart": { + "properties": { + "variable_text": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Variable Text", + "description": "the variable's text as the caller identified it" + }, + "entities": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/ParsedEntity" + }, + "type": "array", + "maxItems": 16 + }, + { + "type": "null" + } + ], + "title": "Entities", + "description": "entities associated with this part's variable, when available; null, omitted, or an empty list all mean no entity was named for this part, resolving the variable globally/entity-less -- the same meaning a raw_text query with no extracted place carries" + }, + "time_text": { + "anyOf": [ + { + "type": "string", + "maxLength": 100, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Time Text", + "description": "this part's time expression, when available; recognised forms include a bare four-digit year, 'YYYY to YYYY' or 'YYYY-YYYY', 'from YYYY to YYYY', 'between YYYY and YYYY', a latest end as in 'between YYYY and the latest' or 'YYYY to latest', 'since YYYY', 'latest', 'latest year available', 'most recent', and 'last N years'. Anything else resolves dateless with a time_text_not_parsed warning, whose message lists every form" + }, + "unit_text": { + "anyOf": [ + { + "type": "string", + "maxLength": 100, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Unit Text", + "description": "this part's requested unit or measurement basis, when available; recognised phrasing names a currency (ISO 4217 code or curated name/alias), a price basis (current or constant prices), and/or a base year (e.g. '2015 US dollars', 'constant prices, 2015 base year'). A phrase this text failed to parse cleanly resolves no_data with unit_not_resolved; a phrase the request grammar cannot express at all resolves unsupported with unit_request_unsupported. A phrase the grammar CAN express is checked against this deployment's own unit data: a currency/prices/base_year combination no unit this deployment carries expresses at all resolves unsupported with facet_binding_unsupported; one this deployment can express but that matches no candidate observation resolves no_data with facet_not_available; a match resolves definite, applying the completed request to the resolved spec's identity and carrying request_basis on resolved.facets.unit" + }, + "sources": { + "items": { + "$ref": "#/components/schemas/SourceMention" + }, + "type": "array", + "maxItems": 8, + "title": "Sources", + "description": "the data sources this part names or excludes, in query order. Empty, the part answers from the sources the engine elects. A restatement echoes each mention with the reference it resolved to" + }, + "source_text": { + "anyOf": [ + { + "type": "string", + "maxLength": 200, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Source Text", + "description": "deprecated: post `sources` instead. Read as one included mention with this text, appended to `sources`" + }, + "provenance": { + "anyOf": [ + { + "type": "string", + "maxLength": 200, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Provenance", + "description": "deprecated: post `sources` instead. Read as one included mention with this ref, appended to `sources`. The served request schema lists the code index's declared datasets under this field, each with its label, description and opt-in flag" + }, + "source_code": { + "anyOf": [ + { + "type": "string", + "maxLength": 64, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Source Code", + "description": "a publisher's own series code for this part's variable, such as the World Bank's DT.TDS.DEGG.CD, when the user or a skill gives one. Compared upper-cased, it names the variables the publisher gives that code, and the part answers from them in place of matching variable_text; variable_text, entities and open_roles still choose among them. A code is never a constraint and narrows nothing else. A code whose variables cannot answer the part, because no source search serves holds it, the part's sources leave out every source holding it, or its variables cannot answer the part as asked, resolves no_data with source_code_not_held, its message naming the cause; a code two of the part's sources hold resolves no_data with source_code_ambiguous until `sources` names one; a code whose variable another code of its source also names resolves no_data with source_code_shares_variable, naming those codes" + }, + "operations": { + "items": { + "$ref": "#/components/schemas/Operation" + }, + "type": "array", + "maxItems": 8, + "title": "Operations", + "description": "the operations the question asks for over this part's data, in query order; the engine echoes them onto the part it resolves. Empty when the question asks for none" + }, + "open_roles": { + "anyOf": [ + { + "items": { + "type": "string", + "maxLength": 64, + "minLength": 1 + }, + "type": "array", + "maxItems": 2 + }, + { + "type": "null" + } + ], + "title": "Open Roles", + "description": "the roles this part asks for member by member, at most one word per flow axis, e.g. ['creditor'] for 'debt service paid to each creditor'. Each is a role_text word: creditor, donor, recipient, debtor, origin, destination, or a synonym. Where the answer's family declares the role, the answer holds one series per member of it and its identity states the axis in open_roles; a role named in neither entities nor open_roles reads as the total over that role. An unrecognised word, or a role one of this part's entities binds through role_text, refuses request_invalid. An operation whose over is origin or destination opens that axis too" + }, + "separate": { + "type": "boolean", + "title": "Separate", + "description": "true when this part is asked beside the others to be compared with them, as in 'health ODA versus education ODA': it answers as its own part and never folds into another part of the same shape (binding_folded). False, the default, folds parts that share a shape into one set answer", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "variable_text" + ], + "title": "ParsedPart", + "description": "One variable ask within a parsed request, with its own entities, time, unit, and source." + }, + "PartyBlock": { + "properties": { + "roles": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Roles", + "description": "the role properties a node of these types can fill, by the role ranges the graph declares (rangeIncludes and its subClassOf closure); null when that read failed" + } + }, + "type": "object", + "required": [ + "roles" + ], + "title": "GraphPartyBlock", + "description": "An organisation's or aggregate's detail block." + }, + "PeriodCoverage": { + "properties": { + "period": { + "type": "string", + "maxLength": 32, + "minLength": 1, + "title": "Period" + }, + "entities": { + "type": "integer", + "minimum": 0.0, + "title": "Entities" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "period", + "entities" + ], + "title": "PeriodCoverage", + "description": "How many entities one period's total covers." + }, + "PinRequest": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "description": "contract schema version; exactly 1 for v1", + "default": 1 + }, + "artifact_digest": { + "type": "string", + "pattern": "^sha256:", + "title": "Artifact Digest", + "description": "the exact bytes to pin, e.g. 'sha256:3e7a...'" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "artifact_digest" + ], + "title": "PinRequest" + }, + "PinResponse": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "default": 1 + }, + "pinned": { + "$ref": "#/components/schemas/PinnedCoordinates" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "pinned" + ], + "title": "PinResponse" + }, + "PinnedCoordinates": { + "properties": { + "id": { + "type": "string", + "title": "Id", + "description": "the spec_id from the path" + }, + "content_version": { + "type": "string", + "title": "Content Version" + }, + "artifact_digest": { + "type": "string", + "title": "Artifact Digest" + }, + "pinned_at": { + "type": "string", + "title": "Pinned At" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "content_version", + "artifact_digest", + "pinned_at" + ], + "title": "PinnedCoordinates" + }, + "PivotOptionModel": { + "properties": { + "index": { + "type": "string", + "title": "Index" + }, + "columns": { + "type": "string", + "title": "Columns" + }, + "state": { + "type": "string", + "title": "State" + }, + "reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reason" + }, + "varying": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/VaryingColumnModel" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Varying" + }, + "width": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Width" + }, + "cells": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Cells" + }, + "unavailable_formats": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/UnavailableFormatModel" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Unavailable Formats" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "index", + "columns", + "state" + ], + "title": "PivotOptionModel", + "description": "One ordered `(index, columns)` pivot pair. `varying` is populated\nfor a `pivot_not_unique` refusal caused by a duplicate key group. A\nstringification collision, where distinct `columns` values share an\noutput column name, is also `unavailable` as `pivot_not_unique`, with\nno `varying` since no duplicate key group exists. `width` and `cells`\nare populated only when the pair is feasible." + }, + "PivotOptions": { + "properties": { + "index": { + "type": "string", + "minLength": 1, + "title": "Index" + }, + "columns": { + "type": "string", + "minLength": 1, + "title": "Columns" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "index", + "columns" + ], + "title": "PivotOptions", + "description": "`options.pivot`: long-to-wide, `index` and `columns` each naming\nexactly one column." + }, + "PlaceBlock": { + "properties": { + "contained_in": { + "items": { + "$ref": "#/components/schemas/NodeRef" + }, + "type": "array", + "title": "Contained In", + "description": "the containedInPlace targets" + }, + "membership": { + "anyOf": [ + { + "$ref": "#/components/schemas/MembershipBlock" + }, + { + "type": "null" + } + ] + } + }, + "type": "object", + "required": [ + "contained_in", + "membership" + ], + "title": "GraphPlaceBlock", + "description": "A place's detail block. `membership` is set for a region the membership policy holds." + }, + "PlaceCounts": { + "properties": { + "publishers": { + "type": "integer", + "title": "Publishers", + "description": "distinct sources with data at the country" + }, + "variables": { + "type": "integer", + "title": "Variables", + "description": "distinct StatVars with data at the country" + }, + "aid": { + "$ref": "#/components/schemas/AidCounts" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "publishers", + "variables", + "aid" + ], + "title": "PlaceCounts", + "description": "What DFO holds at one country. For aid, `donors` counts the donors to\nthe country and `recipients` the recipients of its own aid." + }, + "PlaceOtherNode": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the node's dcid" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "the node's name; for a Provenance, its parent Dataset's name where it has one. Null, and named in gaps, when the graph gives none" + }, + "types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Types", + "description": "the node's typeOf values, as the graph holds them" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "the node's prose in the graph; null when it has none" + }, + "links": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "codes", + "children", + "members", + "countries", + "datasets", + "variables", + "facets" + ] + }, + "type": "object", + "title": "Links", + "description": "each list relation the node has, mapped to its route; empty when none" + }, + "gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Gaps", + "description": "the member path of every value this door cannot know" + }, + "built_from": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "code_index", + "origin_catalogue", + "coverage_index", + "membership" + ] + }, + "type": "object", + "title": "Built From", + "description": "the build of each table the response read" + }, + "kind": { + "type": "string", + "const": "place_other", + "title": "Kind", + "default": "place_other" + }, + "place_other": { + "$ref": "#/components/schemas/PlaceBlock" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "types", + "description", + "links", + "gaps", + "built_from", + "kind", + "place_other" + ], + "title": "PlaceOtherNode" + }, + "PriceBasisWords": { + "properties": { + "prices": { + "type": "string", + "enum": [ + "current", + "constant" + ], + "title": "Prices" + }, + "base_year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Base Year" + } + }, + "type": "object", + "required": [ + "prices", + "base_year" + ], + "title": "GraphPriceBasis", + "description": "Current or constant prices, with the base year of constant prices when known." + }, + "Projection": { + "type": "string", + "enum": [ + "countries", + "other_states", + "territories", + "former_states", + "institutions" + ], + "title": "Projection", + "description": "A named cut of a membership by member class." + }, + "ProjectionCount": { + "properties": { + "projection": { + "$ref": "#/components/schemas/Projection" + }, + "count": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Count", + "description": "members under the projection; null when the authority does not record it" + }, + "complete": { + "type": "boolean", + "title": "Complete", + "description": "false when the authority does not record the projection, or is known to hold it only in part (`membership_incomplete`)" + } + }, + "type": "object", + "required": [ + "projection", + "count", + "complete" + ], + "title": "GraphProjectionCount", + "description": "One projection of a membership and its member count at the block's date." + }, + "ProvenanceEntry": { + "properties": { + "ref": { + "type": "string", + "title": "Ref" + }, + "label": { + "type": "string", + "title": "Label" + } + }, + "type": "object", + "required": [ + "ref", + "label" + ], + "title": "ProvenanceEntry", + "description": "One admitted provenance: its dcid and the provenance table's name for it." + }, + "ProvenanceNode": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the node's dcid" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "the node's name; for a Provenance, its parent Dataset's name where it has one. Null, and named in gaps, when the graph gives none" + }, + "types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Types", + "description": "the node's typeOf values, as the graph holds them" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "the node's prose in the graph; null when it has none" + }, + "links": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "codes", + "children", + "members", + "countries", + "datasets", + "variables", + "facets" + ] + }, + "type": "object", + "title": "Links", + "description": "each list relation the node has, mapped to its route; empty when none" + }, + "gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Gaps", + "description": "the member path of every value this door cannot know" + }, + "built_from": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "code_index", + "origin_catalogue", + "coverage_index", + "membership" + ] + }, + "type": "object", + "title": "Built From", + "description": "the build of each table the response read" + }, + "kind": { + "type": "string", + "const": "provenance", + "title": "Kind", + "default": "provenance" + }, + "provenance": { + "$ref": "#/components/schemas/SourceBlock" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "types", + "description", + "links", + "gaps", + "built_from", + "kind", + "provenance" + ], + "title": "ProvenanceNode" + }, + "ProvenanceRef": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the graph identifier" + }, + "label": { + "type": "string", + "title": "Label", + "description": "plain-language display name, read from the graph" + }, + "source": { + "anyOf": [ + { + "$ref": "#/components/schemas/SourceRef" + }, + { + "type": "null" + } + ], + "description": "the organisation behind the provenance" + }, + "data_commons": { + "anyOf": [ + { + "$ref": "#/components/schemas/search__models__grammar__DataCommonsRef" + }, + { + "type": "null" + } + ], + "description": "the Data Commons the provenance's data comes from" + }, + "documentation": { + "type": "string", + "title": "Documentation", + "description": "the Graph API route of the provenance's document, GET /api/graph/documentation/{dcid}" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref", + "label" + ], + "title": "ProvenanceRef", + "description": "A provenance on the wire: its dcid and label, the source behind it, the\nData Commons its data comes from, and the route of its document, which\nfollows from the dcid. `label`, `source` and `data_commons` come from the\norigin catalogue's provenance table. A provenance the table does not list\ncarries its graph label and neither `source` nor `data_commons`, and is\nomitted when the graph has no label for it." + }, + "PublishFrameRequest": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "description": "contract schema version; exactly 1 for v1", + "default": 1 + }, + "spec_id": { + "type": "string", + "pattern": "^ops_[0-9a-f]{6,64}$", + "title": "Spec Id", + "description": "the derived frame's own op-spec hash id, ops_-prefixed" + }, + "content_version": { + "type": "string", + "pattern": "^ocv_[0-9a-f]{6,64}$", + "title": "Content Version", + "description": "the derived frame's own toolkit content version, ocv_-prefixed" + }, + "role_keys": { + "items": { + "type": "string", + "maxLength": 1024 + }, + "type": "array", + "maxItems": 16, + "title": "Role Keys", + "description": "`dfo_frame_grammar.Frame.build`'s own `role_keys` argument; empty is a valid subject-only frame with no role columns, `build_frame` accepts it, so no minimum is imposed here. Bounded at 16 entries, each at most 1024 characters, a schema fact rather than a deployment ceiling -- see this module's own docstring" + }, + "rows": { + "items": { + "additionalProperties": { + "anyOf": [ + { + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "maxLength": 1024 + }, + { + "additionalProperties": { + "type": "string", + "maxLength": 200, + "pattern": "^dcid:." + }, + "type": "object", + "maxProperties": 1 + }, + { + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "maxLength": 1024 + }, + { + "type": "integer" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "type": "object", + "maxProperties": 3 + } + ] + }, + "type": "object", + "maxProperties": 2 + }, + { + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "maxLength": 1024 + }, + { + "type": "integer" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "type": "object", + "maxProperties": 3 + }, + { + "anyOf": [ + { + "type": "string", + "maxLength": 1024 + }, + { + "type": "integer" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + ] + }, + "type": "object", + "maxProperties": 22 + }, + "type": "array", + "maxItems": 1000000, + "title": "Rows", + "description": "`dfo_frame_grammar.Frame.build`'s own `rows` argument; empty is a valid frame (an analysis verb whose filter matches nothing produces exactly this), `build_frame` accepts it, so no minimum is imposed here. Each row is bounded at 22 keys; the outer list is bounded at 1000000 rows, a fixed schema backstop, well above doors.publish's own fixed PUBLISH_MAX_ROWS that actually governs `len(rows)` at publish time -- see this module's own docstring for why the two are not the same kind of cap. A cell is a scalar, or under `unit` alone a mapping of scalars bounded at 3 entries or a composed unit, `numerator` over `denominator`, each a unit ref, a mapping of scalars, or `{stat_var}` -- see this module's own docstring for the shapes refused at parse time" + }, + "input_content_versions": { + "items": { + "type": "string", + "pattern": "^(?:cv_[0-9a-f]{32}|ocv_[0-9a-f]{6,64})$" + }, + "type": "array", + "maxItems": 256, + "minItems": 1, + "title": "Input Content Versions", + "description": "every input frame's own frame-grammar content_version this derived frame was computed from. Bounded at 256 entries, a schema fact rather than a deployment ceiling -- see this module's own docstring" + }, + "recipe": { + "anyOf": [ + { + "$ref": "#/components/schemas/Recipe" + }, + { + "type": "null" + } + ], + "description": "the recipe that produced this frame. The door stores it beside the version, outside the body a republish is compared on, so a republish may add one to a frame published without it and may omit one the frame already holds" + }, + "steps": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/Step" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Steps", + "description": "the frame's step records, one per operation that computed it, in order, in the shape of dfo-spec-kit's step schema. `op` is any operation name. At most 62 steps and 65536 bytes of canonical JSON; step ids are distinct, an input that names a step names an earlier one, and only a `retrieve` step's `input` names a version, which at least one does. The versions `retrieve` steps name are the frame's root inputs, which `input_content_versions`, the immediate input frames, need not list. Absent when the publish carries none" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "spec_id", + "content_version", + "role_keys", + "rows", + "input_content_versions" + ], + "title": "PublishFrameRequest" + }, + "PublishFrameResponse": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "default": 1 + }, + "published": { + "$ref": "#/components/schemas/PublishedFrameCoordinates" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "published" + ], + "title": "PublishFrameResponse" + }, + "PublishedFrameCoordinates": { + "properties": { + "spec_id": { + "type": "string", + "title": "Spec Id" + }, + "content_version": { + "type": "string", + "title": "Content Version" + }, + "artifact_digest": { + "type": "string", + "title": "Artifact Digest" + }, + "created": { + "type": "boolean", + "title": "Created", + "description": "true when this call newly recorded the version row; false when an identical publish of this exact pair had already been recorded (the idempotent replay path)" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "spec_id", + "content_version", + "artifact_digest", + "created" + ], + "title": "PublishedFrameCoordinates" + }, + "QueryEcho": { + "properties": { + "entry_path": { + "type": "string", + "enum": [ + "raw_text", + "parsed", + "dataset_resubmit" + ], + "title": "Entry Path", + "description": "which input was used" + }, + "raw_query": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Raw Query", + "description": "the original query text, when one was supplied" + }, + "normalized_query": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Normalized Query", + "description": "normalised query text, when extraction ran" + }, + "extract_skipped": { + "type": "boolean", + "title": "Extract Skipped", + "description": "true when the extraction step was skipped for this request" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "entry_path", + "extract_skipped" + ], + "title": "QueryEcho", + "description": "What the response was understood to be answering." + }, + "RawTextInput": { + "properties": { + "kind": { + "type": "string", + "const": "raw_text", + "title": "Kind", + "description": "discriminator for natural-language query input", + "default": "raw_text" + }, + "query": { + "type": "string", + "title": "Query", + "description": "the user's natural-language request" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "RawTextInput", + "description": "Natural-language query input. The engine extracts, resolves, and grounds it." + }, + "Recipe": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "description": "recipe schema version; exactly 1" + }, + "normal_form_hash": { + "type": "string", + "pattern": "^rnf_[0-9a-f]{32}$", + "title": "Normal Form Hash", + "description": "hash of the recipe's normal form, in which every derived input is replaced by its own recipe, every root by its dataset spec_id and rendering, and every literal a rolling overlay governs is dropped. Two frames replayed from one recipe on different data share it" + }, + "replay_key": { + "type": "string", + "pattern": "^rpk_[0-9a-f]{32}$", + "title": "Replay Key", + "description": "hash of the normal form hash, the root dataset pairs, and the execution identity. It names the one frame replayed from them" + }, + "execution_identity": { + "type": "string", + "maxLength": 1024, + "minLength": 1, + "title": "Execution Identity", + "description": "the engine, grammar, and reduction versions that ran the recipe" + }, + "tree": { + "additionalProperties": { + "$ref": "#/components/schemas/JsonValue" + }, + "type": "object", + "title": "Tree", + "description": "the op-spec tree, opaque here; analysis-mcp owns its shape" + }, + "roots": { + "items": { + "$ref": "#/components/schemas/JsonValue" + }, + "type": "array", + "title": "Roots", + "description": "how each root dataset was minted, opaque here; analysis-mcp owns its shape" + }, + "anchor": { + "anyOf": [ + { + "$ref": "#/components/schemas/RecipeAnchor" + }, + { + "type": "null" + } + ], + "description": "the rolling anchor, or null for a recipe with no rolling period" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "schema_version", + "normal_form_hash", + "replay_key", + "execution_identity", + "tree", + "roots" + ], + "title": "Recipe" + }, + "RecipeAnchor": { + "properties": { + "period": { + "type": "string", + "maxLength": 1024, + "minLength": 1, + "title": "Period", + "description": "a period label at the frame's grain" + }, + "rule": { + "type": "string", + "const": "half1", + "title": "Rule", + "description": "the anchor rule: the newest period at least half of the series hold" + }, + "left_out": { + "items": { + "$ref": "#/components/schemas/RecipeLeftOutSeries" + }, + "type": "array", + "title": "Left Out" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "period", + "rule", + "left_out" + ], + "title": "RecipeAnchor", + "description": "The period a rolling recipe's `latest` resolved to, and the series it left out." + }, + "RecipeLeftOutSeries": { + "properties": { + "root": { + "type": "integer", + "minimum": 0.0, + "title": "Root", + "description": "index of the population the series belongs to, in the order of the recipe's populations: one per root dataset" + }, + "coordinates": { + "additionalProperties": { + "type": "string", + "maxLength": 1024, + "minLength": 1 + }, + "type": "object", + "title": "Coordinates", + "description": "the series' dimension values, column name to value. Holds `stat_var` or at least one entity-role column" + }, + "label": { + "anyOf": [ + { + "type": "string", + "maxLength": 1024, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "the series' display name. Optional: a reader of the recipe resolves the name from `coordinates` when it is absent" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "root", + "coordinates" + ], + "title": "RecipeLeftOutSeries", + "description": "One series a rolling anchor left out: it holds no row at the anchor period.\n\n`coordinates` must name the series, since a reader labels it from them: they hold\n`stat_var`, or at least one entity-role column, which is any column other than the frame\ngrammar's fixed columns (`stat_var`, `time_period`, `value`, `unit`, `status`) and its\nfacet identity columns (`measurementMethod`, `provenance`). Empty coordinates, and\ncoordinates of only those other columns, are refused." + }, + "RecipeWriteResponse": { + "properties": { + "spec_id": { + "type": "string", + "title": "Spec Id" + }, + "content_version": { + "type": "string", + "title": "Content Version" + }, + "created": { + "type": "boolean", + "title": "Created", + "description": "true when this call stored the recipe; false when the frame already held a recipe with the same normal_form_hash and replay_key" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "spec_id", + "content_version", + "created" + ], + "title": "RecipeWriteResponse" + }, + "RefreshFrameRequest": { + "properties": { + "spec_id": { + "type": "string", + "maxLength": 200, + "pattern": "^(?:spec|ops)_[^/\\s]+$", + "title": "Spec Id" + }, + "content_version": { + "type": "string", + "maxLength": 200, + "pattern": "^(?:cv|ocv)_[^/\\s]+$", + "title": "Content Version" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "spec_id", + "content_version" + ], + "title": "RefreshFrameRequest", + "description": "The frame to refresh. An `ops_` id is accepted by the grammar and refused\n`frame_not_refreshable`." + }, + "RegisterRequest": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "description": "contract schema version; exactly 1 for v1" + }, + "definition": { + "$ref": "#/components/schemas/CanonicalDefinition", + "description": "the canonical definition to register" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "schema_version", + "definition" + ], + "title": "RegisterRequest", + "description": "`POST /api/datasets/register`'s body: one canonical `definition`.\n`unsupported_schema_version` (the top-level `schema_version` field's own\nrefusal) and any other shape failure surface through the platform's\ngeneric `RequestValidationError` handling." + }, + "RelatedMeasure": { + "properties": { + "stat_var": { + "$ref": "#/components/schemas/GraphRef", + "description": "the StatVar this measure reads, labelled with its graph name, or its dcid when it has none" + }, + "definition": { + "$ref": "#/components/schemas/SpecDefinition", + "description": "the measure's own {schema_version, spec_id, identity}" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "stat_var", + "definition" + ], + "title": "RelatedMeasure", + "description": "One other StatVar from the StatVarGroup this Spec's one StatVar belongs to (see\nResolvedSpec.related_measures), with data at the Spec's places.\n\n`definition` is minted from the member's own five-tuple and constraint values, with this\nSpec's entities and requested window and no facets, since a unit or source this Spec\npins belongs to its own measure. Post `definition` back as `identity` on a\ndataset_resubmit identity entry to switch onto this measure." + }, + "Relaxation": { + "properties": { + "axis": { + "type": "string", + "enum": [ + "what", + "how", + "where", + "when", + "source" + ], + "title": "Axis", + "description": "the slot axis whose binding was relaxed" + }, + "property_dcid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Property Dcid", + "description": "the constraint property dcid the relaxed slot carried, when one exists" + }, + "dropped_value_dcids": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Dropped Value Dcids", + "description": "the taxonomy member dcid(s) the relaxed binding dropped" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "axis", + "dropped_value_dcids" + ], + "title": "Relaxation", + "description": "Which definition part a nearest_real suggestion relaxed to find data.\n\nCaptured at the point a constraint binding is dropped and the resulting,\nwidened request is re-confirmed against the live graph (see\nNearestRealSpec). Names the definition part relaxed (axis + the\nconstraint property it carried) and the value(s) it dropped." + }, + "ReleaseDocumentResponse": { + "properties": { + "catalog_version": { + "type": "string", + "title": "Catalog Version", + "description": "the catalogue release this deployment serves" + }, + "schema_version": { + "type": "integer", + "title": "Schema Version", + "description": "the envelope schema version this release resolves against" + }, + "member_types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Member Types", + "description": "every component type this release's catalogue defines" + }, + "constraint_ids": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Constraint Ids", + "description": "every constraint id this release's registry enforces" + }, + "retry_modes": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Retry Modes", + "description": "`retry_modes` is the headline mode per code, and the per-response `retryable` boolean is the authoritative value for every code. `schema_invalid` and `frame_unavailable` vary by cause, and `request_invalid` is always false although its headline mode is `correct_and_retry`." + }, + "envelope_schema": { + "additionalProperties": true, + "type": "object", + "title": "Envelope Schema", + "description": "the envelope JSON Schema this release's assembler validates a minted envelope against; every create/revise/read body's `resolved_payload` conforms to it" + }, + "component_schemas": { + "additionalProperties": { + "additionalProperties": true, + "type": "object" + }, + "type": "object", + "title": "Component Schemas", + "description": "each member type's own component JSON Schema, keyed by member type. `envelope_schema`'s `component` field `$ref`s these schemas by their own `$id`, which otherwise resolves nowhere, so a client validating `resolved_payload` resolves those `$ref`s against this map" + }, + "intent_schemas_tolerant": { + "additionalProperties": { + "additionalProperties": true, + "type": "object" + }, + "type": "object", + "title": "Intent Schemas Tolerant", + "description": "each member type's own tolerant intent schema" + }, + "minimal_intents": { + "additionalProperties": { + "additionalProperties": true, + "type": "object" + }, + "type": "object", + "title": "Minimal Intents", + "description": "each member type's own minimal legal intent" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "catalog_version", + "schema_version", + "member_types", + "constraint_ids", + "retry_modes", + "envelope_schema", + "component_schemas", + "intent_schemas_tolerant", + "minimal_intents" + ], + "title": "ReleaseDocumentResponse", + "description": "`GET /api/presentation/release`'s body. It carries the pinned\ncatalogue release's own identity and the vocabulary a client needs\nto mount tools without a second, out-of-band fetch of the catalogue\nbundle." + }, + "ReleaseModel": { + "properties": { + "date": { + "type": "string", + "title": "Date", + "description": "the release date, YYYY-MM-DD" + }, + "title": { + "type": "string", + "title": "Title", + "description": "the release title, plain text" + }, + "changes": { + "items": { + "$ref": "#/components/schemas/ChangeModel" + }, + "type": "array", + "title": "Changes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "date", + "title" + ], + "title": "ReleaseModel", + "description": "One release of a source's DFO pipeline." + }, + "RenderBody": { + "properties": { + "frame": { + "$ref": "#/components/schemas/RenderFrame" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "frame" + ], + "title": "RenderBody", + "description": "The frame to draw the revision on." + }, + "RenderFrame": { + "properties": { + "spec_id": { + "type": "string", + "title": "Spec Id" + }, + "content_version": { + "type": "string", + "title": "Content Version" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "spec_id", + "content_version" + ], + "title": "RenderFrame" + }, + "ReplayedFrameResponse": { + "properties": { + "spec_id": { + "type": "string", + "title": "Spec Id" + }, + "content_version": { + "type": "string", + "title": "Content Version" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "spec_id", + "content_version" + ], + "title": "ReplayedFrameResponse" + }, + "Resolution": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "description": "contract schema version; exactly 1 for v1. Required on every response.", + "default": 1 + }, + "query_echo": { + "$ref": "#/components/schemas/QueryEcho", + "description": "what the response was understood to be answering" + }, + "diagnostics": { + "$ref": "#/components/schemas/Diagnostics", + "description": "run health, warnings, timing, build stamp" + }, + "kind": { + "type": "string", + "const": "resolution", + "title": "Kind", + "description": "discriminator for a response that resolved the question into data", + "default": "resolution" + }, + "parts": { + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/DefinitePart" + }, + { + "$ref": "#/components/schemas/CandidatesPart" + }, + { + "$ref": "#/components/schemas/NoDataPart" + }, + { + "$ref": "#/components/schemas/UnsupportedPart" + } + ], + "discriminator": { + "propertyName": "status", + "mapping": { + "candidates": "#/components/schemas/CandidatesPart", + "definite": "#/components/schemas/DefinitePart", + "no_data": "#/components/schemas/NoDataPart", + "unsupported": "#/components/schemas/UnsupportedPart" + } + } + }, + "type": "array", + "minItems": 1, + "title": "Parts", + "description": "one entry per variable asked, in query order" + }, + "rendered_sentence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Rendered Sentence", + "description": "the envelope-level confirmation sentence describing the whole query, composed across every part's own sentence in query order. When every contributing part is definite, their headings join into one sentence. A qualifier axis (where, when, or source, each a wire value of axis, plus origin, identified by role=='origin' instead since SentenceAxis has no 'origin' member) whose bound value agrees across every contributing part is stated once after the joined phrases, a possessive lead every part shares opens the sentence once, and the byline follows once. A qualifier that differs stays inline in each part's own phrase. The response falls back to one sentence per part, each part's own text left exactly as that part rendered it, when a part is still resolving, when the parts' bylines differ, or when a differing qualifier's connective opens with a comma (a period range). A part still resolving contributes up to three tokens of its own: an optional prefix text token, its own variable_text as an editable slot, and a text token stating the outcome. A lone part that is not definite composes to exactly that part's own sentence. After the headings and bylines, each part's departures follow in part order as segment='departure' tokens carrying that part's part_index. This is the one sentence that writes out a definite part's departures." + }, + "sentence_plan": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/SentenceToken" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Sentence Plan", + "description": "the ordered token form of rendered_sentence, present under the same condition; null or omitted otherwise. Composed the same way rendered_sentence is, from every part's own sentence_plan -- see SentenceToken.part_index for how a client recovers which parts[i] each variable phrase and attached qualifier belongs to, and which tokens are shared skeleton (an inter-phrase connective, a hoisted shared qualifier, the terminal '.', or the shared ' ' the per-part fallback puts between two sentences) rather than any one part's own." + }, + "skills": { + "anyOf": [ + { + "additionalProperties": { + "$ref": "#/components/schemas/Skill" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Skills", + "description": "every skill named by any Spec.resolved.skills across this response's parts, keyed by id -- each id any Spec carries is a key here, and each key's front matter is carried once regardless of how many Specs name it. Present under response_options.include_skills; null when the option is off, {} when it is on and no Spec matched anything." + }, + "status": { + "type": "string", + "enum": [ + "definite", + "candidates", + "no_data", + "unsupported", + "mixed" + ], + "title": "Status", + "description": "the parts' shared status when every part agrees, or 'mixed' when two or more parts differ; derived from parts, never independently settable", + "readOnly": true + } + }, + "type": "object", + "required": [ + "query_echo", + "diagnostics", + "parts", + "status" + ], + "title": "Resolution", + "description": "A resolve response that resolved the question into data: one part per\nvariable asked, in query order, each a complete outcome carrying its own\nstatus and payload.\n\nA single-variable query is one part, so `status` reads that one part's\nstatus directly. A query in which extraction found no variable is also\none part, whose `variable_text` is the whole query text.\n\n`status` below is a computed field that rides in every serialised\nresponse body without being a settable input, so this class stays a\nplain `BaseModel`, which allows unknown fields. `StrictModel` forbids them,\nwhich would make `Resolution.model_validate` reject its own `model_dump()`\noutput, breaking every round-trip a client or this codebase does on a\nfetched response body. A posted `status` is ignored and recomputed.\n\nUsage::\n\n resp = RESOLVE_RESPONSE_ADAPTER.validate_python(obj)\n if resp.kind == \"resolution\":\n resp.status # \"definite\" | \"candidates\" | \"no_data\" | \"unsupported\" | \"mixed\"\n resp.parts[0].status # this part's own status" + }, + "ResolutionTrace": { + "properties": { + "resolved_entities": { + "items": { + "$ref": "#/components/schemas/GraphRef" + }, + "type": "array", + "title": "Resolved Entities", + "description": "every entity" + }, + "resolved_sources": { + "items": { + "$ref": "#/components/schemas/ProvenanceRef" + }, + "type": "array", + "title": "Resolved Sources", + "description": "every dataset/source (a Data Commons provenance)" + }, + "slot_filters": { + "items": { + "$ref": "#/components/schemas/ResolvedFilter" + }, + "type": "array", + "title": "Slot Filters", + "description": "each applied bind decision, slot by slot" + }, + "query_qualifiers": { + "items": { + "$ref": "#/components/schemas/ResolvedQualifier" + }, + "type": "array", + "title": "Query Qualifiers", + "description": "each narrowing term the request's text named, and what became of it (see ResolvedQualifier). Defaulted empty: a dataset_resubmit identity entry carries no query text to re-derive this from, and every hand-built fixture and same-shape merge that predates this field still validates." + }, + "requested_window": { + "anyOf": [ + { + "$ref": "#/components/schemas/TimeWindow" + }, + { + "type": "string", + "const": "latest" + }, + { + "type": "null" + } + ], + "title": "Requested Window", + "description": "the date window originally requested (query intent), independent of coverage narrowing; None when no date was requested. The literal \"latest\" means the query explicitly asked for the most-recent/current value -- distinct from None (no date signal at all), since a resubmit of a \"latest\" spec must re-resolve to whatever year is CURRENTLY latest, not pin to the year this response happened to resolve. spec_id is anchored on this value, not on the served window, so identity stays stable across a resubmit even when coverage narrows the dates. Preserve the returned Spec.definition.identity when resubmitting; if editing it, carry this value at ResubmitIdentityPayload.identity.requested_window to keep that stability." + }, + "capability_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Capability Version", + "description": "the deployment capability version that produced this Spec, shared verbatim with GET /api/search/capabilities and every problem-details body's own capability_version. None only in hand-built fixtures that predate this field; every engine-produced Spec populates it." + }, + "default_reading": { + "anyOf": [ + { + "$ref": "#/components/schemas/TraceDefaultReading" + }, + { + "type": "null" + } + ], + "description": "what the default price-basis reading did before bind (see TraceDefaultReading); None when no bind ran for this Spec, as on a resubmit, or in hand-built fixtures that predate this field" + }, + "stated_form": { + "anyOf": [ + { + "type": "string", + "enum": [ + "per_person", + "per_head_base", + "per_area", + "rate", + "share" + ] + }, + { + "type": "null" + } + ], + "title": "Stated Form", + "description": "the normalised form the quantity read found in the question when no wording pattern named one (\"debt to GDP\" asks for a rate), and which the answer was then checked against; None when a wording pattern named the form, when the question asks for none, and when no bind ran for this Spec" + }, + "conversion": { + "anyOf": [ + { + "$ref": "#/components/schemas/TraceConversion" + }, + { + "type": "null" + } + ], + "description": "always absent: conversion is recorded per series in resolved.observations.series[].conversion (see TraceConversion)" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "resolved_entities", + "resolved_sources", + "slot_filters" + ], + "title": "ResolutionTrace", + "description": "Consolidated record of how the query was understood." + }, + "ResolveOptions": { + "properties": { + "include_option_coverage": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Include Option Coverage", + "description": "when true, the engine probes each top-level interpretation and candidate Spec's slot_options for observation coverage (e.g. 'Kenya — 205 obs') and populates SlotOption.coverage; false/absent (the default) never fires the extra probes, so this is opt-in latency, not a hidden cost on the hot path. Delivery differs by transport, for every input kind: over SSE (Accept: text/event-stream), coverage arrives via trailing slot_options/entity_options events emitted after the response event, and the response event's own Spec.resolved.slot_options / entity_options stay coverage=null; on the buffered JSON body, coverage is embedded directly in the returned Spec. Spec.resolved.facet_options is computed whether or not this is set; over SSE with this set, it arrives in trailing facet_options events instead of the response event." + }, + "include_observations": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Include Observations", + "description": "when true (the default is false -- absent also means false), the engine populates Spec.resolved.observations with the resolved answer's observation values: the full series when small enough, otherwise a bounded latest-points preview. This per-spec fetch runs only after the engine commits to a definite spec, including a promoted candidate; a multi-candidate response keeps per-candidate metadata and coverage without fetching observations. Delivery mirrors include_option_coverage's transport split: over SSE, observations arrive via a trailing observations event emitted after the response event, and the response event's own Spec.resolved.observations stays null or omitted; on the buffered JSON body, observations are embedded directly in the returned Spec." + }, + "include_skills": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Include Skills", + "description": "when true (the default is false -- absent also means false), the engine matches every resolved Spec's bound graph nodes (its shape's structural anchors and the dcids its bound constraint slots name) and its selected provenance (facets.provenance.ref, when one provenance serves every series) against the shared skills index and populates Spec.resolved.skills with the matching skill ids: skills matched through a graph node first, nearest-attachment-first, then skills matched only through the provenance, by id; [] when nothing matched. The response's own skills map then carries every named skill's front matter once, keyed by id. When the shared skills index has not yet built a first snapshot, the response carries the skills_index_unavailable diagnostics warning instead and no Spec gets a populated skills field; when a snapshot is available but its own build may have left out a published skill or served one excluded or understated (a read stopped at a budget or bound, the build's content budget ran out before a skill's turn, or a build step failed), the response instead carries the skills_index_incomplete diagnostics warning alongside whatever matches it did serve; a part with no resolved spec (no_data, unsupported) carries the part-scoped skills_not_matchable warning, since it binds no graph nodes to match against." + } + }, + "additionalProperties": false, + "type": "object", + "title": "ResolveOptions", + "description": "Optional resolution parameters the caller may supply." + }, + "ResolveResponse": { + "properties": { + "results": { + "items": { + "$ref": "#/components/schemas/ResolveResult" + }, + "type": "array", + "title": "Results" + } + }, + "type": "object", + "required": [ + "results" + ], + "title": "GraphResolveResponse", + "description": "`results` is index-aligned with the request's `texts`." + }, + "ResolveResult": { + "properties": { + "input": { + "type": "string", + "title": "Input" + }, + "status": { + "type": "string", + "enum": [ + "resolved", + "ambiguous", + "not_found", + "not_held" + ], + "title": "Status" + }, + "entity": { + "anyOf": [ + { + "$ref": "#/components/schemas/EntityRef" + }, + { + "type": "null" + } + ] + }, + "matched": { + "anyOf": [ + { + "$ref": "#/components/schemas/Matched" + }, + { + "type": "null" + } + ] + }, + "reading": { + "anyOf": [ + { + "type": "string", + "enum": [ + "members", + "entity" + ] + }, + { + "type": "null" + } + ], + "title": "Reading" + }, + "projection": { + "anyOf": [ + { + "$ref": "#/components/schemas/Projection" + }, + { + "type": "null" + } + ] + }, + "member_count": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Member Count" + }, + "members": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "$ref": "#/components/schemas/NodeRef" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Members" + }, + "candidates": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/EntityRef" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Candidates" + }, + "near_matches": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/EntityRef" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Near Matches" + } + }, + "type": "object", + "required": [ + "input", + "status", + "entity", + "matched", + "reading", + "projection", + "member_count", + "members", + "candidates", + "near_matches" + ], + "title": "GraphResolveResult", + "description": "One text's outcome. `input` echoes the text; fields a status does not use are `null`.\n\n- `resolved`: `entity`, `matched` and `reading`. A group or region adds `projection`,\n `member_count` and `members`: the list route's link, or the members inline (at most\n 256) when the request expanded them. The three are `null` for a region the membership\n policy does not hold.\n- `ambiguous`: `candidates`, in the resolver's order.\n- `not_found`: `near_matches`, hints for a person; a program should pick none by id.\n- `not_held`: `entity`, the id the resolver named, which does not open on the node route.\n\n`reading` is `members` when the text names a group's members (\"EU countries\"), else\n`entity`." + }, + "ResolvedEntity": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the resolved entity's dcid" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "plain-language display name" + }, + "entity_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Entity Type", + "description": "e.g. Country, AdministrativeArea1, Organization" + }, + "role": { + "type": "string", + "enum": [ + "observationAbout", + "origin", + "destination" + ], + "title": "Role", + "description": "the role key this entity plays; observationAbout, origin, or destination" + }, + "confidence": { + "anyOf": [ + { + "type": "string", + "enum": [ + "high", + "medium", + "low" + ] + }, + { + "type": "null" + } + ], + "title": "Confidence", + "description": "the engine's confidence in this entity resolution; None when not assessed -- no entity-resolution confidence signal exists yet, so this ships None on every entity today" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref", + "role" + ], + "title": "ResolvedEntity", + "description": "One resolved entity on the wire, under `resolved.entities`: the flat\nprojection of the engine's own `Entity` -- `ref`/`entity_type` collapse from\na `GraphRef` to a bare dcid/label pair, and `role` collapses from the\nengine's richer role model to the role-key string it already derives from\n(the identity core's own vocabulary, so this never adds a second mapping)." + }, + "ResolvedFacet": { + "properties": { + "basis": { + "type": "string", + "enum": [ + "bound", + "declared_default", + "fallback" + ], + "title": "Basis", + "description": "'bound' when this axis was constrained by the request, 'declared_default' when an unbound axis was completed from a declared deployment policy, 'fallback' when neither applies and the deployment policy supplied the value: facets holding a point in the requested years first, then DFO's facets for a variable both DFO and base Data Commons hold, then the most places or role tuples covered there, then the most requested years the span covers, then most observations, then the latest observation, then a deterministic tie-break" + }, + "ref": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Ref", + "description": "the axis's resolved dcid, present when one distinct value served every carried series; absent when selection is 'per_series'" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "best-effort display label for ref; present only alongside ref" + }, + "currency": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Z]{3}$" + }, + { + "type": "null" + } + ], + "title": "Currency", + "description": "unit axis only, alongside ref: the ISO 4217 code of the currency ref is denominated in, from the graph's currency units (CurrencyUSD, USDollar and the base Data Commons Currency members such as INR); absent when ref is no currency. The sentence reads it: US dollars go to the byline's unit token, any other currency stays in the heading" + }, + "source": { + "anyOf": [ + { + "$ref": "#/components/schemas/SourceRef" + }, + { + "type": "null" + } + ], + "description": "provenance axis only, alongside ref: the organisation behind the provenance, from the origin catalogue" + }, + "data_commons": { + "anyOf": [ + { + "$ref": "#/components/schemas/search__models__grammar__DataCommonsRef" + }, + { + "type": "null" + } + ], + "description": "provenance axis only, alongside ref: the Data Commons the provenance's data comes from" + }, + "documentation": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Documentation", + "description": "provenance axis only, alongside ref: the Graph API route of the provenance's document, GET /api/graph/documentation/{dcid}" + }, + "account": { + "anyOf": [ + { + "$ref": "#/components/schemas/FlowAccount" + }, + { + "type": "null" + } + ], + "description": "provenance axis only, alongside ref: whose account of a flow the provenance gives, when ref is a dataset the code index declares; 'provider' when it reports flows as their providers record them" + }, + "selection": { + "anyOf": [ + { + "type": "string", + "const": "per_series" + }, + { + "type": "null" + } + ], + "title": "Selection", + "description": "'per_series' when the carried series select different values on this axis; present in place of ref/label, never alongside them" + }, + "request_basis": { + "anyOf": [ + { + "additionalProperties": { + "type": "string", + "enum": [ + "bound", + "declared_default", + "fallback" + ] + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Request Basis", + "description": "per-member basis (currency/prices/base_year) for a unit axis bound through the request form; present only on the unit axis, alongside either ref/label or selection" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "basis" + ], + "title": "ResolvedFacet", + "description": "One facet axis's resolved value on a Spec (see ResolvedSpec.facets):\nwhich value backed the answer's observations, and why.\n\nbasis is always present. ref/label are present when one distinct value\nserved every carried series; selection carries \"per_series\" in their\nplace when the carried series select different values on this axis --\nnever alongside ref/label. request_basis joins either shape, present\nonly on the unit axis, only when unit was bound through the request form\n(currency/prices/base_year), one basis value per member the request\nnamed.\n\nFields are flat and optional, validated by a model validator, rather\nthan a discriminated ref/selection union. basis and request_basis are\nshared by both the single-ref and per-series shapes, so a union would\nduplicate them across arms for a mechanical gain (moving the\nref/selection XOR to the type level) without expressing the\nrequest_basis-only-on-unit constraint, since that constraint is about\nwhich AXIS a ResolvedFacet lives under (see ResolvedSpec.facets), not\nits ref/selection shape. This is also response-only data, never\ndeserialized from untrusted client bytes, so a runtime validator is\nthe right tool for catching an illegal engine-side construction." + }, + "ResolvedFilter": { + "properties": { + "key": { + "$ref": "#/components/schemas/SlotKey", + "description": "the slot identity" + }, + "binding_kind": { + "type": "string", + "enum": [ + "value", + "set", + "unbound" + ], + "title": "Binding Kind", + "description": "which binding state was applied" + }, + "refs": { + "items": { + "$ref": "#/components/schemas/GraphRef" + }, + "type": "array", + "title": "Refs", + "description": "the bound graph objects (empty for unbound)" + }, + "provenance": { + "type": "string", + "enum": [ + "binder", + "text_recognized", + "measure_elected", + "declared_default" + ], + "title": "Provenance", + "description": "whether the bind call's own election produced this value, a code row recognised in the query's own text forced it, or the measure-family election forced it on an axis the binder left open", + "default": "binder" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "key", + "binding_kind", + "refs" + ], + "title": "ResolvedFilter", + "description": "One applied bind decision, slot by slot." + }, + "ResolvedQualifier": { + "properties": { + "text": { + "type": "string", + "title": "Text", + "description": "verbatim span of the source text that named the term: variable_text, query_text, or a dropped qualifier phrase" + }, + "named": { + "items": { + "$ref": "#/components/schemas/GraphRef" + }, + "type": "array", + "title": "Named", + "description": "every code row the span names in the packaged index, any code system; empty when none did" + }, + "slot": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Slot", + "description": "property dcid of the slot_filters entry whose binding consumed this term, or, on an unbound value the answer's shape has a slot for but leaves unmet, that slot's property; None otherwise" + }, + "disposition": { + "type": "string", + "enum": [ + "bound", + "unbound", + "no_vocabulary" + ], + "title": "Disposition", + "description": "\"bound\" when a final binding covers a named row (or a descendant of one); \"unbound\" when a row was named but no binding covers it; \"no_vocabulary\" when the term names no code at all" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Start", + "description": "character offset where the term starts in the variable phrase" + }, + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "End", + "description": "character offset where the term ends in the variable phrase" + }, + "evidence": { + "anyOf": [ + { + "type": "string", + "enum": [ + "label", + "synonym", + "model", + "uncovered", + "unavailable", + "unsupported" + ] + }, + { + "type": "null" + } + ], + "title": "Evidence", + "description": "what read the term: a code label or synonym, the bind model, \"uncovered\" for words no reader covers beside a recognised code, \"unavailable\" for a code no table holds, \"unsupported\" for a distinction no binding expresses" + }, + "operation": { + "anyOf": [ + { + "type": "string", + "enum": [ + "union", + "refinement" + ] + }, + { + "type": "null" + } + ], + "title": "Operation", + "description": "how the term's codes combine with another term's on one code system: a union of both, or a refinement to the narrower" + }, + "selected": { + "items": { + "$ref": "#/components/schemas/GraphRef" + }, + "type": "array", + "title": "Selected", + "description": "the codes the term asked for before the combination simplified them" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "named", + "disposition" + ], + "title": "ResolvedQualifier", + "description": "One narrowing term the request's text named, and what became of it.\n\nThe term's text can come from the variable phrase, from the verbatim\n`query_text`, or from an admitted qualifier tie (see\n`_resolve_query_qualifiers`). `text` is the verbatim span of whichever\nsource named it. `named` is every code row -- any system -- that span\nnames in the packaged index;\nempty when the text names no code at all (a `no_vocabulary` term). `slot`\nis the constraint property dcid of the `slot_filters` entry whose\nbinding consumed the term, or, on an `\"unbound\"` value the answer's shape\nhas a slot for but leaves unmet, that slot's property; `None` otherwise.\n`disposition` is\n`\"bound\"` when some final binding on a named row's code system covers\nit (that row or a descendant), `\"unbound\"` when a row was named but no\nbinding covers it, and `\"no_vocabulary\"` when the term names no code at\nall -- an LLM-reported phrase (`bind`'s own `unplaced` output) that no\ntaxonomy in this deployment's index can express.\n\n`start` and `end` locate the term in the part's variable phrase. `evidence` says what\nread it, and `None` means a code's label or synonym matched the term as the query\nspelled it, the reading every recognised span records:\n\n- `\"label\"` and `\"synonym\"` name a match on a code's label or synonym; no record sets\n them, since a recognised span records `None`.\n- `\"model\"` marks a phrase the bind model read through a code it chose from the\n phrase's candidate menu, a lexical hit of the menu or a descendant of one\n (`phase_rank_bind._model_records`); `named` holds the chosen codes.\n- `\"uncovered\"` marks words no reader covers beside a recognised code\n (`phase_rank_bind._coverage_records`), recorded `\"unbound\"` with that code's rows as\n `named`.\n- `\"unavailable\"` marks a code term the elected shape cannot apply: one naming only\n codes no shape can bind, or, on a part naming a dataset, one no row of that dataset\n holds (`phase_rank_bind._unavailable_qualifiers`), recorded `\"unbound\"`.\n- `\"unsupported\"` marks an exclusion or comparison phrase no binding expresses\n (`phase_rank_bind._unsupported_records`), recorded `\"no_vocabulary\"`.\n\n`operation` and `selected` describe how the term's codes combine with\nanother term's on one code system, and the codes it asked for before that\ncombination simplified." + }, + "ResolvedScope": { + "properties": { + "axis": { + "type": "string", + "enum": [ + "observationAbout", + "origin", + "destination" + ], + "title": "Axis", + "description": "the role-keyed axis the request left unnamed and the engine defaulted" + }, + "members": { + "items": { + "$ref": "#/components/schemas/ResolvedEntity" + }, + "type": "array", + "title": "Members", + "description": "every entity on axis this Spec's read plan serves, sorted by ref; each carries role == axis and a best-effort label/entity_type from a batched graph read, None when the graph has neither" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "axis", + "members" + ], + "title": "ResolvedScope", + "description": "The full member set of an entity axis this Spec's request left unnamed\n(see ResolvedSpec.scope).\n\n``axis`` is observationAbout when place defaulting expanded a place-less\nrequest, and origin or destination when directional-role defaulting\nexpanded a role-bearing request. ``members`` lists the entities on that axis\nthe answer's read plan serves, the ones a coverage breadth dimension for the\nsame axis counts. members is the single-element [\"Earth\"] list when the query\nresolved as a worldwide total.\nThe response-level diagnostics may include place_scope_defaulted or\nrole_scope_defaulted for such resolution, but those warnings are not a\nper-Spec one-to-one representation of this field. The scope lives outside\nBaseIdentity, the spec hash, and resolved.entities: a resubmit of the\nsame definition rediscovers it from the live graph." + }, + "ResolvedSpec": { + "properties": { + "shape": { + "$ref": "#/components/schemas/Shape", + "description": "the structural family chosen" + }, + "slots": { + "items": { + "$ref": "#/components/schemas/Slot" + }, + "type": "array", + "title": "Slots", + "description": "one entry per slot the shape defines, each in a binding state" + }, + "inapplicable_slots": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Inapplicable Slots", + "description": "the slots whose property none of the resolved StatVars declares, listed by property dcid; empty when every slot applies. Joins to resolved.slots[*].key.property.ref. Applicability is graph state, so it is reported here and the slot itself reads 'unbound' in the definition either way. It is never a member of BaseIdentity, never hashed." + }, + "unresolved_slots": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Unresolved Slots", + "description": "the slots whose property is present but unresolved on at least one resolved StatVar (the graph asserted a value for this axis but could not resolve it to a dcid), listed by property dcid; empty when no such slot exists. Joins to resolved.slots[*].key.property.ref, and is disjoint from inapplicable_slots: a property is either never asserted by any resolved StatVar (inapplicable_slots), present but unreadable on one (this field), or neither (a genuinely open axis). The slot itself reads 'unbound' in the definition in every one of these cases; it is never a member of BaseIdentity, never hashed." + }, + "stat_vars": { + "$ref": "#/components/schemas/ResolvedStatVars", + "description": "resolved StatVar(s) inside the region, and the scope they were drawn from" + }, + "entities": { + "items": { + "$ref": "#/components/schemas/ResolvedEntity" + }, + "type": "array", + "title": "Entities", + "description": "resolved entities the data is about; may be empty if where is unbound" + }, + "entity_groups": { + "anyOf": [ + { + "additionalProperties": { + "$ref": "#/components/schemas/EntityGroup" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Entity Groups", + "description": "the named group each role's entities stand for, keyed by the role key the entities above carry: each group whose members are exactly the entities definition.identity binds on that role. The heading names a role by its group and member count ('the 27 EU member states') in place of its members. None when no role was asked for as a group" + }, + "coverage": { + "oneOf": [ + { + "$ref": "#/components/schemas/CoverageExact" + }, + { + "$ref": "#/components/schemas/CoverageBreadth" + }, + { + "$ref": "#/components/schemas/CoverageBare" + } + ], + "title": "Coverage", + "description": "observation footprint", + "discriminator": { + "propertyName": "kind", + "mapping": { + "bare": "#/components/schemas/CoverageBare", + "breadth": "#/components/schemas/CoverageBreadth", + "exact": "#/components/schemas/CoverageExact" + } + } + }, + "headline": { + "anyOf": [ + { + "$ref": "#/components/schemas/Headline" + }, + { + "type": "null" + } + ], + "description": "exact latest-year summary for a role-bearing answer (see Headline); None for a non-role-bearing Spec, which coverage above already answers exactly or approximately enough that no separate latest-year summary is computed" + }, + "download": { + "anyOf": [ + { + "$ref": "#/components/schemas/DownloadFacts" + }, + { + "type": "null" + } + ], + "description": "the rows, series, years and licence of the file a mint of this Spec writes (see DownloadFacts). None when the Spec has no read plan: a no-data answer, or same-shape parts merged into one Spec" + }, + "coverage_stamp": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Coverage Stamp", + "description": "the coverage artifact's own data-version stamp this Spec's role-bearing population and headline were confirmed against (series_coverage.CoverageManifest.stamp); None for a non-role-bearing Spec, which never consults coverage. The graph-derived analogue of this stamp (graph_generation) is not itself a wire field; this is coverage's own, published because coverage is a second, independently-versioned data source an answer can be stale against" + }, + "scope": { + "anyOf": [ + { + "$ref": "#/components/schemas/ResolvedScope" + }, + { + "type": "null" + } + ], + "description": "the full member set of an entity axis this Spec's resolution defaulted (see ResolvedScope): observationAbout for place defaulting, or origin/destination for directional-role defaulting. Response-level diagnostics may carry place_scope_defaulted or role_scope_defaulted, but warning presence is not an exact per-Spec equivalence; None when this Spec did not default an entity axis" + }, + "facets": { + "additionalProperties": { + "$ref": "#/components/schemas/ResolvedFacet" + }, + "type": "object", + "title": "Facets", + "description": "the facet axis values of the series this Spec's read plan serves, the series its observations carry (see ResolvedFacet); the same whether or not observations are included or deferred to a trailing SSE event. Sparse, meaning an axis no served series carries is omitted, never a null placeholder. {} when the Spec serves no series" + }, + "observations": { + "anyOf": [ + { + "$ref": "#/components/schemas/SpecObservations" + }, + { + "type": "null" + } + ], + "description": "the observation values behind coverage above; None when not resolved for this Spec (e.g. no entity to probe, or response_options.include_observations is false), when ResolveOptions.include_observations opts into deferred SSE delivery (populated instead via a trailing observations event, mirroring slot_options/entity_options' own coverage-probe transport split), or for a candidates-status entry, nearest_real, or flagged_match spec (this iteration only populates it on a primary definite answer)." + }, + "slot_options": { + "items": { + "$ref": "#/components/schemas/SlotOptions" + }, + "type": "array", + "title": "Slot Options", + "description": "the candidate set each bound slot was chosen from, one entry per slot with a non-empty taxonomy; omits when/source and any slot with no observed or seeded values. spec_id does not depend on this field, so it never affects permalinks or dedup." + }, + "entity_options": { + "items": { + "$ref": "#/components/schemas/EntityOptions" + }, + "type": "array", + "title": "Entity Options", + "description": "candidate sets for directional origin or destination axes. An entry whose entity_ref is omitted describes an axis the role-bearing query left open; its role selects the identity.entities key for a resubmit, and the matching role_axis_facts entry reports that axis's member count. An entry with an entity_ref describes alternatives to a bound axis. Empty when the family has no directional entity-option concept. spec_id does not depend on this field." + }, + "facet_options": { + "items": { + "$ref": "#/components/schemas/FacetOptions" + }, + "type": "array", + "title": "Facet Options", + "description": "the candidate set each facet axis (provenance/measurementMethod/unit) was chosen from, one entry per axis with at least one value observed on the resolved candidates' unfiltered facets; an axis with no observed value is omitted, never an empty entry. Computed for every definite Spec and every candidate. Over SSE with response_options.include_option_coverage set, the entries arrive as trailing facet_options events and this list stays empty. Unlike slot_options, this has no bind-time baseline to fall back to. spec_id does not depend on this field." + }, + "rendered_sentence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Rendered Sentence", + "description": "the editable confirmation sentence for this spec, present on every Spec a part shows; None on an equivalent_readings entry. It holds the heading and the byline only (see SentenceToken.segment): 'Germany's gross ODA disbursements to Kenya, 1973 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).' It states what this Spec is and nothing about the request that produced it, so it reads the same after a dataset_resubmit and serves as the Spec's label. The part that carries this Spec states how it departs from the request (_PartBase.departures)" + }, + "sentence_plan": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/SentenceToken" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Sentence Plan", + "description": "the ordered token form of rendered_sentence, tying its tokens to definition parts; present under the same condition, None otherwise. Every token's segment is 'heading' or 'byline'" + }, + "trace": { + "$ref": "#/components/schemas/ResolutionTrace", + "description": "consolidated record of how the query was understood" + }, + "confidence": { + "anyOf": [ + { + "type": "string", + "enum": [ + "high", + "medium", + "low" + ] + }, + { + "type": "null" + } + ], + "title": "Confidence", + "description": "qualitative, relative retrieval confidence for this interpretation; None when not assessed. Bands are heuristic and may be retuned without a schema-version bump." + }, + "basis": { + "anyOf": [ + { + "type": "string", + "enum": [ + "structural", + "nominated", + "twin", + "direction" + ] + }, + { + "type": "null" + } + ], + "title": "Basis", + "description": "why the part offers this Spec as one of its candidates: 'structural', a reading that differs from the elected one only on a stat type, price basis or denominator the request leaves open; 'nominated', a reading the model named as a genuine reading of the request's phrase; 'twin', an equivalent reading of the elected one, offered where the elected one holds no data; 'direction', the same reading with the other direction for a place the request names without one, which a client shows as a direction prompt. The elected reading, listed first, carries none. None on a definite answer and on every Spec outside CandidateSet.specs." + }, + "available_at_place": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Available At Place", + "description": "whether this spec has lifetime availability at the resolved place, independent of the coverage window. True = confirmed at place; False = the variable matched but has no observation here (the flagged_match case); None = not assessed (no place entity, or a named family such as dev-finance). CoverageExact.has_data may be False for a requested window even when this field is True." + }, + "equivalent_readings": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/Spec" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Equivalent Readings", + "description": "other StatVar(s) confirmed to encode the same real-world indicator as this Spec. Each entry is a full Spec carrying identity and the material needed to re-resolve onto it: its definition.identity, spec_id, and resolved StatVar dcids provide everything ResubmitIdentityPayload requires. Its rendered_sentence, sentence_plan, facet_options, and observations come from re-resolving onto it on a dataset_resubmit identity entry, not from this response. This Spec's own answer stands on its own regardless. Switching to a named entry is optional, offered for its source vocabulary's own coverage. None when no such encoding is known. Never a member of BaseIdentity, never hashed, and never populated on its own entries in turn. An entry's own equivalent_readings is always empty." + }, + "skills": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Skills", + "description": "ids of the skills this Spec's bound graph nodes and selected provenance call for, matched against the shared skills index, most specific first: skills matched through a graph node by hop, then breadth, and skills matched only through the provenance last; present under the include_skills option. None = the request did not ask; [] = it asked and nothing matched." + }, + "alternative_measures": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/SpecAlternativeMeasure" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Alternative Measures", + "description": "every other measure this Spec could equally answer with -- either another populated partition from the same family as the one this Spec's own served rows exhibit (retrieval.bound_values.observed_measure_family), or a genuinely distinct also_plausible candidate whose only difference from this Spec is measured_property (measurement_denominator held equal), folded in here instead of left as a second candidates entry -- each with its own identity, a disambiguating label, and the axis of the sentence token whose menu offers it: 'what' entries are the measure switch beside measure_label below, 'unit' entries the price-basis options of the byline's unit token (binding_ref 'unit:'). A partition or folded candidate with no authored label is left out. None when this Spec's shape carries no measure family at all and no measure-sibling candidate was folded in, or its served rows span more than one partition; a served partition with every sibling unlabelled, or with none, still publishes []. Never a member of BaseIdentity, never hashed." + }, + "measure_label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Measure Label", + "description": "the readable label for the measure partition this Spec's own served rows exhibit, composed the same way as each 'what' alternative_measures entry's label: what a switch built from those entries would show as currently selected. It names no price basis ('gross disbursements', not 'gross disbursements (nominal)'). Current or constant prices belong to the unit, which the byline's unit token states. None under the same condition alternative_measures is None" + }, + "measure_label_axes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Measure Label Axes", + "description": "the declared measure-axis identifiers (code_index.types.MeasureAxis.axis, e.g. 'measuredProperty', 'measurementQualifier', or a constraint-property dcid such as a financial-flow-type or netting-basis axis) that measure_label was composed from. Every axis the served partition carries a value on is included here, whether or not its value appears in measure_label's own text. A renderer uses this to keep a bound how-slot sharing one of these property dcids from repeating what measure_label already said. Always [] when measure_label is None." + }, + "measure_axis_values": { + "items": { + "$ref": "#/components/schemas/MeasureAxisValue" + }, + "type": "array", + "title": "Measure Axis Values", + "description": "each axis in measure_label_axes with the value the served partition holds on it, in the same order, including values the query never named (a declared default such as Gross or Nominal). Labels come from the measure index. Always [] when measure_label is None. Never a member of BaseIdentity, never hashed." + }, + "related_group": { + "anyOf": [ + { + "$ref": "#/components/schemas/GraphRef" + }, + { + "type": "null" + } + ], + "description": "the StatVarGroup related_measures come from: the smallest group this Spec's one StatVar belongs to that holds 2 to 40 members, ties broken by group dcid. None when related_measures is None or []" + }, + "related_measures": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/RelatedMeasure" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Related Measures", + "description": "up to 5 other members of related_group with data at every place this Spec names (and in its requested years when it names a range), ordered by the years they share with this Spec's StatVar there, then by dcid. Only a definite Spec that serves exactly one StatVar, has no measure family (measure_label is None) and names places with no roles carries a list; [] when no group qualifies or no other member has data there. None for any other Spec, and when the graph reads failed or ran past their deadline. Never a member of BaseIdentity, never hashed." + }, + "open_axis_facts": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/OpenConstraintAxisFact" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Open Axis Facts", + "description": "one entry per constraint axis this Spec's own served StatVar members declare (an arc naming the property, resolved or not) that the query left unbound, each naming the axis's property and what those members exhibit on it: whether they agree on a value (varies=False) or differ (varies=True), and undeclared_count for how many declare none at all. None when this Spec's served members declare no constraint property the query left open at all. This is distinct from an open axis every member declares nothing for, which still publishes its own entry (varies=False, undeclared_count equal to the served member count). Never a member of BaseIdentity, never hashed." + }, + "role_axis_facts": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/RoleAxisFact" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Role Axis Facts", + "description": "one entry per directional role axis (origin/destination) this role-bearing Spec's query left open, naming the axis and the member population its own confirmation already resolved (see RoleAxisFact). None when this Spec is not role-bearing, or is role-bearing but every role axis its shape declares carries a bound entity. Never a member of BaseIdentity, never hashed." + }, + "unit_conversion": { + "anyOf": [ + { + "$ref": "#/components/schemas/UnitConversion" + }, + { + "type": "null" + } + ], + "description": "the currencies and price bases a unit request can convert this answer to. Null when the served members' unit is no currency, no conversion recipe converts them (a stock, a series not in nominal prices, or a provenance that declares no recipe), the recipe's tables lack the native currency's rate in a served year, so nothing converts, or no conversion catalogue is loaded, which the part's unit_conversion_unavailable warning states. Never a member of BaseIdentity, never hashed." + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "shape", + "slots", + "stat_vars", + "entities", + "coverage", + "trace" + ], + "title": "ResolvedSpec", + "description": "What the graph held at resolution time: the engine's report of what it\ndid with the ask. Meant for display and diagnostics, never hashed;\n`Spec.spec_id` depends only on `Spec.definition.identity`. Beside the\ncontract's own `resolved` member list (`stat_vars`, `inapplicable_slots`,\n`unresolved_slots`, `entities`, `coverage`, `headline`, `facets`, `observations`,\n`rendered_sentence`/`sentence_plan`, `slot_options`/`entity_options`,\n`trace`, `confidence`), this also carries the engine's own supersets\n(`shape`, `slots`, `available_at_place`) that slot_options/sentence_plan\njoin against and the eval harness scores." + }, + "ResolvedStatVars": { + "properties": { + "member_count": { + "type": "integer", + "title": "Member Count", + "description": "how many members are confirmed to carry observations at this resolve's own probe entities; see this model's own docstring for how this differs from resolved.shape.member_count" + }, + "member_count_exact": { + "type": "boolean", + "title": "Member Count Exact", + "description": "True when member_count is a true total; False when it is a floor -- the population being at least member_count large, not exactly member_count -- because it was measured over a capped recall sample, because the probe stopped once the answer's member was confirmed, or because it is a where-axis merge's max() of its members' own counts rather than a computed union. Defaults to True, correct for a caller that has not measured otherwise", + "default": true + }, + "served_count": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Served Count", + "description": "how many StatVars a Datasets mint of this Spec's definition serves, the length of its trace.resolved_stat_vars; 1 for a single series. Null when the membership is unsettled: Search answered from members the mint may not serve, and the part carries membership_unverified" + }, + "data_date_range": { + "anyOf": [ + { + "$ref": "#/components/schemas/DateRange" + }, + { + "type": "null" + } + ], + "description": "the earliest first date and latest last date of the points the answer's read plan serves over its StatVars; null when it serves none" + }, + "source_codes": { + "items": { + "$ref": "#/components/schemas/SourceCode" + }, + "type": "array", + "title": "Source Codes", + "description": "the publisher series codes of the StatVars the answer serves, sorted by provenance then code and without repeats; left out when no served StatVar has a code. They identify the series a publisher files these StatVars under, and the answer is the same with or without them. A code names the whole answer only where its entry is exact" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "member_count" + ], + "title": "ResolvedStatVars", + "description": "`resolved.stat_vars` on the wire: how many StatVars the answer holds, how many a\nDatasets mint of the Spec's definition serves, and the dates the answer serves over\nthem. The members themselves stay off the wire; `POST /api/datasets/{id}/members`\nlists the ones a mint serves.\n\nmember_count is the population confirmed to carry observations at this\nresolve's own probe entities, not resolved.shape.member_count's\nbindings-admitted population. The two differ for two reasons. A member the\nshape's bindings admit can carry no observation at the resolved place. And on\na role-bearing shape the answer reads one role class of the admitted members:\nwhere a total stands for its breakdowns the breakdowns are folded into it, so a\ndonor-only answer can state 255 admitted members beside 1 confirmed while every\none of the 255 holds data. On a standard (non-role-bearing) shape this population can itself\nbe a floor: the packaged code index does not source members for every\nshape family, so a shape outside it falls back to its recall sample, the\nmembers recall found, and member_count cannot exceed what that sample\nadmitted. An answer naming one member of a family too large for one read stops\nreading once that member is confirmed, so member_count counts the members read: \"latest\nlife expectancy data\" reads the family's total and not its other 350 members. A\nwhere-axis merge (same_shape.py, \"population\nof Kenya and Uganda\") publishes max() of its members' own member_count\nrather than the sum, since the same StatVar is typically confirmed at\nevery member's own place and summing would double-count the\nintersection -- max() is a true lower bound of the union. member_count_exact\nrecords which of these applies.\n\nserved_count is the mint's own count, a function of the definition alone: the\nStatVars a Datasets mint of `definition` serves, the length of its\n`trace.resolved_stat_vars`. It is stated whenever Search settled the membership the\nmint resolves: a family the code index decides, or a family the mint's member walk\nsettled for this definition. Null when Search answers from members it could not\nsettle, which the part flags with a `membership_unverified` warning." + }, + "ResubmitCandidate": { + "properties": { + "identity": { + "$ref": "#/components/schemas/BaseIdentity", + "description": "this candidate's complete identity" + }, + "entity_groups": { + "anyOf": [ + { + "additionalProperties": { + "$ref": "#/components/schemas/EntityGroup" + }, + "propertyNames": { + "enum": [ + "observationAbout", + "origin", + "destination" + ] + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Entity Groups", + "description": "the named group each role's entities were asked for as, keyed by entity role key. Post a prior Spec's resolved.entity_groups beside any identity derived from that Spec. A group is kept when it posts a dcid and the graph's members of that node are exactly the identity's entities on the role; any other group, including one on a role the identity binds no entity on, is dropped" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "identity" + ], + "title": "ResubmitCandidate", + "description": "One candidate identity within a `candidates` dataset_resubmit entry. The\nengine derives its StatVar members as it does for an identity entry." + }, + "ResubmitCandidatesEntry": { + "properties": { + "entry_kind": { + "type": "string", + "const": "candidates", + "title": "Entry Kind", + "description": "discriminator for a candidate-set dataset_resubmit entry", + "default": "candidates" + }, + "variable_text": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Variable Text", + "description": "this part's variable text, echoed back onto the rebuilt part" + }, + "ordering": { + "type": "string", + "enum": [ + "broadest_first", + "intent_rank" + ], + "title": "Ordering", + "description": "how `candidates` below was ordered when this set was first produced; echoed back verbatim onto the rebuilt candidates part, never recomputed" + }, + "truncated": { + "type": "boolean", + "title": "Truncated", + "description": "echoed back verbatim onto the rebuilt candidates part -- see CandidateSet.truncated for what this flags" + }, + "candidates": { + "items": { + "$ref": "#/components/schemas/ResubmitCandidate" + }, + "type": "array", + "maxItems": 50, + "minItems": 2, + "title": "Candidates", + "description": "the competing candidates to re-materialise, in posted order, always -- the rebuilt CandidateSet.specs preserves this exact order. Refused request_invalid, at the engine rather than here, when the posted count exceeds this deployment's own ceiling -- readable in advance as caps.max_candidates from GET /api/search/capabilities" + }, + "separate": { + "type": "boolean", + "title": "Separate", + "description": "true when this part is asked beside the others to be compared with them; it is kept apart from same-shape sibling parts. False, the default, folds parts that share a shape into one set answer", + "default": false + }, + "operations": { + "items": { + "$ref": "#/components/schemas/Operation" + }, + "type": "array", + "maxItems": 8, + "title": "Operations", + "description": "the operations the question asks for over this part's data, in query order; the engine echoes them onto the part it resolves. Empty when the question asks for none" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "variable_text", + "ordering", + "truncated", + "candidates" + ], + "title": "ResubmitCandidatesEntry", + "description": "One part re-materialised from a posted set of competing candidate\nidentities, through the promote path, in posted order, always. `ordering`\nnames the display rule this set already used, restated rather than\nrecomputed: the order rests on the bind model's election and the availability\nreads of the first answer, which do not round-trip -- see `Ordering` and\n`outcomes.CandidateSet`. This entry carries no\n`max_candidates` field: `CandidateSet.max_candidates` on the response is\nnot posted back and is always server-computed, never client-supplied." + }, + "ResubmitIdentityEntry": { + "properties": { + "entry_kind": { + "type": "string", + "const": "identity", + "title": "Entry Kind", + "description": "discriminator for a single-identity dataset_resubmit entry", + "default": "identity" + }, + "variable_text": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Variable Text", + "description": "this part's variable text, echoed back onto the rebuilt part" + }, + "identity": { + "$ref": "#/components/schemas/BaseIdentity", + "description": "the complete identity. Post a prior Spec.definition.identity byte-for-byte for a no-op resubmit; change nested members, including entities.origin or entities.destination, to edit that definition" + }, + "entity_groups": { + "anyOf": [ + { + "additionalProperties": { + "$ref": "#/components/schemas/EntityGroup" + }, + "propertyNames": { + "enum": [ + "observationAbout", + "origin", + "destination" + ] + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Entity Groups", + "description": "the named group each role's entities were asked for as, keyed by entity role key. Post a prior Spec's resolved.entity_groups beside any identity derived from that Spec. A group is kept when it posts a dcid and the graph's members of that node are exactly the identity's entities on the role; any other group, including one on a role the identity binds no entity on, is dropped" + }, + "separate": { + "type": "boolean", + "title": "Separate", + "description": "true when this part is asked beside the others to be compared with them; it is kept apart from same-shape sibling parts. False, the default, folds parts that share a shape into one set answer", + "default": false + }, + "operations": { + "items": { + "$ref": "#/components/schemas/Operation" + }, + "type": "array", + "maxItems": 8, + "title": "Operations", + "description": "the operations the question asks for over this part's data, in query order; the engine echoes them onto the part it resolves. Empty when the question asks for none" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "variable_text", + "identity" + ], + "title": "ResubmitIdentityEntry", + "description": "One part re-resolved from a single identity -- the payload\n`ResubmitIdentityPayload` carries, plus the text echo and operations every\ndataset_resubmit entry needs." + }, + "ResubmitParsedEntry": { + "properties": { + "entry_kind": { + "type": "string", + "const": "parsed", + "title": "Entry Kind", + "description": "discriminator for a re-parsed dataset_resubmit entry", + "default": "parsed" + }, + "part": { + "$ref": "#/components/schemas/ParsedPart", + "description": "this part's resolution inputs -- normally a prior response part's own Part.restatement, posted back verbatim or edited, and resolved through the same per-part machinery the parsed door uses" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "part" + ], + "title": "ResubmitParsedEntry", + "description": "One part genuinely re-resolved through the parsed door's own per-part\npath, from a client-edited restatement of a sibling's own resolution\ninputs (`Part.restatement`) -- re-parsed, where `placeholder` only\nrestates a stub. `part` already carries a required `variable_text` and\nits own `operations`, so this entry needs no separate top-level echo\nfields the way the other three kinds do. Costs one LLM bind per edit, the\ndoor's one entry kind that touches the LLM client at all." + }, + "ResubmitPlaceholderEntry": { + "properties": { + "entry_kind": { + "type": "string", + "const": "placeholder", + "title": "Entry Kind", + "description": "discriminator for a stub dataset_resubmit entry", + "default": "placeholder" + }, + "variable_text": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Variable Text", + "description": "this part's variable text, echoed back onto the rebuilt part" + }, + "status": { + "type": "string", + "enum": [ + "no_data", + "unsupported" + ], + "title": "Status", + "description": "which stub outcome to restate for this part" + }, + "reason": { + "anyOf": [ + { + "type": "string", + "enum": [ + "source_not_resolved", + "source_ambiguous", + "source_code_not_held", + "source_code_ambiguous", + "source_code_shares_variable", + "entity_not_resolved", + "entity_ambiguous", + "entity_set_too_large", + "entity_role_not_admitted", + "variable_not_resolved", + "role_not_resolved", + "unit_not_resolved", + "rate_coverage_gap", + "no_matching_slice", + "binding_mismatch", + "denominator_not_available", + "no_observations", + "facet_not_available", + "role_incompatible", + "role_signature_incompatible", + "qualifier_not_bound" + ] + }, + { + "type": "null" + } + ], + "title": "Reason", + "description": "the NoData.reason to restate onto the rebuilt part; required when status is no_data, refused when status is unsupported" + }, + "code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Code", + "description": "the reason, a code from the platform registry, to restate onto the rebuilt part's Unsupported.code; required when status is unsupported, refused when status is no_data" + }, + "separate": { + "type": "boolean", + "title": "Separate", + "description": "true when this part is asked beside the others to be compared with them; it is kept apart from same-shape sibling parts. False, the default, folds parts that share a shape into one set answer", + "default": false + }, + "operations": { + "items": { + "$ref": "#/components/schemas/Operation" + }, + "type": "array", + "maxItems": 8, + "title": "Operations", + "description": "the operations the question asks for over this part's data, in query order; the engine echoes them onto the part it resolves. Empty when the question asks for none" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "variable_text", + "status" + ], + "title": "ResubmitPlaceholderEntry", + "description": "One part restated as a stub from a no_data/unsupported outcome the\nclient already holds -- zero graph round-trips, zero LLM calls. Carried\nforward unresolved so its sibling parts' composed sentence and fold can\nstill be computed across the whole dataset; the engine stamps a\npart-scoped `part_restated` info warning on the rebuilt part." + }, + "RoleAxis": { + "type": "string", + "enum": [ + "origin", + "destination" + ] + }, + "RoleAxisFact": { + "properties": { + "role": { + "$ref": "#/components/schemas/RoleAxis", + "description": "which flow axis this fact is about" + }, + "member_count": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Member Count", + "description": "how many entities this axis' open scope resolves to. None when the count could not be established without a read this response chose not to make (e.g. a discovered opposite axis whose own role index was omitted after a cap trip); the fact still publishes in that case, naming the axis as open with an explicit unknown rather than staying silent about it" + }, + "members_available": { + "type": "boolean", + "title": "Members Available", + "description": "whether the member list this count summarises is itself known and could be enumerated (e.g. through entity_options or the options door), not just counted. False exactly when member_count is None" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "role", + "member_count", + "members_available" + ], + "title": "RoleAxisFact", + "description": "One directional role axis (origin or destination) a role-bearing\nSpec's query left open, and what this Spec's own confirmation already\nknows about its member scope (see ResolvedSpec.role_axis_facts).\n\nUnlike OpenConstraintAxisFact, a role axis has no declared value of its\nown that could vary across served members -- the axis is a place a flow\nentity binds, not a constraint members assert -- so this carries no\nvaries/undeclared_count of its own; it carries only what a role axis\ngenuinely has: a population size and whether that population is known." + }, + "RootEntry": { + "properties": { + "ref": { + "type": "string", + "title": "Ref" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label" + }, + "count": { + "type": "integer", + "title": "Count", + "description": "codes for a code system, members under the default projection for a group or region, Datasets for a source" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "count" + ], + "title": "GraphRootEntry", + "description": "A place to start listing from, with the length of its list." + }, + "Roots": { + "properties": { + "code_systems": { + "items": { + "$ref": "#/components/schemas/RootEntry" + }, + "type": "array", + "title": "Code Systems" + }, + "groups": { + "items": { + "$ref": "#/components/schemas/RootEntry" + }, + "type": "array", + "title": "Groups" + }, + "regions": { + "items": { + "$ref": "#/components/schemas/RootEntry" + }, + "type": "array", + "title": "Regions" + }, + "sources": { + "items": { + "$ref": "#/components/schemas/RootEntry" + }, + "type": "array", + "title": "Sources" + }, + "built_from": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "code_index", + "origin_catalogue", + "coverage_index", + "membership" + ] + }, + "type": "object", + "title": "Built From", + "description": "the build of each table the document read" + } + }, + "type": "object", + "required": [ + "code_systems", + "groups", + "regions", + "sources", + "built_from" + ], + "title": "GraphRoots", + "description": "`GET /api/graph/roots`: where to start listing. Each list is ordered by dcid." + }, + "Scope-Input": { + "properties": { + "window": { + "anyOf": [ + { + "oneOf": [ + { + "$ref": "#/components/schemas/WindowAll" + }, + { + "$ref": "#/components/schemas/WindowLatest" + }, + { + "$ref": "#/components/schemas/WindowRange" + } + ], + "discriminator": { + "propertyName": "kind", + "mapping": { + "all": "#/components/schemas/WindowAll", + "latest": "#/components/schemas/WindowLatest", + "range": "#/components/schemas/WindowRange" + } + } + }, + { + "type": "null" + } + ], + "title": "Window" + }, + "entities": { + "anyOf": [ + { + "additionalProperties": { + "items": { + "type": "string" + }, + "type": "array" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Entities" + }, + "facets": { + "anyOf": [ + { + "additionalProperties": { + "oneOf": [ + { + "$ref": "#/components/schemas/FacetRefBinding" + }, + { + "oneOf": [ + { + "$ref": "#/components/schemas/UnitCurrentPricesRequestBinding" + }, + { + "$ref": "#/components/schemas/UnitConstantPricesRequestBinding" + } + ], + "discriminator": { + "propertyName": "prices", + "mapping": { + "constant": "#/components/schemas/UnitConstantPricesRequestBinding", + "current": "#/components/schemas/UnitCurrentPricesRequestBinding" + } + } + }, + { + "$ref": "#/components/schemas/FacetNationalCurrencyBinding" + } + ] + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Facets" + } + }, + "additionalProperties": false, + "type": "object", + "title": "Scope", + "description": "The `scope` block a mint request may carry: an omitted member means\nunbound (everything). `window` narrows the result to `all`, `latest`,\nor a `start_year`/`end_year` range. `entities` binds role names to\nnon-empty lists of dcids (a role's values must each be non-empty and\nmust not contain `+` or `,`). `facets` binds a known axis\n(`provenance`, `measurementMethod`, `unit`) to a specific ref, or\n`measurementMethod` or `unit` to a null ref. The `unit` axis alone may\ninstead carry a conversion request (`FacetUnitRequestBinding`) or ask for\neach entity's own currency (`FacetNationalCurrencyBinding`)." + }, + "Scope-Output": { + "properties": { + "place": { + "anyOf": [ + { + "$ref": "#/components/schemas/GraphRef" + }, + { + "type": "null" + } + ], + "description": "the country the question named, when the engine confirmed it as a country; null when the question named no place or named one that is not a confirmed country" + } + }, + "additionalProperties": false, + "type": "object", + "title": "AnswerScope", + "description": "What a catalogue or declined answer was scoped to. Titled apart from the\ndatasets API's own `Scope`, which the composed app's OpenAPI also publishes." + }, + "ScopeAndUnits": { + "properties": { + "countries": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Countries" + }, + "years_covered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Years Covered" + }, + "granularity": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Granularity" + }, + "currencies": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Currencies" + } + }, + "type": "object", + "required": [ + "countries", + "years_covered", + "granularity", + "currencies" + ], + "title": "ScopeAndUnits", + "description": "`countries` is always `[]`. `years_covered` is filled where the graph\nhas it. `currencies` lists every currency unit the coverage index gives the\nsource's Provenances, sorted, and `granularity` is filled where it gives\none period and axis pair for the source." + }, + "SentenceToken": { + "properties": { + "kind": { + "type": "string", + "enum": [ + "text", + "slot" + ], + "title": "Kind", + "description": "'text' is invariant wording: a connective carrying its own surrounding whitespace (' for ', ' to '), a possessive suffix (\"'s\"), a bare ' '/', ' separator, the terminal '.', or a departure sentence; 'slot' is a slot- or entity-bound phrase, or on an entity_ambiguous no_data plan the ambiguous wording itself, which a client hangs the candidate menu on. A client that does not recognise a kind should render its text as plain text regardless." + }, + "text": { + "type": "string", + "title": "Text", + "description": "the rendered text for this token; empty string for a slot with nothing bound" + }, + "axis": { + "anyOf": [ + { + "type": "string", + "enum": [ + "what", + "how", + "where", + "when", + "source", + "unit", + "method" + ] + }, + { + "type": "null" + } + ], + "title": "Axis", + "description": "the grammatical axis this token fills, when kind=='slot': one of the request-slot axes, 'unit' for the byline's unit of measure, or 'method' for the byline's measurement method, which no request slot carries. The unit token's binding_ref is 'unit:', and its options are the Spec's resolved.alternative_measures entries with axis 'unit': the price-basis siblings (current and constant prices) where the graph holds both. The method token appears only when the identity binds measurementMethod (a ref, a null ref, or a set), after the source token; its binding_ref is 'method:', its text the bound method's label without a trailing full stop or 'No stated method' for a null ref, and its options the Spec's facet_options entry with axis 'measurementMethod'" + }, + "segment": { + "type": "string", + "enum": [ + "heading", + "byline", + "departure" + ], + "title": "Segment", + "description": "the part of the sentence this token belongs to: 'heading' (what the answer is), 'byline' (latest-year label, unit, source, and a bound method), or 'departure' (the text of one Departure on the same part, never on a Spec's own plan). A client styles each segment as a block; the plain join of every token's text still equals rendered_sentence", + "default": "heading" + }, + "property_dcid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Property Dcid", + "description": "the constraint property dcid this token renders, when one exists; null or omitted for property-less axes (when/source), for a shape-label fallback phrase with no backing slot, and for entity-role tokens with no backing where slot. Set on a 'destination' entity-role token when the shape declares a where slot backing that axis (e.g. dev-finance)." + }, + "role": { + "anyOf": [ + { + "$ref": "#/components/schemas/RoleAxis" + }, + { + "type": "null" + } + ], + "description": "origin/destination when this token renders a directional entity role (the flow's two endpoints read back), or the directional scope an unbound where slot resolved to. entity_refs is the discriminator: non-empty on the entity read-back, empty on the unbound-where-slot fallback. binding_ref is not: an entity read-back carries binding_ref too whenever the shape declares a where slot backing the 'destination' axis (e.g. dev-finance), the same condition under which the unbound-where-slot fallback always carries it, so a present binding_ref value never separates the two. Both kinds join to the Spec.resolved.entity_options entry on the same role. A third token sits on an entity_ambiguous no_data plan, which has no Spec: the ambiguous wording, with the role the request gave it (null when it gave none), no entity_refs and no binding_ref, and text equal to one NoData.ambiguous_entities[i].text on the same part. The client titles that wording's candidate menu by this role and pins the pick into NoData.data_query." + }, + "binding_ref": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Binding Ref", + "description": "join key correlating this token to its Spec.resolved.slots / SlotOptions entry: 'axis:property_dcid', i.e. SlotKey.as_ref() (matching Slot.key and SlotOptions.key). Set for a slot-backed token, and also for a 'destination' entity-role token when the shape declares a where slot backing that axis (e.g. dev-finance) -- see entity_refs for the entity side of that token. The byline's unit token carries 'unit:', which no slot backs; its options are the resolved.alternative_measures entries with axis 'unit'. The byline's method token carries 'method:', which no slot backs either. Null or omitted for plain connective text, a shape-label fallback phrase with no backing slot, and 'origin'/unbacked-'destination' entity-role tokens." + }, + "entity_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Entity Refs", + "description": "entity dcids this token renders, set on the entity read-back, one of the two token kinds role marks (see role's own docstring for the other, the unbound-where-slot fallback, which leaves entity_refs empty even though it too carries role) -- a directional entity read-back has no Spec.resolved.slots entry of its own, though a 'destination' token may additionally carry binding_ref when a backing where slot exists (e.g. dev-finance); one dcid per entity in the token's group, in the same order as the entities joined into this token's text -- e.g. a 'destination' token reading 'Ethiopia, Kenya, and Uganda' carries all three dcids, so a client can tell a 3-entity answer from a 1-entity one without parsing rendered text. Empty when role is unset, and this emptiness, not binding_ref, is the join rule that separates the two role-bearing kinds." + }, + "states": { + "items": { + "type": "string" + }, + "type": "array", + "title": "States", + "description": "the refs a heading or byline slot token states, so a client edits each from this token: its own binding_ref, then each binding the renderer left silent because this token's text already says it. Refs read as binding_ref does ('how:crsTypeOfFlow', 'where:', 'origin:', 'unit:'), plus 'axis:' for a measure axis no slot carries ('axis:nettingBasis'). The measure noun states the measure axes its label or authored noun carries, the how values it names, and the agreed open axes beside it; a StatVar name or graph name states the how values it folds. The byline's unit token states 'unit:' and, when it names a price basis, the measurementQualifier axis. The byline's source token states 'source:', which is also its binding_ref where the answer binds a source slot. The byline's method token states 'method:', its binding_ref, and while the identity binds no method no token states 'method:'. Empty on a token with empty text, on text tokens, and outside heading and byline slot tokens. Within one part, no ref appears on two tokens with text. A bound slot, an unbound slot with options, or a role that no token states is stated nowhere in the sentence (a boolean member, an adjectival fold dropped whole, an open role with no count), and a client offers it apart from the sentence with its current value. On the envelope plan a token with no part_index states its refs for every part it stands for" + }, + "distinguishes": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Distinguishes", + "description": "true when this token's text differs from the same-bucket text on another candidate in the same CandidateSet; null or omitted on every other token, including every token on a Spec rendered outside a candidate set" + }, + "part_index": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Part Index", + "description": "this token's position in Resolution.parts, when this plan is the envelope-level composed sentence (Resolution.sentence_plan) and this token belongs to exactly one part's own contribution -- a variable phrase token, or a qualifier attached to it because it did not agree across every part, or a token of a part composed as its own sentence. Null carries three distinct readings a client must not conflate: on a part's own plan (DefinitePart.spec.resolved.sentence_plan, or the candidates/no_data/unsupported sentence_plan on _PartBase) the field has no meaning at all and is never set; on a composer-minted connective, it means the token belongs to the sentence as a whole rather than to any one part (the Oxford-joined ' and '/', ', the plan's own terminal '.', and the shared ' ' the per-part fallback puts between two sentences are all such tokens); and on a token every contributing part states alike and the join states once (a hoisted qualifier on the where, when, or source axis, each a wire value of axis, or the origin role, identified by role=='origin' instead since SentenceAxis has no 'origin' member; a shared possessive lead; the shared byline; or a heading or byline token of a part a later part folded into, binding_folded, which both parts state) it means the token no longer describes a single variable." + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind", + "text" + ], + "title": "SentenceToken", + "description": "One token in the ordered sentence plan: a \"text\" token (invariant\nwording such as a connective, a bare separator, the terminal period, or a\ndeparture sentence) or a \"slot\" token (a slot- or entity-bound phrase, or\nthe wording of an ambiguous entity).\n\n``rendered_sentence`` (the flat string) is the plain concatenation of every\ntoken's ``text``, in order. The two are computed together and cannot drift.\nA \"slot\" token with nothing bound appears too, with ``text=\"\"``: the same\ntoken structure serves a loading skeleton (before binding is known) and the\nfinal sentence (after it is). The first non-empty token's text is\ncapitalised.\n\nEvery token belongs to one ``segment``. The heading states what the answer\nis: actor, measure noun, counterpart, and period, in possessive order, one\nslot token per axis (\"Germany's gross ODA disbursements to Kenya, 1973 to\n2024\"). A unit that changes the magnitude (per capita, percent of GDP, PPP\ninternational dollars) stays in the heading. The byline follows it: the\nlatest-year label when one applies, the plain unit with its price basis\n(\"current US dollars\", \"constant 2022 US dollars\") as a slot token with\naxis \"unit\", the source, and, when the identity binds measurementMethod, the\nmethod as a slot token with axis \"method\". Departures come last and sit only on a part's or\nthe envelope's sentence, so ``spec.resolved.sentence_plan`` carries none." + }, + "Series": { + "properties": { + "measurement_method": { + "anyOf": [ + { + "$ref": "#/components/schemas/NodeRef" + }, + { + "type": "null" + } + ], + "description": "null when no facet states a method: no stated method" + }, + "observation_period": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Observation Period" + }, + "scaling": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scaling" + }, + "first_year": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "First Year" + }, + "last_year": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Year" + }, + "places": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Places", + "description": "null for a role-bearing variable" + }, + "observations": { + "type": "integer", + "title": "Observations" + }, + "units": { + "$ref": "#/components/schemas/UnitsFold" + }, + "binding": { + "$ref": "#/components/schemas/Binding" + } + }, + "type": "object", + "required": [ + "measurement_method", + "observation_period", + "scaling", + "first_year", + "last_year", + "places", + "observations", + "units", + "binding" + ], + "title": "GraphAvailabilitySeries", + "description": "A source's facets sharing a measurement method, period and scaling." + }, + "SeriesAxisRef": { + "properties": { + "property": { + "type": "string", + "title": "Property", + "description": "the constraint property's dcid, e.g. 'crsPurpose'" + }, + "ref": { + "type": "string", + "title": "Ref", + "description": "the dcid of the value the StatVar holds on property" + }, + "label": { + "type": "string", + "title": "Label", + "description": "display label for ref: its graph label, else the dcid's tail split into lower-case words" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "property", + "ref", + "label" + ], + "title": "SeriesAxisRef", + "description": "One constraint of a series' StatVar (see ObservationSeries.axes)." + }, + "SeriesConversionFallbackExample": { + "properties": { + "entity": { + "type": "string", + "title": "Entity", + "description": "the entity dcid absent from the deflator table" + }, + "fallback_entity": { + "type": "string", + "title": "Fallback Entity", + "description": "the recipe's fallback entity substituted for it" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "entity", + "fallback_entity" + ], + "title": "SeriesConversionFallbackExample", + "description": "One entity a converted series' recipe substituted with its own\nfallback entity, because the substituted entity carried no row at all\nin the deflator table (see ObservationSeriesConversion.fallback_examples)." + }, + "SeriesEntityRef": { + "properties": { + "role": { + "type": "string", + "enum": [ + "observationAbout", + "origin", + "destination" + ], + "title": "Role", + "description": "observationAbout, origin, or destination" + }, + "ref": { + "type": "string", + "title": "Ref", + "description": "the entity's dcid" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "best-effort display label for ref; None when unresolved, never fabricated" + }, + "party_kind": { + "anyOf": [ + { + "type": "string", + "enum": [ + "party", + "total", + "residual" + ] + }, + { + "type": "null" + } + ], + "title": "Party Kind", + "description": "on an origin or destination entity, what the party is beside the others on its side: 'party' (a country, territory or organisation), 'total' (other parties' figures, so a sum across the role that counts it counts its members twice) or 'residual' (figures no other party holds), as the code index lists it. Absent for a party the index does not list, and on observationAbout" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "role", + "ref" + ], + "title": "SeriesEntityRef", + "description": "One entity in a series' role tuple (see ObservationSeries.entities)." + }, + "SeriesFacetRef": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the facet's dcid for this axis" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "best-effort display label for ref; None when unresolved, never fabricated" + }, + "source": { + "anyOf": [ + { + "$ref": "#/components/schemas/SourceRef" + }, + { + "type": "null" + } + ], + "description": "provenance axis only: the organisation behind the provenance, from the origin catalogue; absent for a provenance the catalogue does not list" + }, + "data_commons": { + "anyOf": [ + { + "$ref": "#/components/schemas/search__models__grammar__DataCommonsRef" + }, + { + "type": "null" + } + ], + "description": "provenance axis only: the Data Commons the provenance's data comes from; absent for a provenance the catalogue does not list" + }, + "documentation": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Documentation", + "description": "provenance axis only: the Graph API route of the provenance's document, GET /api/graph/documentation/{dcid}" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref" + ], + "title": "SeriesFacetRef", + "description": "One axis's value on a single series' selected observation facet (see\nObservationSeries.facet)." + }, + "SeriesStatVarRef": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the StatVar dcid these points observe" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "a row's own distinguishing label: composed from ref's own constraint values when it has any beyond its shape's shared five-tuple, else ref's plain resolved display name; None when unresolved, never fabricated" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref" + ], + "title": "SeriesStatVarRef", + "description": "A series' StatVar identity ({ref, label} -- mirrors SeriesFacetRef's shape)." + }, + "ServedMember": { + "properties": { + "ref": { + "type": "string", + "pattern": "^dcid:", + "title": "Ref" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label" + }, + "roles": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Roles" + }, + "constraints": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "type": "object", + "title": "Constraints" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref", + "label", + "roles", + "constraints" + ], + "title": "ServedMember", + "description": "One StatVar a definition serves: its `dcid:`-prefixed `ref`, as the manifest trace's\n`resolved_stat_vars` names it, its graph `label` (`null` when the graph holds none), the\n`roles` it declares, and its `constraints`, each constraint property with its value\n(`null` when the StatVar leaves it unbound)." + }, + "Shape": { + "properties": { + "shape_id": { + "type": "string", + "title": "Shape Id", + "description": "stable id of this structural family" + }, + "label": { + "type": "string", + "title": "Label", + "description": "plain-language name of what the reading serves: a composed measure label, the served series' name, or the family's name" + }, + "population_type": { + "anyOf": [ + { + "$ref": "#/components/schemas/GraphRef" + }, + { + "type": "null" + } + ], + "description": "the graph populationType; None when the StatVar does not assert it (custom-DC imports may omit any five-tuple arc)" + }, + "measured_property": { + "anyOf": [ + { + "$ref": "#/components/schemas/GraphRef" + }, + { + "type": "null" + } + ], + "description": "the graph measuredProperty; None when the StatVar does not assert it (custom-DC imports may omit any five-tuple arc)" + }, + "stat_type": { + "anyOf": [ + { + "$ref": "#/components/schemas/GraphRef" + }, + { + "type": "null" + } + ], + "description": "the graph statType, e.g. measuredValue; None when the StatVar does not assert it (custom-DC imports may omit any five-tuple arc)" + }, + "measurement_qualifier": { + "anyOf": [ + { + "$ref": "#/components/schemas/GraphRef" + }, + { + "type": "null" + } + ], + "description": "structural anchor; present only when the measured property is qualified" + }, + "measurement_denominator": { + "anyOf": [ + { + "$ref": "#/components/schemas/GraphRef" + }, + { + "type": "null" + } + ], + "description": "a structural anchor, present only on a ratio or per-capita measure. Holds the measurementDenominator arc's target dcid for a resolved StatVar or for a dangling target that itself carries a dcid. Is None both when no denominator arc exists at all and when the arc's target carries no dcid. A null value here does not by itself establish that no denominator arc exists. Read measurement_denominator_unresolved alongside it to tell the two apart" + }, + "measurement_denominator_unresolved": { + "type": "boolean", + "title": "Measurement Denominator Unresolved", + "description": "true when the measurementDenominator arc is present and its target is a ProvisionalNode the graph defines no real StatVar for, whether or not that target carries a dcid. False when no denominator arc exists at all, or when the arc names a confirmed StatVar. A client should read this flag before trusting measurement_denominator on its own. A null ref is consistent with either no arc (this flag false) or a dcid-less dangling target (this flag true), and a populated ref is consistent with either a confirmed StatVar (this flag false) or a dcid-bearing dangling target (this flag true)", + "default": false + }, + "slot_keys": { + "items": { + "$ref": "#/components/schemas/SlotKey" + }, + "type": "array", + "title": "Slot Keys", + "description": "the constraint and facet slots this family exposes, in display order" + }, + "member_count": { + "type": "integer", + "title": "Member Count", + "description": "the size of the resolved population behind this response: how many StatVars the shape's current bindings admit, narrowing as a slot binds and widening again as one is cleared" + }, + "member_digest": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Member Digest", + "description": "lowercase sha256 hex of the RFC 8785 (JCS) canonical JSON of the sorted list of bare dcids (no 'dcid:' prefix) of the family a Datasets mint of this Spec's definition resolves, the mint's trace.family_member_digest: every row of the family the code index resolves, or every member the mint's member walk confirms when it read every candidate. Null when Search did not settle that family for this definition, and when its walk proved the members from a window it did not read to the end, so it cannot name every member of the family" + }, + "refine_supported": { + "type": "boolean", + "title": "Refine Supported", + "description": "true unless the shape's StatVar(s) are ratio-backed (with _AsAFractionOf_ tokens), which construct-and-confirm sibling StatVars cannot refine", + "default": false + }, + "data_commons": { + "items": { + "$ref": "#/components/schemas/search__models__grammar__DataCommonsRef" + }, + "type": "array", + "title": "Data Commons", + "description": "every Data Commons holding admitted data for a member StatVar, in the order dfo, base, un_system; a Data Commons by Google variable lists dfo as well when the Observatory's own imports hold it. Empty when the engine derived the shape without its members" + }, + "upstream": { + "anyOf": [ + { + "$ref": "#/components/schemas/ShapeUpstream" + }, + { + "type": "null" + } + ], + "description": "the one source and Data Commons every member's data comes through, present only for a shape outside the Observatory's own imports whose members the origin catalogue places under exactly one source" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "shape_id", + "label", + "slot_keys", + "member_count" + ], + "title": "Shape", + "description": "The structural family chosen for the query." + }, + "ShapeUpstream": { + "properties": { + "source": { + "$ref": "#/components/schemas/SourceRef", + "description": "the organisation behind every member's data" + }, + "data_commons": { + "$ref": "#/components/schemas/search__models__grammar__DataCommonsRef", + "description": "the Data Commons serving that data" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source", + "data_commons" + ], + "title": "ShapeUpstream", + "description": "The one source, and the Data Commons serving it, behind every member of\nan upstream shape." + }, + "SimpleUnit": { + "properties": { + "ref": { + "type": "string", + "maxLength": 512, + "minLength": 1, + "title": "Ref" + }, + "currency": { + "type": "string", + "pattern": "^[A-Z]{3}$", + "title": "Currency" + }, + "label": { + "type": "string", + "maxLength": 512, + "minLength": 1, + "title": "Label" + }, + "at_mint": { + "type": "boolean", + "const": true, + "title": "At Mint" + }, + "prices": { + "type": "string", + "enum": [ + "current", + "constant" + ], + "title": "Prices" + }, + "base_year": { + "type": "integer", + "maximum": 2100.0, + "minimum": 1900.0, + "title": "Base Year" + } + }, + "additionalProperties": false, + "type": "object", + "title": "SimpleUnit", + "description": "A unit by reference, by currency, or both, with optional words.\n\n`ref` is the unit's dcid. `currency` is an ISO 4217 code, which a converted unit\n`{currency, prices, base_year}` names in place of a dcid. `prices` says whether money is\nin `current` or `constant` prices, and `base_year` names the year constant prices are\nexpressed in; it is present exactly when prices are constant." + }, + "Skill": { + "properties": { + "id": { + "type": "string", + "title": "Id", + "description": "the skill's stable id; the key this entry is filed under" + }, + "name": { + "type": "string", + "title": "Name", + "description": "the skill's declared name" + }, + "description": { + "type": "string", + "title": "Description", + "description": "the skill's declared description" + }, + "content_version": { + "type": "string", + "title": "Content Version", + "description": "sha256: over the skill's manifest, SKILL.md then its references in path order, so any edit to any file in the bundle changes it" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "name", + "description", + "content_version" + ], + "title": "Skill", + "description": "One skill's front matter on the wire, keyed by id in\nResolution.skills. Mirrors skills_index.SkillFrontMatter's four\nmembers -- the search API's own wire model, not that dataclass itself,\nso it carries its own field descriptions the way every other response\nmodel does." + }, + "SkillBody": { + "properties": { + "id": { + "type": "string", + "title": "Id", + "description": "the skill's id, its dcid without the `skill/` prefix" + }, + "name": { + "type": "string", + "title": "Name", + "description": "the front matter's `name`, equal to `id`" + }, + "description": { + "type": "string", + "title": "Description", + "description": "the front matter's `description`" + }, + "frontmatter": { + "additionalProperties": { + "$ref": "#/components/schemas/FrontMatterValue" + }, + "type": "object", + "title": "Frontmatter", + "description": "the whole parsed front matter, every scalar a string" + }, + "content_version": { + "type": "string", + "title": "Content Version", + "description": "`sha256:` digest over the manifest's paths and digests, in order" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Url", + "description": "the skill's source directory for a human reader, never fetched here" + }, + "attached": { + "type": "boolean", + "title": "Attached", + "description": "true when the skill's reach names at least one node on this build, so search can name it" + }, + "excluded": { + "type": "boolean", + "title": "Excluded", + "description": "true when search cannot match this skill on this build: its reach broke a bound or a read the build depended on did not complete" + }, + "statvar_count": { + "type": "integer", + "title": "Statvar Count", + "description": "the distinct StatVars this skill's downward reach carries. A provenance attachment adds nothing to the count, so a skill attached only to provenances reports 0 while covering every series of those datasets" + }, + "statvar_count_truncated": { + "type": "boolean", + "title": "Statvar Count Truncated", + "description": "true when statvar_count stopped at this deployment's count bound rather than exhausting the reach" + }, + "warnings": { + "items": { + "$ref": "#/components/schemas/SkillWarning" + }, + "type": "array", + "title": "Warnings", + "description": "this skill's own warnings" + }, + "resources": { + "items": { + "$ref": "#/components/schemas/SkillFileListing" + }, + "type": "array", + "title": "Resources", + "description": "the skill's manifest: `SKILL.md` first, then its references in path order" + }, + "content_text": { + "type": "string", + "title": "Content Text", + "description": "`SKILL.md` verbatim, front matter included" + } + }, + "type": "object", + "required": [ + "id", + "name", + "description", + "frontmatter", + "content_version", + "url", + "attached", + "excluded", + "statvar_count", + "statvar_count_truncated", + "warnings", + "resources", + "content_text" + ], + "title": "SkillBody", + "description": "The skill door's response: the list entry plus the skill's text." + }, + "SkillFileListing": { + "properties": { + "path": { + "type": "string", + "title": "Path", + "description": "the file's path, relative to its skill's own bundle" + }, + "size": { + "type": "integer", + "title": "Size", + "description": "the byte size of the file's UTF-8 content" + }, + "digest": { + "type": "string", + "title": "Digest", + "description": "`sha256:` plus the lower-case hex SHA-256 of that content" + }, + "media_type": { + "type": "string", + "title": "Media Type", + "description": "the file's media type, from its extension" + } + }, + "type": "object", + "required": [ + "path", + "size", + "digest", + "media_type" + ], + "title": "SkillFileListing", + "description": "One file in a skill's manifest. The client fetches it at the resources door\nby the skill id and this `path`." + }, + "SkillListResponse": { + "properties": { + "skills": { + "items": { + "$ref": "#/components/schemas/SkillSummary" + }, + "type": "array", + "title": "Skills", + "description": "every served skill, ordered by id" + }, + "warnings": { + "items": { + "$ref": "#/components/schemas/SkillWarning" + }, + "type": "array", + "title": "Warnings", + "description": "corpus warnings, including one per skill left out of the catalogue" + } + }, + "type": "object", + "required": [ + "skills", + "warnings" + ], + "title": "SkillListResponse", + "description": "`GET /api/skills`'s response body: every served skill's entry, ordered by\nid, plus the corpus warnings. A per-skill warning rides on that skill's own\nentry." + }, + "SkillResourceContent": { + "properties": { + "skill_id": { + "type": "string", + "title": "Skill Id", + "description": "the skill this file belongs to" + }, + "path": { + "type": "string", + "title": "Path", + "description": "the file's path, relative to its skill's own bundle" + }, + "size": { + "type": "integer", + "title": "Size", + "description": "the byte size of the file's UTF-8 content" + }, + "digest": { + "type": "string", + "title": "Digest", + "description": "`sha256:` plus the lower-case hex SHA-256 of that content" + }, + "media_type": { + "type": "string", + "title": "Media Type", + "description": "the file's media type, from its extension" + }, + "content_text": { + "type": "string", + "title": "Content Text", + "description": "the file's text" + } + }, + "type": "object", + "required": [ + "skill_id", + "path", + "size", + "digest", + "media_type", + "content_text" + ], + "title": "SkillResourceContent", + "description": "The resources door's response: one manifest file and its text.\n\nCarries `skill_id` and `path` so a client that fires several requests\nconcurrently can tell which response answers which request." + }, + "SkillSummary": { + "properties": { + "id": { + "type": "string", + "title": "Id", + "description": "the skill's id, its dcid without the `skill/` prefix" + }, + "name": { + "type": "string", + "title": "Name", + "description": "the front matter's `name`, equal to `id`" + }, + "description": { + "type": "string", + "title": "Description", + "description": "the front matter's `description`" + }, + "frontmatter": { + "additionalProperties": { + "$ref": "#/components/schemas/FrontMatterValue" + }, + "type": "object", + "title": "Frontmatter", + "description": "the whole parsed front matter, every scalar a string" + }, + "content_version": { + "type": "string", + "title": "Content Version", + "description": "`sha256:` digest over the manifest's paths and digests, in order" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Url", + "description": "the skill's source directory for a human reader, never fetched here" + }, + "attached": { + "type": "boolean", + "title": "Attached", + "description": "true when the skill's reach names at least one node on this build, so search can name it" + }, + "excluded": { + "type": "boolean", + "title": "Excluded", + "description": "true when search cannot match this skill on this build: its reach broke a bound or a read the build depended on did not complete" + }, + "statvar_count": { + "type": "integer", + "title": "Statvar Count", + "description": "the distinct StatVars this skill's downward reach carries. A provenance attachment adds nothing to the count, so a skill attached only to provenances reports 0 while covering every series of those datasets" + }, + "statvar_count_truncated": { + "type": "boolean", + "title": "Statvar Count Truncated", + "description": "true when statvar_count stopped at this deployment's count bound rather than exhausting the reach" + }, + "warnings": { + "items": { + "$ref": "#/components/schemas/SkillWarning" + }, + "type": "array", + "title": "Warnings", + "description": "this skill's own warnings" + }, + "resources": { + "items": { + "$ref": "#/components/schemas/SkillFileListing" + }, + "type": "array", + "title": "Resources", + "description": "the skill's manifest: `SKILL.md` first, then its references in path order" + } + }, + "type": "object", + "required": [ + "id", + "name", + "description", + "frontmatter", + "content_version", + "url", + "attached", + "excluded", + "statvar_count", + "statvar_count_truncated", + "warnings", + "resources" + ], + "title": "SkillSummary", + "description": "One skill's list entry: front matter, attachment and breadth figures, own\nwarnings, and manifest. `SkillBody` adds the skill's text.\n\n`url` is the skill's source directory for a human reader. The platform never\nfetches it." + }, + "SkillWarning": { + "properties": { + "code": { + "type": "string", + "title": "Code", + "description": "stable machine code from the platform's code registry" + }, + "severity": { + "type": "string", + "enum": [ + "info", + "warn", + "degraded" + ], + "title": "Severity", + "description": "the severity level" + }, + "message": { + "type": "string", + "title": "Message", + "description": "human-readable explanation of the warning" + }, + "skill_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Skill Id", + "description": "the served skill's id, the dcid of a skill left out of the catalogue, or null for a corpus-level warning" + } + }, + "type": "object", + "required": [ + "code", + "severity", + "message", + "skill_id" + ], + "title": "SkillWarning", + "description": "One corpus-level or skill-level issue, on the wire. `skill_id` is the\ncatalogue id for an issue about a served skill, the roster dcid for a skill\nleft out of the catalogue, or `None` for an issue about the whole corpus.\nOnly an issue about a served skill rides on that skill's entry. The other two\nare corpus warnings on the list door." + }, + "Slot": { + "properties": { + "key": { + "$ref": "#/components/schemas/SlotKey", + "description": "the slot's typed identity (axis + property + label)" + }, + "binding": { + "oneOf": [ + { + "$ref": "#/components/schemas/BindingValue" + }, + { + "$ref": "#/components/schemas/BindingSet" + }, + { + "$ref": "#/components/schemas/BindingUnbound" + } + ], + "title": "Binding", + "description": "exactly one of the three binding states", + "discriminator": { + "propertyName": "kind", + "mapping": { + "set": "#/components/schemas/BindingSet", + "unbound": "#/components/schemas/BindingUnbound", + "value": "#/components/schemas/BindingValue" + } + } + }, + "expansion": { + "anyOf": [ + { + "$ref": "#/components/schemas/Expansion" + }, + { + "type": "null" + } + ], + "description": "codes the resolver admitted beyond this slot's own bound value(s), when the bound value's code system is declared hierarchical; None for every other slot, including one bound on a flat code system (e.g. crsTypeOfFlow) or a property the deployment's code index does not carry at all. Reports resolution-time breadth only -- `binding` alone is what the query asked for and what spec identity hashes." + }, + "summable": { + "type": "boolean", + "title": "Summable", + "description": "true when the datasets door's `groupby` sums the family's members over this slot into one complete series: the slot's property is a code system the deployment's code index declares summable (capabilities `summable_axes`), and the dataset the family is served from declares that an observation it carries no row for reads as zero, so a member with no rows adds nothing. False for every other property, for the property that classifies a dataset's rows, and for every slot of a family whose dataset declares no such reading, where a member with no rows refuses the sum. Independent of the binding, so an unbound, set or value-bound slot reads alike. Spec identity does not hash it.", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "key", + "binding" + ], + "title": "Slot", + "description": "One slot in the chosen shape, with its current binding state." + }, + "SlotKey": { + "properties": { + "axis": { + "type": "string", + "enum": [ + "what", + "how", + "where", + "when", + "source" + ], + "title": "Axis", + "description": "the slot grammar axis" + }, + "property": { + "anyOf": [ + { + "$ref": "#/components/schemas/GraphRef" + }, + { + "type": "null" + } + ], + "description": "the constraint property that defines this slot when one exists; null or omitted for when, source, and the where-axis slot that binds the subject/destination entity directly (no constraint property backs it)" + }, + "label": { + "type": "string", + "title": "Label", + "description": "human label, e.g. purpose, donor" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "axis", + "label" + ], + "title": "SlotKey", + "description": "A slot's typed identity: axis, constraint property, and human label." + }, + "SlotOption": { + "additionalProperties": true, + "type": "object" + }, + "SlotOptions": { + "properties": { + "key": { + "$ref": "#/components/schemas/SlotKey", + "description": "the slot identity this option set belongs to" + }, + "options": { + "items": { + "$ref": "#/components/schemas/SlotOption" + }, + "type": "array", + "title": "Options", + "description": "candidate values, in taxonomy order; a dcid that failed to resolve a label is omitted rather than fabricated. For a level-scoped constraint slot (relation is populated), this is the bound value's children and parent (for a bound root, its children and every other root), or, when the slot is unbound, each classification root followed by its children -- never deeper levels. A counted menu omits every option its answer would serve nothing for except the slot's current value (see SlotOption.served_rows)" + }, + "truncated": { + "type": "boolean", + "title": "Truncated", + "description": "false when options is the full known set for this slot at its current level (a curated seed taxonomy, a level-scoped taxonomy sourced from the packaged code index, or an observed taxonomy from the same source, rather than the recalled candidates); true when options is only the values observed among the resolved candidates (bounded by the recall cut, not exhaustive)" + }, + "source": { + "type": "string", + "enum": [ + "observed", + "seed" + ], + "title": "Source", + "description": "'seed' for a hand-curated family taxonomy (e.g. dev-finance scheme/purpose); 'observed' for the union of values seen on the confirmed StatVars or resolved query entities" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "key", + "options", + "truncated", + "source" + ], + "title": "SlotOptions", + "description": "The full candidate set one slot was bound against.\n\nThe taxonomy the binder chose from and the options a client can offer the user\nare the same artifact; this is that artifact, surfaced per slot. ``key`` matches\nthe ``SlotKey`` of the corresponding entry in ``Spec.resolved.slots`` (join on axis and\n``property.ref``)." + }, + "SlotValue": { + "properties": { + "ref": { + "anyOf": [ + { + "$ref": "#/components/schemas/GraphRef" + }, + { + "type": "null" + } + ], + "description": "the graph object bound, when the value is a graph object" + }, + "value_kind": { + "type": "string", + "enum": [ + "entity", + "enum_value", + "time_window", + "source", + "literal" + ], + "title": "Value Kind", + "description": "what kind of value this is" + }, + "time_window": { + "anyOf": [ + { + "$ref": "#/components/schemas/TimeWindow" + }, + { + "type": "null" + } + ], + "description": "present iff value_kind == time_window" + }, + "literal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Literal", + "description": "present iff value_kind == literal" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "value_kind" + ], + "title": "SlotValue", + "description": "One taxonomy member or facet value bound to a slot." + }, + "SourceAvailability": { + "properties": { + "source": { + "$ref": "#/components/schemas/AvailabilitySource" + }, + "places": { + "anyOf": [ + { + "additionalProperties": { + "type": "integer" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Places", + "description": "the places covered by kind; null for a role-bearing variable, and while the places' kinds are unread (a transient gap)" + }, + "entities": { + "anyOf": [ + { + "additionalProperties": { + "$ref": "#/components/schemas/EntityCounts" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Entities", + "description": "the entities covered per graph role; null for any other variable" + }, + "first_year": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "First Year" + }, + "last_year": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Year" + }, + "facets": { + "type": "integer", + "title": "Facets" + }, + "series": { + "items": { + "$ref": "#/components/schemas/Series" + }, + "type": "array", + "title": "Series" + } + }, + "type": "object", + "required": [ + "source", + "places", + "entities", + "first_year", + "last_year", + "facets", + "series" + ], + "title": "GraphAvailabilitySourceEntry", + "description": "One source's facets of the variable, and their series." + }, + "SourceBlock": { + "properties": { + "publisher": { + "anyOf": [ + { + "$ref": "#/components/schemas/NodeRef" + }, + { + "type": "null" + } + ], + "description": "the source arc's target; null when the node carries no source arc" + }, + "parent": { + "anyOf": [ + { + "$ref": "#/components/schemas/NodeRef" + }, + { + "type": "null" + } + ], + "description": "the isPartOf arc's target; null when the node has no parent Dataset" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "license_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License Type" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Url" + }, + "source_data_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Data Url", + "description": "the sourceDataUrl arc's value" + }, + "description_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description Url", + "description": "the descriptionUrl arc's value" + }, + "transformation_logic_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Transformation Logic Url", + "description": "the dataTransformationLogic arc's value: a URL to the transformation code" + }, + "last_data_refresh_date": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Data Refresh Date", + "description": "the lastDataRefreshDate arc's value" + }, + "next_data_refresh_date": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Next Data Refresh Date", + "description": "the nextDataRefreshDate arc's value" + }, + "earliest_observation_date": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Earliest Observation Date", + "description": "the earliestObservationDate arc's value" + }, + "latest_observation_date": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Latest Observation Date", + "description": "the latestObservationDate arc's value" + }, + "freshness": { + "$ref": "#/components/schemas/Freshness" + }, + "data_commons": { + "anyOf": [ + { + "$ref": "#/components/schemas/graph_api__origin_models__DataCommonsRef" + }, + { + "type": "null" + } + ], + "description": "the Data Commons serving this provenance, from the origin catalogue; null for a provenance the catalogue does not admit, a Dataset, or a Source" + }, + "documentation": { + "type": "string", + "title": "Documentation", + "description": "the path of the node's source document" + } + }, + "type": "object", + "required": [ + "publisher", + "parent", + "license", + "license_type", + "url", + "source_data_url", + "description_url", + "transformation_logic_url", + "last_data_refresh_date", + "next_data_refresh_date", + "earliest_observation_date", + "latest_observation_date", + "freshness", + "data_commons", + "documentation" + ], + "title": "GraphSourceBlock", + "description": "A Source, Dataset or Provenance's detail block. `documentation` is the path of the\nnode's source document on this API." + }, + "SourceCatalogue": { + "properties": { + "sources": { + "items": { + "$ref": "#/components/schemas/SourceCatalogueEntry" + }, + "type": "array", + "title": "Sources" + } + }, + "type": "object", + "required": [ + "sources" + ], + "title": "SourceCatalogue", + "description": "The full `GET /api/graph/sources` response: DFO's sources, then the\norigin registry's base Data Commons entries and UN System Data Commons\nagencies in registry order, each with the provenances the request's\norigin catalogue admits under it, grouped by Dataset. UN agencies are left\nout when the UN origin is off. The response has no count and no pagination." + }, + "SourceCatalogueEntry": { + "properties": { + "source": { + "$ref": "#/components/schemas/SourceNodeRef" + }, + "data_commons": { + "$ref": "#/components/schemas/graph_api__origin_models__DataCommonsRef" + }, + "datasets": { + "items": { + "$ref": "#/components/schemas/DatasetEntry" + }, + "type": "array", + "title": "Datasets" + }, + "exclusions": { + "items": { + "$ref": "#/components/schemas/Exclusion" + }, + "type": "array", + "title": "Exclusions" + } + }, + "type": "object", + "required": [ + "source", + "data_commons", + "datasets", + "exclusions" + ], + "title": "SourceCatalogueEntry", + "description": "One source on one Data Commons, with the datasets this deployment\nadmits under it and the provenances it excludes. DFO provenances and UN\nagencies exclude nothing here." + }, + "SourceCode": { + "properties": { + "provenance": { + "type": "string", + "title": "Provenance", + "description": "the provenance dcid of the publisher that issues the code" + }, + "code": { + "type": "string", + "title": "Code", + "description": "the publisher's series code, as the publisher writes it" + }, + "exact": { + "type": "boolean", + "title": "Exact", + "description": "true when the answer is the series the provenance files under this code and no other: a part naming the code as its source_code and the provenance as its source accepts this Spec as its answer. The answer reads its observations from the provenance alone, the provenance gives none of the code's StatVars another code, and every StatVar a Datasets mint of the Spec serves is one of the code's. False, the default, is omitted: the code names a StatVar the answer serves, and the answer may hold other series or data of another source", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provenance", + "code" + ], + "title": "SourceCode", + "description": "A publisher's own series code for a StatVar, such as World Bank `DT.TDS.DEGG.CD`." + }, + "SourceDetails": { + "properties": { + "name_of_source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name Of Source" + }, + "publisher": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Publisher" + }, + "source": { + "anyOf": [ + { + "$ref": "#/components/schemas/SourceNodeRef" + }, + { + "type": "null" + } + ], + "description": "the origin registry's source for the documented Provenances, null unless the origin catalogue admits every one of them and they share one" + }, + "data_commons": { + "anyOf": [ + { + "$ref": "#/components/schemas/graph_api__origin_models__DataCommonsRef" + }, + { + "type": "null" + } + ], + "description": "the Data Commons serving the documented Provenances, null unless the origin catalogue admits every one of them and they share one" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Url" + }, + "source_data_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Data Url", + "description": "the file the pipeline downloads, the source's `sourceDataUrl`" + }, + "citation": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Citation", + "description": "the source's `licenseAttribution` text" + } + }, + "type": "object", + "required": [ + "name_of_source", + "publisher", + "source", + "data_commons", + "description", + "source_url", + "source_data_url", + "citation" + ], + "title": "SourceDetails" + }, + "SourceDocumentation": { + "properties": { + "details": { + "$ref": "#/components/schemas/SourceDetails" + }, + "license": { + "$ref": "#/components/schemas/SourceLicense" + }, + "scope_and_units": { + "$ref": "#/components/schemas/ScopeAndUnits" + }, + "methodology": { + "$ref": "#/components/schemas/Methodology" + }, + "data_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Data Notes", + "description": "one caveat per entry, as CommonMark" + }, + "usage": { + "$ref": "#/components/schemas/Usage" + }, + "transformation_log": { + "items": { + "$ref": "#/components/schemas/TransformationLogEntry" + }, + "type": "array", + "title": "Transformation Log" + }, + "version_history": { + "items": { + "$ref": "#/components/schemas/VersionHistoryEntry" + }, + "type": "array", + "title": "Version History" + }, + "gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Gaps", + "description": "every member path that is null or empty for this source, in spec order, e.g. 'details.citation', 'scope_and_units.countries'" + }, + "document_errors": { + "items": { + "$ref": "#/components/schemas/DocumentErrorEntry" + }, + "type": "array", + "title": "Document Errors", + "description": "each Markdown document the source carries but this door could not serve" + } + }, + "type": "object", + "required": [ + "details", + "license", + "scope_and_units", + "methodology", + "data_notes", + "usage", + "transformation_log", + "version_history", + "gaps", + "document_errors" + ], + "title": "SourceDocumentation", + "description": "The full `GET /api/graph/documentation/{dcid}` response." + }, + "SourceLicense": { + "properties": { + "type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Type" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Url", + "description": "the licence text on the publisher's site, the source's `license`" + }, + "update_cadence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Update Cadence" + }, + "last_update": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Update" + }, + "next_expected_update": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Next Expected Update" + } + }, + "type": "object", + "required": [ + "type", + "url", + "update_cadence", + "last_update", + "next_expected_update" + ], + "title": "SourceLicense" + }, + "SourceMention": { + "properties": { + "text": { + "anyOf": [ + { + "type": "string", + "maxLength": 120, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Text", + "description": "the user's words naming the source, e.g. 'IDS', 'the OECD' or 'World Bank', without the words that ask for its data ('World Bank' in 'World Bank debt data'). They are matched whole against the names of every admitted publisher, dataset and provenance, and their registered abbreviations, ignoring case, punctuation and a leading 'the'. Included words that match none resolve no_data with source_not_resolved. Excluded words that match none remove nothing and warn query_qualifier_dropped. Words that match two unrelated sources resolve no_data with source_ambiguous, listing both" + }, + "ref": { + "anyOf": [ + { + "type": "string", + "maxLength": 200, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Ref", + "description": "the reference this mention names, when the caller holds one (a provenance dcid, a catalogue Dataset ref or a Source ref), such as a restatement's resolved mention or a NoData.ambiguous_sources candidate carries. It skips matching `text`. A ref the origin catalogue does not admit refuses request_invalid with a pointer to it" + }, + "polarity": { + "type": "string", + "enum": [ + "include", + "exclude" + ], + "title": "Polarity", + "description": "include to answer from this source, exclude to answer from any other. A part with an included source answers from the included sources only. A part with exclusions alone answers from every admitted source but those", + "default": "include" + } + }, + "additionalProperties": false, + "type": "object", + "title": "SourceMention", + "description": "One data source a part names or excludes, as its words, a reference, or both." + }, + "SourceNode": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the node's dcid" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "the node's name; for a Provenance, its parent Dataset's name where it has one. Null, and named in gaps, when the graph gives none" + }, + "types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Types", + "description": "the node's typeOf values, as the graph holds them" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "the node's prose in the graph; null when it has none" + }, + "links": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "codes", + "children", + "members", + "countries", + "datasets", + "variables", + "facets" + ] + }, + "type": "object", + "title": "Links", + "description": "each list relation the node has, mapped to its route; empty when none" + }, + "gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Gaps", + "description": "the member path of every value this door cannot know" + }, + "built_from": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "code_index", + "origin_catalogue", + "coverage_index", + "membership" + ] + }, + "type": "object", + "title": "Built From", + "description": "the build of each table the response read" + }, + "kind": { + "type": "string", + "const": "source", + "title": "Kind", + "default": "source" + }, + "source": { + "$ref": "#/components/schemas/SourceBlock" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "types", + "description", + "links", + "gaps", + "built_from", + "kind", + "source" + ], + "title": "SourceNode" + }, + "SourceNodeRef": { + "properties": { + "ref": { + "type": "string", + "title": "Ref" + }, + "label": { + "type": "string", + "title": "Label" + } + }, + "type": "object", + "required": [ + "ref", + "label" + ], + "title": "GraphSourceNodeRef", + "description": "A Data Commons `Source` node (`dc/s/*`). On the UN System Data Commons, where every\nagency sits under one source, it is the agency provenance (`undata/p/*`)." + }, + "SourceRef": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the source's dcid" + }, + "label": { + "type": "string", + "title": "Label", + "description": "the source's display name" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref", + "label" + ], + "title": "SourceRef", + "description": "The organisation behind a provenance: the Source node its `source` arc\nnames on our Data Commons and on Data Commons by Google, or the agency\nprovenance itself on the UN System Data Commons." + }, + "Spec": { + "properties": { + "spec_id": { + "type": "string", + "title": "Spec Id", + "description": "deterministic hash of (shape + canonical slot bindings); permalink-safe, dedup key, golden-comparison handle, cache key" + }, + "definition": { + "$ref": "#/components/schemas/SpecDefinition", + "description": "the canonical definition this Spec was resolved from: {schema_version, identity}, the same shape Unsupported.definition uses. definition.identity is the identity-core projection this spec_id was minted from, serialised once and never re-derived; hashing it reproduces spec_id by construction. Post definition.identity back byte-for-byte as ResubmitIdentityPayload.identity to edit this Spec. Directional entities remain nested in identity.entities." + }, + "resolved": { + "$ref": "#/components/schemas/ResolvedSpec", + "description": "the engine's report of what it did with the ask: stat_vars, entities, coverage, trace, and every other display/diagnostic field. Never hashed; see ResolvedSpec" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "spec_id", + "definition", + "resolved" + ], + "title": "Spec", + "description": "The unit of meaning: one named region of the graph.\n\nReused as the definite answer, each candidate, and NoData's own\nflagged_match/alternate_match (a plain Spec on both). See NoData's own\ndocstring for the failed-gate code each carries, NoData.gate, kept\nstructurally outside every identity path. NearestRealSpec (below)\nsubclasses Spec for NoData.nearest_real, adding the relaxation each\nsuggestion carries. That stays structurally outside every identity path\nthe same way (spec_id is computed from bindings, never from the model),\nso it cannot perturb spec_id." + }, + "SpecAlternativeMeasure": { + "properties": { + "definition": { + "$ref": "#/components/schemas/SpecDefinition", + "description": "the alternative measure's own {schema_version, spec_id, identity}" + }, + "label": { + "type": "string", + "title": "Label", + "description": "readable text for this option, distinct from every other entry's on the same axis. A 'what' entry names the measure without its price basis ('net disbursements'), and differs from measure_label; a 'unit' entry names the prices it switches to ('constant prices')" + }, + "axis": { + "type": "string", + "enum": [ + "what", + "unit" + ], + "title": "Axis", + "description": "the sentence token whose menu offers this entry: 'what', the measure noun, or 'unit', the byline's unit token (SentenceToken.axis 'unit', binding_ref 'unit:'), for a partition that differs from this Spec's only in price basis" + }, + "measure_axis_values": { + "items": { + "$ref": "#/components/schemas/MeasureAxisValue" + }, + "type": "array", + "title": "Measure Axis Values", + "description": "every axis this measure's partition holds a value on, with that value, in measure-axis declaration order; the same projection as ResolvedSpec.measure_axis_values" + }, + "served_rows": { + "anyOf": [ + { + "type": "integer", + "minimum": 1.0 + }, + { + "type": "null" + } + ], + "title": "Served Rows", + "description": "the rows a resubmit of `definition` would write at this Spec's bound roles, in the terms of download.rows: one per series and year with a point inside the requested window, or under 'latest' one per series holding its StatVar's latest year, a series being a served StatVar at one entity, or donor and recipient pair. A Spec that merges several answers counts at every entity its answers bind. A StatVar the coverage artifact does not hold adds no rows, and a measure that would serve none, including one whose StatVars are all missing from the artifact, is not listed. None where the count needs graph reads (a subject-place family, or a family the code index does not decide), or where the merged answers read different years or coverage" + }, + "served_rows_exact": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Served Rows Exact", + "description": "true when served_rows equals the download.rows of a resubmit of `definition`; false when it is an upper bound: a counted StatVar whose series sit in more than one facet group (provenance, method and unit) in the window; an answer read in bulk whose measure's StatVars sit in more than one facet; under 'latest', a StatVar with a facet observed more often than yearly; an answer that pins a facet value; or a unit request whose conversion cannot be read as download.rows_exact describes, or that converts a counted series from a currency the answer does not serve. Null exactly when served_rows is null" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "definition", + "label", + "axis", + "measure_axis_values" + ], + "title": "SpecAlternativeMeasure", + "description": "One other measure this Spec could equally answer with (see\nResolvedSpec.alternative_measures): either another populated partition\nfrom the same family as the one this Spec's own served rows exhibit, or\na genuinely distinct also_plausible candidate whose only difference from\nthis Spec is measured_property (measurement_denominator held equal),\nfolded in here instead of left as a second candidates entry. Carries its\nown identity and a label that disambiguates it.\n\n`definition` is minted by editing this Spec's own already-minted\nidentity onto this partition's measure axes (retrieval.bound_values.\nmint_sibling_identity), an index-scan projection, not a resolution.\nCarries identity and a label only: no stat_vars, no coverage, no trace.\nResolvedSpec's own required fields have no defaults, so producing one as\na Spec would mean fabricating a resolution that never ran.\n\nPost `definition` back as `identity` on a dataset_resubmit identity entry to\nswitch onto this measure: the identity's own what/how slots (this\npartition's per-partition-declared axes included, e.g. CRS cooperation\nmodality) name the family the packaged code index's own election\nrecovers members from, the same recovery a resubmit of this Spec's own\nidentity uses.\n\n`axis` names the sentence token whose menu offers the entry. A partition\nthat differs from this Spec's only in price basis (`measurementQualifier`\n`Nominal` or `RealValue`) is a unit option, axis \"unit\", offered by the\nbyline's unit token (binding_ref \"unit:\"). Every other entry is a measure\noption, axis \"what\". The measure menu holds one entry per measure\nwhatever its price basis, so no two \"what\" entries differ only in price\nbasis." + }, + "SpecDefinition": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "description": "contract schema version this definition was published under; exactly 1", + "default": 1 + }, + "spec_id": { + "type": "string", + "title": "Spec Id", + "description": "the spec_id minted from `identity`; equals the sibling Spec.spec_id, and is what a detached definition (registry row, permalink) is keyed by" + }, + "identity": { + "$ref": "#/components/schemas/BaseIdentity", + "description": "the identity-core projection this Spec's spec_id was minted from, serialised once and never re-derived; post it back byte-for-byte as ResubmitIdentityPayload.identity to edit this Spec. Directional edits change identity.entities.origin or identity.entities.destination directly" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "spec_id", + "identity" + ], + "title": "SpecDefinition", + "description": "The canonical definition a Spec was resolved from: `{schema_version,\nspec_id, identity}`. This is the form the registry stores and permalinks\ncarry, so it is self-contained. A definition lifted out of its Spec still\nnames which spec it is.\n\n`identity` is the identity-core projection (see `BaseIdentity`) this\nSpec's spec_id was minted from, so hashing `identity` again reproduces\n`spec_id` by construction.\n\n`spec_id` is carried here as well as on `Spec.spec_id` deliberately: the\nduplication is what makes the definition independently meaningful once\ndetached from the response that delivered it. The one exception is an\n`unsupported` response's definition, which omits it: the request was\nvalid and understood but never became a resolvable construction, so no\nspec_id was ever legitimately minted for it." + }, + "SpecIdInput": { + "properties": { + "kind": { + "type": "string", + "const": "spec_id", + "title": "Kind", + "default": "spec_id" + }, + "spec_id": { + "type": "string", + "pattern": "^spec_", + "title": "Spec Id" + }, + "definition": { + "anyOf": [ + { + "$ref": "#/components/schemas/CanonicalDefinition" + }, + { + "type": "null" + } + ] + }, + "scope": { + "anyOf": [ + { + "$ref": "#/components/schemas/Scope-Input" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "spec_id" + ], + "title": "SpecIdInput", + "description": "`kind: \"spec_id\"` -- an id already in the registry, with an optional\ncanonical `definition` sidecar. `definition.spec_id`, when supplied,\nmust equal the outer `spec_id`; the sidecar is required only when the\nregistry does not already hold `spec_id`." + }, + "SpecObservations": { + "properties": { + "series": { + "items": { + "$ref": "#/components/schemas/ObservationSeries" + }, + "type": "array", + "title": "Series", + "description": "one entry per (stat_var, role tuple) pair with observations" + }, + "total_obs": { + "type": "integer", + "title": "Total Obs", + "description": "total observation count across every series' SELECTED facet, window-filtered to the spec's requested window when one exists -- known even when truncated is true and points are truncated. For a windowed per-pair answer, this is the chosen facet's in-window point count, NOT a raw facet obs_count sum and NOT a union across every facet of the pair -- see ObservationSeries. For a scope-defaulted bulk latest-only answer (no requested window), this sums the coverage probe's all-time obs_count per delivered entity instead: with no window to narrow it, that raw obs_count IS the in-window count" + }, + "truncated": { + "type": "boolean", + "title": "Truncated", + "description": "false when every series above carries its FULL point set (the whole answer's point count was within the server's inline threshold and each series within its row limit); true when a series was truncated to its latest points only, its total_obs still counting every point" + }, + "omitted": { + "anyOf": [ + { + "$ref": "#/components/schemas/ObservationsOmission" + }, + { + "type": "null" + } + ], + "description": "why this payload carries no series, when it doesn't; absent when series is genuinely populated. See ObservationsOmission's own docstring" + }, + "order": { + "anyOf": [ + { + "type": "string", + "enum": [ + "ranked", + "fixed" + ] + }, + { + "type": "null" + } + ], + "title": "Order", + "description": "how a role-bearing bulk preview chose the series it shows when it shows fewer than the answer holds: 'ranked' when it read every series and shows the most recent and largest (latest year, then latest value, then identity), 'fixed' when it shows a selection made before any value was read, StatVars newest year first and taken round-robin; absent when every series is shown or the preview is not a role-bearing bulk one" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "series", + "total_obs", + "truncated" + ], + "title": "SpecObservations", + "description": "The observation values behind a Spec's coverage.\n\nAn opt-in bounded preview, or the full series when the resolved answer is\nsmall enough to ship in full -- see truncated. Describes the SAME (stat_var,\nentity) selection Spec.resolved.coverage already reports, so the numbers here never\ndescribe a different variable than what coverage summarises.\n\nEach series carries one lead observation facet's points, never a union\nacross facets: a StatVar/entity pair can have several reporting facets\n(e.g. commitments vs disbursements, current vs constant prices), and\nmerging their points chronologically would interleave same-dated points\nfrom incompatible series into one meaningless line. The one exception is\nthe same source's estimates continuing the lead past its last period: the\nseries carries their points after the lead's, `facet` names the lead, and\nthe `modelled_values` departure marks the estimates. One facet group is\nselected per StatVar instead, across every place and role tuple the answer\nnames: among facets holding a point in the requested years (all facets when\nnone does), DFO's facets first for a variable both DFO and base Data\nCommons hold, then the one covering the most places or role tuples there,\nthen the most requested years, then the most observations, then the latest\nobservation, then a deterministic tie-break." + }, + "StatVarBlock": { + "properties": { + "definition": { + "$ref": "#/components/schemas/VariableDefinition" + }, + "availability": { + "anyOf": [ + { + "$ref": "#/components/schemas/Availability" + }, + { + "type": "null" + } + ], + "description": "where DFO holds observations of the variable; null, and named in gaps, when its read failed or the coverage index is not loaded" + } + }, + "type": "object", + "required": [ + "definition", + "availability" + ], + "title": "GraphStatVarBlock", + "description": "A variable's detail block: what it measures and where DFO holds observations of it." + }, + "StatVarNode": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the node's dcid" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "the node's name; for a Provenance, its parent Dataset's name where it has one. Null, and named in gaps, when the graph gives none" + }, + "types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Types", + "description": "the node's typeOf values, as the graph holds them" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "the node's prose in the graph; null when it has none" + }, + "links": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "codes", + "children", + "members", + "countries", + "datasets", + "variables", + "facets" + ] + }, + "type": "object", + "title": "Links", + "description": "each list relation the node has, mapped to its route; empty when none" + }, + "gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Gaps", + "description": "the member path of every value this door cannot know" + }, + "built_from": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "code_index", + "origin_catalogue", + "coverage_index", + "membership" + ] + }, + "type": "object", + "title": "Built From", + "description": "the build of each table the response read" + }, + "kind": { + "type": "string", + "const": "stat_var", + "title": "Kind", + "default": "stat_var" + }, + "stat_var": { + "$ref": "#/components/schemas/StatVarBlock" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "types", + "description", + "links", + "gaps", + "built_from", + "kind", + "stat_var" + ], + "title": "StatVarNode" + }, + "StatVarSetInput": { + "properties": { + "kind": { + "type": "string", + "const": "statvar_set", + "title": "Kind", + "default": "statvar_set" + }, + "statvars": { + "items": { + "type": "string", + "pattern": "^dcid:" + }, + "type": "array", + "maxItems": 1, + "minItems": 1, + "title": "Statvars" + }, + "scope": { + "anyOf": [ + { + "$ref": "#/components/schemas/Scope-Input" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "statvars" + ], + "title": "StatVarSetInput", + "description": "`kind: \"statvar_set\"` -- resolves one `dcid:`-prefixed StatVar to its\nregistered shape and mints a fully pinned spec for it. `statvars` holds\nexactly one StatVar." + }, + "Step": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$", + "title": "Id" + }, + "op": { + "type": "string", + "pattern": "^[a-z][a-z0-9_]{0,63}$", + "title": "Op" + }, + "stat_var": { + "type": "string", + "maxLength": 512, + "minLength": 1, + "title": "Stat Var" + }, + "input": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$" + }, + { + "$ref": "#/components/schemas/VersionRef" + } + ], + "title": "Input" + }, + "inputs": { + "patternProperties": { + "^[a-z][a-z0-9_]{0,63}$": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$" + }, + { + "$ref": "#/components/schemas/VersionRef" + } + ] + } + }, + "type": "object", + "maxProperties": 8, + "minProperties": 1, + "title": "Inputs" + }, + "sides": { + "patternProperties": { + "^[a-z][a-z0-9_]{0,63}$": { + "additionalProperties": { + "type": "string", + "maxLength": 512, + "minLength": 1 + }, + "propertyNames": { + "maxLength": 64, + "minLength": 1 + }, + "type": "object", + "maxProperties": 16 + } + }, + "type": "object", + "maxProperties": 8, + "minProperties": 1, + "title": "Sides" + }, + "policy": { + "type": "string", + "pattern": "^[a-z][a-z0-9_]{0,63}$", + "title": "Policy" + }, + "params": { + "patternProperties": { + "^[a-z][a-z0-9_]{0,63}$": { + "$ref": "#/components/schemas/JsonValue" + } + }, + "type": "object", + "maxProperties": 32, + "title": "Params" + }, + "options": { + "patternProperties": { + "^[a-z][a-z0-9_]{0,63}$": { + "$ref": "#/components/schemas/JsonValue" + } + }, + "type": "object", + "maxProperties": 32, + "title": "Options" + }, + "kept": { + "patternProperties": { + "^[a-z][a-z0-9_]{0,63}$": { + "type": "integer", + "minimum": 0.0 + } + }, + "type": "object", + "maxProperties": 16, + "title": "Kept" + }, + "left_out": { + "items": { + "$ref": "#/components/schemas/LeftOut" + }, + "type": "array", + "maxItems": 32, + "title": "Left Out" + }, + "period_coverage": { + "items": { + "$ref": "#/components/schemas/PeriodCoverage" + }, + "type": "array", + "maxItems": 500, + "title": "Period Coverage" + }, + "entity_coverage": { + "items": { + "$ref": "#/components/schemas/EntityCoverage" + }, + "type": "array", + "maxItems": 500, + "title": "Entity Coverage" + }, + "choice": { + "$ref": "#/components/schemas/Choice" + }, + "summed": { + "$ref": "#/components/schemas/Summed" + }, + "converted_from": { + "anyOf": [ + { + "$ref": "#/components/schemas/SimpleUnit" + }, + { + "$ref": "#/components/schemas/ComposedUnit" + }, + { + "type": "null" + } + ], + "title": "Converted From" + }, + "unit": { + "anyOf": [ + { + "$ref": "#/components/schemas/SimpleUnit" + }, + { + "$ref": "#/components/schemas/ComposedUnit" + }, + { + "type": "null" + } + ], + "title": "Unit" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "op" + ], + "title": "Step", + "description": "One operation: its inputs by role, its one fixed policy, the caller's own choices,\nwhat it kept, what data gaps it left out, the unit it produces, and, for an operation\nthat writes a new variable (sum, quotient, share, comparison), that variable's bare dcid in\n`stat_var`.\n\nA step takes either `input` or `inputs`, or neither, never both. `stat_var` is the bare\ndcid of the variable a step that makes a new one (a sum, quotient, share or comparison)\nwrites its rows under. `sides` holds, by input role, each role column whose slice of that\ninput holds one entity, with that entity's ref. A comparison records it." + }, + "StepRef": { + "properties": { + "ref": { + "type": "string", + "maxLength": 512, + "minLength": 1, + "title": "Ref" + }, + "label": { + "type": "string", + "maxLength": 512, + "minLength": 1, + "title": "Label" + }, + "at_mint": { + "type": "boolean", + "const": true, + "title": "At Mint" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ref" + ], + "title": "StepRef", + "description": "A reference: the dcid or id it names, and optionally the words for it.\n\n`at_mint` marks a label taken from the evidence stored when the version was made." + }, + "SubregionNode": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the node's dcid" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "the node's name; for a Provenance, its parent Dataset's name where it has one. Null, and named in gaps, when the graph gives none" + }, + "types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Types", + "description": "the node's typeOf values, as the graph holds them" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "the node's prose in the graph; null when it has none" + }, + "links": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "codes", + "children", + "members", + "countries", + "datasets", + "variables", + "facets" + ] + }, + "type": "object", + "title": "Links", + "description": "each list relation the node has, mapped to its route; empty when none" + }, + "gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Gaps", + "description": "the member path of every value this door cannot know" + }, + "built_from": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "code_index", + "origin_catalogue", + "coverage_index", + "membership" + ] + }, + "type": "object", + "title": "Built From", + "description": "the build of each table the response read" + }, + "kind": { + "type": "string", + "const": "subregion", + "title": "Kind", + "default": "subregion" + }, + "subregion": { + "$ref": "#/components/schemas/PlaceBlock" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "types", + "description", + "links", + "gaps", + "built_from", + "kind", + "subregion" + ], + "title": "SubregionNode" + }, + "Summed": { + "properties": { + "count": { + "type": "integer", + "minimum": 0.0, + "title": "Count" + }, + "variables": { + "items": { + "$ref": "#/components/schemas/StepRef" + }, + "type": "array", + "maxItems": 64, + "title": "Variables" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "count", + "variables" + ], + "title": "Summed", + "description": "A sum at mint: how many variables were summed, and up to 64 of them." + }, + "TimeWindow": { + "properties": { + "start_year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Start Year", + "description": "absent means open-ended start" + }, + "end_year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "End Year", + "description": "absent means open-ended end (to latest)" + } + }, + "additionalProperties": false, + "type": "object", + "title": "TimeWindow", + "description": "A date window. Absence of a bound means open-ended in that direction." + }, + "Timing": { + "properties": { + "total": { + "type": "integer", + "title": "Total", + "description": "total latency in milliseconds, at whichever scope this sits" + }, + "by_step": { + "anyOf": [ + { + "additionalProperties": { + "type": "integer" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "By Step", + "description": "per-step latency in ms" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "total" + ], + "title": "Timing", + "description": "Latency breakdown, reused at two scopes: the envelope's own\ndiagnostics.timing_ms, where total is the whole request's wall-clock\nelapsed time and by_step names the steps that run once per request,\nshared across every part (e.g. extract), and a part's own timing_ms,\nwhere total sums that part's own by_step values and by_step names only\nthe phases that part ran, excluding the shared steps already reported\non the envelope. A part's shape_arcs, shape_probe, shape_probe_coverage,\nshape_labels, shape_groups and shape_admission steps are nested inside\nits shape step, so its total leaves them out." + }, + "TraceConversion": { + "properties": { + "recipe": { + "type": "string", + "title": "Recipe", + "description": "the conversion recipe class that ran" + }, + "input_tables": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Input Tables", + "description": "the input series/table dcids the recipe combined, keyed by role" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recipe", + "input_tables" + ], + "title": "TraceConversion", + "description": "A Spec-level record of a unit-conversion recipe. The engine converts\nper series and records each converted series' recipe and tables in\nObservationSeries.conversion, since one Spec's series can convert under\ndifferent recipes. ResolutionTrace.conversion is modelled here but always\nabsent. Capabilities.recipe_classes lists the recipe members this\ndeployment applies." + }, + "TraceDefaultReading": { + "properties": { + "applied": { + "type": "boolean", + "title": "Applied", + "description": "false when a phrase the request dropped uses a price-basis word no qualifier match read, so every price basis stayed on the menu and the alternate guard applied no default reading" + }, + "removed_stat_vars": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Removed Stat Vars", + "description": "the StatVar dcids the default reading removed; empty when it removed none" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "applied" + ], + "title": "TraceDefaultReading", + "description": "The default price-basis reading applied before bind. Price bases rank Nominal,\nRealValue, InflationAdjusted, then PurchasingPowerParity, with any basis the query names\nmoved first. A StatVar leaves the menu when a StatVar of a better-ranked basis with the\nsame constraints holds data wherever it does over the requested years. The trace records\nwhether the step ran and the StatVars it removed." + }, + "TransformationLogEntry": { + "properties": { + "transformation": { + "type": "string", + "title": "Transformation", + "description": "the step title, plain text" + }, + "description": { + "type": "string", + "title": "Description", + "description": "what the step does, as CommonMark" + } + }, + "type": "object", + "required": [ + "transformation", + "description" + ], + "title": "TransformationLogEntry", + "description": "One step of the pipeline's transformations, in pipeline order." + }, + "TransformationStepModel": { + "properties": { + "transformation": { + "type": "string", + "title": "Transformation", + "description": "the step title, plain text" + }, + "description": { + "type": "string", + "title": "Description", + "description": "what the step does, as CommonMark" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "transformation", + "description" + ], + "title": "TransformationStepModel", + "description": "One step the DFO pipeline applied to a source's data, in pipeline order." + }, + "UnavailableFormatModel": { + "properties": { + "format": { + "type": "string", + "title": "Format" + }, + "reason": { + "type": "string", + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "format", + "reason" + ], + "title": "UnavailableFormatModel" + }, + "UnitAlternative": { + "properties": { + "currency": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Z]{3}$" + }, + { + "$ref": "#/components/schemas/IdentityCurrencyRole" + } + ], + "title": "Currency", + "description": "the value a caller resubmits as facets.unit.request.currency, as written: an ISO 4217 code for an ambiguous currency name, or a role shape for a role-relative currency phrase beside entities on two roles" + }, + "label": { + "type": "string", + "title": "Label", + "description": "the currency's display name, or the role's reader-facing noun" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "currency", + "label" + ], + "title": "UnitAlternative", + "description": "One currency a unit_not_resolved refusal offers in place of the unit\nphrase it could not resolve -- one entry of NoData.unit_alternatives." + }, + "UnitBlock": { + "properties": { + "unit_class": { + "$ref": "#/components/schemas/UnitKind", + "description": "currency, purchasing_power, percent, or other (`unit_words.unit_class`)" + }, + "currency": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Currency", + "description": "its ISO 4217 code when it is a currency" + }, + "currency_noun": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Currency Noun", + "description": "the plural noun a currency reads as, such as `US dollars`" + }, + "price_basis": { + "anyOf": [ + { + "$ref": "#/components/schemas/PriceBasisWords" + }, + { + "type": "null" + } + ], + "description": "the price basis the unit itself states; null when it states none" + }, + "changes_magnitude": { + "type": "boolean", + "title": "Changes Magnitude", + "description": "whether the unit changes what a number means, so a heading states it" + } + }, + "type": "object", + "required": [ + "unit_class", + "currency", + "currency_noun", + "price_basis", + "changes_magnitude" + ], + "title": "GraphUnitBlock", + "description": "A unit's detail block: the words `unit_words` names it by." + }, + "UnitConstantPricesRequestBinding": { + "properties": { + "currency": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Z]{3}$" + }, + { + "$ref": "#/components/schemas/UnitCurrencyRole" + } + ], + "title": "Currency" + }, + "prices": { + "type": "string", + "const": "constant", + "title": "Prices", + "default": "constant" + }, + "base_year": { + "type": "integer", + "title": "Base Year" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "currency", + "base_year" + ], + "title": "UnitConstantPricesRequestBinding", + "description": "The unit axis's own conversion-request form for `prices: \"constant\"`:\n`base_year` is a required member." + }, + "UnitConversion": { + "properties": { + "currencies": { + "items": { + "$ref": "#/components/schemas/ConversionCurrency" + }, + "type": "array", + "title": "Currencies", + "description": "each currency a unit request accepts that converts at least one served year at current prices, at a constant-price base year, or both, sorted by code" + }, + "default_base_year": { + "type": "integer", + "title": "Default Base Year", + "description": "the base year a constant-price request that names none completes to: the deflatorBaseYear every conversion table declares" + }, + "role_currencies": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "observationAbout", + "origin", + "destination" + ] + }, + "type": "object", + "title": "Role Currencies", + "description": "the ISO 4217 code of the national currency (the graph's nationalCurrencyOf arc) of the one entity bound on each role, among `currencies`. A role bound to several entities, or to one no single currency names, is absent. A request may name the role ({'role': 'origin'}) or the code" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "currencies", + "default_base_year" + ], + "title": "UnitConversion", + "description": "The conversions a unit request can ask of this answer: the currencies, years and base\nyears the conversion recipe of its served members converts. A request posts one as the\nidentity's `facets.unit` (`IdentityFacetValueRequest`)." + }, + "UnitCount": { + "properties": { + "ref": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Ref" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label" + }, + "places": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Places", + "description": "the places its facets cover; null for a role-bearing variable" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "places" + ], + "title": "GraphAvailabilityUnit", + "description": "One unit of a series. `ref` is `null` for facets that state no unit." + }, + "UnitCurrencyRole": { + "properties": { + "role": { + "type": "string", + "enum": [ + "origin", + "destination", + "observationAbout" + ], + "title": "Role" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "role" + ], + "title": "UnitCurrencyRole", + "description": "A unit-request `currency` naming a spec role rather than a concrete\nISO 4217 code: convert to the currency of whichever entity is bound in\nthat role. The role must be one the resolved StatVar declares." + }, + "UnitCurrentPricesRequestBinding": { + "properties": { + "currency": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Z]{3}$" + }, + { + "$ref": "#/components/schemas/UnitCurrencyRole" + } + ], + "title": "Currency" + }, + "prices": { + "type": "string", + "const": "current", + "title": "Prices", + "default": "current" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "currency" + ], + "title": "UnitCurrentPricesRequestBinding", + "description": "The unit axis's own conversion-request form for `prices: \"current\"`:\nno `base_year` member." + }, + "UnitKind": { + "type": "string", + "enum": [ + "currency", + "purchasing_power", + "percent", + "other", + "none" + ] + }, + "UnitNode": { + "properties": { + "ref": { + "type": "string", + "title": "Ref", + "description": "the node's dcid" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Label", + "description": "the node's name; for a Provenance, its parent Dataset's name where it has one. Null, and named in gaps, when the graph gives none" + }, + "types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Types", + "description": "the node's typeOf values, as the graph holds them" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "the node's prose in the graph; null when it has none" + }, + "links": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "codes", + "children", + "members", + "countries", + "datasets", + "variables", + "facets" + ] + }, + "type": "object", + "title": "Links", + "description": "each list relation the node has, mapped to its route; empty when none" + }, + "gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Gaps", + "description": "the member path of every value this door cannot know" + }, + "built_from": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "enum": [ + "code_index", + "origin_catalogue", + "coverage_index", + "membership" + ] + }, + "type": "object", + "title": "Built From", + "description": "the build of each table the response read" + }, + "kind": { + "type": "string", + "const": "unit", + "title": "Kind", + "default": "unit" + }, + "unit": { + "$ref": "#/components/schemas/UnitBlock" + } + }, + "type": "object", + "required": [ + "ref", + "label", + "types", + "description", + "links", + "gaps", + "built_from", + "kind", + "unit" + ], + "title": "UnitNode" + }, + "UnitsFold": { + "properties": { + "count": { + "type": "integer", + "title": "Count" + }, + "leading": { + "items": { + "$ref": "#/components/schemas/UnitCount" + }, + "type": "array", + "title": "Leading" + }, + "more": { + "type": "integer", + "title": "More" + }, + "national_currency": { + "anyOf": [ + { + "$ref": "#/components/schemas/NationalCurrency" + }, + { + "type": "null" + } + ], + "description": "the units that are their places' national currency; null when none is" + } + }, + "type": "object", + "required": [ + "count", + "leading", + "more", + "national_currency" + ], + "title": "GraphAvailabilityUnits", + "description": "A series' units: how many, the two covering the most places, and how many more." + }, + "Unsupported": { + "properties": { + "code": { + "type": "string", + "title": "Code", + "description": "the reason, a code from the platform registry" + }, + "pointer": { + "type": "string", + "title": "Pointer", + "description": "a JSON Pointer into `definition` (not the request body) naming the binding at fault -- a text-door request has no structured body to point into" + }, + "detail": { + "type": "string", + "title": "Detail", + "description": "human-readable explanation" + }, + "cause": { + "anyOf": [ + { + "$ref": "#/components/schemas/Cause" + }, + { + "type": "null" + } + ], + "description": "why this refusal fired, present only for code=recipe_not_declared (the structured door's same-named ProblemDetails extension); omitted on every other code" + }, + "definition": { + "additionalProperties": true, + "type": "object", + "title": "Definition", + "description": "the canonical definition as interpreted -- {schema_version, identity: {identity_version, shape, slots, entities, facets, requested_window}} -- without spec_id, since this was never a resolvable construction" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "code", + "pointer", + "detail", + "definition" + ], + "title": "Unsupported", + "description": "The request was valid and fully understood, but not supported.\n\nFires for a text-door condition the request grammar or this deployment\ncannot honour: the unit binder recognises but cannot represent a unit\nphrase at all -- PPP terms, per-capita, a percent/share unit, or a scale\nword (million/billion/thousand) -- code unit_request_unsupported, or a\nrecognised facet axis this deployment cannot bind (code\nfacet_binding_unsupported). A unit phrase the request form COULD\nrepresent, but that this text failed to parse cleanly (two conflicting\ncurrencies, price bases, or base years in one ask; an incomplete \"base\nyear\" cue with no year value), is a different outcome entirely: it lands\nno_data with reason unit_not_resolved, never here. Distinct from every\nrefusal: the request was never malformed or unresolvable, so this is a\n200, not a problem-details body." + }, + "UnsupportedPart": { + "properties": { + "variable_text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Variable Text", + "description": "the variable text this part answers, in the order asked. This part's position in Resolution.parts equals the same variable_index every SSE event keyed by variable_index uses (ShapeEvent, StepEvent, SentenceEvent). Every dataset_resubmit entry kind (identity, candidates, placeholder, and parsed through its nested ParsedPart) requires its own posted variable_text, so this field is always the posted text echoed back onto the rebuilt part, never null. Null only when the whole posted query was empty or whitespace-only (raw_text door), which refuses variable_not_resolved before extraction runs and so has no text to name." + }, + "separate": { + "type": "boolean", + "title": "Separate", + "description": "true when this part was asked beside the others to be compared with them. A client resubmitting an identity, candidate set, or placeholder posts this flag on that entry to preserve the comparison. False, the default, is omitted", + "default": false + }, + "warnings": { + "items": { + "$ref": "#/components/schemas/Warning" + }, + "type": "array", + "title": "Warnings", + "description": "this part's own run-health signals. A part folded into an earlier part's spec (see DefinitePart.spec) carries binding_folded alone. The merged spec's own resolved warnings live only on the first part that carries it. An unfolded part carries the warnings raised while resolving this part, plus observations_omitted on a candidates part when response_options.include_observations was set." + }, + "timing_ms": { + "anyOf": [ + { + "$ref": "#/components/schemas/Timing" + }, + { + "type": "null" + } + ], + "description": "this part's own latency breakdown, where by_step names only the phases this part ran and total sums them, leaving out the shape_* stages nested inside shape. Excludes the shared, once-per-request steps (e.g. extract), which diagnostics.timing_ms.by_step carries once for the whole request; distinct too from diagnostics.timing_ms.total, the whole request's wall-clock elapsed time." + }, + "rendered_sentence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Rendered Sentence", + "description": "a human-readable string. For candidates, a header naming how many readings there are ('3 readings.'), then each shown candidate's heading and a byline led by the source and span that set it apart; for no_data, a heading in the same claim form naming the entity, measure, and counterpart that were checked. Either ends with the text of this part's departures, in order. For a definite part this stays null or omitted: the confirmation sentence (heading and byline) lives at spec.resolved.rendered_sentence, and its departures reach the envelope's composed sentence." + }, + "sentence_plan": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/SentenceToken" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Sentence Plan", + "description": "the ordered token form of rendered_sentence, present whenever it is. For a definite part this stays null or omitted. spec.resolved.sentence_plan carries the confirmation sentence's own plan instead." + }, + "restatement": { + "anyOf": [ + { + "$ref": "#/components/schemas/ParsedPart" + }, + { + "type": "null" + } + ], + "description": "the ParsedPart that reproduces this part's own resolution inputs -- the same entities, resolved time window, unit text, and source text the engine actually used to resolve this one leg -- so a client holding this part alone can copy it straight into a fresh ParsedInput.parts entry and re-resolve it faithfully, without flattening it into the whole query's variable_text the way variable_text alone would. Canonical, not verbatim: for a raw_text part, time_text is the equivalent phrase this door's own time grammar recognises (e.g. '2015 to 2020'), not the user's original words, since the engine's date extraction keeps only the structured window and discards the phrasing. Null whenever this part has no faithful echo to give. On a dataset_resubmit entry's identity/candidates/placeholder kinds, which post an identity or stub rather than a phrase and have no per-part resolution inputs to echo -- a dataset_resubmit parsed entry, genuinely re-resolved from its own posted ParsedPart, carries a real one like any parsed-door part. Also null when this leg's entity was bound to a directional role axis (origin/destination) and no door-supplied role named that axis, since an echo without the axis would resubmit the request with that entity reversed. Also null when one of this leg's own inputs does not fit ParsedPart's own field caps, since a truncated echo would misrepresent what was actually resolved." + }, + "operations": { + "items": { + "$ref": "#/components/schemas/Operation" + }, + "type": "array", + "title": "Operations", + "description": "the operations the question asks for over this part's data, in query order; the engine echoes them onto the part it resolves. Empty when the question asks for none" + }, + "departures": { + "items": { + "$ref": "#/components/schemas/Departure" + }, + "type": "array", + "title": "Departures", + "description": "every way this part's answer differs from what its request asked, ordered by how much each changes the number: closest_match, measure_not_applied, operation_not_applied, breakdown_not_applied, entity_unavailable, year_unavailable, modelled_values, group_read_as_members, direction_discarded, direction_inferred, scope_limited. [] when the answer is what was asked. A client that renders its own sentence reads them here; each one's text also closes the sentence that carries this part (see Departure.text). A warning on the same part reports run health and stays separate" + }, + "status": { + "type": "string", + "const": "unsupported", + "title": "Status", + "description": "valid, understood, not supported" + }, + "unsupported": { + "$ref": "#/components/schemas/Unsupported", + "description": "the reason and definition" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "status", + "unsupported" + ], + "title": "UnsupportedPart", + "description": "This part's variable was valid and understood, but not supported." + }, + "Usage": { + "properties": { + "api_access": { + "anyOf": [ + { + "$ref": "#/components/schemas/UsageEntry" + }, + { + "type": "null" + } + ] + }, + "python": { + "anyOf": [ + { + "$ref": "#/components/schemas/UsageEntry" + }, + { + "type": "null" + } + ] + } + }, + "type": "object", + "required": [ + "api_access", + "python" + ], + "title": "Usage", + "description": "`api_access`/`python` are `None` for every source -- an absent\nmember, not a stand-in object -- named in `gaps` alongside\nevery other absent member. Built by `graph_api.usage.usage_document`,\nnever constructed inline at a call site." + }, + "UsageEntry": { + "properties": { + "documentation_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Documentation Url" + }, + "code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Code" + } + }, + "type": "object", + "required": [ + "documentation_url", + "code" + ], + "title": "UsageEntry", + "description": "The shape a non-null `Usage.api_access`/`.python` entry takes. Both\nof its own members are always `None`, and no dcid produces an entry at\nall -- `graph_api.usage`'s own docstring is the record of why." + }, + "VariableDefinition": { + "properties": { + "population_type": { + "anyOf": [ + { + "$ref": "#/components/schemas/NodeRef" + }, + { + "type": "null" + } + ], + "description": "the populationType; null when the variable declares none" + }, + "measured_property": { + "anyOf": [ + { + "$ref": "#/components/schemas/NodeRef" + }, + { + "type": "null" + } + ], + "description": "the measuredProperty; null when the variable declares none" + }, + "stat_type": { + "anyOf": [ + { + "$ref": "#/components/schemas/NodeRef" + }, + { + "type": "null" + } + ], + "description": "the statType; null when the variable declares none or its read failed" + }, + "measure": { + "anyOf": [ + { + "$ref": "#/components/schemas/Measure" + }, + { + "type": "null" + } + ], + "description": "the measure the code index names; null when it names none" + }, + "roles": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Roles", + "description": "the entity roles the variable's observations carry, from its declared observationProperties, defaulting to observationAbout when it declares none" + }, + "source_indicator_codes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Source Indicator Codes", + "description": "the sourceIndicatorCode arc's values: the codes naming the source series, as the publisher codes it (IMF WEO GDP carries NGDP and NGDPD); empty when it has none" + }, + "constraints": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/Constraint" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Constraints", + "description": "each constraint the measure does not state, ordered by property dcid; null when the read of a variable's constraint values failed" + }, + "definitions": { + "items": { + "$ref": "#/components/schemas/DefinitionText" + }, + "type": "array", + "title": "Definitions", + "description": "the graph's prose per part: the variable's own, then the measure's, then each constraint value's, in constraint order; a part with none is left out" + } + }, + "type": "object", + "required": [ + "population_type", + "measured_property", + "stat_type", + "measure", + "roles", + "source_indicator_codes", + "constraints", + "definitions" + ], + "title": "GraphVariableDefinition", + "description": "What a variable measures, part by part.\n\n`constraints` are ordered by property dcid: the code index holds a variable's constraints\nas a mapping with no declared order, and the graph's `constraintProperties` arc has none." + }, + "VariableSide": { + "properties": { + "stat_var": { + "type": "string", + "maxLength": 512, + "minLength": 1, + "title": "Stat Var" + }, + "label": { + "type": "string", + "maxLength": 512, + "minLength": 1, + "title": "Label" + }, + "at_mint": { + "type": "boolean", + "const": true, + "title": "At Mint" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "stat_var" + ], + "title": "VariableSide", + "description": "One side of a composed unit that counts a variable in place of a unit, such as the\npopulation in a per-capita denominator. `stat_var` is the variable's bare dcid." + }, + "VaryingColumnModel": { + "properties": { + "column": { + "type": "string", + "title": "Column" + }, + "distinct": { + "type": "integer", + "title": "Distinct" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "column", + "distinct" + ], + "title": "VaryingColumnModel" + }, + "VersionHistoryEntry": { + "properties": { + "date": { + "type": "string", + "title": "Date", + "description": "the release date, YYYY-MM-DD" + }, + "title": { + "type": "string", + "title": "Title", + "description": "the release title, plain text" + }, + "changes": { + "items": { + "$ref": "#/components/schemas/ChangeEntry" + }, + "type": "array", + "title": "Changes", + "description": "every change, group by group in order" + } + }, + "type": "object", + "required": [ + "date", + "title", + "changes" + ], + "title": "VersionHistoryEntry", + "description": "One release of the pipeline's changelog, newest first." + }, + "VersionRef": { + "properties": { + "id": { + "type": "string", + "pattern": "^(spec_[0-9a-f]{32}|ops_[0-9a-f]{6,64})$", + "title": "Id" + }, + "content_version": { + "type": "string", + "pattern": "^(cv_[0-9a-f]{32}|ocv_[0-9a-f]{6,64})$", + "title": "Content Version" + }, + "label": { + "type": "string", + "maxLength": 512, + "minLength": 1, + "title": "Label" + }, + "at_mint": { + "type": "boolean", + "const": true, + "title": "At Mint" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "content_version" + ], + "title": "VersionRef", + "description": "A Datasets version: a `spec_` id with its `cv_` content version, or an `ops_` id with\nits `ocv_` content version, and optionally the words for it." + }, + "Warning": { + "properties": { + "code": { + "type": "string", + "title": "Code", + "description": "stable machine code from the platform registry, lower snake_case, e.g. date_coverage_partial, binding_folded" + }, + "severity": { + "type": "string", + "enum": [ + "info", + "warn", + "degraded" + ], + "title": "Severity", + "description": "the severity level" + }, + "message": { + "type": "string", + "title": "Message", + "description": "human-readable explanation of the warning" + }, + "spec_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Spec Id", + "description": "the spec_id this warning attaches to, when it concerns one returned spec specifically; omitted otherwise" + }, + "params": { + "anyOf": [ + { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Params", + "description": "the counts and labels the message states, for a client to compose its own text. observations_series_truncated: {shown, total, order}, the series shown, the confirmed series behind them, and how the shown series were chosen: 'ranked' (the most recent and largest) or 'fixed' (a selection made before values were read, not ranked by value). elected_shape_no_data: {no_data, elected}, the labels of the readings with no data and of the readings answered instead. un_system_unavailable: {places, variables, variable_labels}, the place dcids the UN front door refused, the variables of the UN reads that failed, each empty when none, and each variable's graph name, in variables order, '' where the graph holds none; a warning without params says the UN search itself was unavailable. Omitted for every other code" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "code", + "severity", + "message" + ], + "title": "Warning", + "description": "A run-health signal. Note: this name shadows the Python builtin Warning.\n\nOnly `observations_series_truncated`, `elected_shape_no_data` and `un_system_unavailable`\nset `params`. A `None` `params` is left out of every dump, so other codes' warnings stay\nexactly `{code, severity, message}` plus `spec_id` where one applies." + }, + "WarningModel": { + "properties": { + "code": { + "type": "string", + "title": "Code" + }, + "severity": { + "type": "string", + "title": "Severity" + }, + "message": { + "type": "string", + "title": "Message" + }, + "contributing_member_count": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Contributing Member Count", + "description": "stat_vars_summed only: how many StatVars with rows were summed into the collapsed frame's one series" + }, + "stat_var_ref": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Stat Var Ref", + "description": "stat_vars_summed only: the family ref, `dcid:`, that the collapsed frame's `stat_var` column carries" + }, + "stat_var_label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Stat Var Label", + "description": "stat_vars_summed only: the family's label, the string the presentation door gives `stat_var_ref` on a chart (`code_index.labels.family_label` over the spec identity: its measure partition label, then its bound slots' labels); absent when neither has a label" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "code", + "severity", + "message" + ], + "title": "WarningModel", + "description": "One manifest warning. Only `stat_vars_summed` sets the three structured fields. A `None`\nfield is left out of every dump, so other codes' warnings, on the wire and in stored version\nbodies, stay exactly `{code, severity, message}`." + }, + "WindowAll": { + "properties": { + "kind": { + "type": "string", + "const": "all", + "title": "Kind", + "default": "all" + } + }, + "additionalProperties": false, + "type": "object", + "title": "WindowAll" + }, + "WindowLatest": { + "properties": { + "kind": { + "type": "string", + "const": "latest", + "title": "Kind", + "default": "latest" + } + }, + "additionalProperties": false, + "type": "object", + "title": "WindowLatest" + }, + "WindowModel": { + "properties": { + "start": { + "type": "string", + "title": "Start", + "description": "this window's own start period label" + }, + "end": { + "type": "string", + "title": "End", + "description": "this window's own end period label" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "start", + "end" + ], + "title": "WindowModel", + "description": "A period window, its two boundary labels at the frame's grain." + }, + "WindowRange": { + "properties": { + "kind": { + "type": "string", + "const": "range", + "title": "Kind", + "default": "range" + }, + "start_year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Start Year" + }, + "end_year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "End Year" + } + }, + "additionalProperties": false, + "type": "object", + "title": "WindowRange" + }, + "WriteReplyResponse": { + "properties": { + "component_id": { + "type": "string", + "title": "Component Id", + "description": "the revised component's own id" + }, + "revision": { + "type": "integer", + "title": "Revision", + "description": "the revision this write minted, or the head left unchanged" + }, + "catalog_version": { + "type": "string", + "title": "Catalog Version", + "description": "the catalogue release this revision minted under" + }, + "composition_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Composition Id", + "description": "the composition this component belongs to, null outside one" + }, + "composition_revision": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Composition Revision", + "description": "the composition's current head revision, null outside one" + }, + "changed": { + "items": { + "$ref": "#/components/schemas/ChangedFieldModel" + }, + "type": "array", + "title": "Changed", + "description": "the patch's own fields, each paired with its prior and new value. This array is empty when the write was a no-op." + }, + "fact_summary": { + "$ref": "#/components/schemas/FactSummaryModel", + "description": "the closed, token-capped fact summary this revision reports" + }, + "resolved_payload": { + "additionalProperties": true, + "type": "object", + "title": "Resolved Payload", + "description": "the revision's stored resolved payload, verbatim: the catalogue envelope {schema_version, catalog_version, component_id, revision, provenance, component}, validated against the catalogue release's envelope schema (dfo-spec-kit envelope.schema.json) when minted. GET /api/presentation/release serves the pinned release's envelope_schema and the component_schemas its component field $refs by $id; every payload this door serves carries that pinned catalog_version." + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "component_id", + "revision", + "catalog_version", + "composition_id", + "composition_revision", + "changed", + "fact_summary", + "resolved_payload" + ], + "title": "WriteReplyResponse", + "description": "`PATCH /api/presentation/components/{component_id}`'s 200 body. A\ncreate reply carries this same shape plus `affordance`\n(`CreateReplyResponse` below). A revise reply carries no `affordance`\nkey." + }, + "YearCoverage": { + "properties": { + "year": { + "type": "integer", + "title": "Year" + }, + "series": { + "type": "integer", + "title": "Series" + }, + "role_counts": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Role Counts" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "year", + "series", + "role_counts" + ], + "title": "YearCoverage", + "description": "What the coverage index counts in one calendar year over the series a frame's\nrequests read: the series holding an observation in it and, under `role_counts`, the\ndistinct members of each role those series carry. A role is keyed by the `label` of its\nentry in the frame's `coverage.dimensions`." + }, + "YearRange": { + "properties": { + "first": { + "type": "integer", + "title": "First" + }, + "last": { + "type": "integer", + "title": "Last" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "first", + "last" + ], + "title": "YearRange" + }, + "datasets_api__capabilities__Capabilities": { + "properties": { + "capability_version": { + "type": "string", + "title": "Capability Version", + "description": "deterministic token identifying this capability set; distinct from schema_version and shared verbatim with problem-details bodies" + }, + "build": { + "type": "string", + "title": "Build", + "description": "the commit sha the image was built from, the same value the x-dfo-commit response header carries" + }, + "schema_versions": { + "items": { + "type": "integer" + }, + "type": "array", + "title": "Schema Versions", + "description": "schema_version values this deployment accepts" + }, + "operation_envelope_active": { + "type": "boolean", + "title": "Operation Envelope Active", + "description": "whether POST mint/definition doors can answer 202 with a pollable operation" + }, + "input_kinds": { + "items": { + "$ref": "#/components/schemas/CapabilityKind" + }, + "type": "array", + "title": "Input Kinds", + "description": "per-kind mint-door liveness" + }, + "formats": { + "items": { + "$ref": "#/components/schemas/CapabilityFormat" + }, + "type": "array", + "title": "Formats", + "description": "per-format rendering liveness" + }, + "bundle_active": { + "type": "boolean", + "title": "Bundle Active", + "description": "whether a mint/definition response can deliver a Frictionless Data Package" + }, + "recipe_classes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Recipe Classes", + "description": "the conversion recipes this deployment can apply, the ConversionRecipe members from materialise.recipe_bodies.RECIPE_CLASSES" + }, + "programmatic_pinning": { + "type": "boolean", + "title": "Programmatic Pinning", + "description": "whether a caller other than the site's own share/publish flow may pin" + }, + "enrichment_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Enrichment Fields", + "description": "enrichment field names this deployment enables. A live token qualifies one as {entity_column}_{field} on the columns option. party_kind is a party's kind (party, total, residual) from the code index's declaration for it. Long output writes {role}_party_kind beside {role}_label for every role on a flow axis without a token; a bare party_kind token requests it for every role on a flow axis the table has. party_kind qualifies no subject role, so observationAbout_party_kind refuses column_unknown. A party the index does not list gets an empty cell and an enrichment_unavailable warning" + }, + "decode_code_systems": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Decode Code Systems", + "description": "code systems the packaged code index declares, sorted. Decoding is always on when a rendered frame's StatVars declare one of these -- there is no opt-out. Long output writes each as a {code_system} column (the StatVar's code in that system) and a {code_system}_label column (its label); pivot output, frame-layout output (layout: \"frame\"), groupby.by and the columns option name it stat_var_{code_system}, the label column" + }, + "default_facet_policies_live": { + "type": "boolean", + "title": "Default Facet Policies Live", + "description": "whether the graph declares its own per-StatVar/per-source default facet policy; false does not mean an unbound axis refuses -- see default_facet_policy" + }, + "default_facet_policy": { + "anyOf": [ + { + "$ref": "#/components/schemas/DeploymentFacetPolicy" + }, + { + "type": "null" + } + ], + "description": "this deployment's own default-facet policy, consulted for an unbound axis once the graph declares none; null if this deployment enforces no fallback of its own" + }, + "summability_declarations_live": { + "type": "boolean", + "title": "Summability Declarations Live", + "description": "whether the graph declares its own per-axis summability; true unconditionally, the same way decode carries no separate liveness gate" + }, + "summable_axes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Summable Axes", + "description": "code systems the packaged code index declares summable, sorted -- the axes a groupby request may name in `by` to keep, with every other declared-summable axis this frame decoded collapsed into it" + }, + "groupby_level_axes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Groupby Level Axes", + "description": "code systems the packaged code index declares summable, hierarchical, and disjoint from children (a parent-coded record excludes its children's), sorted. These are the axes groupby.levels accepts, each rolled up to one depth of its parent chain (0 = root codes) before the sum" + }, + "caps": { + "$ref": "#/components/schemas/datasets_api__capabilities__CapabilityCaps", + "description": "published input limits and response caps" + }, + "code_index": { + "$ref": "#/components/schemas/datasets_api__capabilities__CodeIndexStamp", + "description": "provenance for the packaged code index" + } + }, + "type": "object", + "required": [ + "capability_version", + "build", + "schema_versions", + "operation_envelope_active", + "input_kinds", + "formats", + "bundle_active", + "recipe_classes", + "programmatic_pinning", + "enrichment_fields", + "decode_code_systems", + "default_facet_policies_live", + "default_facet_policy", + "summability_declarations_live", + "summable_axes", + "groupby_level_axes", + "caps", + "code_index" + ], + "title": "Capabilities", + "description": "The full `GET /api/datasets/capabilities` document." + }, + "datasets_api__capabilities__CapabilityCaps": { + "properties": { + "definition_candidate_cap": { + "type": "integer", + "title": "Definition Candidate Cap", + "description": "the reverse-arc page a described-arm definition's member walk reads first; a page that fills it without a confirmed root sends the walk to the whole filtered set, up to definition_subject_ceiling" + }, + "definition_subject_ceiling": { + "type": "integer", + "title": "Definition Subject Ceiling", + "description": "ceiling on the whole filtered reverse-arc set a described-arm definition's member walk reads when its first page cannot settle the family; a larger set refuses over_ceiling (candidate_window), and a walk past its read deadline answers timeout (504, retryable)" + }, + "sync_budget_rows": { + "type": "integer", + "title": "Sync Budget Rows", + "description": "sync budget: a mint/definition request whose own coverage estimate (series_coverage.index.CoverageIndex.estimate) stays at or under this many rows, and at or under sync_budget_requests SDMX requests, runs inline" + }, + "sync_budget_requests": { + "type": "integer", + "title": "Sync Budget Requests", + "description": "the SDMX request half of the sync budget -- see sync_budget_rows" + }, + "async_max_rows": { + "type": "integer", + "title": "Async Max Rows", + "description": "async ceiling: an over-sync-budget mint/definition request whose own coverage estimate (series_coverage.index.CoverageIndex.estimate) stays at or under this many rows, and at or under async_max_requests SDMX requests, is recorded as an operation and answered 202; over either, it is refused over_ceiling (ceiling_kind operation_rows) before any operation is recorded" + }, + "async_max_requests": { + "type": "integer", + "title": "Async Max Requests", + "description": "the SDMX request half of the async ceiling -- see async_max_rows; crossing this one alone refuses over_ceiling with ceiling_kind operation_requests" + }, + "pivot_max_output_cells": { + "type": "integer", + "title": "Pivot Max Output Cells", + "description": "cap on a pivot's total output cell count (rows x columns) before pivot_over_cell_cap" + }, + "operation_retention_days": { + "type": "integer", + "title": "Operation Retention Days", + "description": "how long a terminal (done/failed) operation stays guaranteed pollable (contract, 'The operation envelope'). A done operation's own manifest is guaranteed servable for exactly this long, since it is bounded by the same working-tier artifact clock every other mint/definition response is (dataset_store.snapshot.WORKING_TIER_RETENTION) -- pinning it extends that the same way pinning any other snapshot does. A daily maintenance job deletes done and failed operations last updated more than this many days ago, so a poll after that answers operation_not_found" + } + }, + "type": "object", + "required": [ + "definition_candidate_cap", + "definition_subject_ceiling", + "sync_budget_rows", + "sync_budget_requests", + "async_max_rows", + "async_max_requests", + "pivot_max_output_cells", + "operation_retention_days" + ], + "title": "CapabilityCaps", + "description": "Published input limits and response caps, one field per enforced\nconstant." + }, + "datasets_api__capabilities__CodeIndexStamp": { + "properties": { + "content_hash": { + "type": "string", + "title": "Content Hash", + "description": "digest over the exported rows; equal across two exports of the same graph state" + }, + "exported_at": { + "type": "string", + "title": "Exported At", + "description": "when the packaged index was exported from the graph" + }, + "code_counts": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Code Counts", + "description": "code count per code system this index carries -- keyed by whatever code systems the index declares, not a fixed set of named fields" + } + }, + "type": "object", + "required": [ + "content_hash", + "exported_at", + "code_counts" + ], + "title": "CodeIndexStamp", + "description": "Provenance for the packaged code index this deployment reads: which export, and how many codes it carries per code\nsystem. Published so a caller can compare `content_hash` across two\nresponses (two mints, say) and tell whether they\nresolved against the same index." + }, + "graph_api__capabilities__Capabilities": { + "properties": { + "capability_version": { + "type": "string", + "title": "Capability Version", + "description": "deterministic token identifying this capability set; distinct from schema_version and shared verbatim with problem-details bodies" + }, + "build": { + "type": "string", + "title": "Build", + "description": "the commit sha the running image was built from" + }, + "data_builds": { + "$ref": "#/components/schemas/DataBuilds", + "description": "the data builds this process serves; they change without a deploy and leave capability_version unchanged" + }, + "doors": { + "items": { + "$ref": "#/components/schemas/graph_api__capabilities__CapabilityDoor" + }, + "type": "array", + "title": "Doors", + "description": "per-door liveness" + }, + "kinds": { + "items": { + "type": "string", + "enum": [ + "country", + "continent", + "subregion", + "continental_union", + "place_other", + "aggregate", + "organisation", + "group", + "stat_var", + "code_system", + "code", + "unit", + "source", + "dataset", + "provenance", + "other" + ] + }, + "type": "array", + "title": "Kinds", + "description": "the closed kind list resolve and the node route classify entities by" + }, + "resolve_kinds": { + "items": { + "type": "string", + "enum": [ + "country", + "continent", + "subregion", + "continental_union", + "place_other", + "aggregate", + "organisation", + "group", + "stat_var", + "code_system", + "code", + "unit", + "source", + "dataset", + "provenance", + "other" + ] + }, + "type": "array", + "title": "Resolve Kinds", + "description": "the kinds POST /api/graph/resolve accepts in its kinds filter" + }, + "recipe_classes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Recipe Classes", + "description": "live unit-conversion recipe classes; empty, no conversion machinery" + }, + "node_shape_gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Node Shape Gaps", + "description": "member paths the node door names in gaps on every node that carries the member, whatever the node" + }, + "source_document_gaps": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Source Document Gaps", + "description": "member paths the sources door's own documentation document always empties, whatever the source -- materialise.provenance_doc.UNCONDITIONAL_GAPS" + }, + "source_catalogue_curated": { + "type": "boolean", + "title": "Source Catalogue Curated", + "description": "whether GET /api/graph/sources serves the real curated allowlist rather than a sample standing in for one" + }, + "caps": { + "$ref": "#/components/schemas/graph_api__capabilities__CapabilityCaps", + "description": "published input limits" + } + }, + "type": "object", + "required": [ + "capability_version", + "build", + "data_builds", + "doors", + "kinds", + "resolve_kinds", + "recipe_classes", + "node_shape_gaps", + "source_document_gaps", + "source_catalogue_curated", + "caps" + ], + "title": "GraphCapabilities", + "description": "The full `GET /api/graph/capabilities` document." + }, + "graph_api__capabilities__CapabilityCaps": { + "properties": { + "node_pool_size": { + "type": "integer", + "title": "Node Pool Size", + "description": "the bounded DCP-read executor's own worker count, shared by resolve confirmation reads and every node read" + }, + "resolve_timeout_seconds": { + "type": "integer", + "title": "Resolve Timeout Seconds", + "description": "ceiling on how long a client waits for POST /api/graph/resolve before a timeout refusal" + }, + "node_timeout_seconds": { + "type": "integer", + "title": "Node Timeout Seconds", + "description": "ceiling on how long a client waits for GET /api/graph/node/{dcid}, POST /api/graph/nodes, or GET /api/graph/documentation/{dcid} before a timeout refusal; GET /api/graph/node/{dcid}/members bounds its graph reads by it, and a label or profile read it cuts short leaves a gap" + }, + "max_dcid_chars": { + "type": "integer", + "title": "Max Dcid Chars", + "description": "ceiling on the length of the dcid path parameter of GET /api/graph/node/{dcid} and GET /api/graph/documentation/{dcid}, and of each dcid POST /api/graph/nodes takes; a longer value is refused 400 request_invalid" + }, + "max_node_batch_dcids": { + "type": "integer", + "title": "Max Node Batch Dcids", + "description": "the most dcids one POST /api/graph/nodes request names; a longer list is refused 400 request_invalid" + } + }, + "type": "object", + "required": [ + "node_pool_size", + "resolve_timeout_seconds", + "node_timeout_seconds", + "max_dcid_chars", + "max_node_batch_dcids" + ], + "title": "GraphCapabilityCaps", + "description": "Published input limits, one field per enforced constant." + }, + "graph_api__capabilities__CapabilityDoor": { + "properties": { + "name": { + "type": "string", + "title": "Name", + "description": "resolve, node, members, roots, sources, or schema" + }, + "live": { + "type": "boolean", + "title": "Live", + "description": "whether this deployment serves this door" + } + }, + "type": "object", + "required": [ + "name", + "live" + ], + "title": "CapabilityDoor", + "description": "One door's liveness in this deployment." + }, + "graph_api__origin_models__DataCommonsRef": { + "properties": { + "id": { + "type": "string", + "enum": [ + "dfo", + "base", + "un_system" + ], + "title": "Id" + }, + "label": { + "type": "string", + "title": "Label" + } + }, + "type": "object", + "required": [ + "id", + "label" + ], + "title": "GraphDataCommonsRef", + "description": "The Data Commons that serves a fact. `id` is the wire enum; `label` its display name." + }, + "graph_api__resolve_models__ResolveRequest": { + "properties": { + "texts": { + "items": { + "type": "string", + "maxLength": 200, + "minLength": 1 + }, + "type": "array", + "maxItems": 25, + "minItems": 1, + "title": "Texts" + }, + "kinds": { + "items": { + "type": "string", + "enum": [ + "country", + "continent", + "subregion", + "continental_union", + "organisation", + "aggregate", + "place_other", + "group", + "code", + "other" + ] + }, + "type": "array", + "minItems": 1, + "title": "Kinds", + "default": [ + "country", + "continent", + "subregion", + "continental_union", + "organisation", + "aggregate", + "place_other", + "group" + ] + }, + "code_system": { + "anyOf": [ + { + "type": "string", + "maxLength": 200, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Code System" + }, + "expand": { + "items": { + "type": "string", + "const": "members" + }, + "type": "array", + "title": "Expand", + "default": [] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "texts" + ], + "title": "GraphResolveRequest", + "description": "`texts`: 1 to 25 strings resolved as one batch. Each is stripped of surrounding\nwhitespace and must then be 1 to 200 characters.\n\n`kinds` admits only candidates of those kinds. It defaults to `DEFAULT_RESOLVE_KINDS`, so a\nrequest that omits it equals one naming those eight. `code` searches the code index's labels\nand synonyms, and `code_system` narrows codes to one system's graph id\n(`CRSPurposeCodeEnum`); naming `code_system` without `code` in `kinds` is refused at\n`/code_system`. `expand: [\"members\"]` inlines a group's or region's members." + }, + "search__engine__capabilities__Capabilities": { + "properties": { + "capability_version": { + "type": "string", + "title": "Capability Version", + "description": "deterministic token identifying this capability set; distinct from schema_version and shared verbatim with problem-details bodies and resolved.trace" + }, + "build": { + "type": "string", + "title": "Build", + "description": "the commit sha the running image was built from, the same value the x-dfo-commit response header carries" + }, + "axes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Axes", + "description": "valid SlotKey.axis values. Contract-frozen (a schema_version-locked enum, search.models.Axis), republished here for convenience so a caller need not parse the full JSON Schema to enumerate them" + }, + "facet_axes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Facet Axes", + "description": "valid facet-axis names (BaseIdentity.facets / ResubmitIdentityPayload.identity.facets keys), distinct from axes above -- search.models.FacetAxis, a separate vocabulary from SlotKey.axis. Schema-locked like axes: this vocabulary changes only with a schema_version bump, so unlike recipe_classes or the caps below, it is NOT one of capability_version's hash inputs -- schema_version already covers it" + }, + "recipe_classes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Recipe Classes", + "description": "the conversion recipe members this deployment applies (resolved.observations.series[].conversion.recipe_id), the sorted keys of materialise.recipe_bodies.RECIPE_BODIES, so the list and the applied recipes cannot drift apart" + }, + "doors": { + "items": { + "$ref": "#/components/schemas/search__engine__capabilities__CapabilityDoor" + }, + "type": "array", + "title": "Doors", + "description": "per-door liveness" + }, + "default_policies": { + "items": { + "$ref": "#/components/schemas/CapabilityDefaultPolicy" + }, + "type": "array", + "title": "Default Policies", + "description": "declared default policies and whether each is live" + }, + "caps": { + "$ref": "#/components/schemas/search__engine__capabilities__CapabilityCaps", + "description": "published caps and input limits" + }, + "code_index": { + "$ref": "#/components/schemas/search__engine__capabilities__CodeIndexStamp", + "description": "provenance for the packaged code index" + } + }, + "type": "object", + "required": [ + "capability_version", + "build", + "axes", + "facet_axes", + "recipe_classes", + "doors", + "default_policies", + "caps", + "code_index" + ], + "title": "SearchCapabilities", + "description": "The full GET /api/search/capabilities document." + }, + "search__engine__capabilities__CapabilityCaps": { + "properties": { + "max_query_chars": { + "type": "integer", + "title": "Max Query Chars", + "description": "raw_text.query character ceiling; over this refuses query_too_long" + }, + "max_candidates": { + "type": "integer", + "title": "Max Candidates", + "description": "server ceiling enforced two ways: a resolved candidate set is clamped to this length, while a dataset_resubmit candidates entry posting more candidates than this refuses request_invalid at /input/entries/{i}/candidates rather than being clamped" + }, + "max_variables": { + "type": "integer", + "title": "Max Variables", + "description": "variables resolved per query before the rest are dropped with variables_clamped" + }, + "obs_preview_points": { + "type": "integer", + "title": "Obs Preview Points", + "description": "latest points per series carried once observation preview mode applies" + }, + "obs_inline_max": { + "type": "integer", + "title": "Obs Inline Max", + "description": "total observation points above which every series switches to preview mode" + }, + "role_bulk_rank_max_rows": { + "type": "integer", + "title": "Role Bulk Rank Max Rows", + "description": "rows a role-bearing bulk preview may read whole and rank, most recent and largest first; above this it shows a fixed selection, and its observations_series_truncated warning says so with params.order" + }, + "max_options": { + "type": "integer", + "title": "Max Options", + "description": "ceiling on the options door's candidate lists before truncation: graph-enumerated observationAbout candidates, and the sdmx-derived provider and recipient candidate lists alike" + }, + "max_parts": { + "type": "integer", + "title": "Max Parts", + "description": "parsed.parts list length ceiling; a request over this refuses request_invalid. Distinct from max_variables: raw_text clamps an over-limit extraction with a variables_clamped warning and keeps resolving, while parsed enforces this as a hard schema cap" + }, + "max_part_entities": { + "type": "integer", + "title": "Max Part Entities", + "description": "parsed part entities list length ceiling; over this refuses request_invalid" + }, + "max_variable_text_chars": { + "type": "integer", + "title": "Max Variable Text Chars", + "description": "parsed part variable_text character ceiling; over this refuses request_invalid" + }, + "max_entity_text_chars": { + "type": "integer", + "title": "Max Entity Text Chars", + "description": "parsed entity text character ceiling; over this refuses request_invalid" + }, + "max_role_text_chars": { + "type": "integer", + "title": "Max Role Text Chars", + "description": "parsed entity role_text character ceiling; over this refuses request_invalid" + }, + "max_time_text_chars": { + "type": "integer", + "title": "Max Time Text Chars", + "description": "parsed part time_text character ceiling; over this refuses request_invalid" + }, + "max_unit_text_chars": { + "type": "integer", + "title": "Max Unit Text Chars", + "description": "parsed part unit_text character ceiling; over this refuses request_invalid" + }, + "max_source_text_chars": { + "type": "integer", + "title": "Max Source Text Chars", + "description": "parsed part source_text character ceiling; over this refuses request_invalid" + }, + "region_max_members": { + "type": "integer", + "title": "Region Max Members", + "description": "ceiling on the alt-shape population region resolution pre-warms observation facets for; over this, the pre-warm is skipped rather than refused" + }, + "scope_min_year": { + "type": "integer", + "title": "Scope Min Year", + "description": "earliest year role-scope discovery will request; an open-started requested window floors here rather than reaching further back" + }, + "scope_max_window_years": { + "type": "integer", + "title": "Scope Max Window Years", + "description": "ceiling on a requested window's year span for a role-bearing read, named or discovered; over this refuses scope_too_broad" + } + }, + "type": "object", + "required": [ + "max_query_chars", + "max_candidates", + "max_variables", + "obs_preview_points", + "obs_inline_max", + "role_bulk_rank_max_rows", + "max_options", + "max_parts", + "max_part_entities", + "max_variable_text_chars", + "max_entity_text_chars", + "max_role_text_chars", + "max_time_text_chars", + "max_unit_text_chars", + "max_source_text_chars", + "region_max_members", + "scope_min_year", + "scope_max_window_years" + ], + "title": "SearchCapabilityCaps", + "description": "Published caps and input limits, one field per enforced constant." + }, + "search__engine__capabilities__CapabilityDoor": { + "properties": { + "name": { + "type": "string", + "title": "Name", + "description": "raw_text, parsed, dataset_resubmit, or options" + }, + "live": { + "type": "boolean", + "title": "Live", + "description": "whether this deployment serves this door" + } + }, + "type": "object", + "required": [ + "name", + "live" + ], + "title": "SearchCapabilityDoor", + "description": "One door's liveness in this deployment." + }, + "search__engine__capabilities__CodeIndexStamp": { + "properties": { + "content_hash": { + "type": "string", + "title": "Content Hash", + "description": "digest over the exported rows; equal across two exports of the same graph state" + }, + "exported_at": { + "type": "string", + "title": "Exported At", + "description": "when the packaged index was exported from the graph" + }, + "code_counts": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Code Counts", + "description": "code count per code system this index carries -- keyed by whatever code systems the index declares, not a fixed set of named fields" + } + }, + "type": "object", + "required": [ + "content_hash", + "exported_at", + "code_counts" + ], + "title": "SearchCodeIndexStamp", + "description": "Provenance for the packaged code index this deployment's constraint\nresolution reads: which export, and how many codes it carries per code\nsystem. Not one of `capability_version`'s hash inputs (see\n`search.engine.config.settings().capability_version`, computed from static\nconfig constants alone) -- published here as its own field so a caller\ncan compare `content_hash` across two responses (e.g. a preview and a\nlater download) and tell whether they resolved against the same index." + }, + "search__models__grammar__DataCommonsRef": { + "properties": { + "id": { + "type": "string", + "enum": [ + "dfo", + "base", + "un_system" + ], + "title": "Id", + "description": "'dfo', 'base' or 'un_system'" + }, + "label": { + "type": "string", + "title": "Label", + "description": "the Data Commons' display name: Development Finance Observatory, Data Commons by Google, or UN System Data Commons" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "label" + ], + "title": "DataCommonsRef", + "description": "The Data Commons a provenance's data comes from." + }, + "search__models__request__ResolveRequest": { + "properties": { + "schema_version": { + "type": "integer", + "const": 1, + "title": "Schema Version", + "description": "contract version the caller targets", + "default": 1 + }, + "input": { + "oneOf": [ + { + "$ref": "#/components/schemas/RawTextInput" + }, + { + "$ref": "#/components/schemas/ParsedInput" + }, + { + "$ref": "#/components/schemas/DatasetResubmitInput" + } + ], + "title": "Input", + "description": "tagged union; kind discriminates", + "discriminator": { + "propertyName": "kind", + "mapping": { + "dataset_resubmit": "#/components/schemas/DatasetResubmitInput", + "parsed": "#/components/schemas/ParsedInput", + "raw_text": "#/components/schemas/RawTextInput" + } + } + }, + "response_options": { + "anyOf": [ + { + "$ref": "#/components/schemas/ResolveOptions" + }, + { + "type": "null" + } + ], + "description": "optional resolution options" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "input" + ], + "title": "ResolveRequest", + "description": "The single request type for the Search resolve endpoint." + }, + "ProblemDetails": { + "description": "RFC 9457 problem-details body for every non-2xx response.\n\nStandard base fields (type, title, status, detail) plus the platform\nregistry's stable extensions (code, pointer, alternatives, truncated,\nissues, constraint_id, trace_id, capability_version, retryable). Optional\nmembers (pointer, alternatives, truncated, issues, constraint_id) are\nomitted from the wire body when absent -- callers should serialize with\n``model_dump(mode=\"json\", exclude_none=True)``, which ``to_json`` does.", + "properties": { + "type": { + "description": "a relative URI reference to the code's registry entry", + "title": "Type", + "type": "string" + }, + "title": { + "description": "short, human-readable summary of the problem type", + "title": "Title", + "type": "string" + }, + "status": { + "description": "the HTTP status code", + "title": "Status", + "type": "integer" + }, + "detail": { + "description": "human-readable explanation of this occurrence", + "title": "Detail", + "type": "string" + }, + "code": { + "description": "the stable machine-readable code from the platform registry", + "title": "Code", + "type": "string" + }, + "pointer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "a JSON Pointer into the request body naming the field at fault", + "title": "Pointer" + }, + "alternatives": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/Alternative" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "description": "values that would satisfy this request, when known", + "title": "Alternatives" + }, + "truncated": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "description": "present iff alternatives is present; whether the cap cut items", + "title": "Truncated" + }, + "issues": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/ProblemIssue" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "description": "one entry per failure, for a refusal code that reports several at once", + "title": "Issues" + }, + "cause": { + "anyOf": [ + { + "$ref": "#/components/schemas/Cause" + }, + { + "type": "null" + } + ], + "default": null, + "description": "why the refusal fired, for the two codes that carry one -- omitted otherwise" + }, + "constraint_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "the machine-keyable id of the constraint this refusal violates, when known", + "title": "Constraint Id" + }, + "ceiling_kind": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "for over_ceiling: which ceiling was crossed -- member_cardinality, candidate_window, rows, or bytes", + "title": "Ceiling Kind" + }, + "count": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "description": "for over_ceiling: the observed count, in ceiling_kind's own unit, that crossed cap -- omitted only when the count itself is unmeasured, never when it is merely large. Under candidate_window it is the candidates the read actually returned, at most cap: a read that fills its window returns exactly cap, and one that stops early on a surviving continuation token returns fewer", + "title": "Count" + }, + "cap": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "description": "for over_ceiling: the ceiling, in ceiling_kind's own unit, that count crossed. Under candidate_window it is the candidate window the read was allowed", + "title": "Cap" + }, + "trace_id": { + "description": "this request's trace_id, shared with diagnostics and the SSE done event", + "title": "Trace Id", + "type": "string" + }, + "capability_version": { + "description": "the deployment capability version that produced this response", + "title": "Capability Version", + "type": "string" + }, + "retryable": { + "description": "whether retrying the same request might succeed", + "title": "Retryable", + "type": "boolean" + } + }, + "required": [ + "type", + "title", + "status", + "detail", + "code", + "trace_id", + "capability_version", + "retryable" + ], + "title": "ProblemDetails", + "type": "object" + }, + "Alternative": { + "description": "One value that would satisfy the request in place of what was posted.", + "properties": { + "ref": { + "description": "the alternative's own reference (e.g. a code or id)", + "title": "Ref", + "type": "string" + }, + "label": { + "description": "the alternative's human-readable label", + "title": "Label", + "type": "string" + } + }, + "required": [ + "ref", + "label" + ], + "title": "Alternative", + "type": "object" + }, + "ProblemIssue": { + "description": "One failure among several a single refusal can report at once.\n\nEach issue carries its own pointer, the member or axis it concerns, its\nown alternatives and truncation flag, and the machine code and message of\nthe failure it stands for -- mirroring the same-named top-level\nProblemDetails fields, but scoped to one entry among many.\nFields default to None and are omitted from the wire body when absent\n(the envelope's omit-when-absent rule).", + "properties": { + "pointer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "a JSON Pointer into the request body naming the field at fault", + "title": "Pointer" + }, + "member": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "the member this issue concerns, when the refusal is member-scoped", + "title": "Member" + }, + "axis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "the axis this issue concerns, when the refusal is axis-scoped", + "title": "Axis" + }, + "alternatives": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/Alternative" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "description": "values that would satisfy this issue, when known", + "title": "Alternatives" + }, + "truncated": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "description": "present iff alternatives is present; whether the cap cut items", + "title": "Truncated" + }, + "code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "the stable machine-readable code of the failure this issue stands for", + "title": "Code" + }, + "detail": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "human-readable explanation of the failure this issue stands for", + "title": "Detail" + } + }, + "title": "ProblemIssue", + "type": "object" + } + } + } +} diff --git a/python/client-contract/src/dfo_client_contract/strict-fields.json b/python/client-contract/src/dfo_client_contract/strict-fields.json new file mode 100644 index 0000000..e5e1f5a --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/strict-fields.json @@ -0,0 +1,133 @@ +{ + "format_version": 1, + "required": [ + { + "pointer": "/components/schemas/Resolution/properties/parts" + }, + { + "pointer": "/components/schemas/DefinitePart/properties/status" + }, + { + "pointer": "/components/schemas/DefinitePart/properties/spec" + }, + { + "pointer": "/components/schemas/CandidatesPart/properties/status" + }, + { + "pointer": "/components/schemas/CandidatesPart/properties/candidates" + }, + { + "pointer": "/components/schemas/CandidateSet/properties/specs" + }, + { + "pointer": "/components/schemas/NoDataPart/properties/status" + }, + { + "pointer": "/components/schemas/NoDataPart/properties/no_data" + }, + { + "pointer": "/components/schemas/NoData/properties/reason" + }, + { + "pointer": "/components/schemas/UnsupportedPart/properties/status" + }, + { + "pointer": "/components/schemas/UnsupportedPart/properties/unsupported" + }, + { + "pointer": "/components/schemas/Unsupported/properties/code" + }, + { + "pointer": "/components/schemas/Spec/properties/spec_id" + }, + { + "pointer": "/components/schemas/Spec/properties/definition" + }, + { + "pointer": "/components/schemas/SpecDefinition/properties/spec_id" + }, + { + "pointer": "/components/schemas/Manifest/properties/definition" + }, + { + "pointer": "/components/schemas/Manifest/properties/content_version" + }, + { + "pointer": "/components/schemas/Manifest/properties/artifacts" + }, + { + "pointer": "/components/schemas/DefinitionModel/properties/spec_id" + }, + { + "pointer": "/components/schemas/ArtifactEntryModel/properties/artifact_digest" + }, + { + "pointer": "/components/schemas/ArtifactEntryModel/properties/rendering" + }, + { + "pointer": "/components/schemas/ArtifactEntryModel/properties/url" + }, + { + "pointer": "/components/schemas/OperationResource/properties/operation" + }, + { + "pointer": "/components/schemas/OperationEnvelope/properties/operation_id" + }, + { + "pointer": "/components/schemas/OperationEnvelope/properties/status" + } + ], + "enums": [ + { + "pointer": "/components/schemas/Resolution/properties/kind", + "values": [ + "resolution" + ] + }, + { + "pointer": "/components/schemas/CatalogueAnswer/properties/kind", + "values": [ + "catalogue" + ] + }, + { + "pointer": "/components/schemas/DeclinedAnswer/properties/kind", + "values": [ + "declined" + ] + }, + { + "pointer": "/components/schemas/DefinitePart/properties/status", + "values": [ + "definite" + ] + }, + { + "pointer": "/components/schemas/CandidatesPart/properties/status", + "values": [ + "candidates" + ] + }, + { + "pointer": "/components/schemas/NoDataPart/properties/status", + "values": [ + "no_data" + ] + }, + { + "pointer": "/components/schemas/UnsupportedPart/properties/status", + "values": [ + "unsupported" + ] + }, + { + "pointer": "/components/schemas/OperationEnvelope/properties/status", + "values": [ + "pending", + "running", + "done", + "failed" + ] + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/strict-fields.schema.json b/python/client-contract/src/dfo_client_contract/strict-fields.schema.json new file mode 100644 index 0000000..87fa350 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/strict-fields.schema.json @@ -0,0 +1,67 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/python/client-contract/src/dfo_client_contract/strict-fields.schema.json", + "title": "Strict fields", + "description": "The response members the DFO clients act on. Each pointer names one property of one component schema in served/openapi.json. A required entry stays required and non-nullable; an enum entry keeps every listed value.", + "type": "object", + "additionalProperties": false, + "required": [ + "format_version", + "required", + "enums" + ], + "properties": { + "format_version": { + "const": 1 + }, + "required": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "pointer" + ], + "properties": { + "pointer": { + "$ref": "#/$defs/pointer" + } + } + } + }, + "enums": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "pointer", + "values" + ], + "properties": { + "pointer": { + "$ref": "#/$defs/pointer" + }, + "values": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1 + } + } + } + } + } + }, + "$defs": { + "pointer": { + "description": "An RFC 6901 pointer into served/openapi.json naming one property of one component schema.", + "type": "string", + "pattern": "^/components/schemas/[A-Za-z0-9_.-]+/properties/[A-Za-z0-9_]+$" + } + } +} diff --git a/python/client-contract/tests/__init__.py b/python/client-contract/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/python/client-contract/tests/test_contract.py b/python/client-contract/tests/test_contract.py new file mode 100644 index 0000000..c74ed52 --- /dev/null +++ b/python/client-contract/tests/test_contract.py @@ -0,0 +1,45 @@ +"""The accessors read the packaged contract, and a missing record set fails +loudly rather than reading as an empty suite.""" + +from __future__ import annotations + +from pathlib import Path + +import pytest + +import dfo_client_contract +from dfo_client_contract import contract + + +def test_every_rule_file_is_listed() -> None: + rules_dir = dfo_client_contract.contract_dir() / "rules" + files = {p.stem for p in rules_dir.glob("*.json")} - {"rules.schema"} + assert files == set(dfo_client_contract.RULES) + + +def test_the_served_document_names_its_commit() -> None: + source = dfo_client_contract.served_source() + assert dfo_client_contract.openapi()["openapi"].startswith("3.") + assert len(source["commit"]) == 40 + + +def test_records_load() -> None: + assert dfo_client_contract.scenarios() + assert dfo_client_contract.ref_examples() + + +@pytest.mark.parametrize("load", [contract.scenarios, contract.ref_examples]) +def test_an_empty_record_set_is_a_hard_failure( + load: object, tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + (tmp_path / "scenarios").mkdir() + (tmp_path / "refs").mkdir() + monkeypatch.setattr(contract, "contract_dir", lambda: tmp_path) + assert callable(load) + with pytest.raises(RuntimeError, match="no records found"): + load() + + +def test_an_unknown_rule_is_refused() -> None: + with pytest.raises(ValueError, match="unknown rule"): + dfo_client_contract.rule("cache") diff --git a/python/client-contract/tests/test_isolation.py b/python/client-contract/tests/test_isolation.py new file mode 100644 index 0000000..42ceef6 --- /dev/null +++ b/python/client-contract/tests/test_isolation.py @@ -0,0 +1,36 @@ +"""`import dfo_client_contract` loads nothing beyond the standard library. + +Checked against `sys.modules` in a fresh interpreter, so a transitive import +counts, and modules the test process has already imported do not. +""" + +from __future__ import annotations + +import subprocess +import sys + +_SCRIPT = """ +import sys +before = frozenset(sys.modules) +import dfo_client_contract +leaked = sorted( + {name.split(".")[0] for name in sys.modules if name not in before} + - {"dfo_client_contract"} + - set(sys.stdlib_module_names) +) +if leaked: + raise SystemExit("leaked modules: " + ", ".join(leaked)) +print("isolation-ok") +""" + + +def test_import_stays_within_the_standard_library() -> None: + result = subprocess.run( + [sys.executable, "-c", _SCRIPT], + capture_output=True, + text=True, + timeout=30, + check=False, + ) + assert result.returncode == 0, result.stderr + assert "isolation-ok" in result.stdout diff --git a/python/client-contract/tests/test_rules.py b/python/client-contract/tests/test_rules.py new file mode 100644 index 0000000..73a1086 --- /dev/null +++ b/python/client-contract/tests/test_rules.py @@ -0,0 +1,213 @@ +"""Replay every rule vector through a reference implementation of its rule. + +The rules are stated in `dfo_client_contract/rules/README.md`; each function +here is the shortest faithful reading of one of them, so a vector that +disagrees with its rule fails here before a client replays it. +""" + +from __future__ import annotations + +import ntpath +import posixpath +import re +import tomllib +import zlib +from typing import Any + +import pytest + +from dfo_client_contract import RULES, rule + +_BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" +_KEY_PREFIXES = ("dfo_k_", "dfo_p_") +_TABLE = re.compile(r"\[([A-Za-z0-9_-]+)\]") +_ENTRY = re.compile(r'([A-Za-z0-9_-]+)[ \t]*=[ \t]*"([^"\\\x00-\x1f\x7f]*)"') + + +class RuleError(Exception): + def __init__(self, reason: str, line: int | None = None) -> None: + super().__init__(reason) + self.reason = reason + self.line = line + + +def _vectors(name: str) -> list[dict[str, Any]]: + return rule(name)["vectors"] + + +def _ids(name: str) -> list[str]: + return [vector["name"] for vector in _vectors(name)] + + +def _set(env: dict[str, str], name: str) -> str | None: + return env.get(name) or None + + +def _base62(number: int) -> str: + digits = "" + while number: + number, remainder = divmod(number, 62) + digits = _BASE62[remainder] + digits + return digits.rjust(6, "0") + + +def check_key(key: str) -> str | None: + if not key.startswith(_KEY_PREFIXES): + return "unknown_prefix" + rest = key[len(_KEY_PREFIXES[0]) :] + if any(char not in _BASE62 for char in rest): + return "not_base62" + body, checksum = rest[:-6], rest[-6:] + if not body or _base62(zlib.crc32(body.encode("ascii"))) != checksum: + return "checksum_mismatch" + return None + + +def credentials_path(platform: str, home: str, env: dict[str, str]) -> str: + if explicit := _set(env, "DFO_CREDENTIALS_FILE"): + return explicit + if platform == "windows": + appdata = _set(env, "APPDATA") or ntpath.join(home, "AppData", "Roaming") + return ntpath.join(appdata, "dfo", "credentials.toml") + config = _set(env, "XDG_CONFIG_HOME") or posixpath.join(home, ".config") + return posixpath.join(config, "dfo", "credentials.toml") + + +def parse_credentials(text: str) -> dict[str, dict[str, str]]: + profiles: dict[str, dict[str, str]] = {} + table: dict[str, str] | None = None + for number, raw in enumerate(text.split("\n"), start=1): + line = raw.removesuffix("\r").strip(" \t") + if not line or line.startswith("#"): + continue + if match := _TABLE.fullmatch(line): + if match[1] in profiles: + raise RuleError("duplicate_table", number) + table = profiles[match[1]] = {} + elif match := _ENTRY.fullmatch(line): + if table is None: + raise RuleError("outside_table", number) + if match[1] in table: + raise RuleError("duplicate_key", number) + table[match[1]] = match[2] + else: + raise RuleError("invalid_line", number) + return profiles + + +def look_up_key(vector: dict[str, Any]) -> tuple[str, str | None]: + env = vector["env"] + api_key = vector.get("api_key") + if api_key is False: + return "anonymous", None + if api_key is not None: + return "argument", api_key + if from_env := _set(env, "DFO_API_KEY"): + return "environment", from_env + if vector["file"] is None: + return "anonymous", None + try: + profiles = parse_credentials(vector["file"]) + except RuleError as error: + raise RuleError("credentials_file_invalid") from error + named = _set(env, "DFO_PROFILE") + profile = profiles.get(named or "default") + if profile is None: + if named: + raise RuleError("profile_not_found") + return "anonymous", None + if "key" not in profile: + raise RuleError("profile_without_key") + return "credentials_file", profile["key"] + + +def cache_root(vector: dict[str, Any]) -> str: + platform, home, env = vector["platform"], vector["home"], vector["env"] + path = ntpath if platform == "windows" else posixpath + chosen = ( + vector.get("cache_dir") + or _set(env, "DFO_CACHE_DIR") + or _set(env, "BBLOCKS_CACHE_DIR") + ) + if chosen: + if chosen == "~" or chosen.startswith(("~/", "~\\")): + chosen = home + chosen[1:] + return path.normpath(chosen) + if platform == "windows": + local = _set(env, "LOCALAPPDATA") or ntpath.join(home, "AppData", "Local") + return ntpath.join(local, "readerkit", "Cache") + if platform == "macos": + return posixpath.join(home, "Library", "Caches", "readerkit") + xdg = (env.get("XDG_CACHE_HOME") or "").strip() or posixpath.join(home, ".cache") + return posixpath.join(xdg, "readerkit") + + +def cache_entry(vector: dict[str, Any]) -> str: + if vector["entry"] == "file": + return "files/sha256/" + vector["digest"].removeprefix("sha256:") + rendering = vector["rendering"] + key = rendering["format"] + if rendering["bundle"]: + key += "-bundle" + if rendering.get("layout") == "frame": + key += "-frame" + return f"manifests/{vector['spec_id']}/{vector['content_version']}/{key}.json" + + +@pytest.mark.parametrize("name", RULES) +def test_every_rule_has_vectors(name: str) -> None: + assert rule(name)["rule"] == name + assert _vectors(name) + + +@pytest.mark.parametrize("vector", _vectors("key-format"), ids=_ids("key-format")) +def test_key_format(vector: dict[str, Any]) -> None: + assert check_key(vector["key"]) == vector.get("reason") + + +@pytest.mark.parametrize( + "vector", _vectors("credentials-path"), ids=_ids("credentials-path") +) +def test_credentials_path(vector: dict[str, Any]) -> None: + path = credentials_path(vector["platform"], vector["home"], vector["env"]) + assert path == vector["path"] + + +@pytest.mark.parametrize( + "vector", _vectors("credentials-file"), ids=_ids("credentials-file") +) +def test_credentials_file(vector: dict[str, Any]) -> None: + if "error" in vector: + with pytest.raises(RuleError) as excinfo: + parse_credentials(vector["text"]) + assert (excinfo.value.reason, excinfo.value.line) == ( + vector["error"]["reason"], + vector["error"]["line"], + ) + return + assert parse_credentials(vector["text"]) == vector["profiles"] + # The format is a subset of TOML: any TOML reader reads the same profiles. + assert tomllib.loads(vector["text"]) == vector["profiles"] + + +@pytest.mark.parametrize("vector", _vectors("key-lookup"), ids=_ids("key-lookup")) +def test_key_lookup(vector: dict[str, Any]) -> None: + if "error" in vector: + with pytest.raises(RuleError) as excinfo: + look_up_key(vector) + assert excinfo.value.reason == vector["error"]["reason"] + return + assert look_up_key(vector) == (vector["source"], vector["key"]) + + +@pytest.mark.parametrize("vector", _vectors("cache-dir"), ids=_ids("cache-dir")) +def test_cache_dir(vector: dict[str, Any]) -> None: + path = ntpath if vector["platform"] == "windows" else posixpath + root = cache_root(vector) + assert root == vector["root"] + assert path.join(root, "v1", "dfo", "cache1") == vector["directory"] + + +@pytest.mark.parametrize("vector", _vectors("cache-layout"), ids=_ids("cache-layout")) +def test_cache_layout(vector: dict[str, Any]) -> None: + assert cache_entry(vector) == vector["path"] diff --git a/python/client-contract/uv.lock b/python/client-contract/uv.lock new file mode 100644 index 0000000..bee0e2a --- /dev/null +++ b/python/client-contract/uv.lock @@ -0,0 +1,567 @@ +version = 1 +revision = 3 +requires-python = ">=3.12" + +[[package]] +name = "attrs" +version = "26.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055, upload-time = "2026-03-19T14:22:25.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" }, +] + +[[package]] +name = "cfgv" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334, upload-time = "2025-11-19T20:55:51.612Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "coverage" +version = "7.16.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2f/55/d1eaf3e73781174340a00dc1ba2aee8a65f82fadb18e2797b192b6b3925b/coverage-7.16.2.tar.gz", hash = "sha256:ca64d9f1f384f151b9511bec01126072acd2f313439f8ed015a22d8790aab6fa", size = 971999, upload-time = "2026-09-27T12:29:01.118Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5e/2c/f8296c63c5d542f3d21aed685e56b7031a419037d155bb3382fc0940d249/coverage-7.16.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:218d742afca2b5ad5ca759e93eddedfbcc6eadf8322f080dcefc40b7bd4e2d48", size = 223969, upload-time = "2026-09-27T12:26:16.753Z" }, + { url = "https://files.pythonhosted.org/packages/90/23/6f3dcb1423a0d43216e402ea1746e4a7c7c44f38896b97dd573790f56a40/coverage-7.16.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a9a638be322a8d76a41cdb17781c7f82aaee6a66493d8ffb7e2c09ee22423d99", size = 224328, upload-time = "2026-09-27T12:26:18.15Z" }, + { url = "https://files.pythonhosted.org/packages/ac/7d/8f3b6dc920e3fc6732f7678785a2091db439f186afbec30dbf2214d9b1f7/coverage-7.16.2-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:724bd0f1e81856b35e59fc98cf7b4e544a3cb662e4e0864dca73d4326ee9d808", size = 255832, upload-time = "2026-09-27T12:26:19.799Z" }, + { url = "https://files.pythonhosted.org/packages/d1/36/6c45f15be4eca4ac1062c6a55a323286494c99726a7e58951fe85967ac08/coverage-7.16.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5375ebd99038021b35e99dc88255022912c06565d316212f4a576e4b08d30f5d", size = 258571, upload-time = "2026-09-27T12:26:21.199Z" }, + { url = "https://files.pythonhosted.org/packages/34/fb/b54cbeba3ad89082c2e441278681859e538322cc34b84b2af7ebff00080f/coverage-7.16.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a076277ca9f5750cc230f0f578ebd2620cec60255b25707361699fef6fb465c", size = 259680, upload-time = "2026-09-27T12:26:22.822Z" }, + { url = "https://files.pythonhosted.org/packages/6e/a2/0dc65ec3d61930e1e4c2e371763b15eb4290896eb343a12d5d3091308116/coverage-7.16.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:58d4a54c6ea672afef66d49be922a2c69826c5ae1a42a9cd94f0c9c2bacdf800", size = 261945, upload-time = "2026-09-27T12:26:24.336Z" }, + { url = "https://files.pythonhosted.org/packages/d6/93/5fad7a61f2c14e08e98946fc31c1c7ffc1195061bf3fdc351db3be77a863/coverage-7.16.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0dcbcfcc059117284c603ff8cb61a65872512882f84a8cf0339241f7f7c2f148", size = 256191, upload-time = "2026-09-27T12:26:25.89Z" }, + { url = "https://files.pythonhosted.org/packages/2d/47/74e5de9227b939ece9f64e729645ddc4296bea10dbfa98721c1333c8be2e/coverage-7.16.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:afdf43b72ef3876c1fe66423b91466e37877c9e81e8cec70542b7e8525b9d1b7", size = 257610, upload-time = "2026-09-27T12:26:27.35Z" }, + { url = "https://files.pythonhosted.org/packages/13/fe/2cf28d40b43645d1b72388fe3ee7f7c747533a6a9557bb8c24a7ae74fe1a/coverage-7.16.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9acc7f7ec4a1b5f89bd929fde5b8a714f6fafdc6cc18725413d510aa082b47ad", size = 255757, upload-time = "2026-09-27T12:26:28.949Z" }, + { url = "https://files.pythonhosted.org/packages/d7/3d/7c149fd99fc8bbc39c80db5e688d1d39fd040be2ecb78b8335a51a55b9c0/coverage-7.16.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:80d3f7b48d43ee8fc5e8707a8adb43d743a5a1a85256c25a24f9d6d0e2238fa6", size = 259822, upload-time = "2026-09-27T12:26:30.515Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3f/b283fce09d5995e227bd8e513358dd7471bedc0f78abc85a925ebdb0a2f6/coverage-7.16.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:126d1af8804d7224421fe991ff65d3ce649081560df7a98b1a5ffff07f9923bd", size = 255325, upload-time = "2026-09-27T12:26:32.037Z" }, + { url = "https://files.pythonhosted.org/packages/bf/91/f3325edf0c4223fb1fe1532b8dbef2a1d2f729459a9a7d1a44d073bae534/coverage-7.16.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c19cd6d025c1673f22afcd22c7df8a662d779e05d8e3fa6820c22afb895b0206", size = 257191, upload-time = "2026-09-27T12:26:33.525Z" }, + { url = "https://files.pythonhosted.org/packages/c4/89/21eb5e83ecf2eed523c4eb3d65ae513cd082c8fd1b6deb34c4cb6c332f97/coverage-7.16.2-cp312-cp312-win32.whl", hash = "sha256:152877cdc8a07264882cfcd503ba56a3ef6cba56a70e8c70f6eb8ffd7384789a", size = 226034, upload-time = "2026-09-27T12:26:35.021Z" }, + { url = "https://files.pythonhosted.org/packages/db/de/e3ad6d864c0833624b4f1f9b53f9e58e116c945e5e965c3f1e172c5e84cd/coverage-7.16.2-cp312-cp312-win_amd64.whl", hash = "sha256:e6c52d3307824ff93b39efd99e4185d557db40bd841452abfb32e5d9151ca162", size = 226569, upload-time = "2026-09-27T12:26:36.604Z" }, + { url = "https://files.pythonhosted.org/packages/3e/c1/bccc58ebe5489cc70628f635c1932fd371f5d7da850dbcf960f95f4c4afc/coverage-7.16.2-cp312-cp312-win_arm64.whl", hash = "sha256:a678c0b6b22086ec2427359d22e37445d4a792f5fdbbc744112c7dade65cad02", size = 226372, upload-time = "2026-09-27T12:26:38.406Z" }, + { url = "https://files.pythonhosted.org/packages/f0/f6/8eb4f220ef24f84fb27d852d4f9bf83e0c73ec1a4a08dd9a87e3f4529739/coverage-7.16.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1a37c6e478cf687e1aa30a593d19c92c02fad9d122b51ab73f51b8dc7a0c0fc9", size = 223993, upload-time = "2026-09-27T12:26:40.164Z" }, + { url = "https://files.pythonhosted.org/packages/40/23/d4bbaf0c154e0b0c2b5264890dbf6ef098dcb50ec8f2469be9490d191660/coverage-7.16.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0993d0e90858c03943d3cb152e068a20dd4707924deec84dd2230261baae3b1b", size = 224368, upload-time = "2026-09-27T12:26:41.762Z" }, + { url = "https://files.pythonhosted.org/packages/7f/48/fc1e88fd571ec5cb38150b7f89f7696ca1bdf9920e01432febb69774cc85/coverage-7.16.2-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bb2fc905bbf4e6b7f40806ea79e31515abf6349594cdf0adf27c4215f0463204", size = 255358, upload-time = "2026-09-27T12:26:43.442Z" }, + { url = "https://files.pythonhosted.org/packages/1d/56/6785397d07c29c8e70fbb9a07e97d062b43c21ffc5f12385917847f09f63/coverage-7.16.2-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4358b9c8c0125b460407f3017c6cce8156e904b32772c5630d27112f52bdbfe5", size = 257955, upload-time = "2026-09-27T12:26:45.725Z" }, + { url = "https://files.pythonhosted.org/packages/27/3b/c8cdd07721e5f99abd81cea970d971997f99bf158c0b85f51bd284179c8b/coverage-7.16.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f15254427c9b33eedac4f198eaf9e356eb4f6214551afb43da6194a2c088ad7", size = 259183, upload-time = "2026-09-27T12:26:47.208Z" }, + { url = "https://files.pythonhosted.org/packages/9b/11/606b192fe43d32574ec6238549d48de588fdcc18485682a5ec0a8ac357f2/coverage-7.16.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9a75a4704ff640e46170042eec1f984385a121227c505d5a16ad8e495f452541", size = 261325, upload-time = "2026-09-27T12:26:49.084Z" }, + { url = "https://files.pythonhosted.org/packages/67/90/eea481f8b0305ceeb33f081a5f47e298391dbd1b589de0c4b3b3aa50d3f2/coverage-7.16.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:14253fc7bb15749b849795a06f5d3b6d8bc3fb8a4b5ddc341faf7a89dce205fc", size = 255531, upload-time = "2026-09-27T12:26:50.509Z" }, + { url = "https://files.pythonhosted.org/packages/6b/be/dedbf9aea1457b120c27ac10b8fc2a357f37fa2b54c3e7286d42980a0a2a/coverage-7.16.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:921415102a90637fcc2e3f169f61dad7699ecf690e8639fc21b813acbedc0967", size = 257329, upload-time = "2026-09-27T12:26:52.005Z" }, + { url = "https://files.pythonhosted.org/packages/fa/cb/b25c19d5bb2bd0f2e4e27fe8e2ffcae80c7a91ae181c0dc749ed60e9b1a4/coverage-7.16.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cce2bc991293f15cc4084ca116827b5900c5f34e1a54dfe83f10ab5c43162eb7", size = 255294, upload-time = "2026-09-27T12:26:53.634Z" }, + { url = "https://files.pythonhosted.org/packages/5f/a2/892c5c5f4ad44b7b2ca009aee705191f3f268f15052244f2f9e3539b2e35/coverage-7.16.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e1fa594c887365b69745f25a416806e61085dd07b94c9eae68a6e20730629b23", size = 259444, upload-time = "2026-09-27T12:26:55.243Z" }, + { url = "https://files.pythonhosted.org/packages/ed/99/a562537deba0a3e370182ae71c149be796c39d8087365f17a09188f27145/coverage-7.16.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:11e597173af1dc33d5f8a7332ada544199269a223af1ee1770ddd5e245ad0fe8", size = 255111, upload-time = "2026-09-27T12:26:56.851Z" }, + { url = "https://files.pythonhosted.org/packages/2d/20/854ec68641a9b3362ff068a32dfa41637299761617ef253791dbade6fc76/coverage-7.16.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3e7f99698ba3a7d13988bdd984b7ebf13af4dbe2166dc8502eef90d77603b0a4", size = 256882, upload-time = "2026-09-27T12:26:58.41Z" }, + { url = "https://files.pythonhosted.org/packages/db/0d/748e4518b0ac0f9ff2687c248a6e5f8c0737306e709372632a2556f84443/coverage-7.16.2-cp313-cp313-win32.whl", hash = "sha256:f80bd9f9633eafc73d0a913ba2645c96ba58bba1befc30590f7c0fbfde59d865", size = 226045, upload-time = "2026-09-27T12:26:59.983Z" }, + { url = "https://files.pythonhosted.org/packages/31/fa/6e46edba66a183fe4d99d4bb52c173287e9b8dddabe0888d24cb8210e580/coverage-7.16.2-cp313-cp313-win_amd64.whl", hash = "sha256:8be099e979fc42559328a21828281b4578304191ae46ed4e80a407048a82eee6", size = 226581, upload-time = "2026-09-27T12:27:01.494Z" }, + { url = "https://files.pythonhosted.org/packages/1b/d9/9ef6845367600b336ff75d000444a0d32497d6972c833141bd39356abf68/coverage-7.16.2-cp313-cp313-win_arm64.whl", hash = "sha256:28ff850182a67d117990fa2ce5ea1032836d8c9630dae867e8bdd3bff4533b79", size = 226409, upload-time = "2026-09-27T12:27:03.116Z" }, + { url = "https://files.pythonhosted.org/packages/59/4c/577fc0803dab4155dcf808faffbdd7b159256781c0874a8586e17b81b149/coverage-7.16.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:4ee546b9e4872ffa194bf07ac87bfa1202ebb824d0795dc1ef22f175545ca90a", size = 224138, upload-time = "2026-09-27T12:27:05.141Z" }, + { url = "https://files.pythonhosted.org/packages/75/9e/e3785ba3ecba2bd11efc74bfe2801ca4b78c4480b15a375648d809a59da3/coverage-7.16.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a2fac6895eb299a2e52d7bbb8fb3903502b9da8d3f5309ceb16ec40c646b58ee", size = 224445, upload-time = "2026-09-27T12:27:06.805Z" }, + { url = "https://files.pythonhosted.org/packages/f0/d0/963ff22d3fd27117da3b8cc442f5bdc91196f783321e1a8ff0ec43476772/coverage-7.16.2-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:57ff3783f99d75a1e81dd56a9737eb5665e6736a5d93258ba596b6dcad8fd05b", size = 256112, upload-time = "2026-09-27T12:27:08.43Z" }, + { url = "https://files.pythonhosted.org/packages/a8/d4/a306940c81c6ae759e82fff27d20b7fdc6896e422b821f51313cce212b6c/coverage-7.16.2-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:35f37886699cb9abd29958247d718628d5bc6f39e623dff66a09e546c42a7e03", size = 258727, upload-time = "2026-09-27T12:27:09.927Z" }, + { url = "https://files.pythonhosted.org/packages/b9/a3/d3d99d93b02517087aa05bc0cf2d04d372956b849e5443e059079901429b/coverage-7.16.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0fd7a86fdda7cb6d616d178654bd0ad6bc0f3f33c2e478aa598500a1a9e34eda", size = 259909, upload-time = "2026-09-27T12:27:11.55Z" }, + { url = "https://files.pythonhosted.org/packages/08/44/39dd599181726758dd185ae4dc0c0ab3aeabf7ca70e68e145060feeaaa16/coverage-7.16.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ac0f3b379c94acc2f7dce5f5f0b24d44fa1cc6a509717ef83dfee07450c2117c", size = 262481, upload-time = "2026-09-27T12:27:13.17Z" }, + { url = "https://files.pythonhosted.org/packages/99/e8/91ee43f6ded411460c359d7e1aebde4d6fd8f00a2e5394182d9d212eb23c/coverage-7.16.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7d0732c83746bc24123c581a85d9dd96b70ddb538c9076020aa1a041790361e9", size = 256012, upload-time = "2026-09-27T12:27:14.91Z" }, + { url = "https://files.pythonhosted.org/packages/11/8c/e9499ddc33197bd7eabcb1118ca81756fc874457b324e2b479a4804b2ad2/coverage-7.16.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7b451c68218c150f616bc9649783ec8de76a59792c759b43aa0c9c0466a465e4", size = 257898, upload-time = "2026-09-27T12:27:16.588Z" }, + { url = "https://files.pythonhosted.org/packages/5f/6e/c081cb5991a0afba99f9c4ad6c74a5fce9513a38ddc64e3e6680c6fed9af/coverage-7.16.2-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:a56ac4fa5a75c7e182e8f62600cfb4aff43c5ed7356a034f3557659c3bec1d90", size = 255938, upload-time = "2026-09-27T12:27:18.19Z" }, + { url = "https://files.pythonhosted.org/packages/b2/42/1c3d819e8f9b6eb01c2fe90874d67a8882adb9507e0bbb09361ed131ea89/coverage-7.16.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4cc4f73aa3fabc36e32046d6cd2971405948d8a903636508a3d3b2f9128b3a95", size = 260368, upload-time = "2026-09-27T12:27:19.903Z" }, + { url = "https://files.pythonhosted.org/packages/19/4f/d70eac07901fd587b6ab05e659b52afe13959992aa5113bf6cce059cc572/coverage-7.16.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:723dcdab91357159b722935b500ee8abc0a66c8c432e1e9fabf4cc7598952de8", size = 255620, upload-time = "2026-09-27T12:27:21.621Z" }, + { url = "https://files.pythonhosted.org/packages/34/5e/6d87af88317d3d9a9b18a9ca1bc1673eb516917f296e579d0d4a55cb3490/coverage-7.16.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5397e21a90dde0e9c6896b77ded8f0be26b66f8b22b33aed41f6043ed95d55e6", size = 257521, upload-time = "2026-09-27T12:27:23.358Z" }, + { url = "https://files.pythonhosted.org/packages/79/bb/90c2641170d2fa1a6757b3f8450ba2740197317b0ddd749e9604b914e886/coverage-7.16.2-cp314-cp314-win32.whl", hash = "sha256:848893e1d361448c113dc2f0913503522a6f7be231d0e38333d2a22d9698a011", size = 226248, upload-time = "2026-09-27T12:27:25.153Z" }, + { url = "https://files.pythonhosted.org/packages/30/08/d8d0478bb02c8eb0ae20a496fc80c40fcf4d3450bd184300d682ba2d28a6/coverage-7.16.2-cp314-cp314-win_amd64.whl", hash = "sha256:5a27b731c171e43dc8b5f32b76a5051dde2ec9b9366c87028f08a7088ebc2c7b", size = 226732, upload-time = "2026-09-27T12:27:26.907Z" }, + { url = "https://files.pythonhosted.org/packages/32/3f/0001da22155b0a8ce063ec0f7e64ecbe17b373f306e7a74435f6d6accb72/coverage-7.16.2-cp314-cp314-win_arm64.whl", hash = "sha256:1c569a9fd25505f1cd6bea90588818f90373ce90e2632e2cacf19ddbd6e14fdb", size = 226645, upload-time = "2026-09-27T12:27:28.588Z" }, + { url = "https://files.pythonhosted.org/packages/d7/85/6d8813aff9b8b8586691a9d33c43c5604f7227622574da7cdc3d91a86861/coverage-7.16.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d93db87adb6b1c1b408dce4763314b55d76a9f589e96783a84ac9e7689e48bdf", size = 224871, upload-time = "2026-09-27T12:27:30.32Z" }, + { url = "https://files.pythonhosted.org/packages/5c/70/444f3a4981ac2cda40fdcf4cc9b56a4e1a33c222abeb33e51ed3e3eb2a6b/coverage-7.16.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:aa62c85046473959c13ba9edca9dc90a77d5c1095b1ba313556314d77fe5b036", size = 225123, upload-time = "2026-09-27T12:27:32.33Z" }, + { url = "https://files.pythonhosted.org/packages/d0/c1/980681cd7b33eb66ac835044116ef0a92e11fcc7bdd866cc89d10b1130b9/coverage-7.16.2-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:db76506aa5416081f3e8974ae0f7965c58ada0bb0ef7339ac86099588dbb20d3", size = 265049, upload-time = "2026-09-27T12:27:34.085Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e3/87679875c33bb2191f0f05544a1cc9adcc940fe0c35443a10f2df753dde5/coverage-7.16.2-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a0f2285329dac10ab08f79cb11f5692c497018e6c7c511f95e6fd63a70b8f831", size = 267717, upload-time = "2026-09-27T12:27:36.025Z" }, + { url = "https://files.pythonhosted.org/packages/76/64/5d372776d6eb523d4e93bafba2253f96984e3b18261c4cc56a50863c6d0d/coverage-7.16.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:382d3346d56b0eec1b793d53a4c88799c8053f516aa3a8d7c44315696954bacf", size = 270047, upload-time = "2026-09-27T12:27:37.96Z" }, + { url = "https://files.pythonhosted.org/packages/be/c1/44082ff0cbf9f97d0043f57970a71204097ec7ba606361a9fd2065393669/coverage-7.16.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:648352b94507179d82637292e7ae8802508d95f78e2f00a705a50b6c48011681", size = 271360, upload-time = "2026-09-27T12:27:39.766Z" }, + { url = "https://files.pythonhosted.org/packages/b8/17/9a215efe25b5e0ecc87c89dbe525c4a87d14d87c8c0c7316ef140a5f6f3e/coverage-7.16.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fb2bde05838fffae1a1bf75e5d411a6cac3e4e9bb97e6640fed8cd47888b33f0", size = 264736, upload-time = "2026-09-27T12:27:42.072Z" }, + { url = "https://files.pythonhosted.org/packages/a2/da/7f0a31af8e448107d4d32844bd684757f51ea907bc0c68c8fd537b2123ff/coverage-7.16.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:6a75180829efb8ae62b4aded25be6ddca1c888d138d2d82e21d93bfbd88f41cb", size = 267600, upload-time = "2026-09-27T12:27:43.85Z" }, + { url = "https://files.pythonhosted.org/packages/dd/a4/3bfecbd3366b775bacdcb3330394d356cf384b5d8f5b2146ac4b14b252b5/coverage-7.16.2-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:99704f73721e23859112072d522076e11c31744fc96b5652e5dd2018aa4359f7", size = 264767, upload-time = "2026-09-27T12:27:45.768Z" }, + { url = "https://files.pythonhosted.org/packages/b8/3f/5d62163732d87e4a0c4710a0eab30f0fd6a2d480112abe2029f014fe8c9d/coverage-7.16.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:29309ccc86b7f33df7db12813c299f215bbbc470ed6292d0bedd63ffae1ebf64", size = 269026, upload-time = "2026-09-27T12:27:47.787Z" }, + { url = "https://files.pythonhosted.org/packages/49/4d/8e4579f225426535085a9be371cc75e3b026d058d679b80affbdfb4c3ef0/coverage-7.16.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:30c1b65d529e46569899fadca59e4a87c1faf2886923f1307ba61e654d4f3c20", size = 264147, upload-time = "2026-09-27T12:27:49.681Z" }, + { url = "https://files.pythonhosted.org/packages/d1/36/ef1f77e2c3f7bb03c2b13b9a2006f88700fdd75535ef158d70049f425c1c/coverage-7.16.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dcf4bc2aab4e16b1c4c0c2005918f23a7dd5d7821ddae82caed9e3342dc2fcce", size = 266376, upload-time = "2026-09-27T12:27:51.551Z" }, + { url = "https://files.pythonhosted.org/packages/be/79/0cb2bf4428830dec971c718c2c841a039c084415c99e67281f5a72841aab/coverage-7.16.2-cp314-cp314t-win32.whl", hash = "sha256:a9cd3de0a5bfe7b0e21ee10e1a14e3d61bf52efc88217ab1d95d6ace6970bd46", size = 226585, upload-time = "2026-09-27T12:27:53.945Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f9/da17121c16667fd84998e972200ae226a41540f6ea4795776c6d99e8976f/coverage-7.16.2-cp314-cp314t-win_amd64.whl", hash = "sha256:611a44e5229a59d7483ce830160e1a0e85f700562c7a5651c7c63fb8f4eb528c", size = 227378, upload-time = "2026-09-27T12:27:55.778Z" }, + { url = "https://files.pythonhosted.org/packages/74/89/01179c62d1b7e6e33bd5001566b02d7f778cf33d3ec1e81e94ca170c517f/coverage-7.16.2-cp314-cp314t-win_arm64.whl", hash = "sha256:22957cef43ce038641de78ba995de7568d2d6a37c6ddbf7fa0fd7d1ae2344d91", size = 227064, upload-time = "2026-09-27T12:27:57.496Z" }, + { url = "https://files.pythonhosted.org/packages/4c/57/52935003c3f627ba6e5203d7179aad32448c10899663a30336aba8e81a2c/coverage-7.16.2-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:414c26dfdb96aac2d570a54e03008f001e32eb2d413705365503648c6bd361d8", size = 224140, upload-time = "2026-09-27T12:27:59.343Z" }, + { url = "https://files.pythonhosted.org/packages/31/38/df472520f3e626524d7e2fc9d6da0afe7895a2f1489d36b48af8ca40bb41/coverage-7.16.2-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:00d3eb96e9988c45f50cccd1f1496571ac5c1f91386ac02c4d55516eeda19a24", size = 224449, upload-time = "2026-09-27T12:28:01.299Z" }, + { url = "https://files.pythonhosted.org/packages/0c/aa/3be084d5b82e63ccdad4ed751e4acbae294673573e30481d29f8b7402eec/coverage-7.16.2-cp315-cp315-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:4dbbd1155ca46e6e0b6b89d204428c56ef6a459af21333f365d135a2820e5a09", size = 256060, upload-time = "2026-09-27T12:28:03.185Z" }, + { url = "https://files.pythonhosted.org/packages/de/29/48fca82a7ebf7ff7b2e35019cc9537e7f65e4d2aa1215cc5a8792c989251/coverage-7.16.2-cp315-cp315-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8fc15cc8d0d06e873c00ef18e1372d605f9aaf3de27d8c24e50782e75bc8b843", size = 259106, upload-time = "2026-09-27T12:28:05.15Z" }, + { url = "https://files.pythonhosted.org/packages/06/3d/b2d5986f2dd53fe201aa1be2e4ab204fa1aed5101e67c0dbbb419b850aee/coverage-7.16.2-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c6afdd69218202bc1758c9a14b86b8cf1084f37ed2ca143e567a103772b16d1", size = 260674, upload-time = "2026-09-27T12:28:06.868Z" }, + { url = "https://files.pythonhosted.org/packages/ce/7e/b50160be3506ead12e6480d14279af7f0f17627694300a2d1fd2c42d2ff5/coverage-7.16.2-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:aba5c63b7afdc749cc9eae943d5b868cba2b261a176378fa1c5a30bc8bc89982", size = 263139, upload-time = "2026-09-27T12:28:08.771Z" }, + { url = "https://files.pythonhosted.org/packages/14/5e/7c805ac9a32606de1399bd7e9bd375aa2f973dc61b12680d9e6403c2e891/coverage-7.16.2-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9174f0af24e5eff248b9dbfe76ec5275a3d19d37edbc2810543f12cf97347a34", size = 256591, upload-time = "2026-09-27T12:28:10.842Z" }, + { url = "https://files.pythonhosted.org/packages/ab/9e/76f1ed129a2daf658a3ea17122824cf2e3b91fea0460d8d3664fc5a61018/coverage-7.16.2-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:80e9fdb4c3d926b6ba721d4bf7435bdb869c3527ae7803290361d0ab73db13b6", size = 258708, upload-time = "2026-09-27T12:28:12.962Z" }, + { url = "https://files.pythonhosted.org/packages/5a/b7/8d62e75f48b527619239a65294f842d4b7fd02a0839d43ae1de80184e2df/coverage-7.16.2-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:7b3bce4a0d05401d70b7d0d5ca783e686bc9d30e81dbd7d980d532609bf809e4", size = 256562, upload-time = "2026-09-27T12:28:14.934Z" }, + { url = "https://files.pythonhosted.org/packages/b8/8d/0a15f95c3afb78e947c52644786ba4bc9de259905687dd720d5e6fae2e76/coverage-7.16.2-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:44f21e407b278efdfc1ee5e481e00518bd1d500310a30a5fbf2bcbedfef4aaf0", size = 261077, upload-time = "2026-09-27T12:28:17.215Z" }, + { url = "https://files.pythonhosted.org/packages/25/00/88389987305a47d732866c07c8a500000ab574df9505e3114ac69c8d027f/coverage-7.16.2-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:59c3926585e1cd1f2190f4b2ac9014de1bbeaf0d5d0587b0dc6b0aa90d17896a", size = 256034, upload-time = "2026-09-27T12:28:19.08Z" }, + { url = "https://files.pythonhosted.org/packages/92/02/34d079d4952ad461bde037d353f9a6e037a7edc45fe0f9ee8781ff73f028/coverage-7.16.2-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:066429634299e14dd2d511e1e85f8f9cecc500781f6b41907c0dd6f1baea7e63", size = 258034, upload-time = "2026-09-27T12:28:21.242Z" }, + { url = "https://files.pythonhosted.org/packages/f6/d8/3e59a62879285b464ec1b10fd824fbc1af9ce66e842cd39974f80a0becc4/coverage-7.16.2-cp315-cp315-win32.whl", hash = "sha256:893ea9cf86cb8d2546812ac93d973aaf2ee1fb45110a873b014214fd23e3725e", size = 226252, upload-time = "2026-09-27T12:28:23.102Z" }, + { url = "https://files.pythonhosted.org/packages/f4/e1/128026e1b2836e9ad6b219207ba9edf1c5e0088a7869e23088aee7fbbe7a/coverage-7.16.2-cp315-cp315-win_amd64.whl", hash = "sha256:01c6908bc613b420c26c818fe948e1b97dfd041a53c98b01c63bd8321f5c9aae", size = 226728, upload-time = "2026-09-27T12:28:25.21Z" }, + { url = "https://files.pythonhosted.org/packages/a8/f4/c9fa8e7cf525ca7748ac52b0ee89331d13fe09808e45c679830708782e90/coverage-7.16.2-cp315-cp315-win_arm64.whl", hash = "sha256:967d72c835d7a8cf0af99ec813a2d06e3db6df706402f1fe85b31b437645f495", size = 226648, upload-time = "2026-09-27T12:28:27.136Z" }, + { url = "https://files.pythonhosted.org/packages/a2/13/e96b045447a856666f36f9c653e2a80bdaa732aaaf72412b19aa2c26a473/coverage-7.16.2-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:98d9c97f51b334b0adce7b964442a9af33c1a00c6ac856984cc5dc8d18f81c75", size = 224858, upload-time = "2026-09-27T12:28:29.169Z" }, + { url = "https://files.pythonhosted.org/packages/23/90/087f6ad1bd3df059632ca3407a4e6552ed1053ee35354de0a771acf35423/coverage-7.16.2-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:3e861f1071dcc2fec1e88bef0920f6b1eaa66a143555b4f8ab79ba2b0f30ef55", size = 225139, upload-time = "2026-09-27T12:28:31.131Z" }, + { url = "https://files.pythonhosted.org/packages/7e/8e/285dcef0184358044e7cbcd810a1bdc9566bc620f54702d605477155df4a/coverage-7.16.2-cp315-cp315t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:fb9d92ecfe2d5b494367c67f7446f8b75b68d8d0c8cf3bc3e6997478be25d9e2", size = 265090, upload-time = "2026-09-27T12:28:33.04Z" }, + { url = "https://files.pythonhosted.org/packages/06/b2/cc83f3a6e5789a4e89059c69555bc641c2efcde568405a1c06fc702951ab/coverage-7.16.2-cp315-cp315t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:eb57acff4a74246ae513c142d4b36e18c389c3aed8661914a53f7cd0071031b2", size = 268254, upload-time = "2026-09-27T12:28:35.135Z" }, + { url = "https://files.pythonhosted.org/packages/ac/41/f548c19530f5d66ac6e3c92bbcbc49da7261de3a458b9f3e54a3efb1a0b2/coverage-7.16.2-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:444889f7f66b74e4455c0a97e0e166dd41177f1dca8c0239a47cff25e05ba7e1", size = 270695, upload-time = "2026-09-27T12:28:36.959Z" }, + { url = "https://files.pythonhosted.org/packages/94/61/4dc27cf82ef96434d2874110ad0cc10ea4621025705dc5049862bd3bd181/coverage-7.16.2-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a740ea6f083c6db7b926534d159508f80ba275ab35e722522de0d18d0f56e55f", size = 271853, upload-time = "2026-09-27T12:28:38.821Z" }, + { url = "https://files.pythonhosted.org/packages/38/29/bf8072b1b8bd5f2de8b21460a404460b1a2b97e80a9464c78ec0271f6199/coverage-7.16.2-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8e209591f7c41ae4a9171335cf6156afda0b21de73b02f73f5aa95b2d5fbb08d", size = 265644, upload-time = "2026-09-27T12:28:40.815Z" }, + { url = "https://files.pythonhosted.org/packages/7c/2f/0aecb8721be5cdeb8afd9d6d9f6b463f074e4d8d37f00f4c42442522709f/coverage-7.16.2-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:396bb16e04ce04efbb3df91456ae4e3da918e69ecdf67fb711b0a0fdf35ccce0", size = 268530, upload-time = "2026-09-27T12:28:42.725Z" }, + { url = "https://files.pythonhosted.org/packages/ab/0b/92b4b7628268ee711249958e68fc0328779bd3d9a7ab4715379465aedb84/coverage-7.16.2-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:9cdf19874e0d247f32f03609200370343c3c7aa260b191d8c2bb251d36198283", size = 265154, upload-time = "2026-09-27T12:28:44.684Z" }, + { url = "https://files.pythonhosted.org/packages/7b/d9/41c95c1ab29b3dcd357cd1227181d1c98185632aca41ce670ce671b23a43/coverage-7.16.2-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:fd3d72233eb8b48acc94fa57d44e2d32ce8e7abed02882ccb6d855ccc4ed33ec", size = 269799, upload-time = "2026-09-27T12:28:46.672Z" }, + { url = "https://files.pythonhosted.org/packages/80/07/ebeb259aa5362b033a137b86d7274ff4b109d59be8cc9913889b783bf75a/coverage-7.16.2-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:bb4ffe96aa663cee727659db5a2afeb38c95f8677b747d447b90d6d4874ea2c5", size = 265196, upload-time = "2026-09-27T12:28:48.996Z" }, + { url = "https://files.pythonhosted.org/packages/b2/18/8437620f90d023680a072eee02f968055f3658bbfb7d386d0ea34cfb7f30/coverage-7.16.2-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:dba2edfb054f6d4a08df9d1637c39a5aa3865bca6617c13c86be21e45658a59c", size = 267266, upload-time = "2026-09-27T12:28:51.361Z" }, + { url = "https://files.pythonhosted.org/packages/28/6c/f08e8ee4293e6434035424180bef4d45e028e8ecc006c61bf9453e74405e/coverage-7.16.2-cp315-cp315t-win32.whl", hash = "sha256:251aed777c47c77aba047096d4542889db089227655711dfc2b9c54ef0e15e35", size = 226583, upload-time = "2026-09-27T12:28:53.33Z" }, + { url = "https://files.pythonhosted.org/packages/f7/fd/3f939c2847f4a72c20cff8b1ac33da78ea91a2d38d9b43336e60db719103/coverage-7.16.2-cp315-cp315t-win_amd64.whl", hash = "sha256:2aca0bdfa9e91621d5b09d815357bf63def4fc0e9cb66da67bf2cf93f3b1a6f5", size = 227374, upload-time = "2026-09-27T12:28:55.158Z" }, + { url = "https://files.pythonhosted.org/packages/5a/35/b98cdc354c952402132e675a87f2cc3227fb68f959c84aaa491fbe15933d/coverage-7.16.2-cp315-cp315t-win_arm64.whl", hash = "sha256:b88841e654f09732804809e435b3e005a929ffd9998b872b7b213957b8759cb8", size = 227064, upload-time = "2026-09-27T12:28:57.075Z" }, + { url = "https://files.pythonhosted.org/packages/3f/0c/7a64e1ac90541a8edf50daef0914848011fb057a5bf55284a4811e21939a/coverage-7.16.2-py3-none-any.whl", hash = "sha256:11d28e9123a9156cb405d8d27b44256c9a58fb5decc2073a8f17862057e3aa0f", size = 215754, upload-time = "2026-09-27T12:28:59.075Z" }, +] + +[[package]] +name = "dfo-spec-kit-client-contract" +version = "0.1.0" +source = { editable = "." } + +[package.dev-dependencies] +dev = [ + { name = "jsonschema" }, + { name = "pre-commit" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "referencing" }, + { name = "ruff" }, + { name = "ty" }, +] + +[package.metadata] + +[package.metadata.requires-dev] +dev = [ + { name = "jsonschema", specifier = ">=4.23" }, + { name = "pre-commit", specifier = ">=4.6.0" }, + { name = "pytest", specifier = ">=9.1.0" }, + { name = "pytest-cov", specifier = ">=7.1.0" }, + { name = "referencing", specifier = ">=0.36" }, + { name = "ruff", specifier = ">=0.15.0" }, + { name = "ty", specifier = ">=0.0.59" }, +] + +[[package]] +name = "distlib" +version = "0.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/68/bc/d36966de7304047a1001a7559fbf266c464bb5d8cc85464536ef8c9bcc32/distlib-0.4.4.tar.gz", hash = "sha256:ca4175b4ac7f71223cc30ed7248c45d2b38c2439d8ee6e498ab67ed63cf3508d", size = 621304, upload-time = "2026-10-16T13:56:34.203Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/2b/238f02a4927fa2e27aa995371d240a468b52e42eae44a678434aff736b38/distlib-0.4.4-py2.py3-none-any.whl", hash = "sha256:cf09d55b1e85a89576b036aeb71550bfd68320f3f21761ca329eadadad918638", size = 472099, upload-time = "2026-10-16T13:56:32.053Z" }, +] + +[[package]] +name = "filelock" +version = "4.2.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/28/3893324bcadf8f89b1616637468d766af3f625008c0735bf704fdfa86617/filelock-4.2.4.tar.gz", hash = "sha256:c6d8663535e1650ee430507b4ffbac7b464dd64b7647ea0112a9f406499d163d", size = 652444, upload-time = "2026-10-19T01:57:51.001Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/1b/5e74289a1878e666bb4b65fe5805a04cafcac2aa5f519ef1ead67ef91c56/filelock-4.2.4-py3-none-any.whl", hash = "sha256:301241438c57936ef93f4243a94f2559022268bfcf9b375a9a72eb0f8db8358e", size = 162475, upload-time = "2026-10-19T01:57:49.419Z" }, +] + +[[package]] +name = "identify" +version = "2.6.20" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/53/35/d70c0006c7cee65999ea94a6273e60b2094f600a3d8b71b04318253fc643/identify-2.6.20.tar.gz", hash = "sha256:ad729860a923858d26917c2f4fb0a1d83d27a75b1e090c06440c573f048f3285", size = 99681, upload-time = "2026-09-26T20:29:07.187Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/70/fffc9613501877c0a10a1ef73a165e6ded3e53f6e7502227fef56d973933/identify-2.6.20-py2.py3-none-any.whl", hash = "sha256:6a16b69b93187244e0548cbfd25b3e4a6f9a7a2ad784625c3bec2b8d27b81aaa", size = 99506, upload-time = "2026-09-26T20:29:06.054Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/e1/2069291243c926a2ff1cd706c7f3eeb9b62144bf60f77c9fb9ff2fb26bd3/iniconfig-2.3.1.tar.gz", hash = "sha256:67f4b9c50da0dedf52af349e7749a80a9057a5031199791b906c3bb3ae878960", size = 21209, upload-time = "2026-10-06T22:48:38.076Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/43/4ca9e49d27a1fcf6bece6f6aec0ea46bb9112489b93d4b688fb415457bdb/iniconfig-2.3.1-py3-none-any.whl", hash = "sha256:9121e2c1fdb355232495be3194c8dfe87ccc2d5dee45947b78e68f499790d7a7", size = 7552, upload-time = "2026-10-06T22:48:36.959Z" }, +] + +[[package]] +name = "jsonschema" +version = "4.26.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "jsonschema-specifications" }, + { name = "referencing" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" }, +] + +[[package]] +name = "jsonschema-specifications" +version = "2025.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "referencing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, +] + +[[package]] +name = "nodeenv" +version = "1.11.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/105de02c1322cfada6d9710d9146ef8026419d433c9d08359a2d35805811/nodeenv-1.11.0.tar.gz", hash = "sha256:3ce8fe5b71d16e8af7039ca65257354100bc772965d6bc549070649e53b1b146", size = 99301, upload-time = "2026-09-26T11:29:21.367Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/c8/12811c9b48fde162bb72b6f2e78fada9a247a09d7bb5be2050a5d099c77b/nodeenv-1.11.0-py2.py3-none-any.whl", hash = "sha256:edaa16e6c14d7cf395d75d4bbd5a26390f4dc06501a33b4e76282b02cc688a25", size = 34277, upload-time = "2026-09-26T11:29:19.933Z" }, +] + +[[package]] +name = "packaging" +version = "26.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/fa/3944b40b07da9ce895c0e6303a5ab7d53da063554f534556b134a54d6093/packaging-26.3.tar.gz", hash = "sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79", size = 313412, upload-time = "2026-08-04T18:15:28.737Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl", hash = "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c", size = 129956, upload-time = "2026-08-04T18:15:27.159Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.13.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/e6/d0abbb256b44e6a05748c6942511ff67db8dbb068de0c35b24bf1b395b09/platformdirs-4.13.5.tar.gz", hash = "sha256:05831adf87d392760f4b5c3a0a95579ab5a10b18b9b9bd43680dcb47544788a0", size = 62362, upload-time = "2026-10-19T01:02:11.778Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/8a/1d8cb3842909dc193a73835adedf412e32e18f8ffd59f43983949622fe6f/platformdirs-4.13.5-py3-none-any.whl", hash = "sha256:53d3ec4280b815c1e0b02edad7f9ee8fda1ba9c0865dd9c2e6e63849ce82fc1e", size = 32779, upload-time = "2026-10-19T01:02:10.17Z" }, +] + +[[package]] +name = "pluggy" +version = "1.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bf/db/7fc19e6f2dc92a966727031389fc2e08b558f0f25eb7403c1119ad4713cd/pluggy-1.7.0.tar.gz", hash = "sha256:d1eaa46ebb595891b860ab086b4d09c8588af65ebd4361b8e8f4bb8920b90ba8", size = 123304, upload-time = "2026-10-15T09:50:58.343Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/9e/2b38731e0fc536806f16490e1a12d7f0dc2a1235aa8cc07bcc75416a7daa/pluggy-1.7.0-py3-none-any.whl", hash = "sha256:7dd7b0d8832ba3cb632c306926ded123429211b83641b35dc5c41ad2d34f9bec", size = 27082, upload-time = "2026-10-15T09:50:56.808Z" }, +] + +[[package]] +name = "pre-commit" +version = "4.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3a/c3/6965c2690ddce885ec75121572d065a5b94c5a5d8d3e657927ecda9fd715/pre_commit-4.7.0.tar.gz", hash = "sha256:1f3deee12b914c8fa184bd2b5953391c2e4f36763e403d4a23dc9983fa7c6e86", size = 198120, upload-time = "2026-10-12T20:45:40.32Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/83/ce0a196e4f7b20b11ce3aa1fc72fb973f64b7628d51c1b8aebad37fb7f81/pre_commit-4.7.0-py2.py3-none-any.whl", hash = "sha256:2e229038ad3656081b70c27913157e4b636ef306f643f024a8a8e3f0f7b2f877", size = 226261, upload-time = "2026-10-12T20:45:38.858Z" }, +] + +[[package]] +name = "pygments" +version = "2.21.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/49/2e/ced460408999b33da6b31b0021b0f37d329e202d4169aeb164493778f25b/pygments-2.21.0.tar.gz", hash = "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c", size = 5005329, upload-time = "2026-08-17T08:02:48.824Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", size = 1250147, upload-time = "2026-08-17T08:02:44.912Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "pytest-cov" +version = "7.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage" }, + { name = "pluggy" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/51/a849f96e117386044471c8ec2bd6cfebacda285da9525c9106aeb28da671/pytest_cov-7.1.0.tar.gz", hash = "sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2", size = 55592, upload-time = "2026-03-21T20:11:16.284Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" }, +] + +[[package]] +name = "python-discovery" +version = "1.6.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filelock" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f3/ee/cf608372c88ce2c136ee13c69ab6f667dbc0d0c1176af188b4ddc8853e66/python_discovery-1.6.4.tar.gz", hash = "sha256:bc70d31f0ec5de11eda13d4d64c16e24b3506a65984684f2b6c98cb83b2ea9df", size = 89883, upload-time = "2026-10-19T01:45:14.855Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/91/1aa70d3dfcab0dbcf88a2cbc3bce7f7c69562287a90216e617eaa4937e25/python_discovery-1.6.4-py3-none-any.whl", hash = "sha256:530179cc51a1816d512b15635b3dc931295ae12efb183783ad31190a5d425d2b", size = 39385, upload-time = "2026-10-19T01:45:13.668Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "referencing" +version = "0.37.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "rpds-py" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" }, +] + +[[package]] +name = "rpds-py" +version = "2026.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/42/68/3bd46b8a5e01d3c2ebdf9c5e9497912e3fe0cde02bac21a7130ca866e403/rpds_py-2026.9.1.tar.gz", hash = "sha256:4793ef7f78268b124b73fa933440f01d258bbae01de9fa53e9080c9ab0425a12", size = 63948, upload-time = "2026-10-04T16:32:36.469Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/34/a828586ea3329fbb50895b50e9cf98ca3d924a9f41a0b26d443bff1b3794/rpds_py-2026.9.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:50906f5aea24b5a865cbd0a589698288631d9f3a54c3a937c83aefa95a0d14af", size = 346822, upload-time = "2026-10-04T16:29:16.258Z" }, + { url = "https://files.pythonhosted.org/packages/90/81/ac6a0d064982251856ce009c9e1dd51a34110b3c055aa7d1aad18b4899a3/rpds_py-2026.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e21c1429e205828ea886a2293a4a2c8e01f4c25d9893ca330e97a6cf73f52e7b", size = 341380, upload-time = "2026-10-04T16:29:17.706Z" }, + { url = "https://files.pythonhosted.org/packages/42/ff/bf7d54f362748fd6a49277b9d6531c394074110fedf50ad791ec59133fbb/rpds_py-2026.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2693b2728bbcc48d09a981a356954b0c47c53ff25b545856f28a889ea619f69a", size = 373053, upload-time = "2026-10-04T16:29:19.063Z" }, + { url = "https://files.pythonhosted.org/packages/60/de/74b0ccdbbd28687b9b5fdb34c1cabed88352182facaced9d6f5486b8b9ed/rpds_py-2026.9.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8601470267d938bcb7f3ab1a336100af51a4fd5b6ed030ef52461bb3ef5e7e07", size = 377742, upload-time = "2026-10-04T16:29:20.543Z" }, + { url = "https://files.pythonhosted.org/packages/c2/6d/b979775a3057b2a5c26d75ecbff60a20a24ef081db6dd76836fca3f20247/rpds_py-2026.9.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3890a6aa36e6baa53d5258a2a25d3ef8b37ad165a6ab27a892d7c3e3a432cd69", size = 487289, upload-time = "2026-10-04T16:29:21.958Z" }, + { url = "https://files.pythonhosted.org/packages/1d/5d/7c34734ce3ece943d9d6ee0122a74a21bbc75b47acb5b7053c83f6efb1ed/rpds_py-2026.9.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6b5b393eda5ea42cca1c1a6665f2a4882b4fd5d1777e41ce0545a107fb008c9d", size = 390710, upload-time = "2026-10-04T16:29:23.378Z" }, + { url = "https://files.pythonhosted.org/packages/1d/6d/b26eb1e75395925b3a142ed351cbed2ec8212f5c9d937aee3df32c701baa/rpds_py-2026.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:addeda51556dac7c1a2f14cda62db8b621cd12afba3091d03a96c72932387eab", size = 371261, upload-time = "2026-10-04T16:29:25.1Z" }, + { url = "https://files.pythonhosted.org/packages/7c/98/b2fdfe10301a9e27af21e634337fbba7baac0bc17fe44619a17c26bba2cb/rpds_py-2026.9.1-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:d9edf30457d74eebfd76b045535e36f1cd89062566a128a0db2145ca042d787e", size = 376075, upload-time = "2026-10-04T16:29:26.748Z" }, + { url = "https://files.pythonhosted.org/packages/c5/b1/c4b8d954e49c3c69cf8063c0c9e0919c99f3d2cecc46311606a1cbe835dc/rpds_py-2026.9.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:815d26356930846a40c7bc1366e7b1b0320ab8a063e66c11298a208bed0fd237", size = 399358, upload-time = "2026-10-04T16:29:28.282Z" }, + { url = "https://files.pythonhosted.org/packages/b3/59/9559a7293c97dff0cbb293efffbd36644103883ecc27741af8ef90c84ca8/rpds_py-2026.9.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3b5a6f40f0a1486b4b36c888123afc67acdbd9f33235927acf5ff295429a0ba3", size = 550267, upload-time = "2026-10-04T16:29:29.851Z" }, + { url = "https://files.pythonhosted.org/packages/6c/9d/6dc60e49511de4c8b00e74f9c1d43aed4d27f712cdb1ade92f2c199cbf64/rpds_py-2026.9.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b5b8b0753718d258fd454283fbd57e14545d3b40583fa672e27cb4f987626bcc", size = 614018, upload-time = "2026-10-04T16:29:31.54Z" }, + { url = "https://files.pythonhosted.org/packages/fb/bc/92a4ecf27301b886232a413360f6b348a81d55ffef654f2ebda5970ebc3d/rpds_py-2026.9.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:46d80bc76b51a6c24f9944368c28d38b8bcbcea1da4f2f8d3ebc31a67e8c6ec6", size = 578509, upload-time = "2026-10-04T16:29:33.01Z" }, + { url = "https://files.pythonhosted.org/packages/08/53/efb97f2e6589b7ab8394385a73870e0b2ab2a195281c117b21fd6d7d4855/rpds_py-2026.9.1-cp312-cp312-win32.whl", hash = "sha256:befc2d6a953e563f8a7bfd87a42c22ebf8a3e980dcb7b6a4d17b70b0e914e8a3", size = 205401, upload-time = "2026-10-04T16:29:34.451Z" }, + { url = "https://files.pythonhosted.org/packages/1c/84/1700cc748d0eaa747486e4e82882d2575224e6e9a3148df583058850c629/rpds_py-2026.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:5ce8943f79c2210f7abcc28e86367b03b28d95027fd01c46d2472373ae70c86f", size = 222923, upload-time = "2026-10-04T16:29:35.709Z" }, + { url = "https://files.pythonhosted.org/packages/c3/89/0302215373c2f8b4408b0fdfee955368cc378a98ff59508d47a7e0dc2dbf/rpds_py-2026.9.1-cp312-cp312-win_arm64.whl", hash = "sha256:501909f2e4a1e2dee528ef766fe3c469060ebc17e54a8383d404ba07a81a6f02", size = 218415, upload-time = "2026-10-04T16:29:37.263Z" }, + { url = "https://files.pythonhosted.org/packages/83/ea/ee88fd9e756ff93fb6b1182a47ec09504a242620e33ce1d20679efefe841/rpds_py-2026.9.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:a36b70596407634ca82d4b989a3729074a008537a0522e4c8046a67c729103e9", size = 346229, upload-time = "2026-10-04T16:29:38.82Z" }, + { url = "https://files.pythonhosted.org/packages/57/71/a097d6552f837500fc36e6b23d09cfb9890c3cc47531f9ca64e149799615/rpds_py-2026.9.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eba5d173f7d5708b22a93815017a4611873ed54db9f268077c0dd1ed99cfc858", size = 340514, upload-time = "2026-10-04T16:29:40.405Z" }, + { url = "https://files.pythonhosted.org/packages/bd/b7/497e85768bf4e0d8ddbaa096a4cac31d1509251dee2728a8490aa367e0b5/rpds_py-2026.9.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:457866b85daf5034296666168b84a69e0b2e89dc4f1af102b46f6448a60b9063", size = 372611, upload-time = "2026-10-04T16:29:41.778Z" }, + { url = "https://files.pythonhosted.org/packages/52/4b/74ab4108916250b6e198e0d3af05bc6835eb046315f22f7a0ceb49667c5a/rpds_py-2026.9.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a3a52a3ba86436ab3aef510fbe21512abc2ddd1993005dfe50514bd2284ef025", size = 377712, upload-time = "2026-10-04T16:29:43.242Z" }, + { url = "https://files.pythonhosted.org/packages/0c/8e/067e77d9d7b3cc793c9d909b7e97e7aadbbb1fb094093b6876902cc96d38/rpds_py-2026.9.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d7841166b7fa64c9c56404617ae4341448847482d45933b13135d26c130519e5", size = 488106, upload-time = "2026-10-04T16:29:44.692Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b4/c5aae6c2dde269bf955f6b7d35065c655a57e47750d9668052ad67e74dda/rpds_py-2026.9.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:926bdd3e3b5998ddf70cc64bc8cf57209571f9044542913afb673799fec77dd0", size = 390795, upload-time = "2026-10-04T16:29:46.129Z" }, + { url = "https://files.pythonhosted.org/packages/a0/36/76fab39973ee11e7f9f357c55138197bb01c86f6502cb76487e3b4f42db0/rpds_py-2026.9.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7868b85224291c6cb6759f9b5adb9745f486d226f62b16a614dd5a2a5ab2b35b", size = 370794, upload-time = "2026-10-04T16:29:47.603Z" }, + { url = "https://files.pythonhosted.org/packages/3d/fe/cd2a80e6d7b871937a60e935c5d507aa390d143f4ff3636f640b9733d5df/rpds_py-2026.9.1-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:3cd182d7291d29b92c521a0069d9c01ba6193628a9a105531d11b40a6d731a33", size = 375673, upload-time = "2026-10-04T16:29:49.223Z" }, + { url = "https://files.pythonhosted.org/packages/6c/18/7464a9953724e55a3b3206062fa0ffdeaa519584c6aabf65d3956d94f131/rpds_py-2026.9.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e6ea1cda8d8c688278430e4268a42f5e5da3bdd74578dfadc0820c3f1766ce83", size = 398758, upload-time = "2026-10-04T16:29:50.601Z" }, + { url = "https://files.pythonhosted.org/packages/c0/86/1534b436700fd49ff411063b7c4d7e938adfabf90895b6cf1622d5a7d1f6/rpds_py-2026.9.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5943980471829f6de242a20b109de3111ba6b77e3af0ffc587028ac854b05e6c", size = 550370, upload-time = "2026-10-04T16:29:52.002Z" }, + { url = "https://files.pythonhosted.org/packages/57/1c/e1fa82a8a01e3c5820f3ba98a8b2673f642128eb368fa88871b01dd2c909/rpds_py-2026.9.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:76d3af9732d2dab69f28179b40ba2d87e2f1d5824b4a694780aa787d685e8f36", size = 613106, upload-time = "2026-10-04T16:29:53.655Z" }, + { url = "https://files.pythonhosted.org/packages/29/55/b20b8c4c3dde8755bfcd5b08492a02d0cd2e26929aedf6199ca2a377d42a/rpds_py-2026.9.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:78326f4cb4427a56ba4996c0762b63be45f06b85f086526420d2b3a66e40f84d", size = 578235, upload-time = "2026-10-04T16:29:55.157Z" }, + { url = "https://files.pythonhosted.org/packages/55/42/df3f7bbc3f7ab37a8a9db8d6c2ff2c985422899f1f7926afbf7ec3c0b8b4/rpds_py-2026.9.1-cp313-cp313-win32.whl", hash = "sha256:172e47169583f46ce118cbec68e6795d0da0f4606b488b6434f8276bca0a058c", size = 205293, upload-time = "2026-10-04T16:29:56.669Z" }, + { url = "https://files.pythonhosted.org/packages/31/9c/ba5a9569d719bfdd6ce863df4133ac6a1658cf1b07cc3534c31db729fbbc/rpds_py-2026.9.1-cp313-cp313-win_amd64.whl", hash = "sha256:3e93b2cd69a9830be33e03945cd7cda940a0a8bfcfbff41d6144f0cb0d3d8bd9", size = 222409, upload-time = "2026-10-04T16:29:58.049Z" }, + { url = "https://files.pythonhosted.org/packages/35/72/f28ca566f6c23c35bbf7445f65eb0364577b25a026305995e24f78b83d94/rpds_py-2026.9.1-cp313-cp313-win_arm64.whl", hash = "sha256:d151e148117294133bf8af7eeace085e7e87432db15ab6adf640330298a47f6f", size = 217681, upload-time = "2026-10-04T16:29:59.449Z" }, + { url = "https://files.pythonhosted.org/packages/8a/f2/67b94be1532767803415c1c5a1fd88ea487643d74a673cec1ba140af77bb/rpds_py-2026.9.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:c9d1aca01f49170fdcf5c92761b1fafe97f554b721ca4570c5949fff778f0d4b", size = 347178, upload-time = "2026-10-04T16:30:00.865Z" }, + { url = "https://files.pythonhosted.org/packages/04/37/b751de2b59b0197a1d92a5dd491de88e8a5e928c2e6562581974f1e85263/rpds_py-2026.9.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3f0e9ac28fc067d4d34b88ae43c48e9489455c97fee9633d851f7eeed5a05d35", size = 341878, upload-time = "2026-10-04T16:30:02.564Z" }, + { url = "https://files.pythonhosted.org/packages/72/e2/5873bc4643c250db9e05d48dc0c93763d4aa68bc3b81164cb1af3b45b284/rpds_py-2026.9.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07deecbfce94c78473018bc7d10b337cc651d12df87a1eb2cb3e4024bc9c33d0", size = 373963, upload-time = "2026-10-04T16:30:04.026Z" }, + { url = "https://files.pythonhosted.org/packages/51/03/5acf7632158247f3f6386ff0af3a1ee48167d575037e8d0920594b76d92b/rpds_py-2026.9.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:821b2755db9194409254012f429c56643416fb96ef9be090be82ec8826b7f477", size = 377975, upload-time = "2026-10-04T16:30:05.555Z" }, + { url = "https://files.pythonhosted.org/packages/e6/00/63fda451b8bffa5808fc8bb311ee7c073b340974b09f273c7b2a145d3d62/rpds_py-2026.9.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c91c210ae7645626c608400e3519b4a642f837cce09ca830db3beb2e9f274d4", size = 490347, upload-time = "2026-10-04T16:30:07.156Z" }, + { url = "https://files.pythonhosted.org/packages/a1/ae/c093ffd070ba0fb02f76c565d06fecc65ad6e4afdbae78f7031076d3cdac/rpds_py-2026.9.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:54ac2158a6f96cfbabff0b2eedaf94b90c5ec7ca8317fcadc61e1c2b2e0ff6ef", size = 392962, upload-time = "2026-10-04T16:30:08.77Z" }, + { url = "https://files.pythonhosted.org/packages/22/9d/d08a1128ab199b2f0cf25bfeb0639bd05119fff4b7c47bec24ef9a8ec23f/rpds_py-2026.9.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eac2f5dbafd585dfe31f86a23ebf0d3ba480a9d49ebc87947267b5608d4ea0cd", size = 371623, upload-time = "2026-10-04T16:30:10.501Z" }, + { url = "https://files.pythonhosted.org/packages/53/c7/4758ddcbb75609414bbccfcb11d612436f9b3ee821bd2f33f0f1604ee648/rpds_py-2026.9.1-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:8aa5dda18d39b6143eb24809d158f9252c88f402749b6f1b62a506cc7d96cc35", size = 376997, upload-time = "2026-10-04T16:30:12.124Z" }, + { url = "https://files.pythonhosted.org/packages/87/e4/947bd7f608ff60faf46dc9d389c3dffd0e3d767d78a0be19978448ef0ce7/rpds_py-2026.9.1-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5c90e7fa02e8f5de0d10c17595c568ada48c5302e749462c0ea1a4c362111a86", size = 400169, upload-time = "2026-10-04T16:30:13.804Z" }, + { url = "https://files.pythonhosted.org/packages/4b/35/fe93e020a0543b5670472c18d7e6af3197c08da571240ce1965c84f85c0f/rpds_py-2026.9.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e6d198bad4e49dd6732fbd636e2fc5c082f45c8cad0b4acb756b00c82c76072e", size = 551615, upload-time = "2026-10-04T16:30:15.332Z" }, + { url = "https://files.pythonhosted.org/packages/0d/4f/5d2a0136bb03b2a56a39dc6ff92d58a6e3e53a2e17079238b86228882f16/rpds_py-2026.9.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:96beca19ec79de272e8668585380ff9092c47077c1d7a1e098e00bbd921f4785", size = 614655, upload-time = "2026-10-04T16:30:16.92Z" }, + { url = "https://files.pythonhosted.org/packages/09/1c/3f1025aaf70d9bf7272cc41f8b64ee76b48bf01726248138430e16f23b38/rpds_py-2026.9.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a5cf77eb04f20b720be95265a3e00eb2a14814074255cc27069c551b2db53118", size = 579602, upload-time = "2026-10-04T16:30:18.555Z" }, + { url = "https://files.pythonhosted.org/packages/53/0d/5c72e6204f76610608706da32b6b7e11ef7e10317558a7bb15a122e008dc/rpds_py-2026.9.1-cp314-cp314-win32.whl", hash = "sha256:a03d57b86d2a51d0a66c92177e2be154ad015f357791d306e714569999cdb4cc", size = 206315, upload-time = "2026-10-04T16:30:20.05Z" }, + { url = "https://files.pythonhosted.org/packages/a4/0b/489d48abbcc7d70cf3fbf662d9d22abf1f4650761c0a9ae05260800800d3/rpds_py-2026.9.1-cp314-cp314-win_amd64.whl", hash = "sha256:837c6b305e26fe0f75b15c92cf3b2ba29e0ae19dc40b1c557b026cb426347d0c", size = 222852, upload-time = "2026-10-04T16:30:21.604Z" }, + { url = "https://files.pythonhosted.org/packages/91/16/bbb05a7e6a10cf79ba639be7f799d770ee15f64175cc61d081b218dd402a/rpds_py-2026.9.1-cp314-cp314-win_arm64.whl", hash = "sha256:fce4b85234a0cbad67bf8e6e1201ee815d172c9aebad75f25645bc4d834f8e31", size = 218709, upload-time = "2026-10-04T16:30:23.036Z" }, + { url = "https://files.pythonhosted.org/packages/22/ac/ac507a0a4ec478ca470440a09583db4be5259ba7670aeba0620822f1e57a/rpds_py-2026.9.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:3a72c11530d71abfb66c8d7696a2f86c43e63fca8b948f1a784ac490f4ec688e", size = 349596, upload-time = "2026-10-04T16:30:24.558Z" }, + { url = "https://files.pythonhosted.org/packages/e9/f2/817a46b658d5070f477f722c298ee9a24525b0e4017347964146ef5fdd0e/rpds_py-2026.9.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:068c37bba854ec2fe42f7365c640af11dd9895890ccbf2df5070d0c059bd7f96", size = 343114, upload-time = "2026-10-04T16:30:26.048Z" }, + { url = "https://files.pythonhosted.org/packages/6c/42/6ade976b13ac1b4cb3bf2eb603f1be2fe74df19a29988d4c2b386be59d6f/rpds_py-2026.9.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fca4eb6df565e2a928f1c7dad92d27db8f9df0f449e76423ed5d7e713ed445", size = 374197, upload-time = "2026-10-04T16:30:27.699Z" }, + { url = "https://files.pythonhosted.org/packages/d9/70/77cdf1d3f1a07faabe936016ae623aec7981f73108a8fe7a203ed2e21998/rpds_py-2026.9.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c933c6678c6f116ff8af47a4c6db0868b8ace74af0343016c0ef00f00272ea69", size = 378025, upload-time = "2026-10-04T16:30:29.451Z" }, + { url = "https://files.pythonhosted.org/packages/3f/6b/18a44a3beaa9b7931acb04af7bd9539836477c630a794452d4826d6185d4/rpds_py-2026.9.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:028ad274ea951dac64491b5d1e65712a4aeabfdbdb9fccf797b57bd899b0c495", size = 491969, upload-time = "2026-10-04T16:30:30.995Z" }, + { url = "https://files.pythonhosted.org/packages/73/27/fb39cfd6bddaf741b024f813890374578ff8ac1f1adc473659c048b03b05/rpds_py-2026.9.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:740d0a99cf9de0b17a3943388e9294a59becf75e7c43421f387bd3c7a9901f7c", size = 393905, upload-time = "2026-10-04T16:30:32.628Z" }, + { url = "https://files.pythonhosted.org/packages/ed/71/0fa7bb77b57af0d710273964180d11b503f62b8a5c358eb2d8c3f62feff6/rpds_py-2026.9.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0da298fb372dc192610a4b9ecbc68a0cd8b675bbbd1fc519d01b41cfd658333e", size = 374569, upload-time = "2026-10-04T16:30:34.257Z" }, + { url = "https://files.pythonhosted.org/packages/54/22/f41cfac269af3b449513ef1bc3d7f32fde52abbbd2d01c7e76b47743acd9/rpds_py-2026.9.1-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:eb61be926bb81567c1f48bdc8aa22b9855048dc2efd53871f9f7e6e9a5632346", size = 377482, upload-time = "2026-10-04T16:30:35.997Z" }, + { url = "https://files.pythonhosted.org/packages/b4/fc/312b49006e7f8f9ca5f96647577b8aa6f3df30519c46bd448f5c425af0b2/rpds_py-2026.9.1-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:42e75466f83cd43f6026c81eab74246efb2bdadafb307b85700632d06c68f299", size = 400040, upload-time = "2026-10-04T16:30:37.76Z" }, + { url = "https://files.pythonhosted.org/packages/cf/a6/18cca7a878dc7fa95165a83343fd4d7b65643fd22e54e47340a451121d5c/rpds_py-2026.9.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:617f59cde379b4f648a09797b7f683d04b90a46344cddab85639da5aff0f5531", size = 551849, upload-time = "2026-10-04T16:30:39.443Z" }, + { url = "https://files.pythonhosted.org/packages/e4/6d/1f5685e20f39604691bdc3c05aaa6b8bd2f954e9e996477adf2376768e33/rpds_py-2026.9.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:3edae8c5ddfdb6985d49ae9d150516e5076888879022f91a26c2de9276ce0bdb", size = 614842, upload-time = "2026-10-04T16:30:41.231Z" }, + { url = "https://files.pythonhosted.org/packages/c6/25/98652109fd9f7e10268dd4571aa52b81987001b806f37ef1a18260de714a/rpds_py-2026.9.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0f045bb053c9057720d72c56dffe30dffdc05997b2897a827b9325f0ab6623fa", size = 582606, upload-time = "2026-10-04T16:30:43.345Z" }, + { url = "https://files.pythonhosted.org/packages/19/03/11ca09099bab5f53373a80a334c424ec917c13d050760a59499d2af5171e/rpds_py-2026.9.1-cp314-cp314t-win32.whl", hash = "sha256:bf35d0568abda97233239ce32896d3ad53fccc537832c104e30c94aa5fb93569", size = 203341, upload-time = "2026-10-04T16:30:44.954Z" }, + { url = "https://files.pythonhosted.org/packages/6f/8a/88909e3ffd9f47f5b58211473875d8c3c09079f0058c46fb72c55a702a26/rpds_py-2026.9.1-cp314-cp314t-win_amd64.whl", hash = "sha256:1e8d4d79d828299bf44a55db22a9388ab967b49d17132c88eab0f4360b48da8e", size = 222843, upload-time = "2026-10-04T16:30:46.486Z" }, + { url = "https://files.pythonhosted.org/packages/f6/b7/a662f367d4896dd0a10cef2fc91f10b7f08af1c10858e287e019563f338d/rpds_py-2026.9.1-cp315-cp315-macosx_10_12_x86_64.whl", hash = "sha256:1d77b649e6f7cdf12ca5c2a98dad0ad37f9ea9b6f960408a92f0cb12bb3d04d9", size = 347463, upload-time = "2026-10-04T16:30:48.203Z" }, + { url = "https://files.pythonhosted.org/packages/ae/3f/ad45d03df4f84ebae5439577ee81f3999d182711e82235c8037b6528890e/rpds_py-2026.9.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:00ba2d8c7dd4ee537978ddf4b3fbd712bef2d8751603f7f3146b3f4287768e25", size = 342051, upload-time = "2026-10-04T16:30:49.872Z" }, + { url = "https://files.pythonhosted.org/packages/7e/31/3dcd68c13d4bcc59c1f7eb33ac8e80698f06f3eb0d8a1e06419836071c20/rpds_py-2026.9.1-cp315-cp315-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec450527cbf485e13c8d3602a54f428ab0432fdade0ede75efd74b735421c871", size = 374143, upload-time = "2026-10-04T16:30:51.508Z" }, + { url = "https://files.pythonhosted.org/packages/cf/0d/68c1f058a250fbd1380ebda9fc227cbf50117adf8ffe8161ef383ea79f68/rpds_py-2026.9.1-cp315-cp315-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:306ee1850d8105b5baf977e78d45fcadd12c1a54678d614c9baf217708446e91", size = 378604, upload-time = "2026-10-04T16:30:53.206Z" }, + { url = "https://files.pythonhosted.org/packages/d7/d6/2d4c59b85397cb4800594fadf692688ccf5ce556adc930e7a5bf21061a5e/rpds_py-2026.9.1-cp315-cp315-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ef6b65b03247c54692ad4fd9ee97cb772781927db72e3cb05e70b3db6d1ff14f", size = 490790, upload-time = "2026-10-04T16:30:54.925Z" }, + { url = "https://files.pythonhosted.org/packages/da/04/7e05dc3aebaf52f4e026766bd668fdd09a9d0e23f64a14686b36b3501892/rpds_py-2026.9.1-cp315-cp315-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a575404ebc9cf2e91edd32eaf570ec1430eb900d4f56724ba7dd4bc1fc9c176d", size = 393146, upload-time = "2026-10-04T16:30:56.625Z" }, + { url = "https://files.pythonhosted.org/packages/57/ca/e2e9a0a46a74ed51a0498ba1fe10f4ea6b2d9a155f372a2f91e51f18cf10/rpds_py-2026.9.1-cp315-cp315-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c16ab111bc27c646ba8aa005d0527754edc538ebb636f0b1bf8e244b48d1945", size = 372022, upload-time = "2026-10-04T16:30:58.295Z" }, + { url = "https://files.pythonhosted.org/packages/ba/cb/8f8774df5134e23424372838bcc5c7ed4127d723e1ff52f7bebd4dcb2563/rpds_py-2026.9.1-cp315-cp315-manylinux_2_31_riscv64.whl", hash = "sha256:7664419f27db41d4f1c43a78dccda7dd6e8ef2428df3ee01d0c2a07a6b071297", size = 377092, upload-time = "2026-10-04T16:30:59.984Z" }, + { url = "https://files.pythonhosted.org/packages/90/02/8d7095d73bf9114219be40230baa5df00611e0a82ed9517779ff9c19f82b/rpds_py-2026.9.1-cp315-cp315-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4b26b03d9d2658ee2fa234f8f4f19f38a09773fe5261028025032e26d4d35af0", size = 400830, upload-time = "2026-10-04T16:31:01.721Z" }, + { url = "https://files.pythonhosted.org/packages/ec/02/8206856f8f363cd042a8315dc86b3912f5dcb6d3c66bbb24b69c2bfb0775/rpds_py-2026.9.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:be3e47e2d91aa3942ff9bf4077a505226005abfc39b6f7554a91c1b9393986b9", size = 551478, upload-time = "2026-10-04T16:31:03.472Z" }, + { url = "https://files.pythonhosted.org/packages/41/6b/36211f1bb1f0b0313f496d92f5905b74ea107f27cb16fa3355a82f04575e/rpds_py-2026.9.1-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:6307a0da524939decb8ca4a3933b8ab62525794411d6984fca6726e732804af6", size = 615173, upload-time = "2026-10-04T16:31:05.281Z" }, + { url = "https://files.pythonhosted.org/packages/35/77/cda0c4a6f055446b692f0ed5692f73707cafd3dff82672ede31b1a9b59de/rpds_py-2026.9.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:159a7aab5c5e8b112c8830f54717ce56da1252ebdbb526f5be2df2309280b9e7", size = 579653, upload-time = "2026-10-04T16:31:07.065Z" }, + { url = "https://files.pythonhosted.org/packages/74/ec/d8385f446240aed643b9e92a5055cff3015cc04a13c61f73b2883c478ed5/rpds_py-2026.9.1-cp315-cp315-win32.whl", hash = "sha256:dbc2673f9223d420c91145599b3ba45a8a50c207d1976908e5fb5ddb0c9b9429", size = 206498, upload-time = "2026-10-04T16:31:08.989Z" }, + { url = "https://files.pythonhosted.org/packages/6d/a5/71b5cd00e0521e3b6b81828baea368c62b6b700ebdd9554cd7d41ddf12fa/rpds_py-2026.9.1-cp315-cp315-win_amd64.whl", hash = "sha256:75c38c50ab9aca840225d9a9a3810bf11d04bd5c1f186cabbb8aee56db3e9b15", size = 223121, upload-time = "2026-10-04T16:31:10.84Z" }, + { url = "https://files.pythonhosted.org/packages/33/58/dba857c3bc8221b31b62eb170a3080f4f191de79f047200389b7ed1b06a7/rpds_py-2026.9.1-cp315-cp315-win_arm64.whl", hash = "sha256:a431156bb41865fc14cd5d79bb9d7bbed83110b0159e34e62ae30951f96c0009", size = 218741, upload-time = "2026-10-04T16:31:12.592Z" }, + { url = "https://files.pythonhosted.org/packages/5b/d0/320ab28ccc1415eeb509d68682b0014fb74690cd49f1c2d29a232475af50/rpds_py-2026.9.1-cp315-cp315t-macosx_10_12_x86_64.whl", hash = "sha256:ef0d8c843e2827d6c120ab4687e9423fb1d893db1df27b7c1506615bcb9734a0", size = 349719, upload-time = "2026-10-04T16:31:14.48Z" }, + { url = "https://files.pythonhosted.org/packages/56/88/f5b12f1358f443c08b7ce3cc8391d82d335f4872580e2e097847fd36087a/rpds_py-2026.9.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:45bc6bccf78b20fd834237d18db64965d7ee68ba7f60440a26c7ab71e7b8d51a", size = 343267, upload-time = "2026-10-04T16:31:16.827Z" }, + { url = "https://files.pythonhosted.org/packages/f7/0c/c765b0059d532acb3b9c45d781ccc22f15a96dbe443d00903f643ba9df10/rpds_py-2026.9.1-cp315-cp315t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d55198263bb51f557550c6ed2e6d1cb6a6fed6eb5c9120b741c5926bef8a45d", size = 374555, upload-time = "2026-10-04T16:31:18.931Z" }, + { url = "https://files.pythonhosted.org/packages/6b/8a/cafddfda77564a10cd21184640c3bffda6a2b8d20972fb5dedd5e0166328/rpds_py-2026.9.1-cp315-cp315t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a8763f20692da7df39b0afdd1ba3042b004c50a45994f76c2d9a25641f7673db", size = 378346, upload-time = "2026-10-04T16:31:20.75Z" }, + { url = "https://files.pythonhosted.org/packages/b9/01/5e626016eff72c183bf6c96539240cace15d402468647a453ec08415b2fc/rpds_py-2026.9.1-cp315-cp315t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e43d4a1f673e8a1cbd8533e809e02b4bf9d4f2280269bb640436556312121250", size = 492373, upload-time = "2026-10-04T16:31:22.614Z" }, + { url = "https://files.pythonhosted.org/packages/3b/9c/15a2469e9389242f46896b3f0a01d68caea8a5a35c011fcb05ef333aae73/rpds_py-2026.9.1-cp315-cp315t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea394a937f17a54c51239348bdbe2e3518124c8d4a8951ba04a311d3095bd18f", size = 394371, upload-time = "2026-10-04T16:31:24.768Z" }, + { url = "https://files.pythonhosted.org/packages/63/f5/c100ff77e1e6366e947c75969c258fdfc4b7bc5bbfe7351e62ffbf2a1228/rpds_py-2026.9.1-cp315-cp315t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdeaa99ce822dca76cfb1b993e9120c5ea212f2eb66d48950ad63c349668a018", size = 375132, upload-time = "2026-10-04T16:31:26.588Z" }, + { url = "https://files.pythonhosted.org/packages/dd/f4/fe0269c9de253e99c81cabc12b8971a5feaa083debdaff1221e06264d9e3/rpds_py-2026.9.1-cp315-cp315t-manylinux_2_31_riscv64.whl", hash = "sha256:b4f062343e7ad3fa94f2c66e5ae667dee47ee74dd41a9057c4fbe163236a123d", size = 377642, upload-time = "2026-10-04T16:31:28.677Z" }, + { url = "https://files.pythonhosted.org/packages/05/65/b34a7b257baccff8f4a24a722933166d4941d5ebdc9c3f4bc4ffcd5ce4f4/rpds_py-2026.9.1-cp315-cp315t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:22ffd29a63d71fb1b81552c21f2c2b734949b7ac751a9be70675a939a900839b", size = 400855, upload-time = "2026-10-04T16:31:30.802Z" }, + { url = "https://files.pythonhosted.org/packages/98/32/844e54176b6071b90b38a564e6940bc6eb8f97b2890dc709c19db9dec0f4/rpds_py-2026.9.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:08dae4a4095150a7c4545a1fb40b98e1ab1744fbc2770d92c977b9dadaa49ab6", size = 552573, upload-time = "2026-10-04T16:31:32.709Z" }, + { url = "https://files.pythonhosted.org/packages/17/73/6041d20729dffbfdf155c02d65be58bc225a1c1fb548fd87c23ef306138f/rpds_py-2026.9.1-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:9a0460d43603d1fd9ef59c30278531e15d78581721ddb538fa560aa7817ea4ad", size = 615840, upload-time = "2026-10-04T16:31:34.565Z" }, + { url = "https://files.pythonhosted.org/packages/af/9e/418094adaee6b056ce199051b255448ed872829051e341b2294c80da0977/rpds_py-2026.9.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:1c2d1f6da5128eabf34e963d7163a818846075a52568250d006c4c953b40f903", size = 582764, upload-time = "2026-10-04T16:31:36.665Z" }, + { url = "https://files.pythonhosted.org/packages/3d/9b/1698ebf6b840ddfe8b472198abbed6ace35c6e398faeecd6c47dae742a4e/rpds_py-2026.9.1-cp315-cp315t-win32.whl", hash = "sha256:5c6ee90dee3e85e055ddfd502d611643d9b0fd94c818220bda84ec3dacd9b27b", size = 203795, upload-time = "2026-10-04T16:31:38.53Z" }, + { url = "https://files.pythonhosted.org/packages/8a/e2/91f70d804c61f8eac39a417e82aa1024f655ab9e8bdd7393b196242bc41b/rpds_py-2026.9.1-cp315-cp315t-win_amd64.whl", hash = "sha256:fe5ad0664ec772b02c45859041aa17655709cced7a31005817fbbbd988c25567", size = 223037, upload-time = "2026-10-04T16:31:40.468Z" }, + { url = "https://files.pythonhosted.org/packages/a3/90/a9ba81408369d34c1aca73319c15adc91ed45c1d21e9e8ee4832ffb7fe0b/rpds_py-2026.9.1-pp312-pypy312_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cdc537c8633d7fd92a82e2e0d2ab74320a3f63d5e59fb9cf08711e08fe151c4", size = 381109, upload-time = "2026-10-04T16:32:08.994Z" }, + { url = "https://files.pythonhosted.org/packages/b3/44/5192a0bed94cec86bd2a5e1cc5a1bb8f7eec3aec907eacd2deb13e87e326/rpds_py-2026.9.1-pp312-pypy312_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:10e208f2425d973938afcd56e28a7c4be32e27b6a60b5d381f49fb9d8acf9759", size = 388222, upload-time = "2026-10-04T16:32:11.321Z" }, + { url = "https://files.pythonhosted.org/packages/92/cd/5356549711448f18b52f7a11ffbe90f1228774996fbf3c6cd1b18d22abaf/rpds_py-2026.9.1-pp312-pypy312_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c0dbbcc19735fe5f8b0a54c07659d154a9e69f47e15d0a6ab7299215daf62cb", size = 500384, upload-time = "2026-10-04T16:32:13.478Z" }, + { url = "https://files.pythonhosted.org/packages/7a/88/ddda9d28adfe33119c75b2e733d4ba7e326f41d7e1b1093951771768ca48/rpds_py-2026.9.1-pp312-pypy312_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:684fd492fff4fead00587544e059be2bbcb6f93454f21fa2a91b66fc7508be82", size = 401661, upload-time = "2026-10-04T16:32:15.653Z" }, + { url = "https://files.pythonhosted.org/packages/32/c3/bb59ba16a6b4a57995d15b8c04c00f28df3b938c4dcdde48fbe0f73edb0c/rpds_py-2026.9.1-pp312-pypy312_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1028417bb44037eb3069c1009bd7b7277212876cda22fbe565b0bca9fab6d2c", size = 380748, upload-time = "2026-10-04T16:32:17.727Z" }, + { url = "https://files.pythonhosted.org/packages/f5/b8/0580faa1c5a32ddc160130dd7ae54d2d007272a89a40a6b5db3e50f9f585/rpds_py-2026.9.1-pp312-pypy312_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:492e5e428cbe126221611f47e068f01660352feec4ad18bc0f5ea9b2ae88fb14", size = 385731, upload-time = "2026-10-04T16:32:19.855Z" }, + { url = "https://files.pythonhosted.org/packages/bf/70/f73564642bbe3322c7eeef2c2f258cf040b71c41a430b532e59d04a1b838/rpds_py-2026.9.1-pp312-pypy312_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:88b5268892fde430d5531f95bc560b6efbbd67c929662c586afd729a96e7461c", size = 412131, upload-time = "2026-10-04T16:32:22.285Z" }, + { url = "https://files.pythonhosted.org/packages/8c/5d/17fff2e1f8f68721a2afb5cb48f7e442c751bb6b4883157c5abaf618cd08/rpds_py-2026.9.1-pp312-pypy312_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:01445c8d194aa032a08e944f16567672da1c62dbdbefd8b6d0693032e290cf68", size = 558193, upload-time = "2026-10-04T16:32:24.4Z" }, + { url = "https://files.pythonhosted.org/packages/2a/d0/869ab6fb08531f97aae4a780b4d61b4190d8aef48fe054ee28bcf7114466/rpds_py-2026.9.1-pp312-pypy312_pp73-musllinux_1_2_i686.whl", hash = "sha256:eef6a03b0b6d08d0835ccfa8ec8d1bc70525e3801387567137b50c557695e6da", size = 622448, upload-time = "2026-10-04T16:32:26.844Z" }, + { url = "https://files.pythonhosted.org/packages/ba/a5/9672e532fe02cd3b92c78cfd8743abca939d96853006c63835009a1ecb6f/rpds_py-2026.9.1-pp312-pypy312_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6b9bf3135b4ad5981df9a73d71a35272d650a2985ae9c2746357b24d59de2448", size = 591126, upload-time = "2026-10-04T16:32:29.274Z" }, + { url = "https://files.pythonhosted.org/packages/80/ef/3a9f8e4279c7920af561deed4cb7ebebed2794a8f608cf404d5eef14a105/rpds_py-2026.9.1-pp312-pypy312_pp80-macosx_10_12_x86_64.whl", hash = "sha256:56c6952a9b15047466d0c2347c446a761d4527f89976156341e68f0ce5cc08b0", size = 357108, upload-time = "2026-10-04T16:32:31.641Z" }, + { url = "https://files.pythonhosted.org/packages/b7/55/4b2fa381a583760aea5c92841e4e928a358e1c6511b129219e9c2826a226/rpds_py-2026.9.1-pp312-pypy312_pp80-macosx_11_0_arm64.whl", hash = "sha256:b242c27c8f836305a4a72df9cdd564386ac57b807bd252a063223331c9316b37", size = 346877, upload-time = "2026-10-04T16:32:34.061Z" }, +] + +[[package]] +name = "ruff" +version = "0.17.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e7/e6d5749983b020e6cb1055abec0a6f361a8e94f0184cdcf56d4760995f02/ruff-0.17.1.tar.gz", hash = "sha256:5bb796c5112e9fb9527f2ef2faa0a130d6312d19de92bcfaddd70dbb2d41020f", size = 5323349, upload-time = "2026-10-15T15:23:18.64Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2e/78/90c46ca6250709f7c37e397b60d06061adee8d0f7d13959ed6a8e49b14fd/ruff-0.17.1-py3-none-linux_armv6l.whl", hash = "sha256:1796c41eafec66f4635125dd1e074a7aa27b8d20c187d484360acf11d247fc4a", size = 10147528, upload-time = "2026-10-15T15:22:33.667Z" }, + { url = "https://files.pythonhosted.org/packages/aa/d2/a2e28bc35b083ae51fa07dfba5280a667c8b01ecaee7802fc8849dcd5c46/ruff-0.17.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:8eadb09a788010be29c895418bdfa513e4e1c65e64b94e5b19e4cd381f6cc7fb", size = 10225974, upload-time = "2026-10-15T15:22:36.328Z" }, + { url = "https://files.pythonhosted.org/packages/8e/71/7a9029a81c8206ee01a98f6cfeeb56e6c095af86857581a37045c46d7e94/ruff-0.17.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:29b454f18ca3eeaf37fbf140841dcf27d36109e29dee9aae8acecb68c26c6f74", size = 9270361, upload-time = "2026-10-15T15:22:38.651Z" }, + { url = "https://files.pythonhosted.org/packages/c0/8c/e075e9c917cb0575297880c96768304e881240171c870cbd8d9b7b54bec2/ruff-0.17.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872e03dd231744d6c5ec5c8af6be52b71323fc6ee096e4c8b34d9f844ee3b978", size = 9938300, upload-time = "2026-10-15T15:22:41.284Z" }, + { url = "https://files.pythonhosted.org/packages/87/27/0b4bb926a49de2383f161272b4d863571a4c7ecdbf595a6bc58813a13367/ruff-0.17.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4c0d6cb5f8fbac77eec9af49f4fc0eaf856b05545e372b0694d24b4e76b1c640", size = 9948464, upload-time = "2026-10-15T15:22:43.681Z" }, + { url = "https://files.pythonhosted.org/packages/14/27/518d57e0e02aecb8ea4acac6b57b51a53173d25fa734952bfdd7d531e88e/ruff-0.17.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78beced4a3c94dfedbee4b999b95b6a27b35820fdc0afbacc6d37a8da26c1cd1", size = 10638639, upload-time = "2026-10-15T15:22:46.081Z" }, + { url = "https://files.pythonhosted.org/packages/01/82/d89a4e498ade59e6cee52d67f8da569019372212b87468c1fdeae884601c/ruff-0.17.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7feefc63921202894f0e158b0e32f45a5950d70a7fb693ccb9264816c25b1c05", size = 11337238, upload-time = "2026-10-15T15:22:48.894Z" }, + { url = "https://files.pythonhosted.org/packages/a2/7c/3b0fdef9352656317c977086fe1d802902406e4f2a0d8578da90c0e6d1c5/ruff-0.17.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:684154861a819bf1f433669d2a0ce9c3e54677c65b8ebb866cc2a7ec86345785", size = 10896327, upload-time = "2026-10-15T15:22:51.45Z" }, + { url = "https://files.pythonhosted.org/packages/62/86/5566290219708ce2928f3a29c4f843a1185b341ec6111c4631a33c5ceced/ruff-0.17.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6ef98e51de8ef38082f90653ceeb84944bd7673783eea13e1647c5b9b064189", size = 10350811, upload-time = "2026-10-15T15:22:54.401Z" }, + { url = "https://files.pythonhosted.org/packages/ad/d2/ca8462dabb3c413990d49703ba306c30c862195a75448d080fa8fcce9775/ruff-0.17.1-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:8f9aa5b5bd5fa1937803ea609c8f153b8de39bf3e0e149897ae34b0c5b52f467", size = 10569994, upload-time = "2026-10-15T15:22:57.142Z" }, + { url = "https://files.pythonhosted.org/packages/e3/ad/dd1864c1f1db17c8cfb297ce70b352388e6977620f66f7182c52855407df/ruff-0.17.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:80e53b0e5faa3c5667f035daaa032893ae42b7cfe708c886d39ed131e54688ab", size = 10059672, upload-time = "2026-10-15T15:23:00.084Z" }, + { url = "https://files.pythonhosted.org/packages/65/45/3f56cf1d2168c2165cdd5ac6f9668aee66a4cfdd4caf2b2cc5ccb2b1d568/ruff-0.17.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:056c5d5fa0ac790051ae165d7035c7bf956d02de2db557f2e9b31d877a505fca", size = 9947803, upload-time = "2026-10-15T15:23:03.132Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4b/5457cb2be4c1d1ea5e919558131a0f197a4a454a0530d9e30820e8206e4c/ruff-0.17.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bd8f5a55b10f371642eacd0e8665a42a8b97da15c9a7187c79e697b77b5e0ce4", size = 10351807, upload-time = "2026-10-15T15:23:05.628Z" }, + { url = "https://files.pythonhosted.org/packages/49/fb/db15b4f8fa24a1e36b99e1401f42ef6df16ee299a48670d5d262b771e7d7/ruff-0.17.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ce05e6f3973611d9550a600e04bb531061e368baba31610eb57c1509a8f21a0a", size = 10765716, upload-time = "2026-10-15T15:23:08.092Z" }, + { url = "https://files.pythonhosted.org/packages/0a/e8/1e186578076aff7a80735f625005fde678412ab609cd323ed182eb7d6b87/ruff-0.17.1-py3-none-win32.whl", hash = "sha256:1de0030a8aa78c65c5fecb84b2e5c390ac684c0452875a02afc7c083d49a496a", size = 9895093, upload-time = "2026-10-15T15:23:10.582Z" }, + { url = "https://files.pythonhosted.org/packages/6a/2e/da3d9589bae8e8b58f3a48bd5bc0b980232fb14a83bf02c3be7660f87c1b/ruff-0.17.1-py3-none-win_amd64.whl", hash = "sha256:5df76f16580fab58d0f6c98a3ac254a4abceb7b2489b8b678335869cff77b3d7", size = 10097955, upload-time = "2026-10-15T15:23:13.309Z" }, + { url = "https://files.pythonhosted.org/packages/df/c9/0f2a4dea06a5e12c1191ee3d96b1e1233797d0d5e18f97a2b909a95a9836/ruff-0.17.1-py3-none-win_arm64.whl", hash = "sha256:42400b9a6ff8515ff27796f07f92e0195be011c86e81e381606f58ea5502fef4", size = 9853542, upload-time = "2026-10-15T15:23:16.05Z" }, +] + +[[package]] +name = "ty" +version = "0.0.90" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/68/b1/613b5534624442a9118828d7a9e54d50b16f0f5c8b67c80eb6623f33b921/ty-0.0.90.tar.gz", hash = "sha256:25cef63ec07a0254c2f5d885a63b001d0bfa437b20caa0a408f4f52e66b133e7", size = 7996206, upload-time = "2026-10-20T14:25:19.477Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/33/0e3395afa2c31c0e8e91547629858d2a5de213c69af237e6e50f37545565/ty-0.0.90-py3-none-linux_armv6l.whl", hash = "sha256:0dedb54977b40bc86638fec2c90eefd593f3a6683003a86b7e6cb67c17bcc476", size = 14281945, upload-time = "2026-10-20T14:24:21.018Z" }, + { url = "https://files.pythonhosted.org/packages/d7/fd/5d632b2f88d5c18991a4936da8643c7f204cfbc4980f8c7cd9080af988ad/ty-0.0.90-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3d7c30ceaac76dfbfcf36b72d36272d21c3898e98fc4de296aa9cbae956dec9d", size = 13786355, upload-time = "2026-10-20T14:24:24.392Z" }, + { url = "https://files.pythonhosted.org/packages/79/08/0d2f37bb4f766ab9630f01b07f4d11f1f7a6a6188f920d5ca9fa8a4676b1/ty-0.0.90-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c0b7e4d9ae0939294f0a18652de9ad7d81da2d7f567cf93f1edda1263008c124", size = 12856535, upload-time = "2026-10-20T14:24:27.386Z" }, + { url = "https://files.pythonhosted.org/packages/e4/77/70658f6b80c345ae0c12f2192a5cc89b8ca13eccfe06616b0fac3806c261/ty-0.0.90-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c4a095a86a132df374e652894fe08392aeb1601d6347e1eb4b58808094a302", size = 13696342, upload-time = "2026-10-20T14:24:30.413Z" }, + { url = "https://files.pythonhosted.org/packages/b9/3e/693049f93653d2f6412bb0c2c0af1d01675e31643af29bef7177d3ff7e79/ty-0.0.90-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4e24a8aa07c05d9d14648289e79a88b7c7c2c522c58b53bb5f466a6ba4704e22", size = 14014180, upload-time = "2026-10-20T14:24:33.783Z" }, + { url = "https://files.pythonhosted.org/packages/27/08/19e373f97501eaadc8fc42e8c07cd54a64e375fbcf1470797be13590d5ba/ty-0.0.90-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40c3ea8fc1dfcf7502f71b93b12e80da1f7a8a5fd7e55ec9feabcf4ac39f72ea", size = 14935189, upload-time = "2026-10-20T14:24:37.459Z" }, + { url = "https://files.pythonhosted.org/packages/33/54/3331984f2c896a7383b6b18c86e968a63dd046baf503119a8e8e7682c752/ty-0.0.90-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1af75532bbe3e305089c30806fa5e804f8b01de231c1fa07918f7f3b335626da", size = 15311482, upload-time = "2026-10-20T14:24:40.87Z" }, + { url = "https://files.pythonhosted.org/packages/bf/f3/179acf8d730c2c864767ffcc9081f5ea6fdb1b34ef711f1bd226200e9cff/ty-0.0.90-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f09449b34d837a044dab043aeb2b4b6ff2d2cef5eaf8116c7c19d34cc2a16a21", size = 15278844, upload-time = "2026-10-20T14:24:44.539Z" }, + { url = "https://files.pythonhosted.org/packages/71/7e/661bc2fa20e0ac84c4d5f92e4c098ec667a0e920851a6d10c10a0251f0dc/ty-0.0.90-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc868ffa7dfcb3169eea3ba7d634e5a3283c7133fb932c6e47a2e16620d26ca5", size = 14558774, upload-time = "2026-10-20T14:24:47.814Z" }, + { url = "https://files.pythonhosted.org/packages/f4/2e/3f65f61f4545f75255373be7646a606e004bb4cdc851e236bf17ca94bdc2/ty-0.0.90-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:e2405206533dc896a2b711e781f2955d5883d85536f4df0ac262fca6517103c2", size = 14788158, upload-time = "2026-10-20T14:24:51.223Z" }, + { url = "https://files.pythonhosted.org/packages/1e/10/3c91a529591667b89d63c86806bfe2ac56d6989c7e0a09ee0964b7512deb/ty-0.0.90-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0dca4a29e8778285d2fc204af19254571486106fd14aed60769bfd272c795f6f", size = 13687177, upload-time = "2026-10-20T14:24:54.611Z" }, + { url = "https://files.pythonhosted.org/packages/21/b2/1b6d48606c67614bfb0c8e61a5d67a053ca1e3c5956ddb584f8569b8dc3d/ty-0.0.90-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d004b8e4e898fead929eceea669b73936444671748e0dd44e624cc109346c0dd", size = 14027780, upload-time = "2026-10-20T14:24:59.045Z" }, + { url = "https://files.pythonhosted.org/packages/4f/c4/a0771debf725312524ca1434f8a146d37e573d45257ca4bebb9cc8e35bbc/ty-0.0.90-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a6be182da4281b4581c4a1b27c6a0caebeed7212e4bdc98c6b8fe0d9bc36dea0", size = 14355890, upload-time = "2026-10-20T14:25:03.034Z" }, + { url = "https://files.pythonhosted.org/packages/a7/4c/036724b6936ffc38e28ff5e20ab7972d609c65a3dd9645f3d10f57cfd16f/ty-0.0.90-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:0ba6fe0a24ff4cbc5034f3aa1c88b3ad1397315dd3369357e694fd157a11864e", size = 14692306, upload-time = "2026-10-20T14:25:07.461Z" }, + { url = "https://files.pythonhosted.org/packages/a8/2a/c74fd5fc3fb5b046fe06a9067cabf5417b73e28249dc9af90ef72700f8fd/ty-0.0.90-py3-none-win32.whl", hash = "sha256:4c46a79caf84c4da0f7293e16bd769bd467c7cbc38015cac7608ab4e5ec8ba9c", size = 13235434, upload-time = "2026-10-20T14:25:10.545Z" }, + { url = "https://files.pythonhosted.org/packages/d2/54/be5cd6b17d8087a5e4c26892311c07e39d42b66c925b0f06cfc51a9ce83b/ty-0.0.90-py3-none-win_amd64.whl", hash = "sha256:8d77c16d20201b7a07ccaafb610eaf60488783dbba9865c4f9182e584f1426f8", size = 13855668, upload-time = "2026-10-20T14:25:13.648Z" }, + { url = "https://files.pythonhosted.org/packages/33/68/6dea089a897e8b314504eecc2633de3c8fe14f70e71a35606d14a2ba169e/ty-0.0.90-py3-none-win_arm64.whl", hash = "sha256:bfb63e74eeedb0a29d49cf58d611c540bfdfc0975dfce26efc6575bcf439208d", size = 13330853, upload-time = "2026-10-20T14:25:16.642Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] + +[[package]] +name = "virtualenv" +version = "21.14.11" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "packaging" }, + { name = "platformdirs" }, + { name = "python-discovery" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7f/be/4d1d59d309db76b5808fcfd78bd5996f4e7241366691c38fc331a3136398/virtualenv-21.14.11.tar.gz", hash = "sha256:593052d8477ea8c55a842387ce111bd08c72618f0c1133c302cafe335e570a57", size = 5503091, upload-time = "2026-10-18T07:06:34.716Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/6b/d85da8982b41190eafcb9df91dff9d83fc6989e98af4b5be4c8f85510c95/virtualenv-21.14.11-py3-none-any.whl", hash = "sha256:b319f8590a84e5de5f8f2c803ecd2237e9bc0ffa7c1e875e3169c107cecb7454", size = 5495268, upload-time = "2026-10-18T07:06:32.719Z" }, +] diff --git a/python/spec-kit/.pre-commit-config.yaml b/python/spec-kit/.pre-commit-config.yaml index ca2af49..c98d770 100644 --- a/python/spec-kit/.pre-commit-config.yaml +++ b/python/spec-kit/.pre-commit-config.yaml @@ -97,7 +97,8 @@ repos: .*\.lock| .*\.parquet| .*\.feather| - .*/dfo_descriptions/vectors/.*\.json + .*/dfo_descriptions/vectors/.*\.json| + .*/dfo_client_contract/.*\.json )$ # --------------------------------------------------------------------------- diff --git a/tools/README.md b/tools/README.md index 91f0700..ab1b3a7 100644 --- a/tools/README.md +++ b/tools/README.md @@ -38,6 +38,12 @@ uv run tools/validate_provenance_docs_vectors.py uv run tools/validate_descriptions_vectors.py ``` +`validate_client_contract.py` validates the client contract under `python/client-contract/src/dfo_client_contract/` against its schemas, then checks what they cannot express: every `strict-fields.json` pointer resolves in `served/openapi.json` and stays required and non-nullable, or keeps its enum values; `actions.json` holds one row, in code order, for each active refusal code in `registries/codes.json` that reaches a problem document or a no_data reason, with a gap kind exactly for the no_data reasons; each recorded scenario's requests match a served route and its JSON bodies validate against that route's schemas, a required member that admits null allowed to be absent; and each `DatasetRef` example gets the verdict it states. It does not import `dfo_client_contract`, whose `tests/test_rules.py` replays the rule vectors. Also a PEP 723 script: + +```bash +uv run tools/validate_client_contract.py +``` + `validate_unit_vectors.py` validates every file under `vectors/units/` against `schemas/vectors/unit-vector.schema.json`, and checks what the schema cannot express: file names match names, names are unique, the suite meets its floor, and every classification, compare outcome and typed-unit kind has a vector. It does not import `dfo_spec_kit`. Also a PEP 723 script: ```bash diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py new file mode 100644 index 0000000..12ef165 --- /dev/null +++ b/tools/tests/test_validate_client_contract.py @@ -0,0 +1,310 @@ +"""Tests for tools/validate_client_contract.py. + +The real contract must validate, and each fault the schemas cannot catch +must be reported: a strict pointer the served document does not hold or holds +as optional or nullable, an action row out of step with the code registry, a +recorded body the served document rejects, a scenario whose steps or body +files do not fit, and a ref example with the wrong verdict. + +Each case validates a whole copy of the contract, the served document's +bodies included, which takes about a third of a second. + +Run with: uv run --with jsonschema --with pytest pytest tools/tests -q +""" + +from __future__ import annotations + +import importlib.util +import json +import shutil +import sys +from collections.abc import Callable +from pathlib import Path +from typing import Any + +import pytest + +_MODULE_PATH = Path(__file__).resolve().parent.parent / "validate_client_contract.py" +_spec = importlib.util.spec_from_file_location("validate_client_contract", _MODULE_PATH) +validator = importlib.util.module_from_spec(_spec) +sys.modules["validate_client_contract"] = validator +_spec.loader.exec_module(validator) + +_SEARCH = "scenarios/search-place-ambiguous.json" +_FETCH = "scenarios/fetch-spec-known-sentence.json" + + +@pytest.fixture +def package_dir(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path: + """A copy of the real contract and registry the test may break.""" + copy = tmp_path / "dfo_client_contract" + shutil.copytree(validator.PACKAGE_DIR, copy) + registry = tmp_path / "codes.json" + shutil.copyfile(validator.REGISTRY_PATH, registry) + monkeypatch.setattr(validator, "PACKAGE_DIR", copy) + monkeypatch.setattr(validator, "REGISTRY_PATH", registry) + return copy + + +def _edit(path: Path, change: Callable[[Any], None]) -> None: + document = json.loads(path.read_text(encoding="utf-8")) + change(document) + path.write_text(json.dumps(document), encoding="utf-8") + + +def test_the_real_contract_is_valid(package_dir: Path) -> None: + assert validator.validate() == [] + assert validator.main() == 0 + + +def _strict(pointer: str) -> Callable[[Any], None]: + return lambda doc: doc["required"].append({"pointer": pointer}) + + +def _drop_action(code: str) -> Callable[[Any], None]: + def change(doc: Any) -> None: + doc["codes"] = [row for row in doc["codes"] if row["code"] != code] + + return change + + +def _add_action(row: dict[str, Any]) -> Callable[[Any], None]: + def change(doc: Any) -> None: + doc["codes"] = sorted([*doc["codes"], row], key=lambda r: r["code"]) + + return change + + +def _set_action(code: str, **fields: Any) -> Callable[[Any], None]: + def change(doc: Any) -> None: + row = next(r for r in doc["codes"] if r["code"] == code) + row.update(fields) + for name, value in fields.items(): + if value is None: + del row[name] + + return change + + +def _retire(code: str) -> Callable[[Any], None]: + def change(doc: Any) -> None: + next(e for e in doc["entries"] if e["code"] == code)["lifecycle"] = "retired" + + return change + + +def _set_body(index: int, change: Callable[[Any], None]) -> Callable[[Any], None]: + return lambda doc: change(doc["exchanges"][index]["response"]["json"]) + + +@pytest.mark.parametrize( + ("target", "change", "expected"), + [ + ( + "strict-fields.json", + _strict("/components/schemas/Manifest/properties/sentence"), + "does not resolve", + ), + ( + "strict-fields.json", + _strict("/components/schemas/OperationEnvelope/properties/poll"), + "is not required in OperationEnvelope", + ), + ( + "strict-fields.json", + _strict("/components/schemas/ColumnOptionModel/properties/distinct"), + "admits null", + ), + ( + "strict-fields.json", + lambda doc: doc["enums"][0]["values"].append("verdict"), + "no longer admits ['verdict']", + ), + ( + "strict-fields.json", + _strict("/components/schemas/Manifest/properties/content_version"), + "is listed twice", + ), + ("actions.json", _drop_action("spec_not_found"), "'spec_not_found' has no row"), + ( + "actions.json", + _add_action({"code": "alternates_unevaluated", "action": "report"}), + "outside the active refusals", + ), + ( + "actions.json", + _add_action({"code": "no_such_code", "action": "report"}), + "is not in the registry", + ), + ( + "actions.json", + lambda doc: doc["codes"].reverse(), + "codes are not sorted", + ), + ( + "actions.json", + _set_action("variable_not_resolved", gap_kind=None), + "must carry gap_kind", + ), + ( + "actions.json", + _set_action("entity_ambiguous", action="ask_data_question"), + "choose goes with choice only", + ), + ( + "actions.json", + _set_action("spec_not_found", action="ask_data_question"), + "cannot carry action 'ask_data_question'", + ), + ( + _FETCH, + _set_body(0, lambda body: body.pop("content_version")), + "'content_version' is a required property", + ), + ( + _SEARCH, + _set_body(0, lambda body: body["parts"][0].update(status="maybe")), + "response body", + ), + ( + _SEARCH, + lambda doc: doc["exchanges"][0]["request"]["json"].update(extra=True), + "request body", + ), + ( + _SEARCH, + lambda doc: doc["exchanges"][0]["request"].update(path="/search/nowhere"), + "matches no route", + ), + ( + _FETCH, + lambda doc: doc["exchanges"][1]["request"].update(method="POST"), + "serves no POST", + ), + ( + _SEARCH, + lambda doc: doc["exchanges"][0].update( + response={ + "status": 404, + "json": { + "type": "/codes/request_invalid", + "title": "Not found", + "status": 404, + "detail": "No route.", + "code": "request_invalid", + "trace_id": "t", + "capability_version": "c", + "retryable": False, + }, + } + ), + "not an active code registered with status 404", + ), + (_SEARCH, lambda doc: doc.update(name="search-other"), "differs"), + ( + _SEARCH, + lambda doc: doc["call"].insert(0, {"op": "result"}), + "does not follow a step in ['mint']", + ), + ( + _SEARCH, + lambda doc: doc["expect"].append(doc["expect"][0]), + "1 steps but 2 outcomes", + ), + ( + _SEARCH, + lambda doc: doc.update( + origin={"kind": "synthetic", "derived_from": "absent", "edit": "None."} + ), + "is not a recorded scenario", + ), + ( + _FETCH, + lambda doc: doc["exchanges"][2]["response"].update(body_file="other.bin"), + "does not start with the scenario's name", + ), + ( + "refs/ref-one-member.json", + lambda doc: doc.update(error={"by": "schema"}), + "carries neither or both", + ), + ( + "refs/ref-repeated-spec-id-rejected.json", + lambda doc: doc["ref"]["members"].pop(), + "breaks rule None, expected 'repeated_spec_id'", + ), + ( + "rules/key-format.json", + lambda doc: doc["vectors"].append(doc["vectors"][0]), + "vector 'secret-key-passes' repeats", + ), + ( + "served/SOURCE.json", + lambda doc: doc.update(commit="8408f1f"), + "commit is not a 40-character sha", + ), + ], + ids=[ + "strict-pointer-unresolved", + "strict-pointer-optional", + "strict-pointer-nullable", + "strict-enum-value-gone", + "strict-pointer-repeated", + "action-row-missing", + "action-row-for-a-warning", + "action-row-for-an-unknown-code", + "actions-unsorted", + "gap-kind-missing", + "choose-without-choice", + "answer-action-on-a-problem-code", + "recorded-body-missing-a-strict-member", + "recorded-body-unknown-part-status", + "recorded-request-extra-member", + "unrouted-path", + "unserved-method", + "problem-code-wrong-status", + "scenario-name-mismatch", + "step-out-of-order", + "outcome-count-mismatch", + "synthetic-without-a-parent", + "body-file-misnamed", + "ref-example-both-verdicts", + "ref-example-wrong-verdict", + "rule-vector-repeated", + "source-commit-short", + ], +) +def test_a_broken_contract_is_reported( + package_dir: Path, + target: str, + change: Callable[[Any], None], + expected: str, +) -> None: + _edit(package_dir / target, change) + problems = validator.validate() + assert any(expected in problem for problem in problems), problems + + +def test_a_retired_code_with_a_row_is_reported(package_dir: Path) -> None: + _edit(validator.REGISTRY_PATH, _retire("spec_not_found")) + problems = validator.validate() + assert any("'spec_not_found' is retired refusal" in p for p in problems), problems + + +def test_a_missing_body_file_is_reported(package_dir: Path) -> None: + (package_dir / "scenarios" / "fetch-spec-known-sentence.parquet").unlink() + problems = validator.validate() + assert any("is missing" in p for p in problems), problems + assert validator.main() == 1 + + +def test_an_orphan_body_file_is_reported(package_dir: Path) -> None: + (package_dir / "scenarios" / "stray.parquet").write_bytes(b"") + problems = validator.validate() + assert any("no scenario names this body file" in p for p in problems), problems + + +def test_no_scenarios_is_a_hard_failure(package_dir: Path) -> None: + for path in (package_dir / "scenarios").iterdir(): + path.unlink() + assert "scenarios: no scenario records found" in validator.validate() diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py new file mode 100644 index 0000000..de9cff9 --- /dev/null +++ b/tools/validate_client_contract.py @@ -0,0 +1,679 @@ +# /// script +# requires-python = ">=3.12" +# dependencies = [ +# "jsonschema>=4.23", +# ] +# /// +"""Validate the client contract under +`python/client-contract/src/dfo_client_contract/`. + +Usage: + uv run tools/validate_client_contract.py + +Checks that every packaged schema is valid draft 2020-12 and that every +document validates against its schema, then what the schemas cannot express: + +- `served/SOURCE.json` names a 40-character dfo-apis commit. +- Every `strict-fields.json` pointer resolves in `served/openapi.json` and + names each property once. A required entry's property stays in its schema's + `required` list and admits no null; an enum entry's property admits every + value listed. +- `actions.json` lists codes in order, each once. Every active refusal code in + `registries/codes.json` with a `problem_details` or `no_data_reason` mapping + has a row, and no row names another code. A row carries `gap_kind` exactly + when its code has a `no_data_reason` mapping; `choose` goes with the + `choice` gap kind and only with it; and a code with a `problem_details` + mapping takes an action a problem document can carry. +- Each scenario's file name matches its `name`, names are unique, `expect` + holds one outcome per step, a step that acts on an earlier result follows + one, a synthetic scenario derives from a recorded one, and every body file + is named by its scenario and exists. In a recorded scenario each API request + matches a route and method in `served/openapi.json`, its JSON body validates + against the route's request schema, each JSON response body validates + against the route's schema for its status, and a problem document's `code` + is an active code registered with that status. +- Each ref example's file name matches its `name` and gets the verdict it + states: from `dataset-ref.schema.json`, then from the rules that each + member's definition carries its own `spec_id` and that members hold + distinct `spec_id`s. +- Each rule file under `rules/` validates against `rules.schema.json`, names + the rule its file name names, and names each vector once. + +A recorded body is checked with one allowance: a required member whose schema +admits null may be absent, because the server leaves null members out of the +bodies it serves. It does not import `dfo_client_contract`, whose tests replay +the rule vectors. +""" + +from __future__ import annotations + +import json +import re +import sys +from collections.abc import Iterator +from pathlib import Path +from typing import Any +from urllib.parse import urlsplit + +import jsonschema +from referencing import Registry, Resource +from referencing.jsonschema import DRAFT202012 + +REPO_ROOT = Path(__file__).resolve().parent.parent +PACKAGE_DIR = REPO_ROOT / "python" / "client-contract" / "src" / "dfo_client_contract" +REGISTRY_PATH = REPO_ROOT / "registries" / "codes.json" + +_OPENAPI_URI = "urn:dfo-client-contract:served-openapi" +_ACTION_CHANNELS = {"problem_details", "no_data_reason"} +_ANSWER_ONLY_ACTIONS = {"choose", "ask_data_question"} +_ACTS_ON_PREVIOUS = {"choose": {"search", "choose"}, "result": {"mint"}} +_STRICT_POINTER = re.compile(r"^/components/schemas/([^/]+)/properties/([^/]+)$") + + +def _reject_duplicate_keys(pairs: list[tuple[str, Any]]) -> dict[str, Any]: + keys = [key for key, _ in pairs] + duplicates = sorted({key for key in keys if keys.count(key) > 1}) + if duplicates: + raise ValueError(f"duplicate keys {duplicates}") + return dict(pairs) + + +def _load(path: Path) -> Any: + return json.loads( + path.read_text(encoding="utf-8"), object_pairs_hook=_reject_duplicate_keys + ) + + +def _where(error: jsonschema.ValidationError) -> str: + return "/".join(str(part) for part in error.absolute_path) or "" + + +def _schema_problems( + label: str, validator: jsonschema.Draft202012Validator, document: Any +) -> list[str]: + return [ + f"{label}: schema: {_where(error)}: {error.message}" + for error in sorted( + validator.iter_errors(document), key=lambda e: list(e.absolute_path) + ) + ] + + +def _contract_validators() -> dict[str, jsonschema.Draft202012Validator]: + """One validator per packaged schema, sharing a registry so the scenario + schema's `$ref` to `dataset-ref.schema.json` resolves by `$id`.""" + names = ( + "strict-fields.schema.json", + "actions.schema.json", + "scenario.schema.json", + "dataset-ref.schema.json", + "rules/rules.schema.json", + ) + schemas = {name: _load(PACKAGE_DIR / name) for name in names} + for schema in schemas.values(): + jsonschema.Draft202012Validator.check_schema(schema) + registry = Registry().with_resources( + (schema["$id"], Resource.from_contents(schema)) for schema in schemas.values() + ) + return { + name: jsonschema.Draft202012Validator( + schema, + registry=registry, + format_checker=jsonschema.Draft202012Validator.FORMAT_CHECKER, + ) + for name, schema in schemas.items() + } + + +# --- the served document ---------------------------------------------------- + + +def _resolve(document: Any, pointer: str) -> Any: + """The value at an RFC 6901 `pointer` in `document`; raises `KeyError`.""" + node = document + for raw in pointer.split("/")[1:]: + token = raw.replace("~1", "/").replace("~0", "~") + if isinstance(node, list): + if not token.isdigit() or int(token) >= len(node): + raise KeyError(pointer) + node = node[int(token)] + elif isinstance(node, dict) and token in node: + node = node[token] + else: + raise KeyError(pointer) + return node + + +def _expand(openapi: dict[str, Any], schema: Any) -> Iterator[dict[str, Any]]: + """`schema` and every schema its `$ref`, `anyOf`, `oneOf` and `allOf` + reach, local references followed through `openapi`.""" + if not isinstance(schema, dict): + return + yield schema + ref = schema.get("$ref") + if isinstance(ref, str) and ref.startswith("#/"): + yield from _expand(openapi, _resolve(openapi, ref[1:])) + for keyword in ("anyOf", "oneOf", "allOf"): + for branch in schema.get(keyword, []): + yield from _expand(openapi, branch) + + +def _admits_null(openapi: dict[str, Any], schema: Any) -> bool: + for branch in _expand(openapi, schema): + kind = branch.get("type") + if kind == "null" or (isinstance(kind, list) and "null" in kind): + return True + if branch.get("nullable") is True or branch.get("const", 0) is None: + return True + if None in branch.get("enum", []): + return True + return False + + +def _allowed_values(openapi: dict[str, Any], schema: Any) -> set[str]: + values: set[str] = set() + for branch in _expand(openapi, schema): + if "const" in branch: + values.add(branch["const"]) + values.update(branch.get("enum", [])) + return values + + +def _check_source(source: Any) -> list[str]: + if not isinstance(source, dict): + return ["served/SOURCE.json: not an object"] + problems = [] + if source.get("format_version") != 1: + problems.append("served/SOURCE.json: format_version is not 1") + if not isinstance(source.get("repository"), str): + problems.append("served/SOURCE.json: repository is not a string") + if not re.fullmatch(r"[0-9a-f]{40}", str(source.get("commit"))): + problems.append("served/SOURCE.json: commit is not a 40-character sha") + if not isinstance(source.get("captured_from"), str): + problems.append("served/SOURCE.json: captured_from is not a string") + return problems + + +def _check_strict_fields( + document: dict[str, Any], openapi: dict[str, Any] +) -> list[str]: + problems = [] + for kind in ("required", "enums"): + pointers = [entry["pointer"] for entry in document[kind]] + problems.extend( + f"strict-fields.json: {kind}: {pointer} is listed twice" + for pointer in sorted({p for p in pointers if pointers.count(p) > 1}) + ) + for entry in document[kind]: + pointer = entry["pointer"] + try: + prop = _resolve(openapi, pointer) + except KeyError: + problems.append( + f"strict-fields.json: {pointer} does not resolve in " + "served/openapi.json" + ) + continue + if kind == "enums": + missing = [ + v + for v in entry["values"] + if v not in _allowed_values(openapi, prop) + ] + if missing: + problems.append( + f"strict-fields.json: {pointer} no longer admits {missing}" + ) + continue + match = _STRICT_POINTER.match(pointer) + if match is None: # the strict-fields schema pins the pointer form + continue + schema_name, field = match.groups() + required = openapi["components"]["schemas"][schema_name].get("required", []) + if field not in required: + problems.append( + f"strict-fields.json: {pointer} is not required in {schema_name}" + ) + if _admits_null(openapi, prop): + problems.append(f"strict-fields.json: {pointer} admits null") + return problems + + +# --- actions ---------------------------------------------------------------- + + +def _check_actions(document: dict[str, Any], registry: dict[str, Any]) -> list[str]: + rows = document["codes"] + codes = [row["code"] for row in rows] + problems = [ + f"actions.json: code {code!r} is listed twice" + for code in sorted({c for c in codes if codes.count(c) > 1}) + ] + if codes != sorted(codes): + problems.append("actions.json: codes are not sorted") + + entries = {entry["code"]: entry for entry in registry["entries"]} + channels = { + code: {mapping["channel"] for mapping in entry["mappings"]} + for code, entry in entries.items() + } + expected = { + code + for code, entry in entries.items() + if entry["lifecycle"] == "active" + and entry["classification"] == "refusal" + and channels[code] & _ACTION_CHANNELS + } + problems.extend( + f"actions.json: active code {code!r} has no row" + for code in sorted(expected - set(codes)) + ) + for row in rows: + code = row["code"] + entry = entries.get(code) + if entry is None: + problems.append(f"actions.json: {code!r} is not in the registry") + continue + if code not in expected: + problems.append( + f"actions.json: {code!r} is {entry['lifecycle']} " + f"{entry['classification']} on {sorted(channels[code])}, outside " + "the active refusals on problem_details and no_data_reason" + ) + continue + on_no_data = "no_data_reason" in channels[code] + if on_no_data != ("gap_kind" in row): + problems.append( + f"actions.json: {code!r} must carry gap_kind exactly when it maps " + "to no_data_reason" + ) + if (row["action"] == "choose") != (row.get("gap_kind") == "choice"): + problems.append( + f"actions.json: {code!r} pairs action {row['action']!r} with " + f"gap_kind {row.get('gap_kind')!r}; choose goes with choice only" + ) + if "problem_details" in channels[code] and row["action"] in ( + _ANSWER_ONLY_ACTIONS + ): + problems.append( + f"actions.json: {code!r} reaches problem documents, which cannot " + f"carry action {row['action']!r}" + ) + return problems + + +# --- scenarios -------------------------------------------------------------- + + +class _Routes: + """The served document's routes, matched against concrete paths.""" + + def __init__(self, openapi: dict[str, Any]) -> None: + self.openapi = openapi + self._templates = [(t, t.split("/")) for t in openapi["paths"]] + registry = Registry().with_resource( + _OPENAPI_URI, DRAFT202012.create_resource(openapi) + ) + self._validator = jsonschema.validators.extend( + jsonschema.Draft202012Validator, {"required": _required_unless_nullable} + ) + self._registry = registry + + def template(self, path: str) -> str | None: + """The route template matching `path`, preferring a literal segment + over a parameter, as the server's router does.""" + segments = path.split("/") + matches = [ + template + for template, parts in self._templates + if len(parts) == len(segments) + and all( + part == segment or (part.startswith("{") and bool(segment)) + for part, segment in zip(parts, segments, strict=True) + ) + ] + return min(matches, key=lambda t: t.count("{"), default=None) + + def validate(self, pointer: str, body: Any) -> list[str]: + validator = self._validator( + {"$ref": f"{_OPENAPI_URI}#{pointer}"}, registry=self._registry + ) + return [ + f"{_where(error)}: {error.message[:300]}" + for error in validator.iter_errors(body) + ] + + +def _required_unless_nullable( + validator: Any, required: list[str], instance: Any, schema: dict[str, Any] +) -> Iterator[jsonschema.ValidationError]: + """`required`, except that a member whose schema admits null may be + absent: the server leaves null members out of the bodies it serves.""" + if not validator.is_type(instance, "object"): + return + properties = schema.get("properties", {}) + for name in required: + if name in instance: + continue + member = properties.get(name) + if member is not None and validator.evolve(schema=member).is_valid(None): + continue + yield jsonschema.ValidationError(f"{name!r} is a required property") + + +def _pointer_token(text: str) -> str: + return text.replace("~", "~0").replace("/", "~1") + + +def _body_schema(content: dict[str, Any]) -> str | None: + for media in ("application/json", "application/problem+json"): + if media in content: + return media + return None + + +def _check_exchange( + label: str, + exchange: dict[str, Any], + base_path: str, + routes: _Routes, + registry: dict[str, Any], +) -> list[str]: + request, response = exchange["request"], exchange["response"] + if "url" in request: + return [] + raw = base_path + request["path"] if "path" in request else request["origin_path"] + path = urlsplit(raw).path + template = routes.template(path) + if template is None: + return [f"{label}: {path} matches no route in served/openapi.json"] + method = request["method"].lower() + operation = routes.openapi["paths"][template].get(method) + if operation is None: + return [f"{label}: {template} serves no {request['method']}"] + + problems = [] + route = f"/paths/{_pointer_token(template)}/{method}" + if "json" in request: + media = _body_schema(operation.get("requestBody", {}).get("content", {})) + if media is None: + problems.append(f"{label}: {template} takes no JSON request body") + else: + pointer = f"{route}/requestBody/content/{_pointer_token(media)}/schema" + problems.extend( + f"{label}: request body: {problem}" + for problem in routes.validate(pointer, request["json"]) + ) + + responses = operation.get("responses", {}) + status = str(response["status"]) + declared = status if status in responses else "default" + if declared not in responses: + return [*problems, f"{label}: {template} declares no {status} response"] + if "json" in response: + media = _body_schema(responses[declared].get("content", {})) + if media is None: + problems.append(f"{label}: {template} {status} has no JSON body") + else: + pointer = ( + f"{route}/responses/{declared}/content/{_pointer_token(media)}/schema" + ) + problems.extend( + f"{label}: response body: {problem}" + for problem in routes.validate(pointer, response["json"]) + ) + problems.extend(_check_problem_code(label, response, registry)) + return problems + + +def _check_problem_code( + label: str, response: dict[str, Any], registry: dict[str, Any] +) -> list[str]: + body = response["json"] + if response["status"] < 400 or not isinstance(body, dict) or "code" not in body: + return [] + for entry in registry["entries"]: + if entry["code"] != body["code"]: + continue + statuses = { + m.get("http_status") + for m in entry["mappings"] + if m["channel"] == "problem_details" + } + if entry["lifecycle"] != "active" or response["status"] not in statuses: + return [ + f"{label}: problem code {body['code']!r} is not an active code " + f"registered with status {response['status']}" + ] + return [] + return [f"{label}: problem code {body['code']!r} is not in the registry"] + + +def _check_scenarios( + validator: jsonschema.Draft202012Validator, + openapi: dict[str, Any], + registry: dict[str, Any], +) -> list[str]: + directory = PACKAGE_DIR / "scenarios" + paths = sorted(directory.glob("*.json")) + problems = [] if paths else ["scenarios: no scenario records found"] + routes = _Routes(openapi) + records: dict[str, dict[str, Any]] = {} + named_files: set[str] = set() + + for path in paths: + try: + record = _load(path) + except ValueError as exc: + problems.append(f"scenarios/{path.name}: not valid JSON: {exc}") + continue + errors = _schema_problems(f"scenarios/{path.name}", validator, record) + problems.extend(errors) + if errors: + continue + name = record["name"] + if name != path.stem: + problems.append(f"scenarios/{path.name}: name {name!r} differs") + if name in records: + problems.append(f"scenarios/{path.name}: name {name!r} repeats") + records[name] = record + problems.extend(_check_steps(path.name, record)) + + for index, exchange in enumerate(record["exchanges"]): + body_file = exchange["response"].get("body_file") + if body_file is None: + continue + named_files.add(body_file) + if not body_file.startswith(f"{name}"): + problems.append( + f"scenarios/{path.name}: exchange {index}: body file " + f"{body_file!r} does not start with the scenario's name" + ) + if not (directory / body_file).is_file(): + problems.append( + f"scenarios/{path.name}: exchange {index}: body file " + f"{body_file!r} is missing" + ) + + origin = record["origin"] + if origin["kind"] != "recorded": + continue + base_path = urlsplit(origin["base_url"]).path.rstrip("/") + for index, exchange in enumerate(record["exchanges"]): + problems.extend( + _check_exchange( + f"scenarios/{path.name}: exchange {index}", + exchange, + base_path, + routes, + registry, + ) + ) + + for name, record in records.items(): + origin = record["origin"] + if origin["kind"] != "synthetic": + continue + parent = records.get(origin["derived_from"]) + if parent is None or parent["origin"]["kind"] != "recorded": + problems.append( + f"scenarios/{name}.json: derived_from {origin['derived_from']!r} " + "is not a recorded scenario" + ) + + problems.extend( + f"scenarios/{p.name}: no scenario names this body file" + for p in sorted(directory.iterdir()) + if p.is_file() and p.suffix != ".json" and p.name not in named_files + ) + return problems + + +def _check_steps(file_name: str, record: dict[str, Any]) -> list[str]: + call, expect = record["call"], record["expect"] + problems = [] + if len(call) != len(expect): + problems.append( + f"scenarios/{file_name}: {len(call)} steps but {len(expect)} outcomes" + ) + previous: str | None = None + for index, step in enumerate(call): + op = step["op"] + if op == "fetch" and "spec" not in step and "ref" not in step: + needs = {"search", "choose"} + else: + needs = _ACTS_ON_PREVIOUS.get(op) + if needs is not None and previous not in needs: + problems.append( + f"scenarios/{file_name}: step {index} ({op}) does not follow " + f"a step in {sorted(needs)}" + ) + previous = op + return problems + + +# --- refs ------------------------------------------------------------------- + + +def _ref_rule(ref: dict[str, Any]) -> str | None: + """The first ref rule `ref` breaks, or None.""" + seen: set[str] = set() + for member in ref["members"]: + spec = member["spec"] + if spec["definition"]["spec_id"] != spec["spec_id"]: + return "definition_spec_id_mismatch" + if spec["spec_id"] in seen: + return "repeated_spec_id" + seen.add(spec["spec_id"]) + return None + + +def _check_refs(validator: jsonschema.Draft202012Validator) -> list[str]: + paths = sorted((PACKAGE_DIR / "refs").glob("*.json")) + problems = [] if paths else ["refs: no ref examples found"] + verdicts: set[str] = set() + for path in paths: + label = f"refs/{path.name}" + record = _load(path) + if not isinstance(record, dict) or record.get("name") != path.stem: + problems.append(f"{label}: name does not match the file name") + continue + error = record.get("error") + if ("expect" in record) == isinstance(error, dict): + problems.append(f"{label}: carries neither or both of expect and error") + continue + valid = validator.is_valid(record.get("ref")) + by = error.get("by") if isinstance(error, dict) else None + verdicts.add(by or "accept") + if by == "schema": + if valid: + problems.append(f"{label}: the schema accepts a ref it should reject") + continue + if not valid: + first = next(validator.iter_errors(record.get("ref"))) + problems.append(f"{label}: ref fails the schema at {_where(first)}") + continue + broken = _ref_rule(record["ref"]) + wanted = error.get("reason") if by == "rule" else None + if broken != wanted: + problems.append(f"{label}: breaks rule {broken!r}, expected {wanted!r}") + problems.extend( + f"refs: no {verdict} example" + for verdict in ("accept", "schema", "rule") + if paths and verdict not in verdicts + ) + return problems + + +# --- rules ------------------------------------------------------------------ + + +def _check_rules(validator: jsonschema.Draft202012Validator) -> list[str]: + paths = sorted( + p + for p in (PACKAGE_DIR / "rules").glob("*.json") + if p.name != "rules.schema.json" + ) + problems = [] if paths else ["rules: no rule files found"] + for path in paths: + label = f"rules/{path.name}" + document = _load(path) + errors = _schema_problems(label, validator, document) + problems.extend(errors) + if errors: + continue + if document["rule"] != path.stem: + problems.append(f"{label}: rule {document['rule']!r} differs") + names = [vector["name"] for vector in document["vectors"]] + problems.extend( + f"{label}: vector {name!r} repeats" + for name in sorted({n for n in names if names.count(n) > 1}) + ) + return problems + + +def validate() -> list[str]: + validators = _contract_validators() + openapi = _load(PACKAGE_DIR / "served" / "openapi.json") + registry = _load(REGISTRY_PATH) + problems = _check_source(_load(PACKAGE_DIR / "served" / "SOURCE.json")) + + strict = _load(PACKAGE_DIR / "strict-fields.json") + errors = _schema_problems( + "strict-fields.json", validators["strict-fields.schema.json"], strict + ) + problems.extend(errors or _check_strict_fields(strict, openapi)) + + actions = _load(PACKAGE_DIR / "actions.json") + errors = _schema_problems( + "actions.json", validators["actions.schema.json"], actions + ) + problems.extend(errors or _check_actions(actions, registry)) + + problems.extend( + _check_scenarios(validators["scenario.schema.json"], openapi, registry) + ) + problems.extend(_check_refs(validators["dataset-ref.schema.json"])) + problems.extend(_check_rules(validators["rules/rules.schema.json"])) + return problems + + +def main() -> int: + problems = validate() + for problem in problems: + print(problem, file=sys.stderr) + if problems: + print(f"{len(problems)} problem(s) in {PACKAGE_DIR}", file=sys.stderr) + return 1 + strict = _load(PACKAGE_DIR / "strict-fields.json") + print( + f"client contract valid: {len(_load(PACKAGE_DIR / 'actions.json')['codes'])} " + f"action rows, {len(strict['required'])} required and " + f"{len(strict['enums'])} enum pointers, " + f"{len(list((PACKAGE_DIR / 'scenarios').glob('*.json')))} scenarios" + ) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) From 94c83a8c5fbf81980217148f5067bdccbeea7ac3 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Tue, 20 Oct 2026 18:06:41 +0200 Subject: [PATCH 10/39] feat(client-contract): record client scenarios against dev tools/capture_client_contract.py captures the dfo-apis OpenAPI document in process and records scenarios against a base URL, redacting signed download queries. 14 scenarios are recorded on dev and 11 are derived from them: retries, proxy refusals, an unknown part status and enum value, a renamed strict field, and place choices in one and two parts. --- python/client-contract/README.md | 27 + .../answer-candidates-choose-fetch.json | 2879 +++ .../answer-candidates-choose-fetch.parquet | Bin 0 -> 4800 bytes .../scenarios/answer-catalogue.json | 87 + .../scenarios/answer-declined.json | 93 + .../scenarios/answer-definite-fetch.json | 4535 +++++ .../scenarios/answer-definite-fetch.parquet | Bin 0 -> 9785 bytes .../scenarios/answer-mixed-fetch-partial.json | 4168 +++++ .../answer-mixed-fetch-partial.parquet | Bin 0 -> 6025 bytes .../scenarios/answer-mixed-fetch-raises.json | 3575 ++++ .../answer-several-readings-folded-2.parquet | Bin 0 -> 6545 bytes .../answer-several-readings-folded.json | 15414 ++++++++++++++++ .../answer-several-readings-folded.parquet | Bin 0 -> 16150 bytes .../scenarios/answer-unknown-enum-value.json | 218 + .../scenarios/answer-unknown-part-status.json | 3574 ++++ .../scenarios/choose-place-one-part.json | 3516 ++++ .../scenarios/choose-place-two-parts.json | 3954 ++++ .../scenarios/fetch-null-member.json | 4535 +++++ .../scenarios/fetch-null-member.parquet | Bin 0 -> 9785 bytes .../fetch-ref-signed-url-refused.json | 996 + .../fetch-ref-signed-url-refused.parquet | Bin 0 -> 9785 bytes .../scenarios/fetch-ref-unknown-version.json | 137 + .../scenarios/fetch-ref.json | 972 + .../scenarios/fetch-ref.parquet | Bin 0 -> 9785 bytes .../scenarios/fetch-renamed-strict-field.json | 4469 +++++ .../scenarios/fetch-retry-after-504.json | 4634 +++++ .../scenarios/fetch-retry-after-504.parquet | Bin 0 -> 9785 bytes .../scenarios/fetch-spec-known-sentence.json | 113 +- .../scenarios/fetch-spec-narrowed.json | 4638 +++++ .../scenarios/fetch-spec-narrowed.parquet | Bin 0 -> 9541 bytes .../scenarios/fetch-spec-request-invalid.json | 208 + .../scenarios/search-place-ambiguous.json | 14 +- .../scenarios/search-proxy-rate-limited.json | 243 + .../scenarios/search-proxy-unavailable.json | 98 + .../scenarios/search-retry-after-503.json | 248 + .../search-two-parts-place-ambiguous.json | 342 + .../dfo_client_contract/served/SOURCE.json | 2 +- tools/README.md | 6 + tools/capture_client_contract.py | 1710 ++ tools/tests/test_capture_client_contract.py | 355 + 40 files changed, 65696 insertions(+), 64 deletions(-) create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.parquet create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-definite-fetch.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-definite-fetch.parquet create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.parquet create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded-2.parquet create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.parquet create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-place-one-part.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-place-two-parts.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.parquet create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused.parquet create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-unknown-version.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-ref.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-ref.parquet create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.parquet create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.parquet create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json create mode 100644 tools/capture_client_contract.py create mode 100644 tools/tests/test_capture_client_contract.py diff --git a/python/client-contract/README.md b/python/client-contract/README.md index f94ab90..1cf4214 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -120,6 +120,33 @@ A client replays a scenario by serving the exchanges in order: - Sleeps are not replayed: the replay injects the client's clock and sleep, and each wait the client asks for advances the clock at once. - A recorded signed storage URL keeps its scheme, host and path, and its query reads `X-Goog-Signature=redacted`. +The records also fix these client rules: + +- A fetch builds each distinct `spec_id` once, in part order, and finishes one member (build, the sentence when the client lacks it, files, download) before the next. +- A built `spec_id` that differs from the posted one, or a spec with no sentence, takes its sentence from Search: the client posts the built definition's `identity` as one `dataset_resubmit` identity entry, with the member's first part as `variable_text`, or `"dataset"` when no answer part names it, and checks the answer's `spec_id` equals the built one. +- A dataset of several members puts the `part` column first, then each member's columns in member order, each column once. +- A choice among candidates in a one-part answer makes no request. A choice of a no_data option in a one-part answer posts the option's `data_query` as the input. In a several-part answer a choice posts `dataset_resubmit` with one entry per part in part order: the chosen option's part as a parsed entry, a definite part as an identity entry with its `entity_groups`, and any other part's `restatement` as a parsed entry. +- A declined or catalogue answer is not complete, and fetching it raises `DeclinedError`. +- A ref whose version the snapshot route refuses with `snapshot_not_found` raises `NotFoundError` with no further request. +- A retry waits `Retry-After` when the response carries it. A synthetic scenario that retries assumes the default of two retries. + +## Recording + +`tools/capture_client_contract.py` refreshes the served document and the scenarios. Its `openapi` command calls `dfo_apis.app.create_app()` in process, every surface flag on, in a dfo-apis checkout with no uncommitted changes to tracked files, and writes `served/openapi.json` and `served/SOURCE.json`. The checkout needs its environment first. From the repository root, with the checkout at `../dfo-apis`: + +```bash +uv sync --directory ../dfo-apis --extra eval --extra api --extra engine --extra datasets --extra graph +uv run tools/capture_client_contract.py openapi --dfo-apis ../dfo-apis +``` + +Its `record` command runs every scenario against a base URL, dev's Cloud Run URL by default, checks each live answer still has the shape its scenario names, derives the synthetic scenarios from the fresh records, and then runs the validator. It fails when the validator reports a problem or the binary bodies pass 5 MB. `--only` records the scenarios it names. Each record names the commit in the responses' `x-dfo-commit` header, and the run refuses responses that name none or several. To record against a local app, run the composed app, every surface mounted, from the checkout the document came from, with `DFO_BUILD_COMMIT` set to that checkout's commit, then pass its base URL: + +```bash +uv run tools/capture_client_contract.py record --base-url http://127.0.0.1:8083/api +``` + +`mint-async-build` lands only from a server whose document declares the build's 202 response, since the validator checks each recorded body against its route's schema for that status. `--scenarios-dir` writes records outside the package, unvalidated. + ## DatasetRef `dataset-ref.schema.json` is the frozen format a client writes for `data.ref` and reads back in any language: `format_version: 1` and one or more `members`, each `{parts, sentence, spec: {spec_id, definition}, content_version, artifact: {digest, rendering}}`. `parts` holds the variable text of each answer part the member answers, in query order, and is empty for a spec fetched outside an answer. `rendering` is the selector a client matches an artifact on, `{format, bundle}` with `layout: "frame"` for the frame layout, never the server's rendering object. Beyond the schema, each member's `definition.spec_id` equals its `spec.spec_id`, and members hold distinct `spec_id`s. `refs/` holds accepted examples and rejected ones, each `{format_version, name, description, ref}` with `expect: "accept"` or `error`, `{by: "schema"}` or `{by: "rule", reason}`, the reason `definition_spec_id_mismatch` or `repeated_spec_id`. diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json new file mode 100644 index 0000000..0f573ba --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json @@ -0,0 +1,2879 @@ +{ + "format_version": 1, + "name": "answer-candidates-choose-fetch", + "description": "A question with three readings answers one candidates part, a choice gap with three options. Choosing option 0 makes no request: the new answer is definite, its sentence is that candidate's spec.resolved.rendered_sentence, and fetching it builds that candidate's spec.", + "origin": { + "kind": "recorded", + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "recorded_at": "2026-10-20T16:03:53Z" + }, + "call": [ + { + "op": "search", + "question": "GNI of Germany from 2015 to 2022" + }, + { + "op": "choose", + "option": 0 + }, + { + "op": "fetch" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "GNI of Germany from 2015 to 2022" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "GNI of Germany from 2015 to 2022", + "normalized_query": "GNI of Germany from 2015 to 2022", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "trace_id": "b018f4db7a8e41cbac1f24b9e43abab8", + "warnings": [], + "timing_ms": { + "total": 2, + "by_step": { + "coverage": 0, + "response_cache_layer1": 0 + } + }, + "llm_usage": { + "input_tokens": 0, + "output_tokens": 0, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GNI", + "warnings": [], + "timing_ms": { + "total": 4620, + "by_step": { + "recall": 478, + "shape_arcs": 3, + "shape_probe_coverage": 13, + "shape_probe": 108, + "shape_groups": 200, + "shape_labels": 12, + "shape_admission": 10, + "shape": 1457, + "bind": 2338, + "materialise": 186, + "answer": 161 + } + }, + "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "sentence_plan": [ + { + "kind": "text", + "text": "3 readings.", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "primary income", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross of fixed capital consumption", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "OECD DAC1", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity per capita", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "GNI", + "entities": [ + { + "text": "Germany" + } + ], + "time_text": "2015 to 2022", + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "candidates", + "candidates": { + "ordering": "intent_rank", + "max_candidates": 6, + "specs": [ + { + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "definition": { + "schema_version": 1, + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicunit_primaryincome_measuredvalue_nominal", + "label": "Gross national income", + "population_type": { + "ref": "EconomicUnit", + "label": "economic unit" + }, + "measured_property": { + "ref": "primaryIncome", + "label": "primary income" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "distinguishes": true + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + }, + { + "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "definition": { + "schema_version": 1, + "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "PurchasingPowerParity" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossNationalIncome" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity", + "label": "Gross National Income Based on Purchasing Power Parity", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "PurchasingPowerParity", + "label": "PurchasingPowerParity" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "833b9da89613fa6c1775652daac2388f38204c6c9f9929ca113deed9a0d08369", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ], + "upstream": { + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + } + } + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "fallback", + "ref": "InternationalDollar", + "label": "InternationalDollar" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "InternationalDollar", + "label": "InternationalDollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross national income based on purchasing power parity in international dollars, 2015 to 2022. World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross national income based on purchasing power parity", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "in international dollars", + "axis": "unit", + "segment": "heading", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + }, + { + "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", + "definition": { + "schema_version": 1, + "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "PurchasingPowerParity", + "measurement_denominator": { + "unresolved": true + } + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossNationalIncome" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity_per_unresolved", + "label": "Gross National Income Based on Purchasing Power Parity Per Capita", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "PurchasingPowerParity", + "label": "PurchasingPowerParity" + }, + "measurement_denominator": { + "ref": "PerCapita", + "label": "PerCapita" + }, + "measurement_denominator_unresolved": true, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "7b2d5b0fc09cfc0215c8d7c6c21a5195fa21e79f2a148a6bca9ce6c3af8bbb9f", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ], + "upstream": { + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + } + } + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "fallback", + "ref": "InternationalDollar", + "label": "InternationalDollar" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "InternationalDollar", + "label": "InternationalDollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross national income based on purchasing power parity per capita in international dollars, 2015 to 2022. World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross national income based on purchasing power parity per capita", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "in international dollars", + "axis": "unit", + "segment": "heading", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "truncated": false + } + } + ], + "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "sentence_plan": [ + { + "kind": "text", + "text": "3 readings.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "primary income", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross of fixed capital consumption", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "OECD DAC1", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity per capita", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "candidates" + } + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "definition": { + "schema_version": 1, + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "ref": "GrossOfFixedCapitalConsumption", + "state": "value" + }, + "property": "fixedCapitalConsumptionBasis" + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2022, + "start_year": 2015 + } + } + }, + "content_version": "cv_3cae36487750f272df16f77858171e89", + "prepared_at": "2026-10-20T15:55:37Z", + "coverage": { + "rows": 8, + "dimensions": [ + { + "label": "observationAbout", + "count": 1 + }, + { + "label": "years", + "count": 8 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2022, + "start_year": 2015 + } + }, + "citation": { + "text": "OECD DAC1 (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?fs[0]=Topic,0%7CDevelopment%23DEV%23&fs[1]=Topic,1%7CDevelopment%23DEV%23%7COfficial%20Development%20Assistance%20%28ODA%29%23DEV_ODA%23&pg=0&fc=Topic&snb=23&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_DAC1%40DF_DAC1&df[ag]=OECD.DCD.FSD&df[vs]=1.7&dq=._Z.....&pd=,&to[TIME_PERIOD]=false&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "DAC1 is the OECD Development Assistance Committee's table of total flows by provider. It reports each donor's ODA, other official flows, export credits and private flows by aid type, with no recipient or sector breakdown. It is the official source for headline ODA, the bilateral and multilateral split, in-donor costs such as refugees in donor countries, and the ODA/GNI ratio.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC1/Table1_Data.zip", + "attribution": "OECD (2026), OECD DAC1, OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC1/Table1_Data.zip (accessed on 2026-10-12)", + "update_cadence": "Quarterly", + "last_update": "2026-10-12", + "years_covered": "1960-2025", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The OECD publishes DAC1 in April, June, September and December. The complete table is downloaded from the OECD each time it is republished, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Standardise providers", + "description": "Provider codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets. The totals DAC1 reports for groups of providers, such as all DAC countries, the G7 and the EU members of the DAC, are kept as providers of their own." + }, + { + "transformation": "Select figures", + "description": "Only figures in current US dollars are included, not constant US dollars or providers' own currencies. Amounts received are left out, though net disbursements, which subtract them, are kept. Where DAC1 reports a grant equivalent under two types of aid, the fuller of the two is used, and total flows as a share of GNI in grant equivalents are left out, since they repeat ODA as a share of GNI." + }, + { + "transformation": "Convert to whole units", + "description": "DAC1 reports amounts, GNI and population in millions, which are converted to whole units." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year and the provider. Flows are broken down by type of aid as DAC1 reports it, and by gross or net disbursements, commitments or grant equivalents, split into grants and non-grants where DAC1 splits them. Shares record that they are a share of the provider's GNI. GNI and population are reported about the provider." + } + ], + "version_history": [ + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Total flows by provider and aid type, including ODA, other official flows and private flows, and ODA as a share of GNI." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDDAC1", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "8223167158242641624", + "default_policy_version": "1" + }, + { + "ref": null, + "axis": "measurementMethod", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "8223167158242641624", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "8223167158242641624", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2022, + "start_year": 2015 + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00259-rpx", + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T13:18:18Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDDAC1", + "revision": "2026-10-12" + } + ], + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "resolved_stat_vars": [ + { + "ref": "dcid:PrimaryIncome_EconomicUnit_GrossOfFixedCapitalConsumption_Nominal", + "roles": [ + "observationAbout" + ], + "observation_count": 8 + } + ], + "family_member_count": 1, + "family_member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "served_from": "head", + "confirmed_at": "2026-10-20T15:55:38.402563+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:9086e741fcbfa1fe56a9d8af57c54ae3784744b50a03086d9e715623d9c71766", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 4800, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T15:55:38.338535+00:00", + "tier": "working", + "url": "/api/datasets/spec_c0f61f3ca3558aac184973441a67601e/cv_3cae36487750f272df16f77858171e89/files/sha256:9086e741fcbfa1fe56a9d8af57c54ae3784744b50a03086d9e715623d9c71766" + }, + { + "artifact_digest": "sha256:d822d05c709d2d1ca448023a433f936b28403893dede278e2b2696eca3587d1c", + "rendering": { + "statistics": "series" + }, + "bytes": 5294, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T15:55:38.338535+00:00", + "tier": "working", + "url": "/api/datasets/spec_c0f61f3ca3558aac184973441a67601e/cv_3cae36487750f272df16f77858171e89/files/sha256:d822d05c709d2d1ca448023a433f936b28403893dede278e2b2696eca3587d1c" + } + ], + "series_count": 1, + "output_options": { + "capability_version": "dset_1e6cd9546fac19e9", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "observationAbout", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 8 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "observationAbout", + "field": "iso3", + "token": "observationAbout_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "observationAbout", + "field": "iso2", + "token": "observationAbout_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "observationAbout", + "field": "label", + "token": "observationAbout_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "observationAbout", + "field": "type", + "token": "observationAbout_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "observationAbout_label" + ], + "long_layout_totals": [], + "pivots": [], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_c0f61f3ca3558aac184973441a67601e/cv_3cae36487750f272df16f77858171e89/files/sha256:9086e741fcbfa1fe56a9d8af57c54ae3784744b50a03086d9e715623d9c71766" + }, + "response": { + "status": 302, + "headers": { + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9086e741fcbfa1fe56a9d8af57c54ae3784744b50a03086d9e715623d9c71766?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9086e741fcbfa1fe56a9d8af57c54ae3784744b50a03086d9e715623d9c71766?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "answer-candidates-choose-fetch.parquet" + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "candidates", + "sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 3 + } + ] + } + }, + { + "answer": { + "kind": "resolution", + "status": "definite", + "sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "complete": true, + "specs": [ + "spec_c0f61f3ca3558aac184973441a67601e" + ], + "gaps": [] + } + }, + { + "dataset": { + "rows": 8, + "columns": [ + "stat_var", + "stat_var_label", + "observationAbout", + "observationAbout_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [ + "GNI" + ], + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "content_version": "cv_3cae36487750f272df16f77858171e89", + "sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1." + } + ], + "missing": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.parquet b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.parquet new file mode 100644 index 0000000000000000000000000000000000000000..4b92f5b78256ab7d29cbbf74f285b2642a8b15e2 GIT binary patch literal 4800 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 Mqc25e!9QdE3x?1k4FCWD literal 0 HcmV?d00001 diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json new file mode 100644 index 0000000..8785d99 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json @@ -0,0 +1,15414 @@ +{ + "format_version": 1, + "name": "answer-several-readings-folded", + "description": "A question with three definite parts, the first two folded into one spec_id (binding_folded), builds each distinct spec_id once, in part order, each through build, files and download before the next. The dataset stacks two members, the first answering both folded parts, into one table with a part column first and each member's columns in member order.", + "origin": { + "kind": "recorded", + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "recorded_at": "2026-10-20T16:03:57Z" + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements for health and for education from Germany to Kenya, and GDP of Kenya" + }, + { + "op": "fetch" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements for health and for education from Germany to Kenya, and GDP of Kenya" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements for health and for education from Germany to Kenya, and GDP of Kenya", + "normalized_query": "ODA disbursements for health and for education from Germany to Kenya, and GDP of Kenya", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "trace_id": "1c42f930c021432697eb26d2af4fb5c4", + "warnings": [], + "timing_ms": { + "total": 5, + "by_step": { + "coverage": 0, + "response_cache_layer1": 1 + } + }, + "llm_usage": { + "input_tokens": 0, + "output_tokens": 0, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "health ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 1771, + "by_step": { + "recall": 2, + "shape_arcs": 1, + "shape_probe_coverage": 183, + "shape_probe": 183, + "shape_groups": 102, + "shape_labels": 20, + "shape_admission": 0, + "shape": 599, + "bind": 39, + "materialise": 585, + "answer": 27, + "options": 519 + } + }, + "restatement": { + "variable_text": "health ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "definite", + "spec": { + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "definition": { + "schema_version": 1, + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal", + "label": "gross disbursements (official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 545, + "member_digest": "0c7508fd1997d6cdc896f2eab0f092a4915cfca9e2400eb9577bb22b527fe882", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "CRSPurposeCode110", + "label": "education" + }, + "value_kind": "enum_value" + }, + { + "ref": { + "ref": "CRSPurposeCode120", + "label": "health" + }, + "value_kind": "enum_value" + } + ] + }, + "expansion": { + "added": [ + { + "ref": "CRSPurposeCode121", + "label": "general health" + }, + { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + { + "ref": "CRSPurposeCode123", + "label": "noncommunicable disease" + }, + { + "ref": "CRSPurposeCode12110", + "label": "health policy and administrative management" + }, + { + "ref": "CRSPurposeCode12181", + "label": "medical education and training" + }, + { + "ref": "CRSPurposeCode12182", + "label": "medical research" + }, + { + "ref": "CRSPurposeCode12191", + "label": "medical service" + }, + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + }, + { + "ref": "CRSPurposeCode12230", + "label": "basic health infrastructure" + }, + { + "ref": "CRSPurposeCode12240", + "label": "basic nutrition" + }, + { + "ref": "CRSPurposeCode12250", + "label": "infectious disease control" + }, + { + "ref": "CRSPurposeCode12261", + "label": "health education" + }, + { + "ref": "CRSPurposeCode12262", + "label": "malaria control" + }, + { + "ref": "CRSPurposeCode12263", + "label": "tuberculosis control" + }, + { + "ref": "CRSPurposeCode12264", + "label": "COVID-19 control" + }, + { + "ref": "CRSPurposeCode12281", + "label": "health personnel development" + }, + { + "ref": "CRSPurposeCode12310", + "label": "general noncommunicable disease control" + }, + { + "ref": "CRSPurposeCode12320", + "label": "tobacco use control" + }, + { + "ref": "CRSPurposeCode12330", + "label": "control of harmful use of alcohol and drugs" + }, + { + "ref": "CRSPurposeCode12340", + "label": "mental health and well-being promotion" + }, + { + "ref": "CRSPurposeCode12350", + "label": "other noncommunicable disease prevention and treatment" + }, + { + "ref": "CRSPurposeCode12382", + "label": "research for noncommunicable disease prevention and control" + } + ] + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "financialObligationType" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 108, + "member_count_exact": true, + "served_count": 545, + "data_date_range": { + "start": "1997", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "breadth", + "has_data": true, + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 12 + }, + { + "label": "variables", + "count": 51 + } + ] + }, + "facets": { + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + }, + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", + "account": "provider" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode121", + "label": "general health" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 6, + "served_rows": 82, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 108, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode123", + "label": "noncommunicable disease" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 3, + "served_rows": 4, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode100", + "label": "social infrastructure and services" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "member_count": 13, + "served_rows": 1214, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode111", + "label": "unspecified-level education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 6, + "served_rows": 78, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode112", + "label": "basic education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 6, + "served_rows": 77, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode113", + "label": "upper secondary education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 5, + "served_rows": 69, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode114", + "label": "post-secondary education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 4, + "served_rows": 94, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 501, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 501, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance420", + "label": "debt instrument" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 11, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance421", + "label": "standard loan" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance420", + "member_count": 4620, + "served_rows": 11, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 512, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 104, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1606, + "served_rows": 21, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 83, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 136, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 136, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 111, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 1600, + "served_rows": 84, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 976, + "served_rows": 27, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE", + "label": "scholarship and student cost in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 38, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 819, + "served_rows": 19, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 315, + "served_rows": 19, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Kenya for education and health, 1997 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "education and health", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1997 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "CRSPurposeCode110", + "label": "education" + }, + { + "ref": "CRSPurposeCode120", + "label": "health" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "measure_elected" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [ + { + "text": "health", + "named": [ + { + "ref": "CRSPurposeCode120", + "label": "health" + } + ], + "slot": "crsPurpose", + "disposition": "bound", + "selected": [] + }, + { + "text": "ODA", + "named": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "slot": "crsTypeOfFlow", + "disposition": "bound", + "selected": [] + }, + { + "text": "education", + "named": [ + { + "ref": "CRSPurposeCode110", + "label": "education" + } + ], + "slot": "crsPurpose", + "disposition": "bound", + "selected": [] + } + ], + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_b438dc000255d174bcc13eb675e603f7", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 512, + "served_rows_exact": true + }, + { + "definition": { + "schema_version": 1, + "spec_id": "spec_e348565295de394da8ddaa23ec5fa475", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialObligation", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialObligationType", + "binding": { + "state": "value", + "ref": "Commitment" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "commitments", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialObligation", + "label": "financial obligation" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialObligationType", + "value": { + "ref": "Commitment", + "label": "commitment" + } + } + ], + "served_rows": 519, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "open_axis_facts": [ + { + "property": "crsTypeOfFinance", + "varies": true, + "distinct_count": 2, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "count": 105 + }, + { + "value": { + "ref": "CRSTypeOfFinance421", + "label": "standard loan" + }, + "count": 3 + } + ] + }, + { + "property": "crsCooperationModality", + "varies": true, + "distinct_count": 7, + "undeclared_count": 19, + "values": [ + { + "value": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "count": 27 + }, + { + "value": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "count": 21 + }, + { + "value": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "count": 16 + }, + { + "value": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "count": 15 + }, + { + "value": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "count": 8 + }, + { + "value": { + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "count": 1 + } + ] + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1991, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1985, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1986, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1991, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1992, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1973, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1994, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1986, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1987, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1989, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1987, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1961, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 1985, + "end_year": 1990 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1991, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "KES", + "origin": "EUR" + } + } + } + } + }, + { + "variable_text": "education ODA disbursements", + "warnings": [ + { + "code": "binding_folded", + "severity": "info", + "message": "'education ODA disbursements' resolved to the same shape as an earlier part; folded into that part's spec." + } + ], + "timing_ms": { + "total": 1681, + "by_step": { + "recall": 1, + "shape_arcs": 1, + "shape_probe_coverage": 16, + "shape_probe": 19, + "shape_groups": 119, + "shape_labels": 14, + "shape_admission": 1, + "shape": 237, + "bind": 24, + "materialise": 881, + "answer": 38, + "options": 500 + } + }, + "restatement": { + "variable_text": "education ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "definite", + "spec": { + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "definition": { + "schema_version": 1, + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal", + "label": "gross disbursements (official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 545, + "member_digest": "0c7508fd1997d6cdc896f2eab0f092a4915cfca9e2400eb9577bb22b527fe882", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "CRSPurposeCode110", + "label": "education" + }, + "value_kind": "enum_value" + }, + { + "ref": { + "ref": "CRSPurposeCode120", + "label": "health" + }, + "value_kind": "enum_value" + } + ] + }, + "expansion": { + "added": [ + { + "ref": "CRSPurposeCode121", + "label": "general health" + }, + { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + { + "ref": "CRSPurposeCode123", + "label": "noncommunicable disease" + }, + { + "ref": "CRSPurposeCode12110", + "label": "health policy and administrative management" + }, + { + "ref": "CRSPurposeCode12181", + "label": "medical education and training" + }, + { + "ref": "CRSPurposeCode12182", + "label": "medical research" + }, + { + "ref": "CRSPurposeCode12191", + "label": "medical service" + }, + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + }, + { + "ref": "CRSPurposeCode12230", + "label": "basic health infrastructure" + }, + { + "ref": "CRSPurposeCode12240", + "label": "basic nutrition" + }, + { + "ref": "CRSPurposeCode12250", + "label": "infectious disease control" + }, + { + "ref": "CRSPurposeCode12261", + "label": "health education" + }, + { + "ref": "CRSPurposeCode12262", + "label": "malaria control" + }, + { + "ref": "CRSPurposeCode12263", + "label": "tuberculosis control" + }, + { + "ref": "CRSPurposeCode12264", + "label": "COVID-19 control" + }, + { + "ref": "CRSPurposeCode12281", + "label": "health personnel development" + }, + { + "ref": "CRSPurposeCode12310", + "label": "general noncommunicable disease control" + }, + { + "ref": "CRSPurposeCode12320", + "label": "tobacco use control" + }, + { + "ref": "CRSPurposeCode12330", + "label": "control of harmful use of alcohol and drugs" + }, + { + "ref": "CRSPurposeCode12340", + "label": "mental health and well-being promotion" + }, + { + "ref": "CRSPurposeCode12350", + "label": "other noncommunicable disease prevention and treatment" + }, + { + "ref": "CRSPurposeCode12382", + "label": "research for noncommunicable disease prevention and control" + } + ] + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "financialObligationType" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 108, + "member_count_exact": true, + "served_count": 545, + "data_date_range": { + "start": "1997", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "breadth", + "has_data": true, + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 12 + }, + { + "label": "variables", + "count": 51 + } + ] + }, + "facets": { + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + }, + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", + "account": "provider" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode121", + "label": "general health" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 6, + "served_rows": 82, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 108, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode123", + "label": "noncommunicable disease" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 3, + "served_rows": 4, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode100", + "label": "social infrastructure and services" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "member_count": 13, + "served_rows": 1214, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode111", + "label": "unspecified-level education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 6, + "served_rows": 78, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode112", + "label": "basic education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 6, + "served_rows": 77, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode113", + "label": "upper secondary education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 5, + "served_rows": 69, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode114", + "label": "post-secondary education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 4, + "served_rows": 94, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 501, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 501, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance420", + "label": "debt instrument" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 11, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance421", + "label": "standard loan" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance420", + "member_count": 4620, + "served_rows": 11, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 512, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 104, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1606, + "served_rows": 21, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 83, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 136, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 136, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 111, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 1600, + "served_rows": 84, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 976, + "served_rows": 27, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE", + "label": "scholarship and student cost in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 38, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 819, + "served_rows": 19, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 315, + "served_rows": 19, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Kenya for education and health, 1997 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "education and health", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1997 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "CRSPurposeCode110", + "label": "education" + }, + { + "ref": "CRSPurposeCode120", + "label": "health" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "measure_elected" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [ + { + "text": "health", + "named": [ + { + "ref": "CRSPurposeCode120", + "label": "health" + } + ], + "slot": "crsPurpose", + "disposition": "bound", + "selected": [] + }, + { + "text": "ODA", + "named": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "slot": "crsTypeOfFlow", + "disposition": "bound", + "selected": [] + }, + { + "text": "education", + "named": [ + { + "ref": "CRSPurposeCode110", + "label": "education" + } + ], + "slot": "crsPurpose", + "disposition": "bound", + "selected": [] + } + ], + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_b438dc000255d174bcc13eb675e603f7", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 512, + "served_rows_exact": true + }, + { + "definition": { + "schema_version": 1, + "spec_id": "spec_e348565295de394da8ddaa23ec5fa475", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialObligation", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialObligationType", + "binding": { + "state": "value", + "ref": "Commitment" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "commitments", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialObligation", + "label": "financial obligation" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialObligationType", + "value": { + "ref": "Commitment", + "label": "commitment" + } + } + ], + "served_rows": 519, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "open_axis_facts": [ + { + "property": "crsTypeOfFinance", + "varies": true, + "distinct_count": 2, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "count": 105 + }, + { + "value": { + "ref": "CRSTypeOfFinance421", + "label": "standard loan" + }, + "count": 3 + } + ] + }, + { + "property": "crsCooperationModality", + "varies": true, + "distinct_count": 7, + "undeclared_count": 19, + "values": [ + { + "value": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "count": 27 + }, + { + "value": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "count": 21 + }, + { + "value": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "count": 16 + }, + { + "value": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "count": 15 + }, + { + "value": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "count": 8 + }, + { + "value": { + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "count": 1 + } + ] + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1991, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1985, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1986, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1991, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1992, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1973, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1994, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1986, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1987, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1989, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1987, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1961, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 1985, + "end_year": 1990 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1991, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "KES", + "origin": "EUR" + } + } + } + } + }, + { + "variable_text": "GDP", + "warnings": [ + { + "code": "direction_discarded", + "severity": "warn", + "message": "Germany was named as the provider; this shape reports the place as its own subject, so the direction was dropped." + }, + { + "code": "direction_discarded", + "severity": "warn", + "message": "Kenya was named as the recipient; this shape reports the place as its own subject, so the direction was dropped." + } + ], + "timing_ms": { + "total": 2176, + "by_step": { + "recall": 1, + "shape_arcs": 3, + "shape_probe_coverage": 11, + "shape_probe": 15, + "shape_groups": 116, + "shape_labels": 14, + "shape_admission": 0, + "shape": 194, + "bind": 1952, + "materialise": 5, + "answer": 9, + "options": 15 + } + }, + "restatement": { + "variable_text": "GDP", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [ + { + "code": "direction_discarded", + "binding_ref": "where:", + "asked": "Germany", + "text": "You named Germany as a provider. This measure has no providers, so this shows the place itself." + }, + { + "code": "direction_discarded", + "binding_ref": "where:", + "asked": "Kenya", + "text": "You named Kenya as a recipient. This measure has no recipients, so this shows the place itself." + } + ], + "status": "definite", + "spec": { + "spec_id": "spec_f8dea3052d1ef6ba5667628815d1a663", + "definition": { + "schema_version": 1, + "spec_id": "spec_f8dea3052d1ef6ba5667628815d1a663", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + }, + { + "property": "economicSector", + "binding": { + "state": "unbound" + } + }, + { + "property": "naics", + "binding": { + "state": "unbound" + } + }, + { + "property": "schoolGradeLevel", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "USDollar" + } + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_nominal", + "label": "Nominal gross domestic product", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 65, + "member_digest": "73519eeb75639bdae33042fc844830cd46becc08e4f9122dfcd0886e9875f657", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "economicSector", + "naics", + "schoolGradeLevel" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 41, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 132, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 2 + }, + { + "label": "observations", + "count": 66 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 132, + "rows_exact": true, + "series": 2, + "window": { + "start_year": 1960, + "end_year": 2025 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "bound", + "ref": "USDollar", + "label": "USDollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossValueAdded", + "label": "GrossValueAdded" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NetDomesticProduction", + "label": "Net Domestic Production" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NetValueAdded", + "label": "Net Value Added" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "AgricultureForestryFishingSector", + "label": "Agriculture,Forestry and Fishing Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ConstructionSector", + "label": "Construction Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ElectricityGasSteamAirConditionSupply", + "label": "Electric Gas Steam Air Condition Supply" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinanceService", + "label": "Finance Service" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MOSPI_OtherService", + "label": "MOSPI Other Service" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ManufacturingSector", + "label": "Manufacturing Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MiningQuarrying", + "label": "Mining quarrying" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TradeSector", + "label": "Trade Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AccommodationAndFoodSector", + "label": "Accommodation and food sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AdministrativeAndSupportServices", + "label": "Administrative and support services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AgriculturalSupportActivities", + "label": "Agricultural support activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Agriculture", + "label": "Agriculture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AirTransportAndSupportServices", + "label": "Air transport and support services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AllEconomicActivities", + "label": "All economic activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AnimalProduction", + "label": "Animal production" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ArtsEntertainmentRecreation", + "label": "Arts entertainment recreation" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Education", + "label": "Education" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ElectricitySupply", + "label": "Electricity supply" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EmployerHouseholdActivities", + "label": "Employer household activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialActivities", + "label": "FinancialActivities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialAndInsuranceActivities", + "label": "Financial and insurance activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialIntermediationServicesIndirectlyMeasured", + "label": "Financial intermediation services indirectly measured" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FishingAquaculture", + "label": "Fishing aquaculture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FoodBeveragesTobaccoManufacture", + "label": "Food beverages tobacco manufacture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ForestryLogging", + "label": "Forestry logging" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "HumanHealthAndSocialWork", + "label": "Human health and social work" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "InformationAndCommunication", + "label": "Information and communication" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "InsuranceActivities", + "label": "Insurance activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "LandTransport", + "label": "Land transport" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherManufacturingAndRepair", + "label": "Other manufacturing and repair" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherServiceSector", + "label": "Other service sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherTransportPostalCourierActivities", + "label": "Other transport postal courier activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ProductTaxes", + "label": "Product taxes" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ProfessionalScientificTechnicalActivities", + "label": "Professional scientific technical activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PublicAdministrationAndDefence", + "label": "Public administration and defence" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PublishingBroadcastingInformationActivities", + "label": "Publishing Broadcasting Information Activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "RealEstate", + "label": "Real estate" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Telecommunications", + "label": "Telecommunications" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TransportStorageSector", + "label": "Transport and Storage" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "WaterSupplySewerageWasteManagement", + "label": "Water supply sewerage waste management" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "WholesaleRetailTradeAndRepair", + "label": "Wholesale retail trade and repair" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "BankingAndInsuranceSector", + "label": "Banking And Insurance Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Construction", + "label": "Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialServices", + "label": "Financial Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Industry", + "label": "Industry" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Services", + "label": "Services" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "options": [ + { + "value": { + "ref": { + "ref": "NAICS/23", + "label": "Construction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/44-45", + "label": "Retail trade" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/53", + "label": "Real estate and rental and leasing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/22", + "label": "Utilities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/55", + "label": "Management of companies and enterprises" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/48-49", + "label": "Transportation and warehousing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/61", + "label": "Educational services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/51", + "label": "Information" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/42", + "label": "Wholesale trade" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/21", + "label": "Mining, quarrying, and oil and gas extraction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/11", + "label": "Agriculture, forestry, fishing and hunting" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/72", + "label": "Accommodation and food services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/52", + "label": "Finance and insurance" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/54", + "label": "Professional, Scientific, and Technical Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/71", + "label": "Arts, entertainment, and recreation" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/311-316_322-326", + "label": "Durable Goods Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/31-33", + "label": "Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/321_327-339", + "label": "Durable Goods Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/56", + "label": "Administrative and Support and Waste Management Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/62", + "label": "Health care and social assistance" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/81", + "label": "Other services, except public administration" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/92", + "label": "Public administration" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "options": [ + { + "value": { + "ref": { + "ref": "HigherSecondaryEducation", + "label": "Higher Secondary Education" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PrePrimaryAndPrimaryEducation", + "label": "PrePrimary and Primary" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SecondaryEducation", + "label": "SecondaryEducation" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "USDollar", + "label": "USDollar" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Euro", + "label": "Euro" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NationalCurrency", + "label": "NationalCurrency" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PurchasingPowerStandard", + "label": "PurchasingPowerStandard" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "GDP in Germany and Kenya, 1960 to 2025. Current US dollars · World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Germany and Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAccommodationFoodServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSFinanceInsurance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSMiningQuarryingOilGasExtraction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSProfessionalScientificTechnicalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSWholesaleTrade_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826", + "dc/zz6gwv838v9w" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "equivalent_readings": [ + { + "spec_id": "spec_2a65bb3dc1332b16173c540e3392b139", + "definition": { + "schema_version": 1, + "spec_id": "spec_2a65bb3dc1332b16173c540e3392b139", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicProduction", + "measured_property": "valueAdded", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "currencyConversionBasis", + "binding": { + "state": "unbound" + } + }, + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + }, + { + "property": "productTaxBasis", + "binding": { + "state": "value", + "ref": "IncludingProductTaxes" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "CurrencyUSD" + } + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicproduction_valueadded_measuredvalue_nominal", + "label": "Gross domestic product (GDP)", + "population_type": { + "ref": "EconomicProduction", + "label": "economic production" + }, + "measured_property": { + "ref": "valueAdded", + "label": "value added" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 2, + "member_digest": "ef9c4356618ed98aab762248e68799d78c74ad249a6041dad0e8a345c85ee02f", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "currencyConversionBasis" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 2, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1980", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 92, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 2 + }, + { + "label": "observations", + "count": 46 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 92, + "rows_exact": true, + "series": 2, + "window": { + "start_year": 1980, + "end_year": 2025 + }, + "licence": { + "label": "IMF Copyright and Usage" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/IMFWorldEconomicOutlook", + "label": "IMF World Economic Outlook (WEO)", + "source": { + "ref": "source/InternationalMonetaryFund", + "label": "International Monetary Fund (IMF)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/IMFWorldEconomicOutlook" + }, + "unit": { + "basis": "bound", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "PurchasingPowerParityRate", + "label": "purchasing power parity rate" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "resolved_sources": [ + { + "ref": "provenance/IMFWorldEconomicOutlook", + "label": "IMF World Economic Outlook (WEO)", + "source": { + "ref": "source/InternationalMonetaryFund", + "label": "International Monetary Fund (IMF)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/IMFWorldEconomicOutlook" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAccommodationFoodServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSFinanceInsurance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSMiningQuarryingOilGasExtraction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSProfessionalScientificTechnicalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSWholesaleTrade_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826", + "dc/zz6gwv838v9w" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "measure_label_axes": [], + "measure_axis_values": [], + "related_group": { + "ref": "dc/g/EconomicActivity_ActivitySource-GrossDomesticProduction", + "label": "Economic Activity With Activity Source = Gross Domestic Production" + }, + "related_measures": [ + { + "stat_var": { + "ref": "GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "label": "Gross domestic product growth rate" + }, + "definition": { + "schema_version": 1, + "spec_id": "spec_4535d09baf2bdffef7c19c7796e96687", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "growthRate" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + } + ] + } + } + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Kenya for education and health, 1997 to 2024. Current US dollars · OECD Creditor Reporting System (CRS). GDP in Germany and Kenya, 1960 to 2025. Current US dollars · World Development Indicators. You named Germany as a provider. This measure has no providers, so this shows the place itself. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "education and health", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1997 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ], + "part_index": 2 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "Germany and Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 2 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 2 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 2 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 2 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "text", + "text": "You named Germany as a provider. This measure has no providers, so this shows the place itself.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "text", + "text": "You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 2 + } + ], + "status": "definite" + } + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "definition": { + "schema_version": 1, + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ], + "state": "set" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/KEN" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + }, + "content_version": "cv_d6ce435ea267b46680c94eae9423d420", + "prepared_at": "2026-10-20T15:55:47Z", + "coverage": { + "rows": 512, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 28 + } + ], + "window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1997 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1997 + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00259-rpx", + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T13:18:18Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11260_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 3 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 5 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11232_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 3 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11260_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 10 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 5 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 8 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12340_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12350_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12382_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11260_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12340_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12350_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12382_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12340_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12350_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12382_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11232_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11260_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12340_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12350_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12382_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11232_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11260_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12340_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 18 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11232_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11260_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 10 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 13 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 5 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 5 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 11 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 7 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 5 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 3 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 3 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 3 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12340_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12350_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12382_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 7 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11232_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11260_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12340_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12350_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12382_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 3 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 14 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 12 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 5 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11232_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11260_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 11 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 8 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 7 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 3 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12340_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12350_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12382_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11232_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 19 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12340_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12382_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 19 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12382_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH02_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 8 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 8 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 3 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 8 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 8 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 12 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12350_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityB031_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityB031_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityB03_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityB03_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityB04_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityB04_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityB04_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11260_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12350_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityE01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance422_CRSCooperationModalityE01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance610_CRSCooperationModalityC01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 545, + "family_member_digest": "0c7508fd1997d6cdc896f2eab0f092a4915cfca9e2400eb9577bb22b527fe882", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "served_from": "head", + "confirmed_at": "2026-10-20T15:55:47.839028+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 16150, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T15:55:47.734234+00:00", + "tier": "working", + "url": "/api/datasets/spec_25f482395c5d012ec278118f38dff29c/cv_d6ce435ea267b46680c94eae9423d420/files/sha256:20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d" + }, + { + "artifact_digest": "sha256:a5d2d7627c8fe1357519ca0ac021c791182ab08c76f44e8055b4bb50a6059179", + "rendering": { + "statistics": "series" + }, + "bytes": 11612, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T15:55:47.734234+00:00", + "tier": "working", + "url": "/api/datasets/spec_25f482395c5d012ec278118f38dff29c/cv_d6ce435ea267b46680c94eae9423d420/files/sha256:a5d2d7627c8fe1357519ca0ac021c791182ab08c76f44e8055b4bb50a6059179" + } + ], + "series_count": 108, + "output_options": { + "capability_version": "dset_1e6cd9546fac19e9", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 108 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 28 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "stat_var", + "columns": "time_period", + "state": "available", + "width": 29, + "cells": 3132 + }, + { + "index": "time_period", + "columns": "stat_var", + "state": "available", + "width": 109, + "cells": 3052 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_25f482395c5d012ec278118f38dff29c/cv_d6ce435ea267b46680c94eae9423d420/files/sha256:20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d" + }, + "response": { + "status": 302, + "headers": { + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "answer-several-readings-folded.parquet" + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_f8dea3052d1ef6ba5667628815d1a663", + "definition": { + "schema_version": 1, + "spec_id": "spec_f8dea3052d1ef6ba5667628815d1a663", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + }, + { + "property": "economicSector", + "binding": { + "state": "unbound" + } + }, + { + "property": "naics", + "binding": { + "state": "unbound" + } + }, + { + "property": "schoolGradeLevel", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "USDollar" + } + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_f8dea3052d1ef6ba5667628815d1a663", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "EconomicActivity", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "ref": "GrossDomesticProduction", + "state": "value" + }, + "property": "activitySource" + }, + { + "binding": { + "state": "unbound" + }, + "property": "economicSector" + }, + { + "binding": { + "state": "unbound" + }, + "property": "naics" + }, + { + "binding": { + "state": "unbound" + }, + "property": "schoolGradeLevel" + } + ], + "facets": { + "unit": { + "ref": "USDollar", + "state": "value" + } + }, + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + }, + "content_version": "cv_91f57bfc5bbc5f09983596996238787d", + "prepared_at": "2026-10-20T15:55:49Z", + "coverage": { + "rows": 132, + "dimensions": [ + { + "label": "observationAbout", + "count": 2 + }, + { + "label": "years", + "count": 66 + } + ], + "window": { + "kind": "all", + "origin": "default", + "end_year": 2025, + "start_year": 1960 + } + }, + "citation": { + "text": "World Development Indicators (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "license": "Creative Commons Attribution License", + "license_type": "CreativeCommonsAttributionLicense", + "license_url": "https://datacatalog.worldbank.org/search/dataset/0037712", + "url": "https://datatopics.worldbank.org/world-development-indicators/", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": { + "publisher": "World Bank", + "description": "The primary World Bank collection of development indicators encompassing global economic and social data.", + "source_data_url": "http://api.worldbank.org/v2/en/country/AFG?downloadformat=csv", + "update_cadence": "Monthly", + "last_update": "2026-10-13", + "currencies": [], + "transformation_log": [], + "version_history": [] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "8535402560764839853", + "default_policy_version": "1" + }, + { + "ref": null, + "axis": "measurementMethod", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "8535402560764839853", + "default_policy_version": "1" + }, + { + "ref": "USDollar", + "axis": "unit", + "basis": "bound", + "default_policy": null, + "selection_reason": null, + "dispatch_facet_id": "8535402560764839853", + "default_policy_version": null + } + ], + "applied_window": { + "kind": "all", + "origin": "default", + "end_year": 2025, + "start_year": 1960 + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00259-rpx", + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T13:18:18Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "dc/base/WorldDevelopmentIndicators", + "revision": "2026-10-13" + } + ], + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_EconomicActivity_GrossDomesticProduction_Nominal", + "roles": [ + "observationAbout" + ], + "observation_count": 132 + } + ], + "family_member_count": 65, + "family_member_digest": "73519eeb75639bdae33042fc844830cd46becc08e4f9122dfcd0886e9875f657", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "served_from": "head", + "confirmed_at": "2026-10-20T15:55:50.035160+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 6545, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T15:55:49.978222+00:00", + "tier": "working", + "url": "/api/datasets/spec_f8dea3052d1ef6ba5667628815d1a663/cv_91f57bfc5bbc5f09983596996238787d/files/sha256:9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839" + }, + { + "artifact_digest": "sha256:8eecb62c1741271464d6d66841353d96f7e36aa9c3915f7948ea7c78c7dbc9e7", + "rendering": { + "statistics": "series" + }, + "bytes": 5379, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T15:55:49.978222+00:00", + "tier": "working", + "url": "/api/datasets/spec_f8dea3052d1ef6ba5667628815d1a663/cv_91f57bfc5bbc5f09983596996238787d/files/sha256:8eecb62c1741271464d6d66841353d96f7e36aa9c3915f7948ea7c78c7dbc9e7" + } + ], + "series_count": 2, + "output_options": { + "capability_version": "dset_1e6cd9546fac19e9", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "observationAbout", + "kind": "role", + "droppable": false, + "distinct": 2 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 66 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "observationAbout", + "field": "iso3", + "token": "observationAbout_iso3", + "state": "available", + "coverage": { + "entities": 2, + "covered": 2 + }, + "missing": [], + "truncated": false + }, + { + "column": "observationAbout", + "field": "iso2", + "token": "observationAbout_iso2", + "state": "available", + "coverage": { + "entities": 2, + "covered": 2 + }, + "missing": [], + "truncated": false + }, + { + "column": "observationAbout", + "field": "label", + "token": "observationAbout_label", + "state": "available", + "coverage": { + "entities": 2, + "covered": 2 + }, + "missing": [], + "truncated": false + }, + { + "column": "observationAbout", + "field": "type", + "token": "observationAbout_type", + "state": "available", + "coverage": { + "entities": 2, + "covered": 2 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "observationAbout_label" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "observationAbout", + "columns": "time_period", + "state": "available", + "width": 67, + "cells": 134 + }, + { + "index": "time_period", + "columns": "observationAbout", + "state": "available", + "width": 3, + "cells": 198 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_f8dea3052d1ef6ba5667628815d1a663/cv_91f57bfc5bbc5f09983596996238787d/files/sha256:9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839" + }, + "response": { + "status": 302, + "headers": { + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "answer-several-readings-folded-2.parquet" + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "definite", + "sentence": "Germany's gross ODA disbursements to Kenya for education and health, 1997 to 2024. Current US dollars · OECD Creditor Reporting System (CRS). GDP in Germany and Kenya, 1960 to 2025. Current US dollars · World Development Indicators. You named Germany as a provider. This measure has no providers, so this shows the place itself. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", + "complete": true, + "specs": [ + "spec_25f482395c5d012ec278118f38dff29c", + "spec_f8dea3052d1ef6ba5667628815d1a663" + ], + "gaps": [] + } + }, + { + "dataset": { + "rows": 644, + "columns": [ + "part", + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "crsCooperationModality", + "crsCooperationModality_label", + "crsPurpose", + "crsPurpose_label", + "crsTypeOfFinance", + "crsTypeOfFinance_label", + "crsTypeOfFlow", + "crsTypeOfFlow_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label", + "stat_var_label", + "observationAbout", + "observationAbout_label" + ], + "complete": true, + "members": [ + { + "parts": [ + "health ODA disbursements", + "education ODA disbursements" + ], + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "content_version": "cv_d6ce435ea267b46680c94eae9423d420", + "sentence": "Germany's gross ODA disbursements to Kenya for education and health, 1997 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." + }, + { + "parts": [ + "GDP" + ], + "spec_id": "spec_f8dea3052d1ef6ba5667628815d1a663", + "content_version": "cv_91f57bfc5bbc5f09983596996238787d", + "sentence": "GDP in Germany and Kenya, 1960 to 2025. Current US dollars · World Development Indicators." + } + ], + "missing": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.parquet b/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.parquet new file mode 100644 index 0000000000000000000000000000000000000000..b05bcc7a75baa61e39295a799831599a342f23f8 GIT binary patch literal 16150 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 literal 0 HcmV?d00001 diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json new file mode 100644 index 0000000..c6414e4 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json @@ -0,0 +1,218 @@ +{ + "format_version": 1, + "name": "answer-unknown-enum-value", + "description": "An enum value the client does not know passes through untouched and changes no outcome.", + "origin": { + "kind": "synthetic", + "derived_from": "search-place-ambiguous", + "edit": "The no_data part's category becomes \"undetermined\", a value the served enum lacks." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Congo", + "normalized_query": "ODA disbursements from Germany to Congo", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "trace_id": "cc29e19289f44bb6bb0a6e0f4c8524a7", + "warnings": [], + "timing_ms": { + "total": 1, + "by_step": { + "coverage": 0, + "response_cache_layer1": 1 + } + }, + "llm_usage": { + "input_tokens": 0, + "output_tokens": 0, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 1, + "by_step": { + "recall": 1 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "undetermined", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "no_data" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "no_data", + "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 0 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json new file mode 100644 index 0000000..130ed6a --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json @@ -0,0 +1,3574 @@ +{ + "format_version": 1, + "name": "answer-unknown-part-status", + "description": "A part status the client does not know parses as an unknown part, counts as an unknown gap with no options, and makes fetching the answer raise IncompleteAnswerError.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-mixed-fetch-raises", + "edit": "Part 1's status becomes \"deferred\", a status no client knows." + }, + "call": [ + { + "op": "search", + "question": "debt service of Kenya and the price of tea in Kenya" + }, + { + "op": "fetch" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "debt service of Kenya and the price of tea in Kenya" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "debt service of Kenya and the price of tea in Kenya", + "normalized_query": "debt service of Kenya and the price of tea in Kenya", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "trace_id": "95437670d1314551aa1fbdce8c8122b6", + "warnings": [], + "timing_ms": { + "total": 140, + "by_step": { + "coverage": 0, + "extract": 1 + } + }, + "llm_usage": { + "input_tokens": 0, + "output_tokens": 0, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "debt service", + "warnings": [], + "timing_ms": { + "total": 58, + "by_step": { + "recall": 0, + "shape_arcs": 2, + "shape_probe_coverage": 15, + "shape_probe": 16, + "shape_groups": 5, + "shape_labels": 9, + "shape_admission": 0, + "shape": 37, + "bind": 2, + "materialise": 9, + "answer": 2, + "options": 8 + } + }, + "restatement": { + "variable_text": "debt service", + "entities": [ + { + "text": "Kenya" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "definite", + "spec": { + "spec_id": "spec_78d04fefc3b3f1ef71acd622957e4995", + "definition": { + "schema_version": 1, + "spec_id": "spec_78d04fefc3b3f1ef71acd622957e4995", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "ServicingPayment" + } + }, + { + "property": "financingResource", + "binding": { + "state": "unbound" + } + }, + { + "property": "guaranteeStatus", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsConcessionality", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsCreditorType", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsDebtorType", + "binding": { + "state": "unbound" + } + }, + { + "property": "includesIMFCredit", + "binding": { + "state": "unbound" + } + }, + { + "property": "maturityBand", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal_by_role", + "label": "Debt service on external debt", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 65, + "member_digest": "b66541c53125ee32113e51b4f52a3a428043b5506e15f96277f37b89547fc1c4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "ServicingPayment", + "label": "servicing payment" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "financingResource", + "guaranteeStatus", + "idsDebtorType", + "idsCreditorType", + "idsConcessionality", + "includesIMFCredit", + "maturityBand" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1970", + "end": "2024" + }, + "source_codes": [ + { + "provenance": "provenance/WorldBankInternationalDebtStatistics", + "code": "DT.TDS.DECT.CD" + } + ] + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 55, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 55 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 1, + "series": 1, + "role_counts": { + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2024, + "observations": 1, + "series": 1, + "role_counts": { + "financingRecipient": 1 + } + }, + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 1, + "series": 1, + "role_counts": { + "financingRecipient": 1 + } + } + ] + }, + "download": { + "rows": 55, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 1970, + "end_year": 2024 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "ServicingPayment", + "label": "servicing payment" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "options": [ + { + "value": { + "ref": { + "ref": "PublicOrPubliclyGuaranteed", + "label": "public or publicly guaranteed" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "NotPubliclyGuaranteed", + "label": "not publicly guaranteed" + }, + "value_kind": "enum_value" + }, + "served_rows": 56, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSDebtorTypePS", + "label": "public sector (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSDebtorTypeGG", + "label": "general government (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSDebtorTypeOPS", + "label": "other public sector (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSDebtorTypePrivateSector", + "label": "private sector (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 56, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSCreditorTypePROP", + "label": "other private creditors (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 46, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypePBND", + "label": "bondholders (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 31, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypePRVT", + "label": "private creditors (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypeOFFT", + "label": "official creditors (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 55, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypeMLAT", + "label": "multilateral (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSConcessional", + "label": "concessional (IDS concessionality)" + }, + "value_kind": "enum_value" + }, + "served_rows": 118, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "options": [ + { + "value": { + "ref": { + "ref": "WithoutIMFCredit", + "label": "without IMF credit" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "options": [ + { + "value": { + "ref": { + "ref": "LongTermMaturity", + "label": "long-term maturity" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Estimated", + "label": "estimated" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "external debt service", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ] + }, + { + "kind": "text", + "text": " owed to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "all creditors", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [], + "states": [ + "origin:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financingResource", + "binding_ref": "how:financingResource", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "guaranteeStatus", + "binding_ref": "how:guaranteeStatus", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsConcessionality", + "binding_ref": "how:idsConcessionality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsCreditorType", + "binding_ref": "how:idsCreditorType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsDebtorType", + "binding_ref": "how:idsDebtorType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "includesIMFCredit", + "binding_ref": "how:includesIMFCredit", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "maturityBand", + "binding_ref": "how:maturityBand", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1970 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Bank International Debt Statistics (IDS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "resolved_sources": [ + { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "ServicingPayment", + "label": "servicing payment" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1985, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1992, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1994, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1981, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1981, + "base_year_max": 2025 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1989, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1987, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "KES" + } + } + } + } + }, + { + "variable_text": "price of tea", + "warnings": [], + "timing_ms": { + "total": 14, + "by_step": { + "recall": 0, + "shape_arcs": 1, + "shape_probe": 3, + "shape_groups": 3, + "shape_labels": 0, + "shape_admission": 2, + "shape": 14 + } + }, + "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", + "sentence_plan": [ + { + "kind": "text", + "text": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "operations": [], + "departures": [], + "status": "deferred", + "no_data": { + "reason": "variable_not_resolved", + "category": "unresolved", + "message": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", + "entity_terms": [], + "ambiguous_entities": [], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [] + } + } + ], + "rendered_sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "external debt service", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " owed to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "all creditors", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [], + "states": [ + "origin:" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financingResource", + "binding_ref": "how:financingResource", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "guaranteeStatus", + "binding_ref": "how:guaranteeStatus", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsConcessionality", + "binding_ref": "how:idsConcessionality", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsCreditorType", + "binding_ref": "how:idsCreditorType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsDebtorType", + "binding_ref": "how:idsDebtorType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "includesIMFCredit", + "binding_ref": "how:includesIMFCredit", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "maturityBand", + "binding_ref": "how:maturityBand", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "1970 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "World Bank International Debt Statistics (IDS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "No match for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "price of tea", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ". Try a different wording or a related indicator.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + } + ], + "status": "mixed" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "mixed", + "sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "complete": false, + "specs": [ + "spec_78d04fefc3b3f1ef71acd622957e4995" + ], + "gaps": [ + { + "part": 1, + "kind": "unknown", + "options": 0 + } + ] + } + }, + { + "error": { + "class": "IncompleteAnswerError", + "code": null + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-place-one-part.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-place-one-part.json new file mode 100644 index 0000000..63e0092 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-place-one-part.json @@ -0,0 +1,3516 @@ +{ + "format_version": 1, + "name": "choose-place-one-part", + "description": "A place refusal offers one option per candidate, so its choice gap has two options. Choosing \"Congo [DRC]\" by label in a one-part answer posts that option's data_query unchanged as the input of a new search, which answers definite.", + "origin": { + "kind": "synthetic", + "derived_from": "search-place-ambiguous", + "edit": "Each refusal's data_query becomes the no_data options Search serves, and the chosen option's answer is recorded live." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + }, + { + "op": "choose", + "option": "Congo [DRC]" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Congo", + "normalized_query": "ODA disbursements from Germany to Congo", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "trace_id": "cc29e19289f44bb6bb0a6e0f4c8524a7", + "warnings": [], + "timing_ms": { + "total": 1, + "by_step": { + "coverage": 0, + "response_cache_layer1": 1 + } + }, + "llm_usage": { + "input_tokens": 0, + "output_tokens": 0, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 1, + "by_step": { + "recall": 1 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + ] + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "no_data" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "parsed", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "trace_id": "5999fc9843df4455932843b0a2ac8175", + "warnings": [], + "timing_ms": { + "total": 3, + "by_step": { + "coverage": 0, + "response_cache_layer2": 1 + } + }, + "llm_usage": { + "input_tokens": 0, + "output_tokens": 0, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "ODA disbursements", + "warnings": [ + { + "code": "retrieval_score_weak", + "severity": "info", + "message": "the chosen reading's match to the query is weak; treat it with less confidence than a strong match." + }, + { + "code": "time_window_defaulted", + "severity": "warn", + "message": "no time_text was given; the answer was resolved across every period with data." + } + ], + "timing_ms": { + "total": 1703, + "by_step": { + "recall": 0, + "shape_arcs": 2, + "shape_probe_coverage": 8, + "shape_probe": 136, + "shape_groups": 41, + "shape_labels": 1, + "shape_admission": 0, + "shape": 380, + "bind": 1297, + "materialise": 13, + "answer": 7, + "options": 6 + } + }, + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "definite", + "spec": { + "spec_id": "spec_53b1ed52ebddd28ce274d419b53037c3", + "definition": { + "schema_version": 1, + "spec_id": "spec_53b1ed52ebddd28ce274d419b53037c3", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/COD" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal_family_f096b1ba", + "label": "gross disbursements (official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "DAC2aAidType206", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "dacTypeOfFinance", + "financialObligationType" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 65, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 65 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2024, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + } + ] + }, + "download": { + "rows": 65, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 1960, + "end_year": 2024 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "DAC2aAidType218", + "label": "ODA loans and other long-term capital" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 2, + "served_rows": 45, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType201", + "label": "ODA grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 1, + "served_rows": 65, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType207", + "label": "free-standing technical co-operation" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 59, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType213", + "label": "developmental food aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 27, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType216", + "label": "humanitarian aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 29, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross disbursements to Democratic Republic of the Congo for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Democratic Republic of the Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/COD" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2a", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "DAC2aAidType206", + "label": "official development assistance" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "measure_elected" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [ + { + "text": "ODA", + "named": [ + { + "ref": "DAC2aAidType206", + "label": "official development assistance" + } + ], + "slot": "dac2aAidType", + "disposition": "bound", + "selected": [] + } + ], + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "high", + "available_at_place": true, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_2e1f188265cd4f5123438ee26a59cc9e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/COD" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 65, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1985, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1992, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1973, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1994, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1987, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1989, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1987, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1961, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 1985, + "end_year": 1990 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "CDF", + "origin": "EUR" + } + } + } + } + } + ], + "rendered_sentence": "Germany's gross disbursements to Democratic Republic of the Congo for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Democratic Republic of the Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/COD" + ], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "status": "definite" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "no_data", + "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 2 + } + ] + } + }, + { + "answer": { + "kind": "resolution", + "status": "definite", + "sentence": "Germany's gross disbursements to Democratic Republic of the Congo for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", + "complete": true, + "specs": [ + "spec_53b1ed52ebddd28ce274d419b53037c3" + ], + "gaps": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-place-two-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-place-two-parts.json new file mode 100644 index 0000000..b3398e8 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-place-two-parts.json @@ -0,0 +1,3954 @@ +{ + "format_version": 1, + "name": "choose-place-two-parts", + "description": "Choosing \"Congo [DRC]\" on part 1 of a two-part answer posts dataset_resubmit with one entry per part in part order: the chosen option's data_query part as a parsed entry, and part 0, still a refusal, as a parsed entry of its restatement. Part 1 answers definite and part 0 refuses again with its two options.", + "origin": { + "kind": "synthetic", + "derived_from": "search-two-parts-place-ambiguous", + "edit": "Each refusal's data_query becomes the no_data options Search serves, and the chosen option's answer is recorded live." + }, + "call": [ + { + "op": "search", + "question": "Kenya's GDP, and ODA disbursements from Germany to Congo" + }, + { + "op": "choose", + "part": 1, + "option": "Congo [DRC]" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "Kenya's GDP, and ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "Kenya's GDP, and ODA disbursements from Germany to Congo", + "normalized_query": "Kenya's GDP, and ODA disbursements from Germany to Congo", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "trace_id": "1fdae229dbd2489c8551682aa2bb6880", + "warnings": [], + "timing_ms": { + "total": 2, + "by_step": { + "coverage": 0, + "response_cache_layer1": 1 + } + }, + "llm_usage": { + "input_tokens": 0, + "output_tokens": 0, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GDP", + "warnings": [], + "timing_ms": { + "total": 1, + "by_step": { + "recall": 1 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "GDP", + "entities": [ + { + "text": "Kenya", + "role_text": "to" + }, + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "GDP", + "entities": [ + { + "text": "Kenya", + "role_text": "to", + "dcid": "country/KEN" + }, + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "GDP", + "entities": [ + { + "text": "Kenya", + "role_text": "to", + "dcid": "country/KEN" + }, + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + ] + } + }, + { + "variable_text": "ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 0, + "by_step": { + "recall": 0 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Kenya", + "role_text": "to" + }, + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Kenya", + "role_text": "to", + "dcid": "country/KEN" + }, + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Kenya", + "role_text": "to", + "dcid": "country/KEN" + }, + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + ] + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "status": "no_data" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "dataset_resubmit", + "entries": [ + { + "entry_kind": "parsed", + "part": { + "variable_text": "GDP", + "entities": [ + { + "text": "Kenya", + "role_text": "to" + }, + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + } + }, + { + "entry_kind": "parsed", + "part": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Kenya", + "role_text": "to", + "dcid": "country/KEN" + }, + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + } + ] + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "dataset_resubmit", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "trace_id": "d81985d7be53420d9ad6129d1c803479", + "warnings": [], + "timing_ms": { + "total": 848, + "by_step": { + "coverage": 0 + } + }, + "llm_usage": { + "input_tokens": 0, + "output_tokens": 0, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GDP", + "warnings": [ + { + "code": "time_window_defaulted", + "severity": "warn", + "message": "no time_text was given; the answer was resolved across every period with data." + } + ], + "timing_ms": { + "total": 1, + "by_step": { + "recall": 1 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "GDP", + "entities": [ + { + "text": "Kenya", + "role_text": "to" + }, + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "GDP", + "entities": [ + { + "text": "Kenya", + "role_text": "to", + "dcid": "country/KEN" + }, + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "GDP", + "entities": [ + { + "text": "Kenya", + "role_text": "to", + "dcid": "country/KEN" + }, + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + ] + } + }, + { + "variable_text": "ODA disbursements", + "warnings": [ + { + "code": "retrieval_score_weak", + "severity": "info", + "message": "the chosen reading's match to the query is weak; treat it with less confidence than a strong match." + }, + { + "code": "time_window_defaulted", + "severity": "warn", + "message": "no time_text was given; the answer was resolved across every period with data." + } + ], + "timing_ms": { + "total": 374, + "by_step": { + "recall": 1, + "shape_arcs": 4, + "shape_probe_coverage": 7, + "shape_probe": 7, + "shape_groups": 42, + "shape_labels": 1, + "shape_admission": 1, + "shape": 335, + "bind": 9, + "materialise": 15, + "answer": 9, + "options": 5 + } + }, + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Kenya", + "role_text": "to", + "dcid": "country/KEN" + }, + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "definite", + "spec": { + "spec_id": "spec_4b8c1ba9efe879b10dc3fde2c24dc483", + "definition": { + "schema_version": 1, + "spec_id": "spec_4b8c1ba9efe879b10dc3fde2c24dc483", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/COD", + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal_family_f096b1ba", + "label": "gross disbursements (official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "DAC2aAidType206", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "dacTypeOfFinance", + "financialObligationType" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 130, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 65 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 2, + "series": 2, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 2 + }, + "recent_years": [ + { + "year": 2024, + "observations": 2, + "series": 2, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 2 + } + }, + { + "year": 2023, + "observations": 2, + "series": 2, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 2 + } + }, + { + "year": 2022, + "observations": 2, + "series": 2, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 2 + } + } + ] + }, + "download": { + "rows": 130, + "rows_exact": true, + "series": 2, + "window": { + "start_year": 1960, + "end_year": 2024 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "DAC2aAidType218", + "label": "ODA loans and other long-term capital" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 2, + "served_rows": 106, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType201", + "label": "ODA grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 1, + "served_rows": 130, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType207", + "label": "free-standing technical co-operation" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 118, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType213", + "label": "developmental food aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 71, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType216", + "label": "humanitarian aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 58, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross disbursements to Democratic Republic of the Congo and Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Democratic Republic of the Congo and Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/COD", + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2a", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "DAC2aAidType206", + "label": "official development assistance" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "measure_elected" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [ + { + "text": "ODA", + "named": [ + { + "ref": "DAC2aAidType206", + "label": "official development assistance" + } + ], + "slot": "dac2aAidType", + "disposition": "bound", + "selected": [] + } + ], + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "high", + "available_at_place": true, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_9de5a8ccb2c8bd8f2ad793949b9c0222", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/COD", + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 130, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1985, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1992, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1973, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1994, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1987, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1989, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1987, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1961, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 1985, + "end_year": 1990 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "origin": "EUR" + } + } + } + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific. Germany's gross disbursements to Democratic Republic of the Congo and Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "Democratic Republic of the Congo and Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/COD", + "country/KEN" + ], + "states": [ + "where:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "1960 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + } + ], + "status": "mixed" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "no_data", + "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 2 + }, + { + "part": 1, + "kind": "choice", + "options": 2 + } + ] + } + }, + { + "answer": { + "kind": "resolution", + "status": "mixed", + "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific. Germany's gross disbursements to Democratic Republic of the Congo and Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", + "complete": false, + "specs": [ + "spec_4b8c1ba9efe879b10dc3fde2c24dc483" + ], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 2 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json new file mode 100644 index 0000000..fcc202d --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json @@ -0,0 +1,4535 @@ +{ + "format_version": 1, + "name": "fetch-null-member", + "description": "A required member that admits null may be left out or served as null; a client reads both as null, and neither changes the outcome. The recording and this record carry the two forms of the status column's distinct.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-definite-fetch", + "edit": "The manifest's status column distinct flips between left out and served as null." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Nigeria for basic health care" + }, + { + "op": "fetch" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Nigeria for basic health care" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Nigeria for basic health care", + "normalized_query": "ODA disbursements from Germany to Nigeria for basic health care", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "trace_id": "c37510c195ea4f928cd9dc72e7adf6b9", + "warnings": [], + "timing_ms": { + "total": 4, + "by_step": { + "coverage": 0, + "response_cache_layer1": 1 + } + }, + "llm_usage": { + "input_tokens": 0, + "output_tokens": 0, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "ODA disbursements for basic health care", + "warnings": [], + "timing_ms": { + "total": 4815, + "by_step": { + "recall": 549, + "shape_arcs": 1, + "shape_probe_coverage": 80, + "shape_probe": 238, + "shape_groups": 142, + "shape_labels": 0, + "shape_admission": 1, + "shape": 1269, + "bind": 2396, + "materialise": 226, + "answer": 227, + "options": 148 + } + }, + "restatement": { + "variable_text": "ODA disbursements for basic health care", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Nigeria", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "definite", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal", + "label": "gross disbursements (basic health care, official development assistance, standard grant)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 21, + "member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "financialObligationType" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 5, + "member_count_exact": true, + "served_count": 21, + "data_date_range": { + "start": "1995", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 30, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 15 + }, + { + "label": "variables", + "count": 5 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 3, + "series": 3, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2024, + "observations": 3, + "series": 3, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + } + ] + }, + "download": { + "rows": 30, + "rows_exact": true, + "series": 5, + "window": { + "start_year": 1995, + "end_year": 2024 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 7, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1606, + "served_rows": 1, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 6, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 7, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 7, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 1, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 1600, + "served_rows": 1, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 88, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 30, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFinance", + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Nigeria", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/NGA" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "basic health care", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1995 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "measure_elected" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/NGA", + "label": "Nigeria" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [ + { + "text": "ODA", + "named": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "slot": "crsTypeOfFlow", + "disposition": "bound", + "selected": [] + }, + { + "text": "basic health care", + "named": [ + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + } + ], + "slot": "crsPurpose", + "disposition": "bound", + "selected": [] + } + ], + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "high", + "available_at_place": true, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_80b92ca1ba1114b426eb5e79b84361d4", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 30, + "served_rows_exact": true + }, + { + "definition": { + "schema_version": 1, + "spec_id": "spec_c394f9108db2100f1c8e4532d8d1c804", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialObligation", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialObligationType", + "binding": { + "state": "value", + "ref": "Commitment" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "commitments", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialObligation", + "label": "financial obligation" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialObligationType", + "value": { + "ref": "Commitment", + "label": "commitment" + } + } + ], + "served_rows": 24, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "open_axis_facts": [ + { + "property": "crsTypeOfFinance", + "varies": false, + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "distinct_count": 1, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "count": 5 + } + ] + }, + { + "property": "crsCooperationModality", + "varies": true, + "distinct_count": 4, + "undeclared_count": 1, + "values": [ + { + "value": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "count": 1 + } + ] + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1995, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 2023, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1995, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "NGN", + "origin": "EUR" + } + } + } + } + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFinance", + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Nigeria", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/NGA" + ], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "basic health care", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1995 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "status": "definite" + } + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + }, + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "prepared_at": "2026-10-11T20:09:36Z", + "coverage": { + "rows": 30, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 27 + } + ], + "window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1995 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS)", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-08)", + "update_cadence": "Quarterly", + "last_update": "2026-10-08", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-09-22", + "title": "Exclude donor core contributions", + "changes": [ + { + "kind": "changed", + "note": "Donor core contributions to multilateral organisations (`bi_multi = 2`) are excluded from bilateral flows, since they would otherwise double count." + } + ] + }, + { + "date": "2026-08-20", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Dataset added to the graph." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1995 + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-10T10:52:17Z", + "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", + "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-08" + } + ], + "capability_version": "dset_ac879dbf49857907", + "materialiser_build": "1f6ed6307bea979d38cc35c4e38e0da896c431ad", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 7 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 15 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261011T194155Z-80081f08", + "served_from": "head", + "confirmed_at": "2026-10-20T15:55:32.214385+00:00" + }, + "warnings": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9785, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-19T10:58:01.080848+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + }, + { + "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", + "rendering": { + "statistics": "series" + }, + "bytes": 5981, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-08T08:43:31.704442+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" + } + ], + "series_count": 5, + "output_options": { + "capability_version": "dset_1e6cd9546fac19e9", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 5 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 27 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true, + "distinct": null + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "stat_var", + "columns": "time_period", + "state": "available", + "width": 28, + "cells": 140 + }, + { + "index": "time_period", + "columns": "stat_var", + "state": "available", + "width": 6, + "cells": 162 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + }, + "response": { + "status": 302, + "headers": { + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "fetch-null-member.parquet" + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "definite", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "complete": true, + "specs": [ + "spec_774d6c001a6250aa67ca676ab067895e" + ], + "gaps": [] + } + }, + { + "dataset": { + "rows": 30, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "crsCooperationModality", + "crsCooperationModality_label", + "crsPurpose", + "crsPurpose_label", + "crsTypeOfFinance", + "crsTypeOfFinance_label", + "crsTypeOfFlow", + "crsTypeOfFlow_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [ + "ODA disbursements for basic health care" + ], + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." + } + ], + "missing": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.parquet b/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.parquet new file mode 100644 index 0000000000000000000000000000000000000000..63e4b1cf3d459223d29806db2b7c855a7d5ef15c GIT binary patch literal 9785 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 literal 0 HcmV?d00001 diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json new file mode 100644 index 0000000..48f0d72 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json @@ -0,0 +1,208 @@ +{ + "format_version": 1, + "name": "fetch-spec-request-invalid", + "description": "Fetching a spec with a facet the server does not know sends it in input.scope.facets; the build refuses 400 request_invalid, which raises InvalidRequestError.", + "origin": { + "kind": "recorded", + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "recorded_at": "2026-10-20T16:04:05Z" + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." + }, + "facets": { + "colour": "blue" + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "scope": { + "facets": { + "colour": { + "ref": "blue" + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 400, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/request_invalid", + "title": "Bad Request", + "status": 400, + "detail": "Value error, unknown facet axis/axes: colour", + "code": "request_invalid", + "pointer": "/input/scope", + "trace_id": "da5687094d8240308063bbf016c61f80", + "capability_version": "dset_1e6cd9546fac19e9", + "retryable": false + } + } + } + ], + "expect": [ + { + "error": { + "class": "InvalidRequestError", + "code": "request_invalid" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json b/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json index 3f6904e..ac21824 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "recorded_at": "2026-10-20T15:12:21Z" + "recorded_at": "2026-10-20T16:04:09Z" }, "call": [ { @@ -38,22 +38,22 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements from Germany to Congo", "normalized_query": "ODA disbursements from Germany to Congo", - "extract_skipped": false + "extract_skipped": true }, "diagnostics": { "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "3ad2cd38008340ea9db5dcf58365f38d", + "trace_id": "cc29e19289f44bb6bb0a6e0f4c8524a7", "warnings": [], "timing_ms": { - "total": 1413, + "total": 1, "by_step": { "coverage": 0, - "extract": 1367 + "response_cache_layer1": 1 } }, "llm_usage": { - "input_tokens": 2249, - "output_tokens": 154, + "input_tokens": 0, + "output_tokens": 0, "cached_tokens": 0 }, "timed_out": false diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json new file mode 100644 index 0000000..cac5983 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json @@ -0,0 +1,243 @@ +{ + "format_version": 1, + "name": "search-proxy-rate-limited", + "description": "The proxy's 429 body carries no code or retryable: error is the code and retry \"retry_after_delay\" makes it retryable, so the client waits the Retry-After seconds, retries, and reaches the same answer.", + "origin": { + "kind": "synthetic", + "derived_from": "search-place-ambiguous", + "edit": "The website proxy's own 429 {error, retry, detail} with Retry-After 2 answers the first search." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 429, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "error": "rate_limited", + "retry": "retry_after_delay", + "detail": "Too many requests from this address. Try again shortly." + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Congo", + "normalized_query": "ODA disbursements from Germany to Congo", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "trace_id": "cc29e19289f44bb6bb0a6e0f4c8524a7", + "warnings": [], + "timing_ms": { + "total": 1, + "by_step": { + "coverage": 0, + "response_cache_layer1": 1 + } + }, + "llm_usage": { + "input_tokens": 0, + "output_tokens": 0, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 1, + "by_step": { + "recall": 1 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "no_data" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "no_data", + "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 0 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json new file mode 100644 index 0000000..af2d05b --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json @@ -0,0 +1,98 @@ +{ + "format_version": 1, + "name": "search-proxy-unavailable", + "description": "The proxy's 502 body is retryable through its retry member and has no Retry-After, so the client backs off and retries twice, then raises ServerError with the error member, transient_unavailable, as its code.", + "origin": { + "kind": "synthetic", + "derived_from": "search-place-ambiguous", + "edit": "The website proxy's own 502 {error, retry, detail} answers the search and both retries." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 502, + "headers": { + "content-type": "application/json" + }, + "json": { + "error": "transient_unavailable", + "retry": "retry_after_delay", + "detail": "The Search API is unreachable." + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 502, + "headers": { + "content-type": "application/json" + }, + "json": { + "error": "transient_unavailable", + "retry": "retry_after_delay", + "detail": "The Search API is unreachable." + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 502, + "headers": { + "content-type": "application/json" + }, + "json": { + "error": "transient_unavailable", + "retry": "retry_after_delay", + "detail": "The Search API is unreachable." + } + } + } + ], + "expect": [ + { + "error": { + "class": "ServerError", + "code": "transient_unavailable" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json b/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json new file mode 100644 index 0000000..d3de644 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json @@ -0,0 +1,248 @@ +{ + "format_version": 1, + "name": "search-retry-after-503", + "description": "A retryable 503 problem with Retry-After is retried after the wait it names, and the search then reaches the same answer; the retry spends one of the two default retries.", + "origin": { + "kind": "synthetic", + "derived_from": "search-place-ambiguous", + "edit": "A 503 service_unavailable with retryable true and Retry-After 1 answers the first search." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 503, + "headers": { + "content-type": "application/problem+json", + "retry-after": "1" + }, + "json": { + "type": "/codes/service_unavailable", + "title": "Service Unavailable", + "status": 503, + "detail": "The service is busy.", + "code": "service_unavailable", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": true + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Congo", + "normalized_query": "ODA disbursements from Germany to Congo", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "trace_id": "cc29e19289f44bb6bb0a6e0f4c8524a7", + "warnings": [], + "timing_ms": { + "total": 1, + "by_step": { + "coverage": 0, + "response_cache_layer1": 1 + } + }, + "llm_usage": { + "input_tokens": 0, + "output_tokens": 0, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 1, + "by_step": { + "recall": 1 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "no_data" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "no_data", + "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 0 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json b/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json new file mode 100644 index 0000000..f29b30a --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json @@ -0,0 +1,342 @@ +{ + "format_version": 1, + "name": "search-two-parts-place-ambiguous", + "description": "A two-part question naming a place that matches two countries answers no_data on both parts, each an entity_ambiguous choice gap. This build carries no options, so the gaps offer none.", + "origin": { + "kind": "recorded", + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "recorded_at": "2026-10-20T16:04:09Z" + }, + "call": [ + { + "op": "search", + "question": "Kenya's GDP, and ODA disbursements from Germany to Congo" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "Kenya's GDP, and ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "Kenya's GDP, and ODA disbursements from Germany to Congo", + "normalized_query": "Kenya's GDP, and ODA disbursements from Germany to Congo", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "trace_id": "1fdae229dbd2489c8551682aa2bb6880", + "warnings": [], + "timing_ms": { + "total": 2, + "by_step": { + "coverage": 0, + "response_cache_layer1": 1 + } + }, + "llm_usage": { + "input_tokens": 0, + "output_tokens": 0, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GDP", + "warnings": [], + "timing_ms": { + "total": 1, + "by_step": { + "recall": 1 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "GDP", + "entities": [ + { + "text": "Kenya", + "role_text": "to" + }, + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "GDP", + "entities": [ + { + "text": "Kenya", + "role_text": "to", + "dcid": "country/KEN" + }, + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + }, + { + "variable_text": "ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 0, + "by_step": { + "recall": 0 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Kenya", + "role_text": "to" + }, + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Kenya", + "role_text": "to", + "dcid": "country/KEN" + }, + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "status": "no_data" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "no_data", + "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 0 + }, + { + "part": 1, + "kind": "choice", + "options": 0 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/served/SOURCE.json b/python/client-contract/src/dfo_client_contract/served/SOURCE.json index 9a4786c..cfcdd98 100644 --- a/python/client-contract/src/dfo_client_contract/served/SOURCE.json +++ b/python/client-contract/src/dfo_client_contract/served/SOURCE.json @@ -2,5 +2,5 @@ "format_version": 1, "repository": "DevelopmentFinanceObservatory/apis", "commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "captured_from": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/openapi.json" + "captured_from": "dfo_apis.app.create_app() in process" } diff --git a/tools/README.md b/tools/README.md index ab1b3a7..2fcebc2 100644 --- a/tools/README.md +++ b/tools/README.md @@ -44,6 +44,12 @@ uv run tools/validate_descriptions_vectors.py uv run tools/validate_client_contract.py ``` +`capture_client_contract.py` refreshes the client contract from dfo-apis. `openapi --dfo-apis PATH` builds the composed app in that checkout's environment, in process, and writes `served/openapi.json` and `served/SOURCE.json`; `record` runs the contract's scenarios against a base URL, dev by default, writes the records with signed URLs redacted, derives the synthetic ones and validates the result. `python/client-contract/README.md` has the recipe. A PEP 723 script; its tests run without network or pyarrow: + +```bash +uv run tools/capture_client_contract.py record +``` + `validate_unit_vectors.py` validates every file under `vectors/units/` against `schemas/vectors/unit-vector.schema.json`, and checks what the schema cannot express: file names match names, names are unique, the suite meets its floor, and every classification, compare outcome and typed-unit kind has a vector. It does not import `dfo_spec_kit`. Also a PEP 723 script: ```bash diff --git a/tools/capture_client_contract.py b/tools/capture_client_contract.py new file mode 100644 index 0000000..5675bfb --- /dev/null +++ b/tools/capture_client_contract.py @@ -0,0 +1,1710 @@ +# /// script +# requires-python = ">=3.12" +# dependencies = [ +# "jsonschema>=4.23", +# "pyarrow>=15", +# ] +# /// +"""Capture the client contract's served document and record its scenarios. + +Usage: + uv run tools/capture_client_contract.py openapi --dfo-apis PATH + uv run tools/capture_client_contract.py record [--base-url URL] + [--only NAME ...] [--scenarios-dir DIR] + +`openapi` builds the composed dfo-apis app from the checkout at PATH, every +surface flag on, by calling `dfo_apis.app.create_app()` in that checkout's +environment, and writes `app.openapi()` to `served/openapi.json` and the +checkout's commit to `served/SOURCE.json`. No server runs. The surfaces load +an origin catalogue and a coverage index when they are built, so the capture +gives them the checkout's own test fixtures; the document does not depend on +the data they hold. A checkout with uncommitted changes to tracked files is +refused, because the commit would not describe the document. + +`record` runs every scenario this file defines against the API at the base +URL (dev by default; a local app at `http://127.0.0.1:8083/api`), the way a +client would, and writes each record and its binary bodies to `scenarios/`. +Each recorded scenario checks that its live answer still has the shape the +scenario is named for and refuses to write one that does not. Synthetic +scenarios are derived from the recorded records after them, so a recording +refreshes both. Signed storage URLs keep their path, and their query becomes +`X-Goog-Signature=redacted`. The run ends by validating the whole contract +with `tools/validate_client_contract.py`, and fails when it reports a +problem or the binary bodies pass 5 MB. + +The module imports only the standard library at load time, so its tests run +without pyarrow. +""" + +from __future__ import annotations + +import argparse +import copy +import hashlib +import importlib.util +import io +import json +import os +import re +import subprocess +import sys +import tempfile +import time +import urllib.error +import urllib.request +from collections.abc import Callable, Mapping, Sequence +from dataclasses import dataclass, field +from datetime import UTC, datetime +from pathlib import Path +from typing import Any, Protocol +from urllib.parse import parse_qsl, urlsplit, urlunsplit + +REPO_ROOT = Path(__file__).resolve().parent.parent +PACKAGE_DIR = REPO_ROOT / "python" / "client-contract" / "src" / "dfo_client_contract" +DEV_BASE_URL = "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api" +REPOSITORY = "DevelopmentFinanceObservatory/apis" +BINARY_BUDGET = 5_000_000 + +# The rendering both clients ask for: bare long Parquet. +RENDERING = {"format": "parquet", "bundle": False} +# The response headers a client reads, and so the ones a record keeps. +KEPT_HEADERS = ("content-type", "location", "retry-after") +# The variable text an identity resubmit sends for a member no answer part names. +UNNAMED_VARIABLE_TEXT = "dataset" +POLL_PATH = "/datasets/operations/{operation_id}" + +# The class each action in actions.json maps to, as the contract README states. +ACTION_CLASSES = { + "fix_request": "InvalidRequestError", + "check_id": "NotFoundError", + "choose": "IncompleteAnswerError", + "ask_data_question": "IncompleteAnswerError", + "take_newest_version": "VersionUnavailableError", + "log_in": "AuthenticationError", + "request_scope": "PermissionDeniedError", + "wait": "RateLimitError", + "wait_for_reset": "QuotaExceededError", + "report": "ServerError", + "upgrade": "ContractError", +} +STATUS_CLASSES = { + 400: "InvalidRequestError", + 401: "AuthenticationError", + 403: "PermissionDeniedError", + 404: "NotFoundError", + 422: "InvalidRequestError", + 429: "RateLimitError", +} + + +def dump_json(document: Any) -> str: + """`document` in the kit's JSON formatting: two-space indent, non-ASCII + kept, one trailing newline.""" + return json.dumps(document, indent=2, ensure_ascii=False) + "\n" + + +def _write_json(path: Path, document: Any) -> None: + path.write_text(dump_json(document), encoding="utf-8") + + +# --- the served document ---------------------------------------------------- + +# Runs in the dfo-apis checkout's environment, with the checkout as cwd. +_CAPTURE_SCRIPT = """ +import json, os, sys, tempfile +from pathlib import Path + +with tempfile.TemporaryDirectory() as tmp: + from tests.origin_catalogue.support import publish_sample + + os.environ["ORIGIN_CATALOGUE_URI"] = f"file://{tmp}/origin-catalogue" + publish_sample(os.environ["ORIGIN_CATALOGUE_URI"]) + from dfo_apis.app import create_app + + document = create_app().openapi() +Path(sys.argv[1]).write_text(json.dumps(document), encoding="utf-8") +""" + +# Placeholders the surfaces need to be built. None of them reaches the document. +_CAPTURE_ENV = { + "SEARCH_GRAPH_BASE": "https://graph.offline.invalid", + "DFO_PUBLIC_SITE_URL": "https://site.example", + "COVERAGE_RECHECK_SECONDS": "0", + "COVERAGE_INDEX_CHECK": "off", + "DFO_DATASETS_SURFACE": "1", + "DFO_GRAPH_SURFACE": "1", + "DFO_PRESENTATION_SURFACE": "1", + "DFO_SKILLS_SURFACE": "1", +} +_PASSED_ENV = ("HOME", "PATH", "TMPDIR", "UV_CACHE_DIR", "UV_PYTHON") + + +def capture_env(checkout: Path, environ: Mapping[str, str]) -> dict[str, str]: + """The capture's environment: a few of the caller's variables and the + placeholders, so a variable in the caller's shell cannot reach the app.""" + env = {name: environ[name] for name in _PASSED_ENV if name in environ} + env.update(_CAPTURE_ENV) + coverage = checkout / "tests" / "fixtures" / "coverage_slice" + env["COVERAGE_ARTIFACT_URI"] = coverage.as_uri() + return env + + +def _git(checkout: Path, *args: str) -> str: + return subprocess.run( + ["git", "-C", str(checkout), *args], + check=True, + capture_output=True, + text=True, + ).stdout.strip() + + +def capture_openapi(checkout: Path) -> tuple[dict[str, Any], str]: + """`app.openapi()` of the composed app in `checkout`, and its commit.""" + if _git(checkout, "status", "--porcelain", "--untracked-files=no"): + raise SystemExit(f"{checkout} has uncommitted changes to tracked files") + commit = _git(checkout, "rev-parse", "HEAD") + with tempfile.TemporaryDirectory() as tmp: + out = Path(tmp) / "openapi.json" + result = subprocess.run( + [ + "uv", + "run", + "--project", + str(checkout), + "--frozen", + "--no-sync", + "python", + "-c", + _CAPTURE_SCRIPT, + str(out), + ], + cwd=checkout, + env=capture_env(checkout, os.environ), + capture_output=True, + text=True, + check=False, + ) + if result.returncode != 0: + raise SystemExit( + f"the capture failed in {checkout}; its environment needs " + "`uv sync --extra eval --extra api --extra engine --extra datasets " + f"--extra graph`:\n{result.stderr}" + ) + return json.loads(out.read_text(encoding="utf-8")), commit + + +def write_served( + package_dir: Path, document: dict[str, Any], commit: str, captured_from: str +) -> None: + served = package_dir / "served" + _write_json(served / "openapi.json", document) + _write_json( + served / "SOURCE.json", + { + "format_version": 1, + "repository": REPOSITORY, + "commit": commit, + "captured_from": captured_from, + }, + ) + + +# --- transport and recorder ------------------------------------------------- + + +@dataclass(frozen=True, slots=True) +class Response: + status: int + headers: dict[str, str] + body: bytes + + def json(self) -> Any: + return json.loads(self.body) + + +class Transport(Protocol): + def __call__( + self, + method: str, + url: str, + *, + body: bytes | None, + headers: Mapping[str, str], + timeout: float, + ) -> Response: ... + + +class _NoRedirect(urllib.request.HTTPRedirectHandler): + """Leaves a redirect to the caller: the files route's 302 is read by hand.""" + + def redirect_request(self, *_: Any, **__: Any) -> None: + return None + + +def urllib_transport( + method: str, + url: str, + *, + body: bytes | None, + headers: Mapping[str, str], + timeout: float, +) -> Response: + request = urllib.request.Request( + url, data=body, method=method, headers=dict(headers) + ) + opener = urllib.request.build_opener(_NoRedirect) + try: + with opener.open(request, timeout=timeout) as reply: + return Response(reply.status, _lower(reply.headers.items()), reply.read()) + except urllib.error.HTTPError as error: + return Response(error.code, _lower(error.headers.items()), error.read()) + + +def _lower(items: Any) -> dict[str, str]: + return {name.lower(): value for name, value in items} + + +def redact_signed_url(url: str) -> str: + """`url` with a signed query replaced by `X-Goog-Signature=redacted`.""" + parts = urlsplit(url) + if not any(name.startswith("X-Goog-") for name, _ in parse_qsl(parts.query)): + return url + return urlunsplit(parts._replace(query="X-Goog-Signature=redacted")) + + +def _origin(base_url: str) -> str: + parts = urlsplit(base_url) + return f"{parts.scheme}://{parts.netloc}" + + +def _is_json(content_type: str) -> bool: + media = content_type.split(";", maxsplit=1)[0].strip() + return media == "application/json" or media.endswith("+json") + + +_EXTENSIONS = {"application/vnd.apache.parquet": "parquet"} + + +@dataclass +class Recorder: + """Sends requests the way a client does and keeps each exchange. + + `canned` exchanges are served in order, before the network, to the + requests that match them; `edit` rewrites each live JSON response body.""" + + name: str + base_url: str + transport: Transport + canned: list[dict[str, Any]] = field(default_factory=list) + edit: Callable[[Any], Any] | None = None + exchanges: list[dict[str, Any]] = field(default_factory=list) + bodies: dict[str, bytes] = field(default_factory=dict) + commits: set[str] = field(default_factory=set) + + def api(self, method: str, path: str, json_body: Any = None) -> Response: + """A request to `path` under the base URL.""" + return self._send( + method, {"path": path}, self.base_url.rstrip("/") + path, json_body + ) + + def origin(self, method: str, origin_path: str) -> Response: + """A request to a root-relative URL the server returned.""" + url = _origin(self.base_url) + origin_path + return self._send(method, {"origin_path": origin_path}, url, None) + + def external(self, url: str) -> Response: + """A bare GET outside the API, with no client header and no key.""" + return self._send("GET", {"url": redact_signed_url(url)}, url, None, bare=True) + + def _send( + self, + method: str, + target: dict[str, str], + url: str, + json_body: Any, + *, + bare: bool = False, + ) -> Response: + request: dict[str, Any] = {"method": method, **target} + if json_body is not None: + request["json"] = json_body + if self.canned and self.canned[0]["request"] == request: + exchange = self.canned.pop(0) + self.exchanges.append(exchange) + return _canned_response(exchange["response"]) + + headers = {} if bare else {"user-agent": "dfo-client-contract-recorder/1"} + body = None + if json_body is not None: + headers["content-type"] = "application/json" + body = json.dumps(json_body).encode() + response = self.transport( + method, url, body=body, headers=headers, timeout=300.0 + ) + if not bare and "x-dfo-commit" in response.headers: + self.commits.add(response.headers["x-dfo-commit"]) + if self.edit is not None and _is_json(response.headers.get("content-type", "")): + edited = json.dumps(self.edit(response.json())).encode() + response = Response(response.status, response.headers, edited) + self.exchanges.append({"request": request, "response": self._keep(response)}) + return response + + def _keep(self, response: Response) -> dict[str, Any]: + kept: dict[str, Any] = {"status": response.status} + headers = { + name: redact_signed_url(response.headers[name]) + if name == "location" + else response.headers[name] + for name in KEPT_HEADERS + if name in response.headers + } + if headers: + kept["headers"] = headers + content_type = response.headers.get("content-type", "") + if response.body and _is_json(content_type): + kept["json"] = response.json() + elif response.body and 200 <= response.status < 300: + extension = _EXTENSIONS.get( + content_type.split(";", maxsplit=1)[0].strip(), "bin" + ) + stem = ( + self.name if not self.bodies else f"{self.name}-{len(self.bodies) + 1}" + ) + body_file = f"{stem}.{extension}" + self.bodies[body_file] = response.body + kept["body_file"] = body_file + return kept + + +def _canned_response(response: dict[str, Any]) -> Response: + headers = dict(response.get("headers", {})) + if "json" in response: + return Response( + response["status"], headers, json.dumps(response["json"]).encode() + ) + return Response(response["status"], headers, b"") + + +# --- the answer and dataset rules ------------------------------------------- + + +@dataclass(frozen=True, slots=True) +class Spec: + spec_id: str + definition: dict[str, Any] + sentence: str | None = None + + def step(self) -> dict[str, Any]: + step: dict[str, Any] = {"spec_id": self.spec_id, "definition": self.definition} + if self.sentence is not None: + step["sentence"] = self.sentence + return step + + +def _part_spec(spec: dict[str, Any]) -> Spec: + return Spec( + spec["spec_id"], spec["definition"], spec["resolved"]["rendered_sentence"] + ) + + +@dataclass(frozen=True, slots=True) +class Answer: + body: dict[str, Any] + parts: list[dict[str, Any]] + sentence: str | None + status: str | None + + +def answer_from_body(body: dict[str, Any]) -> Answer: + return Answer( + body, body.get("parts", []), body.get("rendered_sentence"), body.get("status") + ) + + +def answer_gaps(answer: Answer, gap_kinds: Mapping[str, str]) -> list[dict[str, Any]]: + """Each part without a reading: a candidates part is a choice among its + specs; a no_data part takes its reason's gap kind, or `timed_out` when the + answer timed out; a part of unknown status is an `unknown` gap.""" + timed_out = answer.body.get("diagnostics", {}).get("timed_out") is True + gaps = [] + for index, part in enumerate(answer.parts): + match part.get("status"): + case "definite": + continue + case "candidates": + kind, options = "choice", len(part["candidates"]["specs"]) + case "no_data": + no_data = part["no_data"] + kind = ( + "timed_out" + if timed_out + else gap_kinds.get(no_data["reason"], "no_data") + ) + options = len(no_data.get("options", [])) + case "unsupported": + kind, options = "unsupported", 0 + case _: + kind, options = "unknown", 0 + gaps.append({"part": index, "kind": kind, "options": options}) + return gaps + + +def answer_outcome(answer: Answer, gap_kinds: Mapping[str, str]) -> dict[str, Any]: + """An answer outcome. A declined or catalogue answer is never complete.""" + gaps = answer_gaps(answer, gap_kinds) + outcome: dict[str, Any] = {"kind": answer.body["kind"]} + if answer.status is not None: + outcome["status"] = answer.status + outcome["sentence"] = answer.sentence + outcome["complete"] = answer.body["kind"] == "resolution" and not gaps + outcome["specs"] = list(dict.fromkeys(spec.spec_id for _, spec in _members(answer))) + outcome["gaps"] = gaps + return {"answer": outcome} + + +def _members(answer: Answer) -> list[tuple[list[str], Spec]]: + """One member per distinct spec_id of the definite parts, in part order, + with the variable text of every part it answers.""" + members: dict[str, tuple[list[str], Spec]] = {} + for part in answer.parts: + if part.get("status") != "definite": + continue + spec = _part_spec(part["spec"]) + members.setdefault(spec.spec_id, ([], spec))[0].append(part["variable_text"]) + return list(members.values()) + + +@dataclass(frozen=True, slots=True) +class Member: + parts: list[str] + definition: dict[str, Any] + content_version: str + sentence: str + digest: str + rows: int + columns: list[str] + + @property + def spec_id(self) -> str: + return self.definition["spec_id"] + + def ref(self) -> dict[str, Any]: + return { + "parts": self.parts, + "sentence": self.sentence, + "spec": {"spec_id": self.spec_id, "definition": self.definition}, + "content_version": self.content_version, + "artifact": {"digest": self.digest, "rendering": dict(RENDERING)}, + } + + +def dataset_outcome( + members: Sequence[Member], *, missing: Sequence[Mapping[str, Any]] = () +) -> dict[str, Any]: + """A dataset outcome. Several members stack into one long table with a + `part` column first, then every member's columns in member order.""" + if len(members) == 1: + columns = list(members[0].columns) + else: + columns = ["part", *dict.fromkeys(c for m in members for c in m.columns)] + return { + "dataset": { + "rows": sum(member.rows for member in members), + "columns": columns, + "complete": not missing, + "members": [ + { + "parts": member.parts, + "spec_id": member.spec_id, + "content_version": member.content_version, + "sentence": member.sentence, + } + for member in members + ], + "missing": [{"part": gap["part"], "kind": gap["kind"]} for gap in missing], + } + } + + +def parquet_shape(data: bytes) -> tuple[int, list[str]]: + import pyarrow.parquet as pq # noqa: PLC0415 - optional, so the tests run without it + + parquet = pq.ParquetFile(io.BytesIO(data)) + return parquet.metadata.num_rows, list(parquet.schema_arrow.names) + + +def gap_kinds(actions: Mapping[str, Mapping[str, Any]]) -> dict[str, str]: + """The gap kind of each no_data reason in actions.json.""" + return {code: row["gap_kind"] for code, row in actions.items() if "gap_kind" in row} + + +def _reached[T](results: list[T], step: str) -> T: + """The result a step produced; a step that refused cannot be acted on.""" + if not results: + raise ShapeError(f"{step} refused, so the steps after it cannot run") + return results[0] + + +class StepError(Exception): + """A step ended in an error a client raises.""" + + def __init__(self, error_class: str, code: str | None) -> None: + super().__init__(f"{error_class} {code}") + self.outcome = {"error": {"class": error_class, "code": code}} + + +class ShapeError(Exception): + """The live answer no longer has the shape the scenario is named for.""" + + +def require(condition: bool, message: str) -> None: + if not condition: + raise ShapeError(message) + + +@dataclass +class Session: + """A client over a recorder: each step appends to `call` and `expect`.""" + + recorder: Recorder + actions: Mapping[str, Mapping[str, Any]] + read_shape: Callable[[bytes], tuple[int, list[str]]] = parquet_shape + sleep: Callable[[float], None] = time.sleep + call: list[dict[str, Any]] = field(default_factory=list) + expect: list[dict[str, Any]] = field(default_factory=list) + minted: tuple[Spec, dict[str, Any]] | None = None + + @property + def gap_kinds(self) -> dict[str, str]: + return gap_kinds(self.actions) + + def _step(self, step: dict[str, Any], run: Callable[[], dict[str, Any]]) -> None: + self.call.append(step) + try: + outcome = run() + except StepError as refusal: + outcome = refusal.outcome + self.expect.append(outcome) + + def _answered(self, answer: Answer) -> dict[str, Any]: + return answer_outcome(answer, self.gap_kinds) + + def _resolve(self, input_: dict[str, Any]) -> Answer: + response = self.recorder.api( + "POST", "/search/resolve", {"schema_version": 1, "input": input_} + ) + self._raise_problem(response) + return answer_from_body(response.json()) + + def search(self, question: str) -> Answer: + answers: list[Answer] = [] + + def run() -> dict[str, Any]: + answers.append(self._resolve({"kind": "raw_text", "query": question})) + return self._answered(answers[0]) + + self._step({"op": "search", "question": question}, run) + return _reached(answers, "the search") + + def choose( + self, answer: Answer, option: int | str, *, part: int | None = None + ) -> Answer: + """A choice in a one-part answer is local for candidates and posts the + option's data_query for a no_data part. In a several-part answer it + posts dataset_resubmit, with the chosen option's part as a parsed + entry, each definite part as an identity entry and each other part's + restatement as a parsed entry.""" + index = ( + part if part is not None else answer_gaps(answer, self.gap_kinds)[0]["part"] + ) + chosen = answer.parts[index] + step: dict[str, Any] = {"op": "choose"} + if part is not None: + step["part"] = part + step["option"] = option + answers: list[Answer] = [] + + def run() -> dict[str, Any]: + if chosen["status"] == "candidates": + require(len(answer.parts) == 1, "a candidates choice here is one-part") + if not isinstance(option, int): + raise ShapeError("candidates are chosen by index here") + spec = chosen["candidates"]["specs"][option] + part_ = { + "status": "definite", + "variable_text": chosen["variable_text"], + "spec": spec, + } + answers.append( + Answer( + answer.body, + [part_], + spec["resolved"]["rendered_sentence"], + "definite", + ) + ) + return self._answered(answers[0]) + options = chosen["no_data"]["options"] + picked = next( + (o for i, o in enumerate(options) if option in (i, o["label"])), None + ) + if picked is None: + raise ShapeError(f"the gap offers no option {option!r}") + if len(answer.parts) == 1: + answers.append(self._resolve(picked["data_query"])) + return self._answered(answers[0]) + entries = [ + {"entry_kind": "parsed", "part": picked["data_query"]["parts"][0]} + if i == index + else _resubmit_entry(p) + for i, p in enumerate(answer.parts) + ] + answers.append( + self._resolve({"kind": "dataset_resubmit", "entries": entries}) + ) + return self._answered(answers[0]) + + self._step(step, run) + return _reached(answers, "the choice") + + def fetch_answer(self, answer: Answer, *, partial: bool = False) -> None: + step: dict[str, Any] = {"op": "fetch"} + if partial: + step["partial"] = True + + def run() -> dict[str, Any]: + if answer.body["kind"] != "resolution": + raise StepError("DeclinedError", None) + gaps = answer_gaps(answer, self.gap_kinds) + if gaps and not partial: + raise StepError("IncompleteAnswerError", None) + members = [ + self.build(parts, spec, None) for parts, spec in _members(answer) + ] + return dataset_outcome(members, missing=gaps) + + self._step(step, run) + + def fetch_spec( + self, + spec: Spec, + *, + window: str | tuple[int, int] | None = None, + facets: Mapping[str, str] | None = None, + ) -> list[Member]: + step: dict[str, Any] = {"op": "fetch", "spec": spec.step()} + scope: dict[str, Any] = {} + if window is not None: + step["window"] = list(window) if isinstance(window, tuple) else window + scope["window"] = _window(window) + if facets is not None: + step["facets"] = dict(facets) + scope["facets"] = {name: {"ref": ref} for name, ref in facets.items()} + built: list[Member] = [] + + def run() -> dict[str, Any]: + built.append(self.build([], spec, scope or None)) + return dataset_outcome(built) + + self._step(step, run) + return built + + def fetch_ref(self, ref: dict[str, Any]) -> None: + """The exact versions a ref names, through the snapshot and files routes.""" + + def run() -> dict[str, Any]: + members = [] + for member in ref["members"]: + spec_id = member["spec"]["spec_id"] + cv = member["content_version"] + response = self.recorder.api("GET", f"/datasets/{spec_id}/{cv}") + self._raise_problem(response) + digest = member["artifact"]["digest"] + artifact = next( + a + for a in response.json()["artifacts"] + if a["artifact_digest"] == digest + ) + rows, columns = self.read_shape(self._download(artifact)) + members.append( + Member( + member["parts"], + member["spec"]["definition"], + cv, + member["sentence"], + digest, + rows, + columns, + ) + ) + return dataset_outcome(members) + + self._step({"op": "fetch", "ref": ref}, run) + + def mint(self, spec: Spec) -> str: + operation: list[dict[str, Any]] = [] + + def run() -> dict[str, Any]: + response = self.recorder.api("POST", "/datasets", _build_body(spec, None)) + self._raise_problem(response) + require( + response.status == 202, f"the build answered {response.status}, not 202" + ) + operation.append(response.json()["operation"]) + return { + "operation": { + "operation_id": operation[0]["operation_id"], + "status": operation[0]["status"], + } + } + + self._step({"op": "mint", "spec": spec.step()}, run) + self.minted = (spec, _reached(operation, "the mint")) + return self.minted[1]["operation_id"] + + def result(self) -> None: + """Waits for the operation the last mint started.""" + if self.minted is None: + raise ValueError("result follows mint") + spec, operation = self.minted + + def run() -> dict[str, Any]: + manifest = self._wait(operation) + return dataset_outcome([self._member([], spec, manifest)]) + + self._step({"op": "result"}, run) + + # -- building -- + + def build( + self, parts: list[str], spec: Spec, scope: dict[str, Any] | None + ) -> Member: + """Builds one member: the build, the sentence when the client lacks it, + then the file.""" + response = self.recorder.api("POST", "/datasets", _build_body(spec, scope)) + self._raise_problem(response) + body = response.json() + manifest = self._wait(body["operation"]) if response.status == 202 else body + return self._member(parts, spec, manifest) + + def _member(self, parts: list[str], spec: Spec, manifest: dict[str, Any]) -> Member: + definition = manifest["definition"] + sentence = spec.sentence + if definition["spec_id"] != spec.spec_id or sentence is None: + sentence = self._identity_sentence(parts, definition) + artifact = next( + a + for a in manifest["artifacts"] + if a["rendering"].get("format") == "parquet" + and a["rendering"].get("bundle") is False + and a["rendering"].get("layout") != "frame" + ) + rows, columns = self.read_shape(self._download(artifact)) + return Member( + parts, + definition, + manifest["content_version"], + sentence, + artifact["artifact_digest"], + rows, + columns, + ) + + def _identity_sentence(self, parts: list[str], definition: dict[str, Any]) -> str: + entry = { + "entry_kind": "identity", + "variable_text": parts[0] if parts else UNNAMED_VARIABLE_TEXT, + "identity": definition["identity"], + } + answer = self._resolve({"kind": "dataset_resubmit", "entries": [entry]}) + (part,) = answer.parts + require(part["status"] == "definite", "the identity resubmit is definite") + require( + part["spec"]["spec_id"] == definition["spec_id"], + "the resubmit keeps the id", + ) + return part["spec"]["resolved"]["rendered_sentence"] + + def _download(self, artifact: dict[str, Any]) -> bytes: + files = self.recorder.origin("GET", artifact["url"]) + self._raise_problem(files) + require(files.status == 302, f"the files route answered {files.status}") + data = self.recorder.external(files.headers["location"]) + require(data.status == 200, f"the signed download answered {data.status}") + digest = "sha256:" + hashlib.sha256(data.body).hexdigest() + require( + digest == artifact["artifact_digest"], "the download matches its digest" + ) + return data.body + + def _wait(self, operation: dict[str, Any]) -> dict[str, Any]: + """Polls at the server's pacing, else backs off from 1 to 8 seconds.""" + backoff = 1.0 + deadline = time.monotonic() + 1800 + while time.monotonic() < deadline: + if "retry_after_ms" in operation: + self.sleep(operation["retry_after_ms"] / 1000) + else: + self.sleep(backoff) + backoff = min(backoff * 2, 8.0) + path = POLL_PATH.format(operation_id=operation["operation_id"]) + response = self.recorder.api("GET", path) + self._raise_problem(response) + resource = response.json() + operation = resource["operation"] + if operation["status"] == "done": + return resource["manifest"] + raise SystemExit(f"{operation['operation_id']} did not finish in 30 minutes") + + def _raise_problem(self, response: Response) -> None: + if response.status < 400: + return + problem = response.json() + code = problem.get("code") + row = self.actions.get(code) + if row is not None: + raise StepError(ACTION_CLASSES[row["action"]], code) + fallback = "ServerError" if response.status >= 500 else "InvalidRequestError" + raise StepError(STATUS_CLASSES.get(response.status, fallback), code) + + +def _window(window: str | tuple[int, int]) -> dict[str, Any]: + if isinstance(window, tuple): + return {"kind": "range", "start_year": window[0], "end_year": window[1]} + return {"kind": window} + + +def _build_body(spec: Spec, scope: dict[str, Any] | None) -> dict[str, Any]: + input_: dict[str, Any] = { + "kind": "spec_id", + "spec_id": spec.spec_id, + "definition": spec.definition, + } + if scope: + input_["scope"] = scope + return {"schema_version": 1, "input": input_, "options": dict(RENDERING)} + + +def _resubmit_entry(part: dict[str, Any]) -> dict[str, Any]: + if part["status"] == "definite": + spec = part["spec"] + entry = { + "entry_kind": "identity", + "variable_text": part["variable_text"], + "identity": spec["definition"]["identity"], + } + groups = spec["resolved"].get("entity_groups") + if groups: + entry["entity_groups"] = groups + return entry + return {"entry_kind": "parsed", "part": part["restatement"]} + + +def with_place_options(body: Any) -> Any: + """`body` with each no_data `data_query` replaced by the `options` a + choice refusal carries once Search serves them: per ambiguous wording and + candidate, the data_query with that candidate pinned on every row that + has the wording.""" + body = copy.deepcopy(body) + for part in body.get("parts", []) if isinstance(body, dict) else []: + no_data = part.get("no_data") + if not no_data or "data_query" not in no_data: + continue + base = no_data.pop("data_query") + options = [] + for group in no_data.get("ambiguous_entities", []): + for candidate in group["candidates"]: + query = copy.deepcopy(base) + for row in query["parts"][0]["entities"]: + if row["text"] == group["text"]: + row["dcid"] = candidate["ref"] + options.append( + { + "mentions": [group["text"]], + "label": candidate["label"], + "data_query": query, + } + ) + no_data["options"] = options + return body + + +# --- scenarios -------------------------------------------------------------- + +DEFINITE = "ODA disbursements from Germany to Nigeria for basic health care" +CANDIDATES = "GNI of Germany from 2015 to 2022" +MIXED = "debt service of Kenya and the price of tea in Kenya" +FOLDED = "ODA disbursements for health and for education from Germany to Kenya, and GDP of Kenya" +PLACE = "ODA disbursements from Germany to Congo" +TWO_PLACES = "Kenya's GDP, and ODA disbursements from Germany to Congo" +DECLINED = "should donors give more aid to Kenya?" +CATALOGUE = "what data do you have?" +ASYNC = "ODA received by every recipient country from every provider (DAC2a) from 2018 to 2024" +NARROW_WINDOW = (2020, 2023) +SYNC_ROWS = 100_000 + + +@dataclass +class Context: + """Prerequisites a scenario needs but does not record, fetched once.""" + + base_url: str + transport: Transport + actions: Mapping[str, Mapping[str, Any]] + read_shape: Callable[[bytes], tuple[int, list[str]]] = parquet_shape + _cache: dict[str, Any] = field(default_factory=dict) + + def session(self, name: str, **recorder: Any) -> Session: + return Session( + Recorder(name, self.base_url, self.transport, **recorder), + self.actions, + read_shape=self.read_shape, + ) + + def definite_answer(self, question: str) -> Answer: + if question not in self._cache: + answer = self.session("prerequisite").search(question) + require(answer.status == "definite", f"{question!r} is definite") + self._cache[question] = answer + return self._cache[question] + + def definite_spec(self, question: str) -> Spec: + (part,) = self.definite_answer(question).parts + return _part_spec(part["spec"]) + + def narrowed_spec(self) -> Spec: + """The definite spec narrowed to 2020 to 2023, with the sentence its build has.""" + if "narrowed" not in self._cache: + member = self.session("prerequisite").fetch_spec( + self.definite_spec(DEFINITE), window=NARROW_WINDOW + )[0] + self._cache["narrowed"] = Spec( + member.spec_id, member.definition, member.sentence + ) + return self._cache["narrowed"] + + def definite_ref(self) -> dict[str, Any]: + if "ref" not in self._cache: + answer = self.definite_answer(DEFINITE) + session = self.session("prerequisite") + ((parts, spec),) = _members(answer) + member = session.build(parts, spec, None) + self._cache["ref"] = {"format_version": 1, "members": [member.ref()]} + return self._cache["ref"] + + +@dataclass(frozen=True) +class Recorded: + name: str + description: str + run: Callable[[Session, Context], None] + + +def _answer_definite_fetch(s: Session, ctx: Context) -> None: + answer = s.search(DEFINITE) + require(answer.status == "definite" and len(answer.parts) == 1, "one definite part") + s.fetch_answer(answer) + + +def _answer_candidates(s: Session, ctx: Context) -> None: + answer = s.search(CANDIDATES) + require( + answer.status == "candidates" and len(answer.parts) == 1, "one candidates part" + ) + s.fetch_answer(s.choose(answer, 0)) + + +def _answer_mixed_raises(s: Session, ctx: Context) -> None: + answer = s.search(MIXED) + require(answer.status == "mixed", "a mixed answer") + require( + [p["status"] for p in answer.parts] == ["definite", "no_data"], + "definite, no_data", + ) + s.fetch_answer(answer) + + +def _answer_mixed_partial(s: Session, ctx: Context) -> None: + answer = s.search(MIXED) + require( + [p["status"] for p in answer.parts] == ["definite", "no_data"], + "definite, no_data", + ) + s.fetch_answer(answer, partial=True) + + +def _answer_folded(s: Session, ctx: Context) -> None: + answer = s.search(FOLDED) + ids = [p.get("spec", {}).get("spec_id") for p in answer.parts] + require(answer.status == "definite" and len(ids) == 3, "three definite parts") + require(ids[0] == ids[1] != ids[2], "the first two parts fold into one spec") + require( + any(w["code"] == "binding_folded" for w in answer.parts[1]["warnings"]), + "the second part carries binding_folded", + ) + s.fetch_answer(answer) + + +def _fetch_spec_narrowed(s: Session, ctx: Context) -> None: + spec = ctx.definite_spec(DEFINITE) + (member,) = s.fetch_spec(spec, window=NARROW_WINDOW) + require(member.spec_id != spec.spec_id, "the window gives a new spec_id") + require("2020 to 2023" in member.sentence, "the sentence names the window") + + +def _fetch_spec_known_sentence(s: Session, ctx: Context) -> None: + spec = ctx.narrowed_spec() + (member,) = s.fetch_spec(spec) + require(member.spec_id == spec.spec_id, "the build keeps the spec_id") + + +def _fetch_spec_request_invalid(s: Session, ctx: Context) -> None: + s.fetch_spec(ctx.definite_spec(DEFINITE), facets={"colour": "blue"}) + require( + s.expect[-1].get("error", {}).get("code") == "request_invalid", + "request_invalid", + ) + + +def _fetch_ref(s: Session, ctx: Context) -> None: + s.fetch_ref(ctx.definite_ref()) + require("dataset" in s.expect[-1], "the ref's version is fetched") + + +def _fetch_ref_unknown_version(s: Session, ctx: Context) -> None: + ref = copy.deepcopy(ctx.definite_ref()) + ref["members"][0]["content_version"] = "cv_" + "0" * 32 + s.fetch_ref(ref) + require( + s.expect[-1].get("error", {}).get("code") == "snapshot_not_found", + "snapshot_not_found", + ) + + +def _mint_async(s: Session, ctx: Context) -> None: + (part,) = ctx.definite_answer(ASYNC).parts + rows = part["spec"]["resolved"].get("download", {}).get("rows") or 0 + require( + SYNC_ROWS < rows < 2 * SYNC_ROWS, f"{rows} rows is just above the sync budget" + ) + s.mint(_part_spec(part["spec"])) + s.result() + + +def _answer_kind(question: str, kind: str) -> Callable[[Session, Context], None]: + def run(s: Session, ctx: Context) -> None: + answer = s.search(question) + require(answer.body["kind"] == kind, f"a {kind} answer") + s.fetch_answer(answer) + + return run + + +def _search_place(question: str, parts: int) -> Callable[[Session, Context], None]: + def run(s: Session, ctx: Context) -> None: + answer = s.search(question) + require( + [p.get("no_data", {}).get("reason") for p in answer.parts] + == ["entity_ambiguous"] * parts, + f"{parts} entity_ambiguous part(s)", + ) + + return run + + +RECORDED = ( + Recorded( + "answer-definite-fetch", + "A question with one reading answers definite, and fetching the answer builds the " + "part's spec as bare Parquet, follows the files route's redirect with a bare request, " + "and returns one member whose parts hold the part's variable text and whose sentence " + "is the part's spec.resolved.rendered_sentence, with no Search call after the first.", + _answer_definite_fetch, + ), + Recorded( + "answer-candidates-choose-fetch", + "A question with three readings answers one candidates part, a choice gap with three " + "options. Choosing option 0 makes no request: the new answer is definite, its sentence " + "is that candidate's spec.resolved.rendered_sentence, and fetching it builds that " + "candidate's spec.", + _answer_candidates, + ), + Recorded( + "answer-mixed-fetch-raises", + "A question with one answered part and one part Search cannot read answers mixed, " + "incomplete, with a not_understood gap on part 1. Fetching it raises " + "IncompleteAnswerError before any build.", + _answer_mixed_raises, + ), + Recorded( + "answer-mixed-fetch-partial", + "Fetching the mixed answer with partial=True builds only the answered part and returns " + "a dataset that is not complete, with part 1's not_understood gap in missing.", + _answer_mixed_partial, + ), + Recorded( + "answer-several-readings-folded", + "A question with three definite parts, the first two folded into one spec_id " + "(binding_folded), builds each distinct spec_id once, in part order, each through build, " + "files and download before the next. The dataset stacks two members, the first answering " + "both folded parts, into one table with a part column first and each member's columns in " + "member order.", + _answer_folded, + ), + Recorded( + "fetch-spec-narrowed", + "Fetching a spec with window=(2020, 2023) posts the window as input.scope, and the build " + "answers a new spec_id. The client stores the built spec_id and content_version, takes " + "the sentence from Search by posting the built definition's identity as a dataset_resubmit " + 'identity entry (variable_text "dataset" for a spec no answer part names), checks the ' + "answer's spec_id equals the built one, then downloads the file.", + _fetch_spec_narrowed, + ), + Recorded( + "fetch-spec-known-sentence", + "Fetching a spec whose sentence the client holds builds bare Parquet, follows the files " + "route's redirect with a bare request, and returns one member with that sentence and no " + "Search call.", + _fetch_spec_known_sentence, + ), + Recorded( + "fetch-spec-request-invalid", + "Fetching a spec with a facet the server does not know sends it in input.scope.facets; " + "the build refuses 400 request_invalid, which raises InvalidRequestError.", + _fetch_spec_request_invalid, + ), + Recorded( + "fetch-ref", + "Fetching a ref with the cache off reads the stored version through the snapshot route, " + "then the files route at the artifact url whose digest the ref stores, and returns the " + "ref's member with its stored parts and sentence and no build or Search call.", + _fetch_ref, + ), + Recorded( + "fetch-ref-unknown-version", + "Fetching a ref whose content_version the server never built ends at the snapshot " + "route's 404 snapshot_not_found, which raises NotFoundError with no build: an unknown " + "version is not an expired one.", + _fetch_ref_unknown_version, + ), + Recorded( + "mint-async-build", + "Minting a spec whose estimate is just above the 100,000-row sync budget answers 202 " + "with an operation the client reports as pending. Waiting polls the operation path " + "built from operation_id, sleeping retry_after_ms when the response carries it and " + "backing off from 1 to 8 seconds otherwise, until done; the done manifest's file is " + "then downloaded.", + _mint_async, + ), + Recorded( + "answer-declined", + "A question that asks for analysis answers declined, with no parts and no sentence, " + "and is not complete. Fetching it raises DeclinedError with no request.", + _answer_kind(DECLINED, "declined"), + ), + Recorded( + "answer-catalogue", + "A question about what data exists answers catalogue, with no parts and no sentence, " + "and is not complete. Fetching it raises DeclinedError with no request.", + _answer_kind(CATALOGUE, "catalogue"), + ), + Recorded( + "search-place-ambiguous", + "A question naming a place that matches two countries answers with one no_data part " + "whose entity_ambiguous reason makes a choice gap. This build carries no options, so " + "the gap offers none.", + _search_place(PLACE, 1), + ), + Recorded( + "search-two-parts-place-ambiguous", + "A two-part question naming a place that matches two countries answers no_data on both " + "parts, each an entity_ambiguous choice gap. This build carries no options, so the gaps " + "offer none.", + _search_place(TWO_PLACES, 2), + ), +) + + +# --- synthetic scenarios ---------------------------------------------------- + + +def _problem( + code: str, status: int, title: str, detail: str, *, retryable: bool +) -> dict[str, Any]: + return { + "type": f"/codes/{code}", + "title": title, + "status": status, + "detail": detail, + "code": code, + "trace_id": "0" * 32, + "capability_version": "synthetic", + "retryable": retryable, + } + + +def _refusal( + request: dict[str, Any], + status: int, + body: dict[str, Any], + headers: Mapping[str, str] | None = None, +) -> dict[str, Any]: + """An exchange answering `request` with a refusal: a problem document, or + the website proxy's own `{error, retry, detail}` JSON.""" + media = "application/json" if "error" in body else "application/problem+json" + return { + "request": copy.deepcopy(request), + "response": { + "status": status, + "headers": {"content-type": media, **(headers or {})}, + "json": body, + }, + } + + +_PROXY_RATE_LIMITED = { + "error": "rate_limited", + "retry": "retry_after_delay", + "detail": "Too many requests from this address. Try again shortly.", +} +_PROXY_UNAVAILABLE = { + "error": "transient_unavailable", + "retry": "retry_after_delay", + "detail": "The Search API is unreachable.", +} + + +@dataclass(frozen=True) +class Derived: + call: list[dict[str, Any]] + exchanges: list[dict[str, Any]] + expect: list[dict[str, Any]] + + +@dataclass(frozen=True) +class Synthetic: + name: str + derived_from: str + edit: str + description: str + derive: Callable[[dict[str, Any], Context], Derived] + + +def _same(parent: dict[str, Any], exchanges: list[dict[str, Any]]) -> Derived: + return Derived( + copy.deepcopy(parent["call"]), exchanges, copy.deepcopy(parent["expect"]) + ) + + +def _retry_after_503(parent: dict[str, Any], ctx: Context) -> Derived: + first = parent["exchanges"][0] + problem = _problem( + "service_unavailable", + 503, + "Service Unavailable", + "The service is busy.", + retryable=True, + ) + refused = _refusal(first["request"], 503, problem, {"retry-after": "1"}) + return _same(parent, [refused, *copy.deepcopy(parent["exchanges"])]) + + +def _proxy_429(parent: dict[str, Any], ctx: Context) -> Derived: + first = parent["exchanges"][0] + refused = _refusal( + first["request"], 429, dict(_PROXY_RATE_LIMITED), {"retry-after": "2"} + ) + return _same(parent, [refused, *copy.deepcopy(parent["exchanges"])]) + + +def _proxy_502(parent: dict[str, Any], ctx: Context) -> Derived: + first = parent["exchanges"][0] + refused = [ + _refusal(first["request"], 502, dict(_PROXY_UNAVAILABLE)) for _ in range(3) + ] + error = {"error": {"class": "ServerError", "code": "transient_unavailable"}} + return Derived(copy.deepcopy(parent["call"]), refused, [error]) + + +def _build_index(parent: dict[str, Any]) -> int: + return next( + i + for i, e in enumerate(parent["exchanges"]) + if e["request"]["method"] == "POST" and e["request"].get("path") == "/datasets" + ) + + +def _retry_after_504(parent: dict[str, Any], ctx: Context) -> Derived: + exchanges = copy.deepcopy(parent["exchanges"]) + index = _build_index(parent) + problem = _problem( + "timeout", + 504, + "Gateway Timeout", + "The build passed its 120 s limit.", + retryable=True, + ) + exchanges.insert(index, _refusal(exchanges[index]["request"], 504, problem)) + return _same(parent, exchanges) + + +def _signed_url_refused(parent: dict[str, Any], ctx: Context) -> Derived: + exchanges = copy.deepcopy(parent["exchanges"]) + index = next(i for i, e in enumerate(exchanges) if "url" in e["request"]) + files, signed = exchanges[index - 1], exchanges[index] + refused = { + "request": copy.deepcopy(signed["request"]), + "response": {"status": 403, "headers": {"content-type": "application/xml"}}, + } + exchanges[index:index] = [refused, copy.deepcopy(files)] + return _same(parent, exchanges) + + +def _unknown_part_status(parent: dict[str, Any], ctx: Context) -> Derived: + exchanges = copy.deepcopy(parent["exchanges"]) + body = exchanges[0]["response"]["json"] + body["parts"][1]["status"] = "deferred" + expect = copy.deepcopy(parent["expect"]) + expect[0] = answer_outcome(answer_from_body(body), gap_kinds(ctx.actions)) + return Derived(copy.deepcopy(parent["call"]), exchanges, expect) + + +def _unknown_enum_value(parent: dict[str, Any], ctx: Context) -> Derived: + exchanges = copy.deepcopy(parent["exchanges"]) + exchanges[0]["response"]["json"]["parts"][0]["no_data"]["category"] = "undetermined" + return _same(parent, exchanges) + + +def _null_member(parent: dict[str, Any], ctx: Context) -> Derived: + """Flips the status column's `distinct`, a required member that admits + null, between left out and served as null.""" + exchanges = copy.deepcopy(parent["exchanges"]) + manifest = exchanges[_build_index(parent)]["response"]["json"] + column = next( + c for c in manifest["output_options"]["columns"] if c["kind"] == "status" + ) + if "distinct" in column: + require(column["distinct"] is None, "the status column's distinct is null") + del column["distinct"] + else: + column["distinct"] = None + return _same(parent, exchanges) + + +def _renamed_strict_field(parent: dict[str, Any], ctx: Context) -> Derived: + index = _build_index(parent) + exchanges = copy.deepcopy(parent["exchanges"][: index + 1]) + manifest = exchanges[index]["response"]["json"] + manifest["contentVersion"] = manifest.pop("content_version") + error = {"error": {"class": "ContractError", "code": None}} + return Derived( + copy.deepcopy(parent["call"]), exchanges, [parent["expect"][0], error] + ) + + +def _place_choice( + option: str, part: int | None +) -> Callable[[dict[str, Any], Context], Derived]: + def derive(parent: dict[str, Any], ctx: Context) -> Derived: + canned = [ + { + **e, + "response": { + **e["response"], + "json": with_place_options(e["response"]["json"]), + }, + } + for e in copy.deepcopy(parent["exchanges"]) + ] + session = ctx.session("synthetic", canned=canned, edit=with_place_options) + answer = session.search(parent["call"][0]["question"]) + session.choose(answer, option, part=part) + return Derived(session.call, session.recorder.exchanges, session.expect) + + return derive + + +SYNTHETIC = ( + Synthetic( + "search-retry-after-503", + "search-place-ambiguous", + "A 503 service_unavailable with retryable true and Retry-After 1 answers the first search.", + "A retryable 503 problem with Retry-After is retried after the wait it names, and the " + "search then reaches the same answer; the retry spends one of the two default retries.", + _retry_after_503, + ), + Synthetic( + "search-proxy-rate-limited", + "search-place-ambiguous", + "The website proxy's own 429 {error, retry, detail} with Retry-After 2 answers the first search.", + "The proxy's 429 body carries no code or retryable: error is the code and retry " + '"retry_after_delay" makes it retryable, so the client waits the Retry-After seconds, ' + "retries, and reaches the same answer.", + _proxy_429, + ), + Synthetic( + "search-proxy-unavailable", + "search-place-ambiguous", + "The website proxy's own 502 {error, retry, detail} answers the search and both retries.", + "The proxy's 502 body is retryable through its retry member and has no Retry-After, so " + "the client backs off and retries twice, then raises ServerError with the error member, " + "transient_unavailable, as its code.", + _proxy_502, + ), + Synthetic( + "fetch-retry-after-504", + "answer-definite-fetch", + "A 504 timeout with retryable true answers the first build.", + "A synchronous build cut off at the server's limit answers a retryable 504 timeout; the " + "client builds once more and reaches the same dataset.", + _retry_after_504, + ), + Synthetic( + "fetch-ref-signed-url-refused", + "fetch-ref", + "The signed download answers 403 once, and the files route is asked again.", + "A signed storage URL that refuses is never retried: the client asks the files route " + "for a fresh redirect and downloads from that, reaching the same dataset.", + _signed_url_refused, + ), + Synthetic( + "answer-unknown-part-status", + "answer-mixed-fetch-raises", + 'Part 1\'s status becomes "deferred", a status no client knows.', + "A part status the client does not know parses as an unknown part, counts as an " + "unknown gap with no options, and makes fetching the answer raise " + "IncompleteAnswerError.", + _unknown_part_status, + ), + Synthetic( + "answer-unknown-enum-value", + "search-place-ambiguous", + 'The no_data part\'s category becomes "undetermined", a value the served enum lacks.', + "An enum value the client does not know passes through untouched and changes no " + "outcome.", + _unknown_enum_value, + ), + Synthetic( + "fetch-null-member", + "answer-definite-fetch", + "The manifest's status column distinct flips between left out and served as null.", + "A required member that admits null may be left out or served as null; a client reads " + "both as null, and neither changes the outcome. The recording and this record carry " + "the two forms of the status column's distinct.", + _null_member, + ), + Synthetic( + "fetch-renamed-strict-field", + "answer-definite-fetch", + "The build's manifest names content_version contentVersion, and the exchanges after it go.", + "A manifest without content_version, a strict field, raises ContractError on the build " + "response, before any download.", + _renamed_strict_field, + ), + Synthetic( + "choose-place-one-part", + "search-place-ambiguous", + "Each refusal's data_query becomes the no_data options Search serves, and the chosen option's answer is recorded live.", + "A place refusal offers one option per candidate, so its choice gap has two options. " + 'Choosing "Congo [DRC]" by label in a one-part answer posts that option\'s data_query ' + "unchanged as the input of a new search, which answers definite.", + _place_choice("Congo [DRC]", None), + ), + Synthetic( + "choose-place-two-parts", + "search-two-parts-place-ambiguous", + "Each refusal's data_query becomes the no_data options Search serves, and the chosen option's answer is recorded live.", + 'Choosing "Congo [DRC]" on part 1 of a two-part answer posts dataset_resubmit with one ' + "entry per part in part order: the chosen option's data_query part as a parsed entry, " + "and part 0, still a refusal, as a parsed entry of its restatement. Part 1 answers " + "definite and part 0 refuses again with its two options.", + _place_choice("Congo [DRC]", 1), + ), +) + + +# --- writing and running ---------------------------------------------------- + + +def _now() -> str: + return datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%SZ") + + +def _record( + name: str, description: str, origin: dict[str, Any], derived: Derived +) -> dict[str, Any]: + return { + "format_version": 1, + "name": name, + "description": description, + "origin": origin, + "call": derived.call, + "exchanges": derived.exchanges, + "expect": derived.expect, + } + + +def write_record( + directory: Path, record: dict[str, Any], bodies: Mapping[str, bytes] +) -> None: + """Writes `record` and its bodies, removing the body files an earlier + record of the same name named.""" + path = directory / f"{record['name']}.json" + if path.exists(): + old = json.loads(path.read_text(encoding="utf-8")) + for exchange in old["exchanges"]: + body_file = exchange["response"].get("body_file") + if body_file: + (directory / body_file).unlink(missing_ok=True) + for body_file, data in bodies.items(): + (directory / body_file).write_bytes(data) + _write_json(path, record) + + +def _renamed_bodies( + parent: dict[str, Any], derived: Derived, name: str, directory: Path +) -> dict[str, bytes]: + """Copies of the parent's body files the derived exchanges keep, renamed + to start with `name`.""" + bodies: dict[str, bytes] = {} + renamed: dict[str, str] = {} + for exchange in derived.exchanges: + old = exchange["response"].get("body_file") + if old is None: + continue + if old not in renamed: + renamed[old] = name + old.removeprefix(parent["name"]) + bodies[renamed[old]] = (directory / old).read_bytes() + exchange["response"]["body_file"] = renamed[old] + return bodies + + +def record_recorded(definition: Recorded, ctx: Context, directory: Path) -> None: + recorded_at = _now() + session = ctx.session(definition.name) + definition.run(session, ctx) + commits = session.recorder.commits + if len(commits) != 1 or not re.fullmatch(r"[0-9a-f]{40}", next(iter(commits))): + raise SystemExit( + f"{definition.name}: the responses' x-dfo-commit headers name " + f"{sorted(commits)}, not one commit; start a local app with " + "DFO_BUILD_COMMIT set to its checkout's commit" + ) + origin = { + "kind": "recorded", + "base_url": ctx.base_url, + "dfo_commit": commits.pop(), + "recorded_at": recorded_at, + } + derived = Derived(session.call, session.recorder.exchanges, session.expect) + record = _record(definition.name, definition.description, origin, derived) + write_record(directory, record, session.recorder.bodies) + + +def record_synthetic(definition: Synthetic, ctx: Context, directory: Path) -> None: + parent_path = directory / f"{definition.derived_from}.json" + parent = json.loads(parent_path.read_text(encoding="utf-8")) + derived = definition.derive(parent, ctx) + bodies = _renamed_bodies(parent, derived, definition.name, directory) + origin = { + "kind": "synthetic", + "derived_from": definition.derived_from, + "edit": definition.edit, + } + write_record( + directory, + _record(definition.name, definition.description, origin, derived), + bodies, + ) + + +def binary_total(directory: Path) -> int: + return sum( + p.stat().st_size + for p in directory.iterdir() + if p.is_file() and p.suffix != ".json" + ) + + +def _load_validator() -> Any: + path = Path(__file__).resolve().parent / "validate_client_contract.py" + spec = importlib.util.spec_from_file_location("validate_client_contract", path) + if spec is None or spec.loader is None: + raise SystemExit(f"cannot load {path}") + module = importlib.util.module_from_spec(spec) + sys.modules["validate_client_contract"] = module + spec.loader.exec_module(module) + return module + + +def load_actions(package_dir: Path) -> dict[str, dict[str, Any]]: + rows = json.loads((package_dir / "actions.json").read_text(encoding="utf-8"))[ + "codes" + ] + return {row["code"]: row for row in rows} + + +def run_record(args: argparse.Namespace) -> int: + package_dir: Path = args.package_dir + directory: Path = args.scenarios_dir or package_dir / "scenarios" + names = {d.name for d in (*RECORDED, *SYNTHETIC)} + unknown = set(args.only or ()) - names + if unknown: + raise SystemExit(f"no scenario is named {sorted(unknown)}") + chosen = set(args.only or names) + ctx = Context(args.base_url, urllib_transport, load_actions(package_dir)) + count = 0 + for definition in RECORDED: + if definition.name in chosen: + print(f"recording {definition.name}", flush=True) + record_recorded(definition, ctx, directory) + count += 1 + for synthetic in SYNTHETIC: + if synthetic.name in chosen: + print(f"deriving {synthetic.name}", flush=True) + record_synthetic(synthetic, ctx, directory) + count += 1 + total = binary_total(directory) + print(f"{count} scenario(s) written; binary bodies {total:,} bytes") + if count == 0: + return 1 + if total > BINARY_BUDGET: + print(f"binary bodies pass the {BINARY_BUDGET:,}-byte budget", file=sys.stderr) + return 1 + if args.scenarios_dir is not None: + return 0 + return _load_validator().main() + + +def run_openapi(args: argparse.Namespace) -> int: + checkout = args.dfo_apis.resolve() + document, commit = capture_openapi(checkout) + write_served( + args.package_dir, document, commit, "dfo_apis.app.create_app() in process" + ) + print(f"served/openapi.json captured from {REPOSITORY} at {commit}") + return 0 + + +def main(argv: Sequence[str] | None = None) -> int: + parser = argparse.ArgumentParser(description=__doc__.split("\n\n")[0]) + parser.add_argument("--package-dir", type=Path, default=PACKAGE_DIR) + commands = parser.add_subparsers(dest="command", required=True) + openapi = commands.add_parser("openapi", help="capture served/openapi.json") + openapi.add_argument( + "--dfo-apis", type=Path, required=True, help="a dfo-apis checkout" + ) + record = commands.add_parser("record", help="record the scenarios") + record.add_argument("--base-url", default=DEV_BASE_URL) + record.add_argument("--only", nargs="+", metavar="NAME") + record.add_argument( + "--scenarios-dir", + type=Path, + help="write here, outside the package, unvalidated", + ) + args = parser.parse_args(argv) + return run_openapi(args) if args.command == "openapi" else run_record(args) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/tests/test_capture_client_contract.py b/tools/tests/test_capture_client_contract.py new file mode 100644 index 0000000..f73c1c3 --- /dev/null +++ b/tools/tests/test_capture_client_contract.py @@ -0,0 +1,355 @@ +"""Tests for tools/capture_client_contract.py. + +The recorder's client reproduces each packaged record from the record's own +steps and responses, every derived record follows from its parent, and the +writers keep the kit's JSON formatting. No test reaches the network or needs +pyarrow: a fake transport serves the recorded responses, and the Parquet shape +reader is replaced, so rows and columns are the one part of a dataset outcome +these tests leave to the recording. + +Run with: uv run --with jsonschema --with pytest pytest tools/tests -q +""" + +from __future__ import annotations + +import copy +import importlib.util +import json +import subprocess +import sys +from collections.abc import Mapping +from pathlib import Path +from typing import Any + +import pytest + +_MODULE_PATH = Path(__file__).resolve().parent.parent / "capture_client_contract.py" +_spec = importlib.util.spec_from_file_location("capture_client_contract", _MODULE_PATH) +capture = importlib.util.module_from_spec(_spec) +sys.modules["capture_client_contract"] = capture +_spec.loader.exec_module(capture) + +SCENARIOS = capture.PACKAGE_DIR / "scenarios" +ACTIONS = capture.load_actions(capture.PACKAGE_DIR) + + +def _load(name: str) -> dict[str, Any]: + return json.loads((SCENARIOS / f"{name}.json").read_text(encoding="utf-8")) + + +def _records(kind: str) -> list[str]: + return sorted( + p.stem + for p in SCENARIOS.glob("*.json") + if json.loads(p.read_text(encoding="utf-8"))["origin"]["kind"] == kind + ) + + +class _Served: + """A transport serving one record's responses, and failing on any request + the record does not hold in that order.""" + + def __init__(self, record: dict[str, Any]) -> None: + self.base_url = record["origin"].get("base_url", capture.DEV_BASE_URL) + self.pending = copy.deepcopy(record["exchanges"]) + + def __call__( + self, + method: str, + url: str, + *, + body: bytes | None, + headers: Mapping[str, str], + timeout: float, + ) -> Any: + exchange = self.pending.pop(0) + request, response = exchange["request"], exchange["response"] + assert method == request["method"] + if "url" in request: + assert headers == {}, "a signed download carries no client header" + assert capture.redact_signed_url(url) == request["url"] + elif "origin_path" in request: + assert url == capture._origin(self.base_url) + request["origin_path"] + else: + assert url == self.base_url + request["path"] + assert (json.loads(body) if body else None) == request.get("json") + if "json" in response: + data = json.dumps(response["json"]).encode() + elif "body_file" in response: + data = (SCENARIOS / response["body_file"]).read_bytes() + else: + data = b"" + return capture.Response( + response["status"], dict(response.get("headers", {})), data + ) + + +def _shape(data: bytes) -> tuple[int, list[str]]: + return len(data), ["column"] + + +def _without_shapes(expect: list[dict[str, Any]]) -> list[dict[str, Any]]: + expect = copy.deepcopy(expect) + for outcome in expect: + if "dataset" in outcome: + del outcome["dataset"]["rows"], outcome["dataset"]["columns"] + return expect + + +def _drive(session: Any, call: list[dict[str, Any]]) -> None: + """Runs a record's steps through the recorder's client.""" + answer = None + for step in call: + match step: + case {"op": "search", "question": question}: + answer = session.search(question) + case {"op": "choose", "option": option}: + answer = session.choose(answer, option, part=step.get("part")) + case {"op": "fetch", "spec": spec}: + window = step.get("window") + session.fetch_spec( + capture.Spec( + spec["spec_id"], spec["definition"], spec.get("sentence") + ), + window=tuple(window) if isinstance(window, list) else window, + facets=step.get("facets"), + ) + case {"op": "fetch", "ref": ref}: + session.fetch_ref(ref) + case {"op": "fetch"}: + session.fetch_answer(answer, partial=step.get("partial", False)) + case {"op": "mint", "spec": spec}: + session.mint( + capture.Spec( + spec["spec_id"], spec["definition"], spec.get("sentence") + ) + ) + case {"op": "result"}: + session.result() + + +@pytest.mark.parametrize( + "name", [*_records("recorded"), "choose-place-one-part", "choose-place-two-parts"] +) +def test_the_recorder_reproduces_each_record_from_its_steps(name: str) -> None: + record = _load(name) + served = _Served(record) + recorder = capture.Recorder(name, served.base_url, served) + session = capture.Session( + recorder, ACTIONS, read_shape=_shape, sleep=lambda _: None + ) + _drive(session, record["call"]) + assert served.pending == [], "the client skipped a recorded exchange" + assert session.call == record["call"] + assert recorder.exchanges == record["exchanges"] + assert _without_shapes(session.expect) == _without_shapes(record["expect"]) + + +def test_a_recorder_keeps_bodies_redacts_signed_urls_and_names_the_commit() -> None: + signed = "https://storage.example/bucket/sha256%3Aab?X-Goog-Algorithm=GOOG4&X-Goog-Signature=f00" + replies = [ + capture.Response( + 302, {"location": signed, "x-dfo-commit": "a" * 40, "server": "x"}, b"" + ), + capture.Response( + 200, {"content-type": "application/vnd.apache.parquet"}, b"PAR1" + ), + capture.Response( + 200, {"content-type": "application/vnd.apache.parquet"}, b"PAR2" + ), + ] + sent: list[Mapping[str, str]] = [] + + def transport(method: str, url: str, **kwargs: Any) -> Any: + sent.append(kwargs["headers"]) + return replies.pop(0) + + recorder = capture.Recorder("some-name", "http://127.0.0.1:8000/api", transport) + location = recorder.origin("GET", "/api/datasets/x/y/files/z").headers["location"] + recorder.external(location) + recorder.external(location) + redacted = "https://storage.example/bucket/sha256%3Aab?X-Goog-Signature=redacted" + assert recorder.exchanges[0]["response"] == { + "status": 302, + "headers": {"location": redacted}, + } + assert recorder.exchanges[1]["request"] == {"method": "GET", "url": redacted} + assert [e["response"]["body_file"] for e in recorder.exchanges[1:]] == [ + "some-name.parquet", + "some-name-2.parquet", + ] + assert recorder.bodies == { + "some-name.parquet": b"PAR1", + "some-name-2.parquet": b"PAR2", + } + assert recorder.commits == {"a" * 40} + assert sent[1:] == [{}, {}] + + +@pytest.mark.parametrize( + ("url", "expected"), + [ + ( + "https://storage.googleapis.com/b/o?X-Goog-Algorithm=A&X-Goog-Signature=s", + "https://storage.googleapis.com/b/o?X-Goog-Signature=redacted", + ), + ("https://storage.googleapis.com/b/o", "https://storage.googleapis.com/b/o"), + ( + "/api/datasets/operations/op_1?page=2", + "/api/datasets/operations/op_1?page=2", + ), + ], +) +def test_only_a_signed_query_is_redacted(url: str, expected: str) -> None: + assert capture.redact_signed_url(url) == expected + + +@pytest.mark.parametrize( + "name", [n for n in _records("synthetic") if not n.startswith("choose-place-")] +) +def test_each_derived_record_follows_from_its_parent(name: str) -> None: + record = _load(name) + definition = next(d for d in capture.SYNTHETIC if d.name == name) + parent = _load(record["origin"]["derived_from"]) + ctx = capture.Context(capture.DEV_BASE_URL, _Served(parent), ACTIONS) + derived = definition.derive(copy.deepcopy(parent), ctx) + bodies = capture._renamed_bodies(parent, derived, name, SCENARIOS) + assert record["origin"]["edit"] == definition.edit + assert record["call"] == derived.call + assert record["exchanges"] == derived.exchanges + assert record["expect"] == derived.expect + for body_file, data in bodies.items(): + assert (SCENARIOS / body_file).read_bytes() == data + + +def test_a_renamed_strict_field_ends_the_call_at_the_build() -> None: + record = _load("fetch-renamed-strict-field") + manifest = record["exchanges"][-1]["response"]["json"] + assert "content_version" not in manifest + assert "contentVersion" in manifest + assert record["expect"][-1] == {"error": {"class": "ContractError", "code": None}} + + +def test_place_options_pin_each_candidate_on_the_ambiguous_wording() -> None: + body = _load("search-place-ambiguous")["exchanges"][0]["response"]["json"] + no_data = capture.with_place_options(body)["parts"][0]["no_data"] + assert "data_query" not in no_data + assert [o["label"] for o in no_data["options"]] == [ + "Congo [DRC]", + "Congo [Republic]", + ] + assert [o["mentions"] for o in no_data["options"]] == [["Congo"], ["Congo"]] + pins = [ + {e["text"]: e.get("dcid") for e in o["data_query"]["parts"][0]["entities"]} + for o in no_data["options"] + ] + assert pins == [ + {"Germany": "country/DEU", "Congo": "country/COD"}, + {"Germany": "country/DEU", "Congo": "country/COG"}, + ] + assert "options" not in body["parts"][0]["no_data"], "the input is left unchanged" + + +@pytest.mark.parametrize( + ("timed_out", "status", "expected"), + [ + (False, "no_data", "not_understood"), + (True, "no_data", "timed_out"), + (False, "unsupported", "unsupported"), + (False, "deferred", "unknown"), + ], +) +def test_a_part_without_a_reading_is_a_gap_of_its_kind( + timed_out: bool, status: str, expected: str +) -> None: + body = copy.deepcopy( + _load("answer-mixed-fetch-raises")["exchanges"][0]["response"]["json"] + ) + body["diagnostics"]["timed_out"] = timed_out + body["parts"][1]["status"] = status + gaps = capture.answer_gaps( + capture.answer_from_body(body), capture.gap_kinds(ACTIONS) + ) + assert gaps == [{"part": 1, "kind": expected, "options": 0}] + + +def test_several_members_stack_with_a_part_column_first() -> None: + member = capture.Member( + [], {"spec_id": "spec_a"}, "cv_a", "A.", "sha256:a", 2, ["x", "y"] + ) + other = capture.Member( + [], {"spec_id": "spec_b"}, "cv_b", "B.", "sha256:b", 3, ["y", "z"] + ) + dataset = capture.dataset_outcome([member, other])["dataset"] + assert dataset["columns"] == ["part", "x", "y", "z"] + assert dataset["rows"] == 5 + assert capture.dataset_outcome([member])["dataset"]["columns"] == ["x", "y"] + + +@pytest.mark.parametrize( + "path", + [ + capture.PACKAGE_DIR / "served" / "openapi.json", + capture.PACKAGE_DIR / "served" / "SOURCE.json", + SCENARIOS / "answer-definite-fetch.json", + ], +) +def test_the_writer_keeps_the_kit_json_formatting(path: Path) -> None: + text = path.read_text(encoding="utf-8") + assert capture.dump_json(json.loads(text)) == text + + +def test_a_rewritten_record_drops_the_body_files_it_no_longer_names( + tmp_path: Path, +) -> None: + def record(*body_files: str) -> dict[str, Any]: + exchanges = [{"response": {"status": 200, "body_file": f}} for f in body_files] + return {"name": "s", "exchanges": exchanges} + + capture.write_record( + tmp_path, + record("s.parquet", "s-2.parquet"), + {"s.parquet": b"1", "s-2.parquet": b"2"}, + ) + (tmp_path / "s-other.parquet").write_bytes(b"kept") + capture.write_record(tmp_path, record("s.parquet"), {"s.parquet": b"3"}) + assert sorted(p.name for p in tmp_path.iterdir()) == [ + "s-other.parquet", + "s.json", + "s.parquet", + ] + assert (tmp_path / "s.parquet").read_bytes() == b"3" + + +def test_the_capture_environment_takes_nothing_else_from_the_caller( + tmp_path: Path, +) -> None: + caller = { + "PATH": "/bin", + "HOME": "/home/x", + "DFO_DATASETS_SURFACE": "0", + "GEMINI_API_KEY": "k", + } + env = capture.capture_env(tmp_path, caller) + assert env["DFO_DATASETS_SURFACE"] == "1" + assert "GEMINI_API_KEY" not in env + assert env["PATH"] == "/bin" + assert ( + env["COVERAGE_ARTIFACT_URI"] + == (tmp_path / "tests" / "fixtures" / "coverage_slice").as_uri() + ) + + +def test_a_checkout_with_uncommitted_changes_is_refused(tmp_path: Path) -> None: + def git(*args: str) -> None: + subprocess.run( + ["git", "-C", str(tmp_path), *args], check=True, capture_output=True + ) + + git("init", "-q") + (tmp_path / "f").write_text("a", encoding="utf-8") + git("add", "f") + git("-c", "user.name=t", "-c", "user.email=t@example.com", "commit", "-qm", "f") + (tmp_path / "f").write_text("b", encoding="utf-8") + with pytest.raises(SystemExit, match="uncommitted changes"): + capture.capture_openapi(tmp_path) From c36e3937f8b9618145fabd787cdc47d797b4a0b2 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Tue, 20 Oct 2026 18:37:37 +0200 Subject: [PATCH 11/39] feat(client-contract): derive each scenario's expected outcome The validator replays each record's steps over its exchanges and fails when expect differs from the outcome the bodies and actions.json imply: error class, gap kinds, option and candidate counts, and a dataset's members, complete and missing. The capture tool imports the same rules. The validator also tests a strict member's nullability with the schema validator itself, refuses an absolute URL or Location header that keeps its query, and lets a synthetic record name its parent's body file. The capture refuses untracked files and an environment out of step with the lock. door_not_implemented now reports and method_not_allowed upgrades. --- python/client-contract/CHANGELOG.md | 4 +- python/client-contract/README.md | 12 +- .../src/dfo_client_contract/actions.json | 4 +- .../scenarios/fetch-null-member.json | 2 +- .../scenarios/fetch-null-member.parquet | Bin 9785 -> 0 bytes .../fetch-ref-signed-url-refused.json | 2 +- .../fetch-ref-signed-url-refused.parquet | Bin 9785 -> 0 bytes .../scenarios/fetch-retry-after-504.json | 2 +- .../scenarios/fetch-retry-after-504.parquet | Bin 9785 -> 0 bytes tools/README.md | 4 +- tools/capture_client_contract.py | 279 ++----- tools/tests/conftest.py | 7 + tools/tests/test_capture_client_contract.py | 88 +- tools/tests/test_validate_client_contract.py | 129 ++- tools/validate_client_contract.py | 764 ++++++++++++++++-- 15 files changed, 1012 insertions(+), 285 deletions(-) delete mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.parquet delete mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused.parquet delete mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.parquet create mode 100644 tools/tests/conftest.py diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index b18b85d..1c7ab7c 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -10,8 +10,10 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be - `served/openapi.json`, the composed dfo-apis app's OpenAPI document, and `served/SOURCE.json`, naming dfo-apis commit `8408f1f95c622223f8fa6e9ba55826ee8e22a852`. - `strict-fields.json` and its schema: 25 members that stay required and non-nullable, and the answer kinds, part statuses and operation statuses the clients branch on. - `actions.json` and its schema: the caller's next step for each of the 101 active refusal codes on `problem_details` or `no_data_reason`, with the gap kind of each no_data reason. -- `scenario.schema.json`, the scenario record, and two recorded scenarios: a place that matches two countries, and a fetch of a spec whose sentence the client holds, with its Parquet body. +- `scenario.schema.json`, the scenario record, and 25 scenarios: 14 recorded against dfo-apis `8408f1f95` and 11 synthetic, each derived from a recorded one by a one-line edit, with eight Parquet bodies totalling 72,172 bytes. - `dataset-ref.schema.json`, the frozen `DatasetRef` format, with accepted and rejected examples. +- `tools/capture_client_contract.py`, which captures `served/openapi.json` from a dfo-apis checkout in process and records the scenarios against a base URL, dev by default. +- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, and checks each scenario's `expect` against the outcomes its exchanges and `actions.json` give. - The client rules and their vectors: the credentials path and file format, the key lookup order, the key format check, and the cache directory and layout. [unreleased]: https://github.com/DevelopmentFinanceObservatory/spec-kit/commits/main/python diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 1cf4214..fb162de 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -66,6 +66,8 @@ uv run ty check src/dfo_client_contract `strict-fields.json` lists the members a client cannot act without. Each pointer names one property of one component schema, `/components/schemas//properties/`. A `required` entry stays in its schema's `required` list and admits no null, so a client raises `ContractError` when one is missing or null. An `enums` entry keeps every listed value, the values a client branches on: the answer kinds, the part statuses and the operation statuses. A client still accepts a value no entry lists. +The answer's `kind` and each part's `status` are the discriminators of their unions in the served document. A search response with no `kind` raises `ContractError`, as a part with no `status` does, although the served document gives `kind` a default and leaves it out of `required`. A `kind` or `status` a client does not know raises nothing. + The required members are each part's `status` and its payload (`spec`, `candidates`, `no_data`, `unsupported`), `Resolution.parts`, `CandidateSet.specs`, `NoData.reason`, `Unsupported.code`, `Spec.spec_id` and `definition`, `SpecDefinition.spec_id`, the manifest's `definition`, `definition.spec_id`, `content_version` and `artifacts`, each artifact's `artifact_digest`, `rendering` and `url`, and the operation resource's `operation`, `operation_id` and `status`. The operation's `poll` is nullable in the served document, so a client builds the poll path from `operation_id`. ## Actions @@ -86,7 +88,7 @@ The required members are each part's `status` and its payload (`spec`, `candidat | `report` | `ServerError` | Reports the trace id, after the client's retries | | `upgrade` | `ContractError` | Upgrades the client | -A code that maps to `no_data_reason` also carries `gap_kind`, the kind of gap a no_data part with that reason becomes: `choice`, `no_data`, `not_understood` or `unsupported`. `choose` goes with `choice` and only with it. `choose` and `ask_data_question` name a next step inside an answer, so a code that also reaches a problem document takes another action. A client maps an unknown code on its HTTP status, and a no_data reason with no row becomes a `no_data` gap. +A code that maps to `no_data_reason` also carries `gap_kind`, the kind of gap a no_data part with that reason becomes: `choice`, `no_data`, `not_understood` or `unsupported`. `choose` goes with `choice` and only with it. `choose` and `ask_data_question` name a next step inside an answer, so a code that also reaches a problem document takes another action. A client maps a code with no row on its HTTP status: 400 and 422 to `InvalidRequestError`, 401 to `AuthenticationError`, 403 to `PermissionDeniedError`, 404 to `NotFoundError`, 429 to `RateLimitError`, any other 5xx to `ServerError` and any other 4xx to `InvalidRequestError`. The website proxy's own `{error, retry, detail}` body carries its code in `error`. A no_data reason with no row becomes a `no_data` gap. An answer's gaps follow from its parts. A candidates part is a `choice` gap, its options the candidates. A no_data part is a gap of its reason's `gap_kind`, its options the no_data `options`, and of kind `timed_out` instead when the answer's `diagnostics.timed_out` is true. An unsupported part is an `unsupported` gap. A part whose status a client does not know is an `unknown` gap. @@ -106,10 +108,12 @@ A scenario is one client-level call, the HTTP exchanges it makes, and the outcom A step that acts on an earlier result follows one: `choose` and a `fetch` with no target follow `search` or `choose`, and `result` follows `mint`. A `spec` in a step holds `spec_id`, the server's unmodified `definition`, and the `sentence` when the client knows it. -An exchange's request names its target in one of three ways. `path` is a path the client composes under the base URL, such as `/search/resolve`. `origin_path` is a root-relative URL the server returned, such as an artifact's `url`, which resolves against the base URL's origin and never against its path. `url` is an absolute URL outside the API, such as the signed storage URL a files route redirects to, which the client fetches with a bare request carrying no client header and no key. `json` holds the request body members that must match; a recorded scenario lists every member the client sent. The response gives `status`, the `headers` a client reads, and a `json` body or a `body_file`, a binary body in `scenarios/` whose name starts with the scenario's name. +An exchange's request names its target in one of three ways. `path` is a path the client composes under the base URL, such as `/search/resolve`. `origin_path` is a root-relative URL the server returned, such as an artifact's `url`, which resolves against the base URL's origin and never against its path. `url` is an absolute URL outside the API, such as the signed storage URL a files route redirects to, which the client fetches with a bare request carrying no client header and no key. `json` holds the request body members that must match; a recorded scenario lists every member the client sent. The response gives `status`, the `headers` a client reads, and a `json` body or a `body_file`, a binary body in `scenarios/`. A scenario's own body files are named `.` and `-.`; a synthetic scenario may instead name a body file its parent names. An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column. An error outcome gives the error `class` and the problem's `code`, or null when no problem document carries the error. +Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry, an error's class is its code's action or else its status, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, and a dataset's members, `complete` and `missing` follow from the answer and the manifests. A dataset's `rows` and `columns` are the Parquet bodies' and are not derived, except that `part` comes first exactly when the dataset has several members. + A recorded scenario's request and response bodies validate against their route's schemas in `served/openapi.json`, with one allowance: a required member whose schema admits null may be absent, because the server leaves null members out of the bodies it serves. A client replays a scenario by serving the exchanges in order: @@ -118,7 +122,7 @@ A client replays a scenario by serving the exchanges in order: - A request with no exchange left, or one that matches none, fails the scenario, and so does an exchange the call never makes. - `path` resolves against the base URL the replay gives the client, and `origin_path` against that base URL's origin, so a replay can run under any base URL form. - Sleeps are not replayed: the replay injects the client's clock and sleep, and each wait the client asks for advances the clock at once. -- A recorded signed storage URL keeps its scheme, host and path, and its query reads `X-Goog-Signature=redacted`. +- Every absolute URL a record holds, a `url` request or a `location` header, keeps its scheme, host and path, and its query reads `X-Goog-Signature=redacted`, whatever signed it. The records also fix these client rules: @@ -132,7 +136,7 @@ The records also fix these client rules: ## Recording -`tools/capture_client_contract.py` refreshes the served document and the scenarios. Its `openapi` command calls `dfo_apis.app.create_app()` in process, every surface flag on, in a dfo-apis checkout with no uncommitted changes to tracked files, and writes `served/openapi.json` and `served/SOURCE.json`. The checkout needs its environment first. From the repository root, with the checkout at `../dfo-apis`: +`tools/capture_client_contract.py` refreshes the served document and the scenarios. Its `openapi` command calls `dfo_apis.app.create_app()` in process, every surface flag on, in a dfo-apis checkout with no uncommitted changes and no untracked files, and writes `served/openapi.json` and `served/SOURCE.json`. It refuses an environment that `uv sync --frozen --check` with the five extras below finds out of step with the checkout's `uv.lock`, so the checkout needs its environment first. From the repository root, with the checkout at `../dfo-apis`: ```bash uv sync --directory ../dfo-apis --extra eval --extra api --extra engine --extra datasets --extra graph diff --git a/python/client-contract/src/dfo_client_contract/actions.json b/python/client-contract/src/dfo_client_contract/actions.json index e8c8ba3..7220529 100644 --- a/python/client-contract/src/dfo_client_contract/actions.json +++ b/python/client-contract/src/dfo_client_contract/actions.json @@ -69,7 +69,7 @@ }, { "code": "door_not_implemented", - "action": "upgrade" + "action": "report" }, { "code": "edit_conflict", @@ -162,7 +162,7 @@ }, { "code": "method_not_allowed", - "action": "fix_request" + "action": "upgrade" }, { "code": "mixed_peers_anchor_types", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json index fcc202d..a22853b 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json @@ -4469,7 +4469,7 @@ "headers": { "content-type": "application/vnd.apache.parquet" }, - "body_file": "fetch-null-member.parquet" + "body_file": "answer-definite-fetch.parquet" } } ], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.parquet b/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.parquet deleted file mode 100644 index 63e4b1cf3d459223d29806db2b7c855a7d5ef15c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9785 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 str: """`document` in the kit's JSON formatting: two-space indent, non-ASCII @@ -137,6 +133,10 @@ def _write_json(path: Path, document: Any) -> None: "DFO_SKILLS_SURFACE": "1", } _PASSED_ENV = ("HOME", "PATH", "TMPDIR", "UV_CACHE_DIR", "UV_PYTHON") +# The dfo-apis extras the composed app imports. +_EXTRAS = tuple( + f"--extra={extra}" for extra in ("eval", "api", "engine", "datasets", "graph") +) def capture_env(checkout: Path, environ: Mapping[str, str]) -> dict[str, str]: @@ -159,10 +159,27 @@ def _git(checkout: Path, *args: str) -> str: def capture_openapi(checkout: Path) -> tuple[dict[str, Any], str]: - """`app.openapi()` of the composed app in `checkout`, and its commit.""" - if _git(checkout, "status", "--porcelain", "--untracked-files=no"): - raise SystemExit(f"{checkout} has uncommitted changes to tracked files") + """`app.openapi()` of the composed app in `checkout`, and its commit. + + Refuses a checkout with uncommitted changes or untracked files, and an + environment that differs from the checkout's `uv.lock` with every extra + the composed app needs, since either would make the commit misdescribe + the document.""" + if _git(checkout, "status", "--porcelain"): + raise SystemExit(f"{checkout} has uncommitted changes or untracked files") commit = _git(checkout, "rev-parse", "HEAD") + check = subprocess.run( + ["uv", "sync", "--project", str(checkout), "--frozen", "--check", *_EXTRAS], + cwd=checkout, + capture_output=True, + text=True, + check=False, + ) + if check.returncode != 0: + raise SystemExit( + f"the environment in {checkout} differs from its uv.lock; run " + f"`uv sync --frozen {' '.join(_EXTRAS)}` there:\n{check.stderr}" + ) with tempfile.TemporaryDirectory() as tmp: out = Path(tmp) / "openapi.json" result = subprocess.run( @@ -185,11 +202,7 @@ def capture_openapi(checkout: Path) -> tuple[dict[str, Any], str]: check=False, ) if result.returncode != 0: - raise SystemExit( - f"the capture failed in {checkout}; its environment needs " - "`uv sync --extra eval --extra api --extra engine --extra datasets " - f"--extra graph`:\n{result.stderr}" - ) + raise SystemExit(f"the capture failed in {checkout}:\n{result.stderr}") return json.loads(out.read_text(encoding="utf-8")), commit @@ -264,10 +277,11 @@ def _lower(items: Any) -> dict[str, str]: return {name.lower(): value for name, value in items} -def redact_signed_url(url: str) -> str: - """`url` with a signed query replaced by `X-Goog-Signature=redacted`.""" +def redact_external_url(url: str) -> str: + """An absolute `url` with its query, whatever signs it, replaced by + `X-Goog-Signature=redacted`; a root-relative URL as it stands.""" parts = urlsplit(url) - if not any(name.startswith("X-Goog-") for name, _ in parse_qsl(parts.query)): + if not parts.netloc: return url return urlunsplit(parts._replace(query="X-Goog-Signature=redacted")) @@ -314,7 +328,9 @@ def origin(self, method: str, origin_path: str) -> Response: def external(self, url: str) -> Response: """A bare GET outside the API, with no client header and no key.""" - return self._send("GET", {"url": redact_signed_url(url)}, url, None, bare=True) + return self._send( + "GET", {"url": redact_external_url(url)}, url, None, bare=True + ) def _send( self, @@ -352,7 +368,7 @@ def _send( def _keep(self, response: Response) -> dict[str, Any]: kept: dict[str, Any] = {"status": response.status} headers = { - name: redact_signed_url(response.headers[name]) + name: redact_external_url(response.headers[name]) if name == "location" else response.headers[name] for name in KEPT_HEADERS @@ -407,71 +423,8 @@ def _part_spec(spec: dict[str, Any]) -> Spec: ) -@dataclass(frozen=True, slots=True) -class Answer: - body: dict[str, Any] - parts: list[dict[str, Any]] - sentence: str | None - status: str | None - - -def answer_from_body(body: dict[str, Any]) -> Answer: - return Answer( - body, body.get("parts", []), body.get("rendered_sentence"), body.get("status") - ) - - -def answer_gaps(answer: Answer, gap_kinds: Mapping[str, str]) -> list[dict[str, Any]]: - """Each part without a reading: a candidates part is a choice among its - specs; a no_data part takes its reason's gap kind, or `timed_out` when the - answer timed out; a part of unknown status is an `unknown` gap.""" - timed_out = answer.body.get("diagnostics", {}).get("timed_out") is True - gaps = [] - for index, part in enumerate(answer.parts): - match part.get("status"): - case "definite": - continue - case "candidates": - kind, options = "choice", len(part["candidates"]["specs"]) - case "no_data": - no_data = part["no_data"] - kind = ( - "timed_out" - if timed_out - else gap_kinds.get(no_data["reason"], "no_data") - ) - options = len(no_data.get("options", [])) - case "unsupported": - kind, options = "unsupported", 0 - case _: - kind, options = "unknown", 0 - gaps.append({"part": index, "kind": kind, "options": options}) - return gaps - - -def answer_outcome(answer: Answer, gap_kinds: Mapping[str, str]) -> dict[str, Any]: - """An answer outcome. A declined or catalogue answer is never complete.""" - gaps = answer_gaps(answer, gap_kinds) - outcome: dict[str, Any] = {"kind": answer.body["kind"]} - if answer.status is not None: - outcome["status"] = answer.status - outcome["sentence"] = answer.sentence - outcome["complete"] = answer.body["kind"] == "resolution" and not gaps - outcome["specs"] = list(dict.fromkeys(spec.spec_id for _, spec in _members(answer))) - outcome["gaps"] = gaps - return {"answer": outcome} - - def _members(answer: Answer) -> list[tuple[list[str], Spec]]: - """One member per distinct spec_id of the definite parts, in part order, - with the variable text of every part it answers.""" - members: dict[str, tuple[list[str], Spec]] = {} - for part in answer.parts: - if part.get("status") != "definite": - continue - spec = _part_spec(part["spec"]) - members.setdefault(spec.spec_id, ([], spec))[0].append(part["variable_text"]) - return list(members.values()) + return [(parts, _part_spec(spec)) for parts, spec in answer_members(answer)] @dataclass(frozen=True, slots=True) @@ -507,23 +460,20 @@ def dataset_outcome( columns = list(members[0].columns) else: columns = ["part", *dict.fromkeys(c for m in members for c in m.columns)] - return { - "dataset": { - "rows": sum(member.rows for member in members), - "columns": columns, - "complete": not missing, - "members": [ - { - "parts": member.parts, - "spec_id": member.spec_id, - "content_version": member.content_version, - "sentence": member.sentence, - } - for member in members - ], - "missing": [{"part": gap["part"], "kind": gap["kind"]} for gap in missing], - } - } + summary = dataset_summary( + [ + { + "parts": member.parts, + "spec_id": member.spec_id, + "content_version": member.content_version, + "sentence": member.sentence, + } + for member in members + ], + missing, + ) + rows = sum(member.rows for member in members) + return {"dataset": {"rows": rows, "columns": columns, **summary}} def parquet_shape(data: bytes) -> tuple[int, list[str]]: @@ -533,11 +483,6 @@ def parquet_shape(data: bytes) -> tuple[int, list[str]]: return parquet.metadata.num_rows, list(parquet.schema_arrow.names) -def gap_kinds(actions: Mapping[str, Mapping[str, Any]]) -> dict[str, str]: - """The gap kind of each no_data reason in actions.json.""" - return {code: row["gap_kind"] for code, row in actions.items() if "gap_kind" in row} - - def _reached[T](results: list[T], step: str) -> T: """The result a step produced; a step that refused cannot be acted on.""" if not results: @@ -548,9 +493,9 @@ def _reached[T](results: list[T], step: str) -> T: class StepError(Exception): """A step ended in an error a client raises.""" - def __init__(self, error_class: str, code: str | None) -> None: - super().__init__(f"{error_class} {code}") - self.outcome = {"error": {"class": error_class, "code": code}} + def __init__(self, error: str, code: str | None = None) -> None: + super().__init__(f"{error} {code}") + self.outcome = error_outcome(error, code) class ShapeError(Exception): @@ -629,20 +574,7 @@ def run() -> dict[str, Any]: require(len(answer.parts) == 1, "a candidates choice here is one-part") if not isinstance(option, int): raise ShapeError("candidates are chosen by index here") - spec = chosen["candidates"]["specs"][option] - part_ = { - "status": "definite", - "variable_text": chosen["variable_text"], - "spec": spec, - } - answers.append( - Answer( - answer.body, - [part_], - spec["resolved"]["rendered_sentence"], - "definite", - ) - ) + answers.append(candidate_answer(answer, index, option)) return self._answered(answers[0]) options = chosen["no_data"]["options"] picked = next( @@ -674,10 +606,10 @@ def fetch_answer(self, answer: Answer, *, partial: bool = False) -> None: def run() -> dict[str, Any]: if answer.body["kind"] != "resolution": - raise StepError("DeclinedError", None) + raise StepError("DeclinedError") gaps = answer_gaps(answer, self.gap_kinds) if gaps and not partial: - raise StepError("IncompleteAnswerError", None) + raise StepError("IncompleteAnswerError") members = [ self.build(parts, spec, None) for parts, spec in _members(answer) ] @@ -859,13 +791,8 @@ def _wait(self, operation: dict[str, Any]) -> dict[str, Any]: def _raise_problem(self, response: Response) -> None: if response.status < 400: return - problem = response.json() - code = problem.get("code") - row = self.actions.get(code) - if row is not None: - raise StepError(ACTION_CLASSES[row["action"]], code) - fallback = "ServerError" if response.status >= 500 else "InvalidRequestError" - raise StepError(STATUS_CLASSES.get(response.status, fallback), code) + code = refusal_code(response.json()) + raise StepError(error_class(response.status, code, self.actions), code) def _window(window: str | tuple[int, int]) -> dict[str, Any]: @@ -1322,7 +1249,8 @@ def _proxy_502(parent: dict[str, Any], ctx: Context) -> Derived: refused = [ _refusal(first["request"], 502, dict(_PROXY_UNAVAILABLE)) for _ in range(3) ] - error = {"error": {"class": "ServerError", "code": "transient_unavailable"}} + code = refusal_code(_PROXY_UNAVAILABLE) + error = error_outcome(error_class(502, code, ctx.actions), code) return Derived(copy.deepcopy(parent["call"]), refused, [error]) @@ -1396,7 +1324,7 @@ def _renamed_strict_field(parent: dict[str, Any], ctx: Context) -> Derived: exchanges = copy.deepcopy(parent["exchanges"][: index + 1]) manifest = exchanges[index]["response"]["json"] manifest["contentVersion"] = manifest.pop("content_version") - error = {"error": {"class": "ContractError", "code": None}} + error = error_outcome("ContractError") return Derived( copy.deepcopy(parent["call"]), exchanges, [parent["expect"][0], error] ) @@ -1547,38 +1475,21 @@ def _record( def write_record( directory: Path, record: dict[str, Any], bodies: Mapping[str, bytes] ) -> None: - """Writes `record` and its bodies, removing the body files an earlier - record of the same name named.""" + """Writes `record` and its bodies, removing the body files of its own an + earlier record of the same name named. A parent's body file it names + stays.""" path = directory / f"{record['name']}.json" if path.exists(): old = json.loads(path.read_text(encoding="utf-8")) for exchange in old["exchanges"]: body_file = exchange["response"].get("body_file") - if body_file: + if body_file and owns_body_file(record["name"], body_file): (directory / body_file).unlink(missing_ok=True) for body_file, data in bodies.items(): (directory / body_file).write_bytes(data) _write_json(path, record) -def _renamed_bodies( - parent: dict[str, Any], derived: Derived, name: str, directory: Path -) -> dict[str, bytes]: - """Copies of the parent's body files the derived exchanges keep, renamed - to start with `name`.""" - bodies: dict[str, bytes] = {} - renamed: dict[str, str] = {} - for exchange in derived.exchanges: - old = exchange["response"].get("body_file") - if old is None: - continue - if old not in renamed: - renamed[old] = name + old.removeprefix(parent["name"]) - bodies[renamed[old]] = (directory / old).read_bytes() - exchange["response"]["body_file"] = renamed[old] - return bodies - - def record_recorded(definition: Recorded, ctx: Context, directory: Path) -> None: recorded_at = _now() session = ctx.session(definition.name) @@ -1605,7 +1516,6 @@ def record_synthetic(definition: Synthetic, ctx: Context, directory: Path) -> No parent_path = directory / f"{definition.derived_from}.json" parent = json.loads(parent_path.read_text(encoding="utf-8")) derived = definition.derive(parent, ctx) - bodies = _renamed_bodies(parent, derived, definition.name, directory) origin = { "kind": "synthetic", "derived_from": definition.derived_from, @@ -1614,7 +1524,7 @@ def record_synthetic(definition: Synthetic, ctx: Context, directory: Path) -> No write_record( directory, _record(definition.name, definition.description, origin, derived), - bodies, + {}, ) @@ -1626,17 +1536,6 @@ def binary_total(directory: Path) -> int: ) -def _load_validator() -> Any: - path = Path(__file__).resolve().parent / "validate_client_contract.py" - spec = importlib.util.spec_from_file_location("validate_client_contract", path) - if spec is None or spec.loader is None: - raise SystemExit(f"cannot load {path}") - module = importlib.util.module_from_spec(spec) - sys.modules["validate_client_contract"] = module - spec.loader.exec_module(module) - return module - - def load_actions(package_dir: Path) -> dict[str, dict[str, Any]]: rows = json.loads((package_dir / "actions.json").read_text(encoding="utf-8"))[ "codes" @@ -1673,7 +1572,7 @@ def run_record(args: argparse.Namespace) -> int: return 1 if args.scenarios_dir is not None: return 0 - return _load_validator().main() + return validate_main() def run_openapi(args: argparse.Namespace) -> int: diff --git a/tools/tests/conftest.py b/tools/tests/conftest.py new file mode 100644 index 0000000..6af09f2 --- /dev/null +++ b/tools/tests/conftest.py @@ -0,0 +1,7 @@ +"""Puts `tools/` on the import path, where `capture_client_contract.py` +imports `validate_client_contract` from when it runs as a script.""" + +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) diff --git a/tools/tests/test_capture_client_contract.py b/tools/tests/test_capture_client_contract.py index f73c1c3..0aed3df 100644 --- a/tools/tests/test_capture_client_contract.py +++ b/tools/tests/test_capture_client_contract.py @@ -17,7 +17,7 @@ import json import subprocess import sys -from collections.abc import Mapping +from collections.abc import Callable, Mapping from pathlib import Path from typing import Any @@ -67,7 +67,7 @@ def __call__( assert method == request["method"] if "url" in request: assert headers == {}, "a signed download carries no client header" - assert capture.redact_signed_url(url) == request["url"] + assert capture.redact_external_url(url) == request["url"] elif "origin_path" in request: assert url == capture._origin(self.base_url) + request["origin_path"] else: @@ -193,15 +193,23 @@ def transport(method: str, url: str, **kwargs: Any) -> Any: "https://storage.googleapis.com/b/o?X-Goog-Algorithm=A&X-Goog-Signature=s", "https://storage.googleapis.com/b/o?X-Goog-Signature=redacted", ), - ("https://storage.googleapis.com/b/o", "https://storage.googleapis.com/b/o"), + ( + "https://storage.googleapis.com/b/o?GoogleAccessId=sa%40p.iam.gserviceaccount.com&Signature=s", + "https://storage.googleapis.com/b/o?X-Goog-Signature=redacted", + ), + ( + "https://storage.googleapis.com/b/o", + "https://storage.googleapis.com/b/o?X-Goog-Signature=redacted", + ), ( "/api/datasets/operations/op_1?page=2", "/api/datasets/operations/op_1?page=2", ), ], + ids=["v4-signed", "v2-signed", "no-query", "root-relative"], ) -def test_only_a_signed_query_is_redacted(url: str, expected: str) -> None: - assert capture.redact_signed_url(url) == expected +def test_every_absolute_url_loses_its_query(url: str, expected: str) -> None: + assert capture.redact_external_url(url) == expected @pytest.mark.parametrize( @@ -213,13 +221,10 @@ def test_each_derived_record_follows_from_its_parent(name: str) -> None: parent = _load(record["origin"]["derived_from"]) ctx = capture.Context(capture.DEV_BASE_URL, _Served(parent), ACTIONS) derived = definition.derive(copy.deepcopy(parent), ctx) - bodies = capture._renamed_bodies(parent, derived, name, SCENARIOS) assert record["origin"]["edit"] == definition.edit assert record["call"] == derived.call assert record["exchanges"] == derived.exchanges assert record["expect"] == derived.expect - for body_file, data in bodies.items(): - assert (SCENARIOS / body_file).read_bytes() == data def test_a_renamed_strict_field_ends_the_call_at_the_build() -> None: @@ -312,8 +317,13 @@ def record(*body_files: str) -> dict[str, Any]: {"s.parquet": b"1", "s-2.parquet": b"2"}, ) (tmp_path / "s-other.parquet").write_bytes(b"kept") + (tmp_path / "parent.parquet").write_bytes(b"kept") + capture.write_record( + tmp_path, record("s.parquet", "parent.parquet"), {"s.parquet": b"3"} + ) capture.write_record(tmp_path, record("s.parquet"), {"s.parquet": b"3"}) assert sorted(p.name for p in tmp_path.iterdir()) == [ + "parent.parquet", "s-other.parquet", "s.json", "s.parquet", @@ -340,16 +350,62 @@ def test_the_capture_environment_takes_nothing_else_from_the_caller( ) -def test_a_checkout_with_uncommitted_changes_is_refused(tmp_path: Path) -> None: +def _checkout(path: Path) -> Path: + """A git checkout with one committed file.""" + def git(*args: str) -> None: - subprocess.run( - ["git", "-C", str(tmp_path), *args], check=True, capture_output=True - ) + subprocess.run(["git", "-C", str(path), *args], check=True, capture_output=True) git("init", "-q") - (tmp_path / "f").write_text("a", encoding="utf-8") + (path / "f").write_text("a", encoding="utf-8") git("add", "f") git("-c", "user.name=t", "-c", "user.email=t@example.com", "commit", "-qm", "f") - (tmp_path / "f").write_text("b", encoding="utf-8") - with pytest.raises(SystemExit, match="uncommitted changes"): - capture.capture_openapi(tmp_path) + return path + + +@pytest.mark.parametrize( + ("change", "refusal"), + [ + ( + lambda p: (p / "f").write_text("b", encoding="utf-8"), + "uncommitted changes or untracked files", + ), + ( + lambda p: (p / "stray.py").write_text("", encoding="utf-8"), + "uncommitted changes or untracked files", + ), + ], + ids=["tracked-change", "untracked-file"], +) +def test_a_checkout_that_is_not_its_commit_is_refused( + tmp_path: Path, change: Callable[[Path], None], refusal: str +) -> None: + checkout = _checkout(tmp_path) + change(checkout) + with pytest.raises(SystemExit, match=refusal): + capture.capture_openapi(checkout) + + +def test_an_environment_out_of_step_with_the_lock_is_refused( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """uv reports the environment differs, so nothing runs in it.""" + checkout = _checkout(tmp_path) + run = subprocess.run + commands: list[list[str]] = [] + + def fake_run(args: list[str], **kwargs: Any) -> Any: + if args[0] != "uv": + return run(args, **kwargs) + commands.append(args) + return subprocess.CompletedProcess(args, 1, "", "Would install 3 packages") + + monkeypatch.setattr(capture.subprocess, "run", fake_run) + with pytest.raises(SystemExit, match=r"differs from its uv\.lock"): + capture.capture_openapi(checkout) + (command,) = commands + assert command[:2] == ["uv", "sync"] + assert {"--frozen", "--check"} <= set(command) + assert {a for a in command if a.startswith("--extra=")} == { + f"--extra={e}" for e in ("eval", "api", "engine", "datasets", "graph") + } diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index 12ef165..0f004e3 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -4,7 +4,8 @@ must be reported: a strict pointer the served document does not hold or holds as optional or nullable, an action row out of step with the code registry, a recorded body the served document rejects, a scenario whose steps or body -files do not fit, and a ref example with the wrong verdict. +files do not fit, an outcome its exchanges and actions.json do not give, an +unredacted URL, and a ref example with the wrong verdict. Each case validates a whole copy of the contract, the served document's bodies included, which takes about a third of a second. @@ -32,6 +33,7 @@ _SEARCH = "scenarios/search-place-ambiguous.json" _FETCH = "scenarios/fetch-spec-known-sentence.json" +_MIXED = "scenarios/answer-mixed-fetch-raises.json" @pytest.fixture @@ -97,6 +99,20 @@ def _set_body(index: int, change: Callable[[Any], None]) -> Callable[[Any], None return lambda doc: change(doc["exchanges"][index]["response"]["json"]) +def _set_property(schema: str, name: str, value: Any) -> Callable[[Any], None]: + return lambda doc: doc["components"]["schemas"][schema]["properties"].update( + {name: value} + ) + + +def _set_outcome(index: int, change: Callable[[Any], None]) -> Callable[[Any], None]: + return lambda doc: change(doc["expect"][index]) + + +def _first_gap(**fields: Any) -> Callable[[Any], None]: + return _set_outcome(0, lambda o: o["answer"]["gaps"][0].update(fields)) + + @pytest.mark.parametrize( ("target", "change", "expected"), [ @@ -200,6 +216,99 @@ def _set_body(index: int, change: Callable[[Any], None]) -> Callable[[Any], None ), "not an active code registered with status 404", ), + ( + "served/openapi.json", + _set_property("Manifest", "content_version", {"title": "Content Version"}), + "content_version admits null", + ), + ( + "served/openapi.json", + _set_property( + "ArtifactEntryModel", "url", {"anyOf": [{"type": "string"}, {}]} + ), + "url admits null", + ), + ( + "scenarios/fetch-ref-unknown-version.json", + _set_outcome(0, lambda o: o["error"].update({"class": "ServerError"})), + "step 0 expects", + ), + ( + _MIXED, + _first_gap(kind="no_data"), + "step 0 expects", + ), + ( + "scenarios/choose-place-one-part.json", + _first_gap(options=7), + "step 0 expects", + ), + ( + _MIXED, + _set_outcome(0, lambda o: o["answer"].update(complete=True)), + "step 0 expects", + ), + ( + "actions.json", + _set_action("snapshot_not_found", action="report"), + "scenarios/fetch-ref-unknown-version.json: step 0 expects", + ), + ( + "actions.json", + _set_action("variable_not_resolved", gap_kind="no_data"), + "scenarios/answer-mixed-fetch-raises.json: step 0 expects", + ), + ( + _SEARCH, + _set_body(0, lambda body: body.pop("kind")), + "step 0 expects", + ), + ( + "scenarios/fetch-ref.json", + _set_outcome( + 0, + lambda o: o["dataset"]["members"][0].update( + content_version="cv_" + "0" * 32 + ), + ), + "step 0 expects", + ), + ( + "scenarios/answer-several-readings-folded.json", + _set_outcome(1, lambda o: o["dataset"]["columns"].pop(0)), + "the part column comes first", + ), + ( + _SEARCH, + lambda doc: doc["exchanges"].append(doc["exchanges"][0]), + "never make exchanges 1 to 1", + ), + ( + _FETCH, + lambda doc: doc["exchanges"].pop(0), + "do not fit the steps", + ), + ( + "scenarios/fetch-ref.json", + lambda doc: doc["exchanges"][1]["response"]["headers"].update( + location="https://storage.googleapis.com/b/o?GoogleAccessId=sa&Signature=s" + ), + "keeps a query other than", + ), + ( + "scenarios/fetch-ref.json", + lambda doc: doc["exchanges"][2]["request"].update( + url="https://storage.googleapis.com/b/o" + ), + "keeps a query other than", + ), + ( + "scenarios/fetch-null-member.json", + lambda doc: doc["exchanges"][3]["response"].update( + body_file="fetch-ref.parquet" + ), + "neither the scenario's own nor one its parent names", + ), (_SEARCH, lambda doc: doc.update(name="search-other"), "differs"), ( _SEARCH, @@ -221,7 +330,7 @@ def _set_body(index: int, change: Callable[[Any], None]) -> Callable[[Any], None ( _FETCH, lambda doc: doc["exchanges"][2]["response"].update(body_file="other.bin"), - "does not start with the scenario's name", + "neither the scenario's own", ), ( "refs/ref-one-member.json", @@ -263,6 +372,22 @@ def _set_body(index: int, change: Callable[[Any], None]) -> Callable[[Any], None "unrouted-path", "unserved-method", "problem-code-wrong-status", + "strict-member-untyped", + "strict-member-open-union", + "expect-wrong-error-class", + "expect-wrong-gap-kind", + "expect-wrong-option-count", + "expect-wrong-complete", + "expect-stale-after-action-change", + "expect-stale-after-gap-kind-change", + "answer-without-kind", + "expect-wrong-content-version", + "stacked-without-part-column", + "exchange-never-made", + "exchanges-unfit", + "location-v2-signed", + "signed-url-without-redacted-query", + "body-file-of-another-scenario", "scenario-name-mismatch", "step-out-of-order", "outcome-count-mismatch", diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index de9cff9..6073eaa 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -27,11 +27,17 @@ - Each scenario's file name matches its `name`, names are unique, `expect` holds one outcome per step, a step that acts on an earlier result follows one, a synthetic scenario derives from a recorded one, and every body file - is named by its scenario and exists. In a recorded scenario each API request - matches a route and method in `served/openapi.json`, its JSON body validates - against the route's request schema, each JSON response body validates - against the route's schema for its status, and a problem document's `code` - is an active code registered with that status. + exists and is the scenario's own or, for a synthetic scenario, one its + parent names. In a recorded scenario each API request matches a route and + method in `served/openapi.json`, its JSON body validates against the + route's request schema, each JSON response body validates against the + route's schema for its status, and a problem document's `code` is an active + code registered with that status. +- Each scenario's `expect` equals the outcomes its steps reach over its + exchanges, with error classes and gap kinds from `actions.json`, as + `expected_outcomes` derives them; a dataset's rows and columns are left to + the Parquet bodies. Every absolute URL a record holds, a `url` request or a + `location` header, has the query `X-Goog-Signature=redacted`. - Each ref example's file name matches its `name` and gets the verdict it states: from `dataset-ref.schema.json`, then from the rules that each member's definition carries its own `spec_id` and that members hold @@ -42,7 +48,8 @@ A recorded body is checked with one allowance: a required member whose schema admits null may be absent, because the server leaves null members out of the bodies it serves. It does not import `dfo_client_contract`, whose tests replay -the rule vectors. +the rule vectors. `tools/capture_client_contract.py` imports the outcome +rules from here, so the records are written by the code that checks them. """ from __future__ import annotations @@ -50,7 +57,8 @@ import json import re import sys -from collections.abc import Iterator +from collections.abc import Iterator, Mapping, Sequence +from dataclasses import dataclass from pathlib import Path from typing import Any from urllib.parse import urlsplit @@ -158,16 +166,16 @@ def _expand(openapi: dict[str, Any], schema: Any) -> Iterator[dict[str, Any]]: yield from _expand(openapi, branch) -def _admits_null(openapi: dict[str, Any], schema: Any) -> bool: - for branch in _expand(openapi, schema): - kind = branch.get("type") - if kind == "null" or (isinstance(kind, list) and "null" in kind): - return True - if branch.get("nullable") is True or branch.get("const", 0) is None: - return True - if None in branch.get("enum", []): - return True - return False +def _openapi_registry(openapi: dict[str, Any]) -> Registry: + return Registry().with_resource(_OPENAPI_URI, DRAFT202012.create_resource(openapi)) + + +def _admits_null(registry: Registry, pointer: str) -> bool: + """Whether the schema at `pointer` accepts null. A schema with no type, + or a union with an open branch, accepts null as well as one that names + it.""" + schema = {"$ref": f"{_OPENAPI_URI}#{pointer}"} + return jsonschema.Draft202012Validator(schema, registry=registry).is_valid(None) def _allowed_values(openapi: dict[str, Any], schema: Any) -> set[str]: @@ -198,6 +206,7 @@ def _check_strict_fields( document: dict[str, Any], openapi: dict[str, Any] ) -> list[str]: problems = [] + registry = _openapi_registry(openapi) for kind in ("required", "enums"): pointers = [entry["pointer"] for entry in document[kind]] problems.extend( @@ -234,7 +243,7 @@ def _check_strict_fields( problems.append( f"strict-fields.json: {pointer} is not required in {schema_name}" ) - if _admits_null(openapi, prop): + if _admits_null(registry, pointer): problems.append(f"strict-fields.json: {pointer} admits null") return problems @@ -311,9 +320,7 @@ class _Routes: def __init__(self, openapi: dict[str, Any]) -> None: self.openapi = openapi self._templates = [(t, t.split("/")) for t in openapi["paths"]] - registry = Registry().with_resource( - _OPENAPI_URI, DRAFT202012.create_resource(openapi) - ) + registry = _openapi_registry(openapi) self._validator = jsonschema.validators.extend( jsonschema.Draft202012Validator, {"required": _required_unless_nullable} ) @@ -334,6 +341,34 @@ def template(self, path: str) -> str | None: ] return min(matches, key=lambda t: t.count("{"), default=None) + def operation( + self, base_path: str, request: dict[str, Any] + ) -> tuple[str, str, dict[str, Any] | None] | None: + """The route template an API request matches, its method's JSON + pointer under `/paths`, and the operation it serves; None for a + request outside the API or one that matches no route.""" + if "url" in request: + return None + template = self.template(_api_path(base_path, request)) + if template is None: + return None + method = request["method"].lower() + route = f"/paths/{_pointer_token(template)}/{method}" + return template, route, self.openapi["paths"][template].get(method) + + def response_schema( + self, base_path: str, request: dict[str, Any], status: int + ) -> dict[str, Any] | None: + """The JSON body schema `request`'s route declares for `status`.""" + found = self.operation(base_path, request) + if found is None or found[2] is None: + return None + responses = found[2].get("responses", {}) + declared = str(status) if str(status) in responses else "default" + content = responses.get(declared, {}).get("content", {}) + media = _body_schema(content) + return None if media is None else content[media].get("schema") + def validate(self, pointer: str, body: Any) -> list[str]: validator = self._validator( {"$ref": f"{_OPENAPI_URI}#{pointer}"}, registry=self._registry @@ -361,6 +396,13 @@ def _required_unless_nullable( yield jsonschema.ValidationError(f"{name!r} is a required property") +def _api_path(base_path: str, request: dict[str, Any]) -> str: + """The path an API request reaches: a `path` under the base URL's path, + or an `origin_path` as it stands.""" + raw = base_path + request["path"] if "path" in request else request["origin_path"] + return urlsplit(raw).path + + def _pointer_token(text: str) -> str: return text.replace("~", "~0").replace("/", "~1") @@ -382,18 +424,15 @@ def _check_exchange( request, response = exchange["request"], exchange["response"] if "url" in request: return [] - raw = base_path + request["path"] if "path" in request else request["origin_path"] - path = urlsplit(raw).path - template = routes.template(path) - if template is None: + found = routes.operation(base_path, request) + if found is None: + path = _api_path(base_path, request) return [f"{label}: {path} matches no route in served/openapi.json"] - method = request["method"].lower() - operation = routes.openapi["paths"][template].get(method) + template, route, operation = found if operation is None: return [f"{label}: {template} serves no {request['method']}"] problems = [] - route = f"/paths/{_pointer_token(template)}/{method}" if "json" in request: media = _body_schema(operation.get("requestBody", {}).get("content", {})) if media is None: @@ -449,17 +488,599 @@ def _check_problem_code( return [f"{label}: problem code {body['code']!r} is not in the registry"] +# --- outcomes --------------------------------------------------------------- +# +# A client's outcome for each step follows from the exchanges and from +# `actions.json`. The functions here derive it; the validator checks each +# record's `expect` against them, and `tools/capture_client_contract.py` +# imports them to write `expect` when it records. + +# The class each action in actions.json maps to, as the contract README states. +ACTION_CLASSES = { + "fix_request": "InvalidRequestError", + "check_id": "NotFoundError", + "choose": "IncompleteAnswerError", + "ask_data_question": "IncompleteAnswerError", + "take_newest_version": "VersionUnavailableError", + "log_in": "AuthenticationError", + "request_scope": "PermissionDeniedError", + "wait": "RateLimitError", + "wait_for_reset": "QuotaExceededError", + "report": "ServerError", + "upgrade": "ContractError", +} +# The class of a refusal whose code has no row, by HTTP status. Any other 5xx +# is a ServerError and any other 4xx an InvalidRequestError. +STATUS_CLASSES = { + 400: "InvalidRequestError", + 401: "AuthenticationError", + 403: "PermissionDeniedError", + 404: "NotFoundError", + 422: "InvalidRequestError", + 429: "RateLimitError", +} + + +def gap_kinds(actions: Mapping[str, Mapping[str, Any]]) -> dict[str, str]: + """The gap kind of each no_data reason in actions.json, keyed by code.""" + return {code: row["gap_kind"] for code, row in actions.items() if "gap_kind" in row} + + +def refusal_code(body: Any) -> str | None: + """A refusal's code: a problem document's `code`, or the `error` member + of the website proxy's own `{error, retry, detail}` body.""" + if not isinstance(body, dict): + return None + code = body.get("code", body.get("error")) + return code if isinstance(code, str) else None + + +def error_class( + status: int, code: str | None, actions: Mapping[str, Mapping[str, Any]] +) -> str: + """The error class a client raises for a refusal: its code's action, else + its HTTP status.""" + row = actions.get(code) if code is not None else None + if row is not None: + return ACTION_CLASSES[row["action"]] + fallback = "ServerError" if status >= 500 else "InvalidRequestError" + return STATUS_CLASSES.get(status, fallback) + + +def error_outcome(error: str, code: str | None = None) -> dict[str, Any]: + return {"error": {"class": error, "code": code}} + + +@dataclass(frozen=True, slots=True) +class Answer: + """A search answer as a client holds it: the response body, its parts, + sentence and status, which a local choice replaces.""" + + body: dict[str, Any] + parts: list[dict[str, Any]] + sentence: str | None + status: str | None + + +def answer_from_body(body: dict[str, Any]) -> Answer: + return Answer( + body, body.get("parts", []), body.get("rendered_sentence"), body.get("status") + ) + + +def candidate_answer(answer: Answer, part: int, candidate: int) -> Answer: + """The answer a choice among one part's candidates makes with no request: + that part definite on the chosen spec, with that spec's sentence.""" + chosen = answer.parts[part] + spec = chosen["candidates"]["specs"][candidate] + definite = { + "status": "definite", + "variable_text": chosen["variable_text"], + "spec": spec, + } + return Answer( + answer.body, [definite], spec["resolved"]["rendered_sentence"], "definite" + ) + + +def answer_gaps(answer: Answer, kinds: Mapping[str, str]) -> list[dict[str, Any]]: + """Each part without a reading: a candidates part is a choice among its + specs; a no_data part takes its reason's gap kind, or `timed_out` when the + answer timed out; a part of unknown status is an `unknown` gap.""" + timed_out = answer.body.get("diagnostics", {}).get("timed_out") is True + gaps = [] + for index, part in enumerate(answer.parts): + match part.get("status"): + case "definite": + continue + case "candidates": + kind, options = "choice", len(part["candidates"]["specs"]) + case "no_data": + no_data = part["no_data"] + kind = ( + "timed_out" + if timed_out + else kinds.get(no_data["reason"], "no_data") + ) + options = len(no_data.get("options", [])) + case "unsupported": + kind, options = "unsupported", 0 + case _: + kind, options = "unknown", 0 + gaps.append({"part": index, "kind": kind, "options": options}) + return gaps + + +def answer_members(answer: Answer) -> list[tuple[list[str], dict[str, Any]]]: + """One member per distinct spec_id of the definite parts, in part order: + the variable text of every part it answers, and the first such part's + spec.""" + members: dict[str, tuple[list[str], dict[str, Any]]] = {} + for part in answer.parts: + if part.get("status") != "definite": + continue + spec = part["spec"] + members.setdefault(spec["spec_id"], ([], spec))[0].append(part["variable_text"]) + return list(members.values()) + + +def answer_outcome(answer: Answer, kinds: Mapping[str, str]) -> dict[str, Any]: + """An answer outcome. A declined or catalogue answer is never complete.""" + gaps = answer_gaps(answer, kinds) + outcome: dict[str, Any] = {"kind": answer.body["kind"]} + if answer.status is not None: + outcome["status"] = answer.status + outcome["sentence"] = answer.sentence + outcome["complete"] = answer.body["kind"] == "resolution" and not gaps + outcome["specs"] = [spec["spec_id"] for _, spec in answer_members(answer)] + outcome["gaps"] = gaps + return {"answer": outcome} + + +def dataset_summary( + members: Sequence[Mapping[str, Any]], missing: Sequence[Mapping[str, Any]] +) -> dict[str, Any]: + """A dataset outcome's members and gaps, without the rows and columns the + Parquet bodies hold.""" + return { + "complete": not missing, + "members": [ + { + "parts": list(member["parts"]), + "spec_id": member["spec_id"], + "content_version": member["content_version"], + "sentence": member["sentence"], + } + for member in members + ], + "missing": [{"part": gap["part"], "kind": gap["kind"]} for gap in missing], + } + + +def _strict_members(strict: dict[str, Any]) -> dict[str, list[str]]: + """The required strict members of each component schema.""" + members: dict[str, list[str]] = {} + for entry in strict["required"]: + match = _STRICT_POINTER.match(entry["pointer"]) + if match is not None: + members.setdefault(match.group(1), []).append(match.group(2)) + return members + + +def strict_gaps( + openapi: dict[str, Any], + members: Mapping[str, Sequence[str]], + schema: Any, + body: Any, + where: str = "", +) -> list[str]: + """The strict members `body` lacks or holds as null, read through + `schema`: each component schema it reaches names its own, and a + discriminated union whose discriminator `body` lacks is a gap. A + discriminator value the union does not map, and a union without a + discriminator that offers more than one object branch, reach nothing.""" + if not isinstance(schema, dict): + return [] + ref = schema.get("$ref") + if isinstance(ref, str) and ref.startswith("#/"): + gaps = [] + if isinstance(body, dict): + gaps = [ + f"{where}/{name}" + for name in members.get(ref.rsplit("/", 1)[-1], ()) + if body.get(name) is None + ] + return gaps + strict_gaps( + openapi, members, _resolve(openapi, ref[1:]), body, where + ) + discriminator = schema.get("discriminator") + if isinstance(discriminator, dict) and isinstance(body, dict): + name = discriminator["propertyName"] + if body.get(name) is None: + return [f"{where}/{name}"] + target = discriminator.get("mapping", {}).get(body[name]) + if target is None: + return [] + return strict_gaps(openapi, members, {"$ref": target}, body, where) + gaps = [] + for keyword in ("anyOf", "oneOf"): + branches = [b for b in schema.get(keyword, []) if b.get("type") != "null"] + if len(branches) == 1: + gaps.extend(strict_gaps(openapi, members, branches[0], body, where)) + for branch in schema.get("allOf", []): + gaps.extend(strict_gaps(openapi, members, branch, body, where)) + if isinstance(body, dict): + for name, member in schema.get("properties", {}).items(): + if name in body: + gaps.extend( + strict_gaps(openapi, members, member, body[name], f"{where}/{name}") + ) + if isinstance(body, list) and "items" in schema: + for index, item in enumerate(body): + gaps.extend( + strict_gaps(openapi, members, schema["items"], item, f"{where}/{index}") + ) + return gaps + + +class _StepEndedError(Exception): + """A step ends in `outcome`, an error a client raises.""" + + def __init__(self, outcome: dict[str, Any]) -> None: + super().__init__(outcome) + self.outcome = outcome + + +class _UnfitError(Exception): + """The exchanges do not fit the steps, so no outcome follows from them.""" + + +_SEARCH = ("POST", "/search/resolve") +_BUILD = ("POST", "/datasets") +_POLL = ("GET", "/datasets/operations/") +_MANIFEST = {"$ref": "#/components/schemas/Manifest"} + + +@dataclass +class _Replay: + """A record's steps run over its exchanges the way a client makes them, + each giving the outcome it reaches.""" + + exchanges: list[dict[str, Any]] + routes: _Routes + base_path: str + members: Mapping[str, Sequence[str]] + actions: Mapping[str, Mapping[str, Any]] + cursor: int = 0 + answer: Answer | None = None + minted: tuple[dict[str, Any], dict[str, Any]] | None = None + + @property + def kinds(self) -> dict[str, str]: + return gap_kinds(self.actions) + + # -- exchanges -- + + def call(self, method: str, target: str) -> dict[str, Any]: + """The exchange a client acts on for its next request: the last of a + run that repeats one request, each refusal before it a retry. + `target` is a path under the base URL, a path prefix ending in `/`, + `origin` for a root-relative URL or `url` for an absolute one.""" + if self.cursor >= len(self.exchanges): + raise _UnfitError(f"the steps make a {method} {target} the record lacks") + exchange = self.exchanges[self.cursor] + request = exchange["request"] + actual = request.get("path") or ( + "origin" if "origin_path" in request else "url" + ) + fits = request["method"] == method and ( + actual == target or (target.endswith("/") and actual.startswith(target)) + ) + if not fits: + raise _UnfitError( + f"exchange {self.cursor} is {request['method']} {actual}, where the " + f"steps make a {method} {target}" + ) + self.cursor += 1 + while ( + exchange["response"]["status"] >= 400 + and self.cursor < len(self.exchanges) + and self.exchanges[self.cursor]["request"] == request + ): + exchange = self.exchanges[self.cursor] + self.cursor += 1 + return exchange + + def acted_on(self, exchange: dict[str, Any]) -> Any: + """The JSON body a client acts on. A refusal raises its error, and a + body without a strict member raises ContractError.""" + response = exchange["response"] + body = response.get("json") + if response["status"] >= 400: + code = refusal_code(body) + error = error_class(response["status"], code, self.actions) + raise _StepEndedError(error_outcome(error, code)) + schema = self.routes.response_schema( + self.base_path, exchange["request"], response["status"] + ) + self.strict(schema, body) + return body + + def strict(self, schema: Any, body: Any) -> None: + if strict_gaps(self.routes.openapi, self.members, schema, body): + raise _StepEndedError(error_outcome("ContractError")) + + def download(self) -> None: + """The files route, then its signed URL; a refused signed URL asks the + files route again.""" + while True: + self.acted_on(self.call("GET", "origin")) + if self.call("GET", "url")["response"]["status"] < 400: + return + + def resolve(self) -> Answer: + return answer_from_body(self.acted_on(self.call(*_SEARCH))) + + def wait(self, operation: dict[str, Any]) -> dict[str, Any]: + """Polls until the operation is done. The done resource's manifest is + untyped in the served document, so it is checked as a Manifest.""" + manifest = None + while operation["status"] != "done": + resource = self.acted_on(self.call(*_POLL)) + operation, manifest = resource["operation"], resource.get("manifest") + if not isinstance(manifest, dict): + raise _StepEndedError(error_outcome("ContractError")) + self.strict(_MANIFEST, manifest) + return manifest + + def build(self, parts: list[str], spec: dict[str, Any]) -> dict[str, Any]: + """One member: the build, then the member's files.""" + body = self.acted_on(self.call(*_BUILD)) + manifest = self.wait(body["operation"]) if "operation" in body else body + return self.member(parts, spec, manifest) + + def member( + self, parts: list[str], spec: dict[str, Any], manifest: dict[str, Any] + ) -> dict[str, Any]: + """A built member: its sentence from Search when the build changed the + spec_id or the client lacks it, then the download.""" + built = manifest["definition"]["spec_id"] + sentence = spec.get("sentence") + if built != spec["spec_id"] or sentence is None: + (part,) = self.resolve().parts + sentence = part["spec"]["resolved"]["rendered_sentence"] + self.download() + return { + "parts": parts, + "spec_id": built, + "content_version": manifest["content_version"], + "sentence": sentence, + } + + # -- steps -- + + def step(self, step: dict[str, Any]) -> dict[str, Any]: + """The outcome `step` reaches.""" + op = step["op"] + if op == "fetch": + op = ( + "fetch_ref" if "ref" in step else "fetch_spec" if "spec" in step else op + ) + try: + return getattr(self, f"_{op}")(step) + except _StepEndedError as ended: + if op in {"search", "choose"}: + self.answer = None + return ended.outcome + + def _answered(self) -> Answer: + if self.answer is None: + raise _UnfitError("the step follows no answer") + return self.answer + + def _search(self, step: dict[str, Any]) -> dict[str, Any]: + self.answer = self.resolve() + return answer_outcome(self.answer, self.kinds) + + def _choose(self, step: dict[str, Any]) -> dict[str, Any]: + answer = self._answered() + part, option = step.get("part"), step["option"] + if isinstance(part, str): + part = next( + i for i, p in enumerate(answer.parts) if p.get("variable_text") == part + ) + index = answer_gaps(answer, self.kinds)[0]["part"] if part is None else part + chosen = answer.parts[index] + if chosen.get("status") == "candidates" and len(answer.parts) == 1: + if not isinstance(option, int): + raise _UnfitError("candidates are chosen by index") + self.answer = candidate_answer(answer, index, option) + else: + options = chosen.get("no_data", {}).get("options", []) + if not any(option in (i, o.get("label")) for i, o in enumerate(options)): + raise _StepEndedError(error_outcome("InvalidRequestError")) + self.answer = self.resolve() + return answer_outcome(self.answer, self.kinds) + + def _fetch(self, step: dict[str, Any]) -> dict[str, Any]: + answer = self._answered() + if answer.body.get("kind") != "resolution": + raise _StepEndedError(error_outcome("DeclinedError")) + gaps = answer_gaps(answer, self.kinds) + if gaps and not step.get("partial", False): + raise _StepEndedError(error_outcome("IncompleteAnswerError")) + members = [ + self.build( + parts, + { + "spec_id": spec["spec_id"], + "sentence": spec["resolved"]["rendered_sentence"], + }, + ) + for parts, spec in answer_members(answer) + ] + return {"dataset": dataset_summary(members, gaps)} + + def _fetch_spec(self, step: dict[str, Any]) -> dict[str, Any]: + return {"dataset": dataset_summary([self.build([], step["spec"])], [])} + + def _fetch_ref(self, step: dict[str, Any]) -> dict[str, Any]: + members = [] + for member in step["ref"]["members"]: + spec_id, version = member["spec"]["spec_id"], member["content_version"] + self.acted_on(self.call("GET", f"/datasets/{spec_id}/{version}")) + self.download() + members.append({**member, "spec_id": spec_id}) + return {"dataset": dataset_summary(members, [])} + + def _mint(self, step: dict[str, Any]) -> dict[str, Any]: + operation = self.acted_on(self.call(*_BUILD))["operation"] + self.minted = (step["spec"], operation) + return {"operation": {k: operation[k] for k in ("operation_id", "status")}} + + def _result(self, step: dict[str, Any]) -> dict[str, Any]: + if self.minted is None: + raise _UnfitError("result follows no mint") + spec, operation = self.minted + member = self.member([], spec, self.wait(operation)) + return {"dataset": dataset_summary([member], [])} + + +def expected_outcomes( + record: dict[str, Any], + *, + routes: _Routes, + base_path: str, + strict: dict[str, Any], + actions: Mapping[str, Mapping[str, Any]], +) -> list[dict[str, Any]]: + """The outcome each of `record`'s steps reaches over its exchanges, and + over `actions` for error classes and gap kinds. A dataset outcome holds + what `dataset_summary` gives, without rows and columns. + + Raises: + ValueError: The exchanges do not fit the steps. + """ + replay = _Replay( + record["exchanges"], routes, base_path, _strict_members(strict), actions + ) + try: + outcomes = [replay.step(step) for step in record["call"]] + except (_UnfitError, KeyError, IndexError, StopIteration, ValueError) as exc: + raise ValueError(f"the exchanges do not fit the steps: {exc!r}") from exc + if replay.cursor != len(replay.exchanges): + raise ValueError( + f"the steps never make exchanges {replay.cursor} to " + f"{len(replay.exchanges) - 1}" + ) + return outcomes + + +def owns_body_file(name: str, body_file: str) -> bool: + """Whether `body_file` is one the scenario `name` writes: `.`, + or `-.` for its n-th body.""" + return ( + re.fullmatch(rf"{re.escape(name)}(-[0-9]+)?\.[a-z0-9]+", body_file) is not None + ) + + +_REDACTED_QUERY = "X-Goog-Signature=redacted" + + +def _check_redaction(label: str, exchange: dict[str, Any]) -> list[str]: + """An absolute URL a record holds, a `url` request or a `location` + header, keeps no query but the redacted signature.""" + urls = [ + exchange["request"].get("url"), + exchange["response"].get("headers", {}).get("location"), + ] + return [ + f"{label}: {url.split('?', 1)[0]} keeps a query other than {_REDACTED_QUERY}" + for url in urls + if isinstance(url, str) + and urlsplit(url).netloc + and urlsplit(url).query != _REDACTED_QUERY + ] + + +def _check_body_files( + file_name: str, + record: dict[str, Any], + parent: dict[str, Any] | None, + directory: Path, +) -> list[str]: + """A body file is the scenario's own, or for a synthetic scenario one + its parent names, and it exists.""" + inherited = ( + {e["response"].get("body_file") for e in parent["exchanges"]} + if parent + else set() + ) + problems = [] + for index, exchange in enumerate(record["exchanges"]): + body_file = exchange["response"].get("body_file") + if body_file is None: + continue + if not owns_body_file(record["name"], body_file) and body_file not in inherited: + problems.append( + f"scenarios/{file_name}: exchange {index}: body file {body_file!r} is " + "neither the scenario's own nor one its parent names" + ) + if not (directory / body_file).is_file(): + problems.append( + f"scenarios/{file_name}: exchange {index}: body file " + f"{body_file!r} is missing" + ) + return problems + + +def _check_expect( + file_name: str, + record: dict[str, Any], + derived: list[dict[str, Any]], +) -> list[str]: + """Each outcome in `expect` against the one its exchanges give. A dataset + outcome's rows and columns are the Parquet bodies' and are not derived, + except that several members put the `part` column first.""" + problems = [] + for index, (stated, wanted) in enumerate( + zip(record["expect"], derived, strict=False) + ): + compared = stated + if "dataset" in stated and "dataset" in wanted: + dataset = stated["dataset"] + compared = { + "dataset": { + k: v for k, v in dataset.items() if k not in {"rows", "columns"} + } + } + several = len(dataset["members"]) > 1 + if (dataset["columns"][:1] == ["part"]) != several: + problems.append( + f"scenarios/{file_name}: step {index}: the part column comes " + "first exactly when the dataset has several members" + ) + if compared != wanted: + problems.append( + f"scenarios/{file_name}: step {index} expects " + f"{json.dumps(compared)[:300]}, but its exchanges give " + f"{json.dumps(wanted)[:300]}" + ) + return problems + + def _check_scenarios( validator: jsonschema.Draft202012Validator, openapi: dict[str, Any], registry: dict[str, Any], + strict: dict[str, Any], + actions: Mapping[str, Mapping[str, Any]], ) -> list[str]: directory = PACKAGE_DIR / "scenarios" paths = sorted(directory.glob("*.json")) problems = [] if paths else ["scenarios: no scenario records found"] routes = _Routes(openapi) records: dict[str, dict[str, Any]] = {} - named_files: set[str] = set() for path in paths: try: @@ -478,48 +1099,55 @@ def _check_scenarios( problems.append(f"scenarios/{path.name}: name {name!r} repeats") records[name] = record problems.extend(_check_steps(path.name, record)) - - for index, exchange in enumerate(record["exchanges"]): - body_file = exchange["response"].get("body_file") - if body_file is None: - continue - named_files.add(body_file) - if not body_file.startswith(f"{name}"): - problems.append( - f"scenarios/{path.name}: exchange {index}: body file " - f"{body_file!r} does not start with the scenario's name" - ) - if not (directory / body_file).is_file(): - problems.append( - f"scenarios/{path.name}: exchange {index}: body file " - f"{body_file!r} is missing" - ) - - origin = record["origin"] - if origin["kind"] != "recorded": - continue - base_path = urlsplit(origin["base_url"]).path.rstrip("/") for index, exchange in enumerate(record["exchanges"]): problems.extend( - _check_exchange( - f"scenarios/{path.name}: exchange {index}", - exchange, - base_path, - routes, - registry, - ) + _check_redaction(f"scenarios/{path.name}: exchange {index}", exchange) ) + named_files: set[str] = set() for name, record in records.items(): + file_name = f"{name}.json" origin = record["origin"] - if origin["kind"] != "synthetic": - continue - parent = records.get(origin["derived_from"]) - if parent is None or parent["origin"]["kind"] != "recorded": - problems.append( - f"scenarios/{name}.json: derived_from {origin['derived_from']!r} " - "is not a recorded scenario" + parent = None + if origin["kind"] == "synthetic": + parent = records.get(origin["derived_from"]) + if parent is None or parent["origin"]["kind"] != "recorded": + problems.append( + f"scenarios/{file_name}: derived_from {origin['derived_from']!r} " + "is not a recorded scenario" + ) + continue + named_files.update( + e["response"]["body_file"] + for e in record["exchanges"] + if "body_file" in e["response"] + ) + problems.extend(_check_body_files(file_name, record, parent, directory)) + recorded = parent or record + base_path = urlsplit(recorded["origin"]["base_url"]).path.rstrip("/") + if origin["kind"] == "recorded": + for index, exchange in enumerate(record["exchanges"]): + problems.extend( + _check_exchange( + f"scenarios/{file_name}: exchange {index}", + exchange, + base_path, + routes, + registry, + ) + ) + try: + derived = expected_outcomes( + record, + routes=routes, + base_path=base_path, + strict=strict, + actions=actions, ) + except ValueError as exc: + problems.append(f"scenarios/{file_name}: {exc}") + continue + problems.extend(_check_expect(file_name, record, derived)) problems.extend( f"scenarios/{p.name}: no scenario names this body file" @@ -651,7 +1279,13 @@ def validate() -> list[str]: problems.extend(errors or _check_actions(actions, registry)) problems.extend( - _check_scenarios(validators["scenario.schema.json"], openapi, registry) + _check_scenarios( + validators["scenario.schema.json"], + openapi, + registry, + strict, + {row["code"]: row for row in actions["codes"]}, + ) ) problems.extend(_check_refs(validators["dataset-ref.schema.json"])) problems.extend(_check_rules(validators["rules/rules.schema.json"])) From f8b37b95ebe41ef83a0a58a91e5e9732e8a2edaa Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Tue, 20 Oct 2026 22:22:58 +0200 Subject: [PATCH 12/39] feat(client-contract): add scenarios for every answer and choice rule Nineteen scenarios, four recorded on dev and fifteen derived from recorded parents, cover a timed-out and an unsupported part, an unknown answer kind, every choice refusal, a choice named by a mention, a several-part candidates choice, a candidates part left alone beside a chosen one, a placeholder for a part with no restatement, and the SearchWarning rule. An unchosen candidates part posts its candidate set in the server's order. The validator checks every Search request a record holds against the input the rules derive, and pins the part column of a stacked dataset. --- python/client-contract/CHANGELOG.md | 4 +- python/client-contract/README.md | 17 +- .../dfo_client_contract/scenario.schema.json | 32 +- .../answer-candidates-choose-fetch.json | 3 +- .../scenarios/answer-definite-fetch.json | 3 +- .../scenarios/answer-mixed-fetch-partial.json | 3 +- .../answer-several-readings-folded.json | 13 +- .../scenarios/answer-timed-out.json | 3574 ++++ .../scenarios/answer-unknown-kind.json | 208 + .../scenarios/answer-unsupported-part.json | 3569 ++++ .../choose-candidate-two-parts-2.parquet | Bin 0 -> 10503 bytes .../scenarios/choose-candidate-two-parts.json | 17701 ++++++++++++++++ .../choose-candidate-two-parts.parquet | Bin 0 -> 9453 bytes .../scenarios/choose-part-by-mention.json | 3516 +++ .../choose-place-beside-definite.json | 9827 +++++++++ .../choose-refused-answered-part.json | 3576 ++++ ...hoose-refused-mention-names-two-parts.json | 436 + .../scenarios/choose-refused-no-choice.json | 3700 ++++ .../scenarios/choose-refused-no-options.json | 228 + .../choose-refused-option-out-of-range.json | 2385 +++ .../scenarios/choose-refused-two-choices.json | 351 + .../choose-refused-unknown-label.json | 265 + .../choose-refused-unknown-part.json | 3576 ++++ .../scenarios/fetch-null-member.json | 3 +- .../fetch-partial-nothing-answered.json | 228 + .../scenarios/fetch-retry-after-504.json | 3 +- .../scenarios/fetch-strict-info-notice.json | 4542 ++++ .../resubmit-candidates-sibling.json | 5641 +++++ ...ubmit-placeholder-without-restatement.json | 3324 +++ .../scenarios/search-warning-top5.json | 4006 ++++ .../scenarios/search-warning-top5.parquet | Bin 0 -> 10828 bytes tools/README.md | 2 +- tools/capture_client_contract.py | 519 +- tools/tests/test_capture_client_contract.py | 36 +- tools/tests/test_validate_client_contract.py | 147 + tools/validate_client_contract.py | 397 +- 36 files changed, 71637 insertions(+), 198 deletions(-) create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts-2.parquet create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.parquet create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-part-by-mention.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-place-beside-definite.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-strict-info-notice.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/resubmit-candidates-sibling.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/resubmit-placeholder-without-restatement.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.parquet diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index 1c7ab7c..4fe1214 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -10,10 +10,10 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be - `served/openapi.json`, the composed dfo-apis app's OpenAPI document, and `served/SOURCE.json`, naming dfo-apis commit `8408f1f95c622223f8fa6e9ba55826ee8e22a852`. - `strict-fields.json` and its schema: 25 members that stay required and non-nullable, and the answer kinds, part statuses and operation statuses the clients branch on. - `actions.json` and its schema: the caller's next step for each of the 101 active refusal codes on `problem_details` or `no_data_reason`, with the gap kind of each no_data reason. -- `scenario.schema.json`, the scenario record, and 25 scenarios: 14 recorded against dfo-apis `8408f1f95` and 11 synthetic, each derived from a recorded one by a one-line edit, with eight Parquet bodies totalling 72,172 bytes. +- `scenario.schema.json`, the scenario record, and 44 scenarios: 18 recorded against dfo-apis `8408f1f95` and 26 synthetic, each derived from a recorded one by a one-line edit, with 11 Parquet bodies totalling 102,956 bytes. The scenarios cover the several-part choice entries, the choice refusals, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule and the stacked dataset's `part` column. - `dataset-ref.schema.json`, the frozen `DatasetRef` format, with accepted and rejected examples. - `tools/capture_client_contract.py`, which captures `served/openapi.json` from a dfo-apis checkout in process and records the scenarios against a base URL, dev by default. -- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, and checks each scenario's `expect` against the outcomes its exchanges and `actions.json` give. +- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, and checks each scenario's `expect` against the outcomes its exchanges and `actions.json` give, and each Search request against the input its steps derive. - The client rules and their vectors: the credentials path and file format, the key lookup order, the key format check, and the cache directory and layout. [unreleased]: https://github.com/DevelopmentFinanceObservatory/spec-kit/commits/main/python diff --git a/python/client-contract/README.md b/python/client-contract/README.md index fb162de..e1e2bea 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -66,7 +66,7 @@ uv run ty check src/dfo_client_contract `strict-fields.json` lists the members a client cannot act without. Each pointer names one property of one component schema, `/components/schemas//properties/`. A `required` entry stays in its schema's `required` list and admits no null, so a client raises `ContractError` when one is missing or null. An `enums` entry keeps every listed value, the values a client branches on: the answer kinds, the part statuses and the operation statuses. A client still accepts a value no entry lists. -The answer's `kind` and each part's `status` are the discriminators of their unions in the served document. A search response with no `kind` raises `ContractError`, as a part with no `status` does, although the served document gives `kind` a default and leaves it out of `required`. A `kind` or `status` a client does not know raises nothing. +The answer's `kind` and each part's `status` are the discriminators of their unions in the served document. A search response with no `kind` raises `ContractError`, as a part with no `status` does, although the served document gives `kind` a default and leaves it out of `required`. A part `status` a client does not know raises nothing and makes the part an `unknown` gap. An answer `kind` a client does not know raises `ContractError`, because the client cannot read the answer. The required members are each part's `status` and its payload (`spec`, `candidates`, `no_data`, `unsupported`), `Resolution.parts`, `CandidateSet.specs`, `NoData.reason`, `Unsupported.code`, `Spec.spec_id` and `definition`, `SpecDefinition.spec_id`, the manifest's `definition`, `definition.spec_id`, `content_version` and `artifacts`, each artifact's `artifact_digest`, `rendering` and `url`, and the operation resource's `operation`, `operation_id` and `status`. The operation's `poll` is nullable in the served document, so a client builds the poll path from `operation_id`. @@ -106,13 +106,13 @@ A scenario is one client-level call, the HTTP exchanges it makes, and the outcom | `exchanges` | The requests the call makes, in order, each with the response to give | | `expect` | One outcome per step: an `answer`, a `dataset`, an `operation` or an `error` | -A step that acts on an earlier result follows one: `choose` and a `fetch` with no target follow `search` or `choose`, and `result` follows `mint`. A `spec` in a step holds `spec_id`, the server's unmodified `definition`, and the `sentence` when the client knows it. +A step that acts on an earlier result follows one: `choose` follows `search` or `choose`, a `fetch` with no target follows `search`, `choose` or another `fetch` with no target and acts on the last answer, and `result` follows `mint`. A `spec` in a step holds `spec_id`, the server's unmodified `definition`, and the `sentence` when the client knows it. An exchange's request names its target in one of three ways. `path` is a path the client composes under the base URL, such as `/search/resolve`. `origin_path` is a root-relative URL the server returned, such as an artifact's `url`, which resolves against the base URL's origin and never against its path. `url` is an absolute URL outside the API, such as the signed storage URL a files route redirects to, which the client fetches with a bare request carrying no client header and no key. `json` holds the request body members that must match; a recorded scenario lists every member the client sent. The response gives `status`, the `headers` a client reads, and a `json` body or a `body_file`, a binary body in `scenarios/`. A scenario's own body files are named `.` and `-.`; a synthetic scenario may instead name a body file its parent names. -An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column. An error outcome gives the error `class` and the problem's `code`, or null when no problem document carries the error. +An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and the problem's `code`, or null when no problem document carries the error. -Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry, an error's class is its code's action or else its status, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, and a dataset's members, `complete` and `missing` follow from the answer and the manifests. A dataset's `rows` and `columns` are the Parquet bodies' and are not derived, except that `part` comes first exactly when the dataset has several members. +Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry, an error's class is its code's action or else its status, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, and each Search request posts the input the rules give: the question, a choice's input, or a member's identity. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. A recorded scenario's request and response bodies validate against their route's schemas in `served/openapi.json`, with one allowance: a required member whose schema admits null may be absent, because the server leaves null members out of the bodies it serves. @@ -128,9 +128,14 @@ The records also fix these client rules: - A fetch builds each distinct `spec_id` once, in part order, and finishes one member (build, the sentence when the client lacks it, files, download) before the next. - A built `spec_id` that differs from the posted one, or a spec with no sentence, takes its sentence from Search: the client posts the built definition's `identity` as one `dataset_resubmit` identity entry, with the member's first part as `variable_text`, or `"dataset"` when no answer part names it, and checks the answer's `spec_id` equals the built one. -- A dataset of several members puts the `part` column first, then each member's columns in member order, each column once. -- A choice among candidates in a one-part answer makes no request. A choice of a no_data option in a one-part answer posts the option's `data_query` as the input. In a several-part answer a choice posts `dataset_resubmit` with one entry per part in part order: the chosen option's part as a parsed entry, a definite part as an identity entry with its `entity_groups`, and any other part's `restatement` as a parsed entry. +- A dataset of several members puts the `part` column first, then each member's columns in member order, each column once. The `part` value on a member's rows is the member's `parts` joined by `"; "`, so a member that answers two folded parts reads `"health ODA disbursements; education ODA disbursements"`, or the member's sentence when `parts` is empty. +- A choice names its part by index, by variable text, or by a word that one gap's options mention, and its option by index or label; a candidate is named by index. A label is matched among the options that mention the word the part was named by. With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. +- A choice raises `InvalidRequestError` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is out of range or matches no label or several. +- A choice among candidates in a one-part answer makes no request. A choice of a no_data option in a one-part answer posts the option's `data_query` as the input. +- In a several-part answer a choice posts `dataset_resubmit`, without `raw_query`, with one entry per part in part order. The chosen candidate posts an identity entry with its identity and `entity_groups`, and the chosen option its `data_query`'s one part as a parsed entry. A definite part posts an identity entry with its spec's identity and `entity_groups`. A candidates part left alone posts a `candidates` entry: its candidate set in the server's order, each with its identity and `entity_groups`, and its `ordering` and `truncated` echoed. The server cannot recompute that order, because it rests on the first answer's bind election and availability reads, and a parsed entry would cost an LLM bind. Any other part posts its `restatement` as a parsed entry, or a placeholder entry with its no_data `reason` or unsupported `code` when it has none. Every entry but a parsed one carries the part's `variable_text`, `separate` when true and `operations` when the part has any; `entity_groups` is left out when the spec has none. - A declined or catalogue answer is not complete, and fetching it raises `DeclinedError`. +- Fetching an answer with a gap raises `IncompleteAnswerError` before any request, unless the fetch is partial and some part has a reading. +- A fetch of an answer issues one `SearchWarning` when a definite part has an operation Search did not run, a departure, or a warning at severity `warn` or `degraded`, or the answer's `diagnostics.warnings` holds such a warning. An `info` warning issues nothing. A strict fetch raises the `SearchWarning` before any build. - A ref whose version the snapshot route refuses with `snapshot_not_found` raises `NotFoundError` with no further request. - A retry waits `Retry-After` when the response carries it. A synthetic scenario that retries assumes the default of two retries. diff --git a/python/client-contract/src/dfo_client_contract/scenario.schema.json b/python/client-contract/src/dfo_client_contract/scenario.schema.json index 3c530f4..f89ff93 100644 --- a/python/client-contract/src/dfo_client_contract/scenario.schema.json +++ b/python/client-contract/src/dfo_client_contract/scenario.schema.json @@ -251,7 +251,7 @@ } }, "choose_step": { - "description": "A choice on the answer the previous step produced. part names the part by index or variable text, and may be left out when one part awaits a choice. option names the option by index or label.", + "description": "A choice on the answer the previous step produced. part names the part by index, by variable text, or by a word that one part's options mention, and may be left out when one part awaits a choice. option names the option by index or label; a candidate is named by index.", "type": "object", "additionalProperties": false, "required": [ @@ -289,7 +289,7 @@ } }, "fetch_answer_step": { - "description": "A fetch of the answer the previous step produced.", + "description": "A fetch of the answer the last search or choose step produced.", "type": "object", "additionalProperties": false, "required": [ @@ -663,6 +663,29 @@ "minLength": 1 } }, + "part_rows": { + "description": "For a dataset of several members only: one entry per member, in member order, with the value of the part column on that member's rows and the number of those rows.", + "type": "array", + "minItems": 2, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "part", + "rows" + ], + "properties": { + "part": { + "type": "string", + "minLength": 1 + }, + "rows": { + "type": "integer", + "minimum": 0 + } + } + } + }, "complete": { "type": "boolean" }, @@ -718,6 +741,10 @@ } } } + }, + "search_warning": { + "description": "For a fetch of an answer only: whether the fetch issued a SearchWarning.", + "type": "boolean" } } }, @@ -765,6 +792,7 @@ "QuotaExceededError", "ServerError", "ContractError", + "SearchWarning", "NetworkError", "DfoTimeoutError" ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json index 0f573ba..8f0ec7c 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json @@ -2872,7 +2872,8 @@ "sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1." } ], - "missing": [] + "missing": [], + "search_warning": false } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-definite-fetch.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-definite-fetch.json index c588537..f408299 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-definite-fetch.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-definite-fetch.json @@ -4528,7 +4528,8 @@ "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." } ], - "missing": [] + "missing": [], + "search_warning": false } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json index 005b4c2..7f5e5ec 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json @@ -4161,7 +4161,8 @@ "part": 1, "kind": "not_understood" } - ] + ], + "search_warning": false } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json index 8785d99..bfab004 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json @@ -15387,6 +15387,16 @@ "observationAbout", "observationAbout_label" ], + "part_rows": [ + { + "part": "health ODA disbursements; education ODA disbursements", + "rows": 512 + }, + { + "part": "GDP", + "rows": 132 + } + ], "complete": true, "members": [ { @@ -15407,7 +15417,8 @@ "sentence": "GDP in Germany and Kenya, 1960 to 2025. Current US dollars · World Development Indicators." } ], - "missing": [] + "missing": [], + "search_warning": true } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json new file mode 100644 index 0000000..d5e0b88 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json @@ -0,0 +1,3574 @@ +{ + "format_version": 1, + "name": "answer-timed-out", + "description": "A no_data part of an answer whose diagnostics say Search timed out is a timed_out gap, whatever its reason, and fetching the answer raises IncompleteAnswerError.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-mixed-fetch-raises", + "edit": "The answer's diagnostics.timed_out becomes true." + }, + "call": [ + { + "op": "search", + "question": "debt service of Kenya and the price of tea in Kenya" + }, + { + "op": "fetch" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "debt service of Kenya and the price of tea in Kenya" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "debt service of Kenya and the price of tea in Kenya", + "normalized_query": "debt service of Kenya and the price of tea in Kenya", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "trace_id": "95437670d1314551aa1fbdce8c8122b6", + "warnings": [], + "timing_ms": { + "total": 140, + "by_step": { + "coverage": 0, + "extract": 1 + } + }, + "llm_usage": { + "input_tokens": 0, + "output_tokens": 0, + "cached_tokens": 0 + }, + "timed_out": true + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "debt service", + "warnings": [], + "timing_ms": { + "total": 58, + "by_step": { + "recall": 0, + "shape_arcs": 2, + "shape_probe_coverage": 15, + "shape_probe": 16, + "shape_groups": 5, + "shape_labels": 9, + "shape_admission": 0, + "shape": 37, + "bind": 2, + "materialise": 9, + "answer": 2, + "options": 8 + } + }, + "restatement": { + "variable_text": "debt service", + "entities": [ + { + "text": "Kenya" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "definite", + "spec": { + "spec_id": "spec_78d04fefc3b3f1ef71acd622957e4995", + "definition": { + "schema_version": 1, + "spec_id": "spec_78d04fefc3b3f1ef71acd622957e4995", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "ServicingPayment" + } + }, + { + "property": "financingResource", + "binding": { + "state": "unbound" + } + }, + { + "property": "guaranteeStatus", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsConcessionality", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsCreditorType", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsDebtorType", + "binding": { + "state": "unbound" + } + }, + { + "property": "includesIMFCredit", + "binding": { + "state": "unbound" + } + }, + { + "property": "maturityBand", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal_by_role", + "label": "Debt service on external debt", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 65, + "member_digest": "b66541c53125ee32113e51b4f52a3a428043b5506e15f96277f37b89547fc1c4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "ServicingPayment", + "label": "servicing payment" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "financingResource", + "guaranteeStatus", + "idsDebtorType", + "idsCreditorType", + "idsConcessionality", + "includesIMFCredit", + "maturityBand" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1970", + "end": "2024" + }, + "source_codes": [ + { + "provenance": "provenance/WorldBankInternationalDebtStatistics", + "code": "DT.TDS.DECT.CD" + } + ] + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 55, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 55 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 1, + "series": 1, + "role_counts": { + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2024, + "observations": 1, + "series": 1, + "role_counts": { + "financingRecipient": 1 + } + }, + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 1, + "series": 1, + "role_counts": { + "financingRecipient": 1 + } + } + ] + }, + "download": { + "rows": 55, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 1970, + "end_year": 2024 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "ServicingPayment", + "label": "servicing payment" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "options": [ + { + "value": { + "ref": { + "ref": "PublicOrPubliclyGuaranteed", + "label": "public or publicly guaranteed" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "NotPubliclyGuaranteed", + "label": "not publicly guaranteed" + }, + "value_kind": "enum_value" + }, + "served_rows": 56, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSDebtorTypePS", + "label": "public sector (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSDebtorTypeGG", + "label": "general government (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSDebtorTypeOPS", + "label": "other public sector (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSDebtorTypePrivateSector", + "label": "private sector (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 56, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSCreditorTypePROP", + "label": "other private creditors (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 46, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypePBND", + "label": "bondholders (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 31, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypePRVT", + "label": "private creditors (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypeOFFT", + "label": "official creditors (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 55, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypeMLAT", + "label": "multilateral (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSConcessional", + "label": "concessional (IDS concessionality)" + }, + "value_kind": "enum_value" + }, + "served_rows": 118, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "options": [ + { + "value": { + "ref": { + "ref": "WithoutIMFCredit", + "label": "without IMF credit" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "options": [ + { + "value": { + "ref": { + "ref": "LongTermMaturity", + "label": "long-term maturity" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Estimated", + "label": "estimated" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "external debt service", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ] + }, + { + "kind": "text", + "text": " owed to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "all creditors", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [], + "states": [ + "origin:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financingResource", + "binding_ref": "how:financingResource", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "guaranteeStatus", + "binding_ref": "how:guaranteeStatus", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsConcessionality", + "binding_ref": "how:idsConcessionality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsCreditorType", + "binding_ref": "how:idsCreditorType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsDebtorType", + "binding_ref": "how:idsDebtorType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "includesIMFCredit", + "binding_ref": "how:includesIMFCredit", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "maturityBand", + "binding_ref": "how:maturityBand", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1970 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Bank International Debt Statistics (IDS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "resolved_sources": [ + { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "ServicingPayment", + "label": "servicing payment" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1985, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1992, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1994, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1981, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1981, + "base_year_max": 2025 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1989, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1987, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "KES" + } + } + } + } + }, + { + "variable_text": "price of tea", + "warnings": [], + "timing_ms": { + "total": 14, + "by_step": { + "recall": 0, + "shape_arcs": 1, + "shape_probe": 3, + "shape_groups": 3, + "shape_labels": 0, + "shape_admission": 2, + "shape": 14 + } + }, + "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", + "sentence_plan": [ + { + "kind": "text", + "text": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "operations": [], + "departures": [], + "status": "no_data", + "no_data": { + "reason": "variable_not_resolved", + "category": "unresolved", + "message": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", + "entity_terms": [], + "ambiguous_entities": [], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [] + } + } + ], + "rendered_sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "external debt service", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " owed to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "all creditors", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [], + "states": [ + "origin:" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financingResource", + "binding_ref": "how:financingResource", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "guaranteeStatus", + "binding_ref": "how:guaranteeStatus", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsConcessionality", + "binding_ref": "how:idsConcessionality", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsCreditorType", + "binding_ref": "how:idsCreditorType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsDebtorType", + "binding_ref": "how:idsDebtorType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "includesIMFCredit", + "binding_ref": "how:includesIMFCredit", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "maturityBand", + "binding_ref": "how:maturityBand", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "1970 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "World Bank International Debt Statistics (IDS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "No match for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "price of tea", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ". Try a different wording or a related indicator.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + } + ], + "status": "mixed" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "mixed", + "sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "complete": false, + "specs": [ + "spec_78d04fefc3b3f1ef71acd622957e4995" + ], + "gaps": [ + { + "part": 1, + "kind": "timed_out", + "options": 0 + } + ] + } + }, + { + "error": { + "class": "IncompleteAnswerError", + "code": null + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json new file mode 100644 index 0000000..a78a893 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json @@ -0,0 +1,208 @@ +{ + "format_version": 1, + "name": "answer-unknown-kind", + "description": "A search response whose kind the client does not know raises ContractError, since the client cannot read the answer.", + "origin": { + "kind": "synthetic", + "derived_from": "search-place-ambiguous", + "edit": "The answer's kind becomes \"verdict\", a kind no client knows." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Congo", + "normalized_query": "ODA disbursements from Germany to Congo", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "trace_id": "cc29e19289f44bb6bb0a6e0f4c8524a7", + "warnings": [], + "timing_ms": { + "total": 1, + "by_step": { + "coverage": 0, + "response_cache_layer1": 1 + } + }, + "llm_usage": { + "input_tokens": 0, + "output_tokens": 0, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "verdict", + "parts": [ + { + "variable_text": "ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 1, + "by_step": { + "recall": 1 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "no_data" + } + } + } + ], + "expect": [ + { + "error": { + "class": "ContractError", + "code": null + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json new file mode 100644 index 0000000..6c401f1 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json @@ -0,0 +1,3569 @@ +{ + "format_version": 1, + "name": "answer-unsupported-part", + "description": "An unsupported part is an unsupported gap with no options, and fetching the answer raises IncompleteAnswerError.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-mixed-fetch-raises", + "edit": "Part 1 becomes an unsupported part with code scope_too_broad." + }, + "call": [ + { + "op": "search", + "question": "debt service of Kenya and the price of tea in Kenya" + }, + { + "op": "fetch" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "debt service of Kenya and the price of tea in Kenya" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "debt service of Kenya and the price of tea in Kenya", + "normalized_query": "debt service of Kenya and the price of tea in Kenya", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "trace_id": "95437670d1314551aa1fbdce8c8122b6", + "warnings": [], + "timing_ms": { + "total": 140, + "by_step": { + "coverage": 0, + "extract": 1 + } + }, + "llm_usage": { + "input_tokens": 0, + "output_tokens": 0, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "debt service", + "warnings": [], + "timing_ms": { + "total": 58, + "by_step": { + "recall": 0, + "shape_arcs": 2, + "shape_probe_coverage": 15, + "shape_probe": 16, + "shape_groups": 5, + "shape_labels": 9, + "shape_admission": 0, + "shape": 37, + "bind": 2, + "materialise": 9, + "answer": 2, + "options": 8 + } + }, + "restatement": { + "variable_text": "debt service", + "entities": [ + { + "text": "Kenya" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "definite", + "spec": { + "spec_id": "spec_78d04fefc3b3f1ef71acd622957e4995", + "definition": { + "schema_version": 1, + "spec_id": "spec_78d04fefc3b3f1ef71acd622957e4995", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "ServicingPayment" + } + }, + { + "property": "financingResource", + "binding": { + "state": "unbound" + } + }, + { + "property": "guaranteeStatus", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsConcessionality", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsCreditorType", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsDebtorType", + "binding": { + "state": "unbound" + } + }, + { + "property": "includesIMFCredit", + "binding": { + "state": "unbound" + } + }, + { + "property": "maturityBand", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal_by_role", + "label": "Debt service on external debt", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 65, + "member_digest": "b66541c53125ee32113e51b4f52a3a428043b5506e15f96277f37b89547fc1c4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "ServicingPayment", + "label": "servicing payment" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "financingResource", + "guaranteeStatus", + "idsDebtorType", + "idsCreditorType", + "idsConcessionality", + "includesIMFCredit", + "maturityBand" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1970", + "end": "2024" + }, + "source_codes": [ + { + "provenance": "provenance/WorldBankInternationalDebtStatistics", + "code": "DT.TDS.DECT.CD" + } + ] + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 55, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 55 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 1, + "series": 1, + "role_counts": { + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2024, + "observations": 1, + "series": 1, + "role_counts": { + "financingRecipient": 1 + } + }, + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 1, + "series": 1, + "role_counts": { + "financingRecipient": 1 + } + } + ] + }, + "download": { + "rows": 55, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 1970, + "end_year": 2024 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "ServicingPayment", + "label": "servicing payment" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "options": [ + { + "value": { + "ref": { + "ref": "PublicOrPubliclyGuaranteed", + "label": "public or publicly guaranteed" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "NotPubliclyGuaranteed", + "label": "not publicly guaranteed" + }, + "value_kind": "enum_value" + }, + "served_rows": 56, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSDebtorTypePS", + "label": "public sector (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSDebtorTypeGG", + "label": "general government (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSDebtorTypeOPS", + "label": "other public sector (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSDebtorTypePrivateSector", + "label": "private sector (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 56, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSCreditorTypePROP", + "label": "other private creditors (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 46, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypePBND", + "label": "bondholders (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 31, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypePRVT", + "label": "private creditors (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypeOFFT", + "label": "official creditors (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 55, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypeMLAT", + "label": "multilateral (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSConcessional", + "label": "concessional (IDS concessionality)" + }, + "value_kind": "enum_value" + }, + "served_rows": 118, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "options": [ + { + "value": { + "ref": { + "ref": "WithoutIMFCredit", + "label": "without IMF credit" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "options": [ + { + "value": { + "ref": { + "ref": "LongTermMaturity", + "label": "long-term maturity" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Estimated", + "label": "estimated" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "external debt service", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ] + }, + { + "kind": "text", + "text": " owed to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "all creditors", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [], + "states": [ + "origin:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financingResource", + "binding_ref": "how:financingResource", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "guaranteeStatus", + "binding_ref": "how:guaranteeStatus", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsConcessionality", + "binding_ref": "how:idsConcessionality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsCreditorType", + "binding_ref": "how:idsCreditorType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsDebtorType", + "binding_ref": "how:idsDebtorType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "includesIMFCredit", + "binding_ref": "how:includesIMFCredit", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "maturityBand", + "binding_ref": "how:maturityBand", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1970 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Bank International Debt Statistics (IDS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "resolved_sources": [ + { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "ServicingPayment", + "label": "servicing payment" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1985, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1992, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1994, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1981, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1981, + "base_year_max": 2025 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1989, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1987, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "KES" + } + } + } + } + }, + { + "variable_text": "price of tea", + "warnings": [], + "timing_ms": { + "total": 14, + "by_step": { + "recall": 0, + "shape_arcs": 1, + "shape_probe": 3, + "shape_groups": 3, + "shape_labels": 0, + "shape_admission": 2, + "shape": 14 + } + }, + "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", + "sentence_plan": [ + { + "kind": "text", + "text": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "operations": [], + "departures": [], + "status": "unsupported", + "unsupported": { + "code": "scope_too_broad", + "pointer": "/definition/identity", + "detail": "the family is too broad to settle; bind a what or how slot" + } + } + ], + "rendered_sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "external debt service", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " owed to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "all creditors", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [], + "states": [ + "origin:" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financingResource", + "binding_ref": "how:financingResource", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "guaranteeStatus", + "binding_ref": "how:guaranteeStatus", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsConcessionality", + "binding_ref": "how:idsConcessionality", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsCreditorType", + "binding_ref": "how:idsCreditorType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsDebtorType", + "binding_ref": "how:idsDebtorType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "includesIMFCredit", + "binding_ref": "how:includesIMFCredit", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "maturityBand", + "binding_ref": "how:maturityBand", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "1970 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "World Bank International Debt Statistics (IDS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "No match for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "price of tea", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ". Try a different wording or a related indicator.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + } + ], + "status": "mixed" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "mixed", + "sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "complete": false, + "specs": [ + "spec_78d04fefc3b3f1ef71acd622957e4995" + ], + "gaps": [ + { + "part": 1, + "kind": "unsupported", + "options": 0 + } + ] + } + }, + { + "error": { + "class": "IncompleteAnswerError", + "code": null + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts-2.parquet b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts-2.parquet new file mode 100644 index 0000000000000000000000000000000000000000..b4448d00980c0782da4317456de4789c00009ec5 GIT binary patch literal 10503 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 BQxgCH literal 0 HcmV?d00001 diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json new file mode 100644 index 0000000..bdb34fa --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json @@ -0,0 +1,17701 @@ +{ + "format_version": 1, + "name": "choose-candidate-two-parts", + "description": "Choosing candidate 0 on the candidates part of a two-part answer posts dataset_resubmit with one entry per part in part order: the chosen candidate's identity, and the definite part's identity with its entity_groups. Both parts answer definite, and the fetch stacks two members with each member's parts as its part column value.", + "origin": { + "kind": "recorded", + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "7175fe98eec005479f1397936dc011ad120092d5", + "recorded_at": "2026-10-20T16:52:45Z" + }, + "call": [ + { + "op": "search", + "question": "GNI of Germany from 2015 to 2022, and ODA disbursements from Germany to sub-Saharan Africa" + }, + { + "op": "choose", + "part": 0, + "option": 0 + }, + { + "op": "fetch" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "GNI of Germany from 2015 to 2022, and ODA disbursements from Germany to sub-Saharan Africa" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "GNI of Germany from 2015 to 2022, and ODA disbursements from Germany to sub-Saharan Africa", + "normalized_query": "GNI of Germany from 2015 to 2022, and ODA disbursements from Germany to sub-Saharan Africa", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "7175fe98eec005479f1397936dc011ad120092d5", + "trace_id": "7f6a04c16900442189166cabc9808dda", + "warnings": [], + "timing_ms": { + "total": 6868, + "by_step": { + "coverage": 0, + "extract": 1449 + } + }, + "llm_usage": { + "input_tokens": 11567, + "output_tokens": 611, + "cached_tokens": 864 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GNI", + "warnings": [ + { + "code": "direction_discarded", + "severity": "warn", + "message": "sub-Saharan Africa was named as the recipient; this shape reports the place as its own subject, so the direction was dropped." + }, + { + "code": "direction_discarded", + "severity": "warn", + "message": "Germany was named as the provider; this shape reports the place as its own subject, so the direction was dropped." + } + ], + "timing_ms": { + "total": 4195, + "by_step": { + "recall": 345, + "shape_arcs": 5, + "shape_probe_coverage": 6, + "shape_probe": 105, + "shape_groups": 66, + "shape_labels": 16, + "shape_admission": 173, + "shape": 2104, + "bind": 1323, + "materialise": 194, + "answer": 229 + } + }, + "rendered_sentence": "3 readings. Primary income for gross of fixed capital consumption in 49 places. World Bank International Debt Statistics (IDS) · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in 49 places. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in 49 places. World Development Indicators · 2015 to 2022. You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself.", + "sentence_plan": [ + { + "kind": "text", + "text": "3 readings.", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Primary income", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross of fixed capital consumption", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "49 places", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Bank International Debt Statistics (IDS)", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Gross national income based on purchasing power parity", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "49 places", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Gross national income based on purchasing power parity per capita", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "49 places", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself.", + "segment": "departure", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "GNI", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "sub-Saharan Africa", + "role_text": "to" + } + ], + "time_text": "2015 to 2022", + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [ + { + "code": "direction_discarded", + "binding_ref": "where:", + "asked": "sub-Saharan Africa", + "text": "You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself." + } + ], + "status": "candidates", + "candidates": { + "ordering": "intent_rank", + "max_candidates": 6, + "specs": [ + { + "spec_id": "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", + "definition": { + "schema_version": 1, + "spec_id": "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DEU", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicunit_primaryincome_measuredvalue_nominal", + "label": "Gross national income", + "population_type": { + "ref": "EconomicUnit", + "label": "economic unit" + }, + "measured_property": { + "ref": "primaryIncome", + "label": "primary income" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 348, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 44 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 348, + "rows_exact": true, + "series": 44, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)" + }, + "value_kind": "source" + } + }, + { + "value": { + "ref": { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Primary income for gross of fixed capital consumption in 49 places, 2015 to 2022. Current US dollars · World Bank International Debt Statistics (IDS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "distinguishes": true + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "49 places", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Bank International Debt Statistics (IDS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + }, + { + "spec_id": "spec_07c78f9c1c511ed05a0f700b7f6c121e", + "definition": { + "schema_version": 1, + "spec_id": "spec_07c78f9c1c511ed05a0f700b7f6c121e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "PurchasingPowerParity" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossNationalIncome" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DEU", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity", + "label": "Gross National Income Based on Purchasing Power Parity", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "PurchasingPowerParity", + "label": "PurchasingPowerParity" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "833b9da89613fa6c1775652daac2388f38204c6c9f9929ca113deed9a0d08369", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ], + "upstream": { + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + } + } + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 377, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 48 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 377, + "rows_exact": true, + "series": 48, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "fallback", + "ref": "InternationalDollar", + "label": "InternationalDollar" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "InternationalDollar", + "label": "InternationalDollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Gross national income based on purchasing power parity in international dollars in 49 places, 2015 to 2022. World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Gross national income based on purchasing power parity", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "in international dollars", + "axis": "unit", + "segment": "heading", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "49 places", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + }, + { + "spec_id": "spec_62eeede92636290b4c10e207bd8bffbb", + "definition": { + "schema_version": 1, + "spec_id": "spec_62eeede92636290b4c10e207bd8bffbb", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "PurchasingPowerParity", + "measurement_denominator": { + "unresolved": true + } + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossNationalIncome" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DEU", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity_per_unresolved", + "label": "Gross National Income Based on Purchasing Power Parity Per Capita", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "PurchasingPowerParity", + "label": "PurchasingPowerParity" + }, + "measurement_denominator": { + "ref": "PerCapita", + "label": "PerCapita" + }, + "measurement_denominator_unresolved": true, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "7b2d5b0fc09cfc0215c8d7c6c21a5195fa21e79f2a148a6bca9ce6c3af8bbb9f", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ], + "upstream": { + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + } + } + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 377, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 48 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 377, + "rows_exact": true, + "series": 48, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "fallback", + "ref": "InternationalDollar", + "label": "InternationalDollar" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "InternationalDollar", + "label": "InternationalDollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Gross national income based on purchasing power parity per capita in international dollars in 49 places, 2015 to 2022. World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Gross national income based on purchasing power parity per capita", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "in international dollars", + "axis": "unit", + "segment": "heading", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "49 places", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "truncated": false + } + }, + { + "variable_text": "ODA disbursements", + "warnings": [ + { + "code": "retrieval_score_weak", + "severity": "info", + "message": "the chosen reading's match to the query is weak; treat it with less confidence than a strong match." + } + ], + "timing_ms": { + "total": 4537, + "by_step": { + "recall": 532, + "shape_arcs": 1, + "shape_probe_coverage": 95, + "shape_probe": 218, + "shape_groups": 70, + "shape_labels": 1, + "shape_admission": 3, + "shape": 1461, + "bind": 2124, + "materialise": 35, + "answer": 367, + "options": 18 + } + }, + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "sub-Saharan Africa", + "role_text": "to" + } + ], + "time_text": "2015 to 2022", + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [ + { + "code": "group_read_as_members", + "binding_ref": "where:", + "asked": "sub-Saharan Africa", + "text": "You asked for sub-Saharan Africa. This shows the countries in it, each on its own." + } + ], + "status": "definite", + "spec": { + "spec_id": "spec_941030940d23f46826acaa0c6fed8bbc", + "definition": { + "schema_version": 1, + "spec_id": "spec_941030940d23f46826acaa0c6fed8bbc", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal_family_f096b1ba", + "label": "gross disbursements (official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "DAC2aAidType206", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "dacTypeOfFinance", + "financialObligationType" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "entity_groups": { + "destination": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 372, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "headline": { + "year": 2022, + "year_named": true, + "named_window": { + "start_year": 2015, + "end_year": 2022 + }, + "observations": 46, + "series": 46, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 46 + }, + "recent_years": [ + { + "year": 2022, + "observations": 46, + "series": 46, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 46 + } + }, + { + "year": 2021, + "observations": 46, + "series": 46, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 46 + } + }, + { + "year": 2020, + "observations": 47, + "series": 47, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 47 + } + } + ] + }, + "download": { + "rows": 372, + "rows_exact": true, + "series": 48, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "DAC2aAidType218", + "label": "ODA loans and other long-term capital" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 2, + "served_rows": 68, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType201", + "label": "ODA grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 1, + "served_rows": 372, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType207", + "label": "free-standing technical co-operation" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 372, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType213", + "label": "developmental food aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 129, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType216", + "label": "humanitarian aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 188, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross disbursements to the 48 countries in Sub-Saharan Africa for official development assistance, 2015 to 2022. Current US dollars · OECD DAC2a.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2a", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "DAC2aAidType206", + "label": "official development assistance" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "measure_elected" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [ + { + "text": "ODA", + "named": [ + { + "ref": "DAC2aAidType206", + "label": "official development assistance" + } + ], + "slot": "dac2aAidType", + "disposition": "bound", + "selected": [] + } + ], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "high", + "available_at_place": true, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_f936496b58a844fc044d98a4255f48f2", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 372, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 2015, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2015, + "end_year": 2019 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 2015, + "end_year": 2019 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 2020, + "end_year": 2020 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2015, + "end_year": 2020 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2010, + "current_years": null + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2018, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2018, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "origin": "EUR" + } + } + } + } + } + ], + "rendered_sentence": "GNI has 3 readings. Primary income for gross of fixed capital consumption in 49 places. World Bank International Debt Statistics (IDS) · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in 49 places. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in 49 places. World Development Indicators · 2015 to 2022. You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself. Germany's gross disbursements to the 48 countries in Sub-Saharan Africa for official development assistance, 2015 to 2022. Current US dollars · OECD DAC2a. You asked for sub-Saharan Africa. This shows the countries in it, each on its own.", + "sentence_plan": [ + { + "kind": "slot", + "text": "GNI", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " has 3 readings.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Primary income", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross of fixed capital consumption", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "49 places", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "World Bank International Debt Statistics (IDS)", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Gross national income based on purchasing power parity", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "49 places", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Gross national income based on purchasing power parity per capita", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "49 places", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "states": [ + "where:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "You asked for sub-Saharan Africa. This shows the countries in it, each on its own.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + } + ], + "status": "mixed" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "dataset_resubmit", + "entries": [ + { + "entry_kind": "identity", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DEU", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + }, + "variable_text": "GNI" + }, + { + "entry_kind": "identity", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + }, + "entity_groups": { + "destination": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "variable_text": "ODA disbursements" + } + ] + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "dataset_resubmit", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "7175fe98eec005479f1397936dc011ad120092d5", + "trace_id": "31b91cf34a354255812599acec1c4e74", + "warnings": [], + "timing_ms": { + "total": 1684, + "by_step": { + "coverage": 0 + } + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GNI", + "warnings": [], + "timing_ms": { + "total": 97, + "by_step": { + "validate": 0, + "walk": 78, + "reread_arcs": 0, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 1, + "bind": 0, + "where_places": 0, + "materialise": 10, + "answer": 6, + "options": 2 + } + }, + "operations": [], + "departures": [ + { + "code": "entity_unavailable", + "binding_ref": "where:", + "text": "You asked for Germany, Eritrea, Namibia, South Sudan, and Seychelles. The data holds no values for them." + } + ], + "status": "definite", + "spec": { + "spec_id": "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", + "definition": { + "schema_version": 1, + "spec_id": "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DEU", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicunit_primaryincome_measuredvalue_nominal", + "label": "Gross national income", + "population_type": { + "ref": "EconomicUnit", + "label": "economic unit" + }, + "measured_property": { + "ref": "primaryIncome", + "label": "primary income" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 348, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 44 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 348, + "rows_exact": true, + "series": 44, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)" + }, + "value_kind": "source" + } + }, + { + "value": { + "ref": { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Primary income for gross of fixed capital consumption in 49 places, 2015 to 2022. Current US dollars · World Bank International Debt Statistics (IDS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "49 places", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Bank International Debt Statistics (IDS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_3f35867df5a65761" + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [], + "related_measures": [] + } + } + }, + { + "variable_text": "ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 1514, + "by_step": { + "validate": 0, + "walk": 13, + "reread_arcs": 0, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 1451, + "bind": 0, + "where_places": 0, + "materialise": 31, + "answer": 16, + "options": 3 + } + }, + "operations": [], + "departures": [ + { + "code": "group_read_as_members", + "binding_ref": "where:", + "text": "This shows the 48 countries in Sub-Saharan Africa, each on its own." + } + ], + "status": "definite", + "spec": { + "spec_id": "spec_941030940d23f46826acaa0c6fed8bbc", + "definition": { + "schema_version": 1, + "spec_id": "spec_941030940d23f46826acaa0c6fed8bbc", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal_family_f096b1ba", + "label": "gross disbursements (official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "DAC2aAidType206", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "dacTypeOfFinance" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "entity_groups": { + "destination": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 372, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "headline": { + "year": 2022, + "year_named": true, + "named_window": { + "start_year": 2015, + "end_year": 2022 + }, + "observations": 46, + "series": 46, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 46 + }, + "recent_years": [ + { + "year": 2022, + "observations": 46, + "series": 46, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 46 + } + }, + { + "year": 2021, + "observations": 46, + "series": 46, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 46 + } + }, + { + "year": 2020, + "observations": 47, + "series": 47, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 47 + } + } + ] + }, + "download": { + "rows": 372, + "rows_exact": true, + "series": 48, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "DAC2aAidType218", + "label": "ODA loans and other long-term capital" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 2, + "served_rows": 68, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType201", + "label": "ODA grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 1, + "served_rows": 372, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType207", + "label": "free-standing technical co-operation" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 372, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType213", + "label": "developmental food aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 129, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType216", + "label": "humanitarian aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 188, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross disbursements to the 48 countries in Sub-Saharan Africa for official development assistance, 2015 to 2022. Current US dollars · OECD DAC2a.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2a", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "DAC2aAidType206", + "label": "official development assistance" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_3f35867df5a65761" + }, + "confidence": "high", + "available_at_place": true, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_f936496b58a844fc044d98a4255f48f2", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 372, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 2015, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2015, + "end_year": 2019 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 2015, + "end_year": 2019 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 2020, + "end_year": 2020 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2015, + "end_year": 2020 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2010, + "current_years": null + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2018, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2018, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 2015, + "end_year": 2022 + }, + "constant_years": { + "start_year": 2015, + "end_year": 2022 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "origin": "EUR" + } + } + } + } + } + ], + "rendered_sentence": "Primary income for gross of fixed capital consumption in 49 places, 2015 to 2022. Current US dollars · World Bank International Debt Statistics (IDS). You asked for Germany, Eritrea, Namibia, South Sudan, and Seychelles. The data holds no values for them. Germany's gross disbursements to the 48 countries in Sub-Saharan Africa for official development assistance, 2015 to 2022. Current US dollars · OECD DAC2a. This shows the 48 countries in Sub-Saharan Africa, each on its own.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "49 places", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "World Bank International Debt Statistics (IDS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "You asked for Germany, Eritrea, Namibia, South Sudan, and Seychelles. The data holds no values for them.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "states": [ + "where:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "This shows the 48 countries in Sub-Saharan Africa, each on its own.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + } + ], + "status": "definite" + } + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", + "definition": { + "schema_version": 1, + "spec_id": "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DEU", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "ref": "GrossOfFixedCapitalConsumption", + "state": "value" + }, + "property": "fixedCapitalConsumptionBasis" + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DEU", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2022, + "start_year": 2015 + } + } + }, + "content_version": "cv_18a63cb9e24a4ce6dfcd1c60f0c5a470", + "prepared_at": "2026-10-20T16:52:56Z", + "coverage": { + "rows": 348, + "dimensions": [ + { + "label": "observationAbout", + "count": 44 + }, + { + "label": "years", + "count": 8 + } + ], + "window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022, + "origin": "query" + } + }, + "citation": { + "text": "World Bank International Debt Statistics (IDS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "license": "Creative Commons Attribution License", + "license_type": "CreativeCommonsAttributionLicense", + "license_url": "https://datacatalog.worldbank.org/public-licenses?fragment=cc", + "url": "https://datacatalog.worldbank.org/search/dataset/0038015/international-debt-statistics", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "World Bank", + "description": "International Debt Statistics (IDS) is the World Bank's annual dataset on the external debt of low- and middle-income countries. It reports debt stocks, disbursements, debt service and projected repayments by borrower and creditor type, with public and publicly guaranteed debt broken down by creditor, from 1970 onwards. The data come mainly from countries' loan-by-loan reporting of public and publicly guaranteed debt to the World Bank's Debtor Reporting System, which is a condition of borrowing from IBRD and IDA.", + "source_data_url": "https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092201/A_D.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092202/E_K.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092203/L_M.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0093225/N_Q.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092204/R_U.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092205/V_Z.xlsx", + "attribution": "International Debt Statistics by the World Bank, https://datacatalog.worldbank.org/search/dataset/0038015/international-debt-statistics, licensed under CC BY 4.0. Modified by The ONE Campaign.", + "update_cadence": "Annual", + "last_update": "2026-10-13", + "years_covered": "1970-2032", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The World Bank publishes IDS as six bulk files, split by debtor name. All six are downloaded each time the pipeline runs, and replace the previous copy, so the data reflects the World Bank's latest release." + }, + { + "transformation": "Exclude series outside the debt statistics", + "description": "Non-debt statistics are excluded, including population, balance of payments, investment and reserves. GNI is kept, because some debt ratios are shares of it. Exports of goods, services and primary income, and the three debt ratios that are shares of it, are excluded until the ontology can describe them. Debt forgiveness grants, the stock-flow reconciliation residual, the annual changes in debt stocks and interest arrears, and the present value of debt are also excluded." + }, + { + "transformation": "Omit zeros where no lending took place", + "description": "IDS reports a value for every debtor, creditor and series, including pairs with no lending between them, so most figures are zero. Zeros are kept on world totals, and within or after a period of lending between a debtor and a creditor. They are omitted where a creditor has not lent to a debtor, for the years before lending began, and for averages in years with no new commitments, since there is nothing to average." + }, + { + "transformation": "Standardise debtors and creditors", + "description": "Debtor and creditor codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets. Where a series names a single lender in its code, such as debt owed to the IBRD, that lender becomes the creditor." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the debtor and the creditor, and the dimensions the World Bank encodes in each series code, such as type of flow, maturity and creditor type. GNI is the exception: it describes the debtor economy, so it is reported against the year and the economy alone. Ratios record what they are a share of: GNI or total external debt stocks. Every amount is reported in US dollars at current prices." + }, + { + "transformation": "Mark projections as estimated", + "description": "For the years after the last reported year, the World Bank projects debt service and disbursements on commitments already made. These values are marked as estimated, so they are kept apart from reported values." + } + ], + "version_history": [ + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "External debt stocks, flows and debt service of low- and middle-income countries by borrower and creditor, with related ratios and gross national income." + } + ] + } + ] + } + } + ] + }, + "trace": { + "applied_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022, + "origin": "query" + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00259-rpx", + "code_index_stamp": { + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T13:18:18Z", + "graph_endpoint": "graph_release" + }, + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "source_revisions": [ + { + "source": "provenance/WorldBankInternationalDebtStatistics", + "revision": "2026-10-13" + } + ], + "resolved_stat_vars": [ + { + "ref": "dcid:PrimaryIncome_EconomicUnit_GrossOfFixedCapitalConsumption_Nominal", + "roles": [ + "observationAbout" + ], + "observation_count": 348 + } + ], + "family_member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", + "family_member_count": 1, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/WorldBankInternationalDebtStatistics", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "most_observations_over_disagreement", + "dispatch_facet_id": "2052749850102211920" + }, + { + "axis": "measurementMethod", + "ref": null, + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "2052749850102211920" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "most_observations", + "dispatch_facet_id": "2052749850102211920" + } + ], + "normalisations": [], + "choices": [ + { + "axis": "provenance", + "candidates": [ + { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "places": 44, + "years": 8, + "observations": 2249 + }, + { + "ref": "provenance/OECDDAC1", + "places": 1, + "years": 8, + "observations": 66 + } + ] + } + ], + "frame_grammar_version": "1.1.0", + "materialiser_build": "7175fe98eec005479f1397936dc011ad120092d5", + "capability_version": "dset_1e6cd9546fac19e9", + "served_from": "materialise", + "confirmed_at": "2026-10-20T16:52:56.474699+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for country/DEU, country/ERI, country/NAM, country/SSD, country/SYC." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:05184087a3031ed02bb45806f4a6c134b580ace5cada64878fca2aaa75acdb91", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9453, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T16:52:56.418340+00:00", + "tier": "working", + "url": "/api/datasets/spec_bc87ff8e0f29960c38c96a4f4d2b0e20/cv_18a63cb9e24a4ce6dfcd1c60f0c5a470/files/sha256:05184087a3031ed02bb45806f4a6c134b580ace5cada64878fca2aaa75acdb91" + }, + { + "artifact_digest": "sha256:9f6cef75c54026bc957665229b19adb252d00d61f542483166394fa4aa273370", + "rendering": { + "statistics": "series" + }, + "bytes": 8146, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T16:52:56.418340+00:00", + "tier": "working", + "url": "/api/datasets/spec_bc87ff8e0f29960c38c96a4f4d2b0e20/cv_18a63cb9e24a4ce6dfcd1c60f0c5a470/files/sha256:9f6cef75c54026bc957665229b19adb252d00d61f542483166394fa4aa273370" + } + ], + "series_count": 44, + "output_options": { + "capability_version": "dset_1e6cd9546fac19e9", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "observationAbout", + "kind": "role", + "droppable": false, + "distinct": 44 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 8 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "observationAbout", + "field": "iso3", + "token": "observationAbout_iso3", + "state": "available", + "coverage": { + "entities": 44, + "covered": 44 + }, + "missing": [], + "truncated": false + }, + { + "column": "observationAbout", + "field": "iso2", + "token": "observationAbout_iso2", + "state": "available", + "coverage": { + "entities": 44, + "covered": 44 + }, + "missing": [], + "truncated": false + }, + { + "column": "observationAbout", + "field": "label", + "token": "observationAbout_label", + "state": "available", + "coverage": { + "entities": 44, + "covered": 44 + }, + "missing": [], + "truncated": false + }, + { + "column": "observationAbout", + "field": "type", + "token": "observationAbout_type", + "state": "available", + "coverage": { + "entities": 44, + "covered": 44 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "observationAbout_label" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "observationAbout", + "columns": "time_period", + "state": "available", + "width": 9, + "cells": 396 + }, + { + "index": "time_period", + "columns": "observationAbout", + "state": "available", + "width": 45, + "cells": 360 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_bc87ff8e0f29960c38c96a4f4d2b0e20/cv_18a63cb9e24a4ce6dfcd1c60f0c5a470/files/sha256:05184087a3031ed02bb45806f4a6c134b580ace5cada64878fca2aaa75acdb91" + }, + "response": { + "status": 302, + "headers": { + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A05184087a3031ed02bb45806f4a6c134b580ace5cada64878fca2aaa75acdb91?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A05184087a3031ed02bb45806f4a6c134b580ace5cada64878fca2aaa75acdb91?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "choose-candidate-two-parts.parquet" + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_941030940d23f46826acaa0c6fed8bbc", + "definition": { + "schema_version": 1, + "spec_id": "spec_941030940d23f46826acaa0c6fed8bbc", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_941030940d23f46826acaa0c6fed8bbc", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "ref": "DAC2aAidType206", + "state": "value" + }, + "property": "dac2aAidType" + }, + { + "binding": { + "state": "unbound" + }, + "property": "dacTypeOfFinance" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2022, + "start_year": 2015 + } + } + }, + "content_version": "cv_9362a741d742d00a0f4f5d671e0b400c", + "prepared_at": "2026-10-20T16:52:58Z", + "coverage": { + "rows": 372, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 48, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 8 + } + ], + "window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022, + "origin": "query" + } + }, + "citation": { + "text": "OECD DAC2A (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=dac2a&pg=0&snb=1&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_DAC2%40DF_DAC2A&df[ag]=OECD.DCD.FSD&df[vs]=1.6&dq=.DPGC.206.USD.Q&lom=LASTNPERIODS&lo=5&to[TIME_PERIOD]=false&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "DAC2A is the OECD Development Assistance Committee's table of ODA disbursements by donor and recipient country or region. It covers bilateral donors and multilateral agencies reporting their own outflows, and includes the OECD's estimate of each donor's core multilateral contributions attributed to recipients.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip", + "attribution": "OECD (2026), OECD DAC2A, OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip (accessed on 2026-10-12)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1960-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The OECD publishes DAC2A in April, June, September and December. The complete table is downloaded from the OECD each time it is republished, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets. The totals DAC2A reports for groups of providers, such as all DAC countries, and for groups of recipients, such as regions and income groups, are included as providers and recipients of their own. Where two provider codes name the same organisation and report the same figures, the figures are counted once. Where two recipient codes name the same organisation, such as IDA and IDA's Multilateral Debt Relief Initiative, their flows are added." + }, + { + "transformation": "Select figures", + "description": "Only figures in current US dollars are included, not constant US dollars. Only flows to recipients on Part I of the DAC List are included: the developing countries, and the multilateral organisations DAC2A reports as recipients, such as development banks and UN agencies. Flows to Part II recipients, the countries in transition, are excluded." + }, + { + "transformation": "Convert to whole units", + "description": "DAC2A reports amounts in millions, which are converted to whole units. ODA per person and ODA as a share of GNI are kept as reported." + }, + { + "transformation": "Select dimensions", + "description": "Each figure is reported by year, provider, recipient and type of aid, such as grants, repayments, interest received, or debt forgiven or rescheduled. DAC2A is a table of disbursements, so every figure, repayments and interest included, is recorded as a disbursement. Figures are marked as gross or net, except where DAC2A does not say which, and as grants or non-grants where the type of aid is wholly one or the other. Imputed multilateral ODA, the OECD's estimate of each provider's share of multilateral organisations' ODA, is marked as modelled. ODA as a share of GNI records the recipient's GNI as its denominator, and ODA per person records the recipient's population." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "ODA disbursements by donor and recipient country or region, including the OECD's imputed multilateral contributions, and ODA per person and as a share of recipient GNI." + } + ] + } + ] + } + } + ] + }, + "trace": { + "applied_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022, + "origin": "query" + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00259-rpx", + "code_index_stamp": { + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T13:18:18Z", + "graph_endpoint": "graph_release" + }, + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "source_revisions": [ + { + "source": "provenance/OECDDAC2A", + "revision": "2026-10-15" + } + ], + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 372 + } + ], + "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "family_member_count": 1, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDDAC2A", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253" + }, + { + "axis": "measurementMethod", + "ref": null, + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "1962969911839422253" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253" + } + ], + "normalisations": [], + "frame_grammar_version": "1.1.0", + "materialiser_build": "7175fe98eec005479f1397936dc011ad120092d5", + "capability_version": "dset_1e6cd9546fac19e9", + "served_from": "materialise", + "confirmed_at": "2026-10-20T16:52:58.346624+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:8fd31163adf485e022515e99d523bd1b93a1274726800598df8583981bc0984d", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 10503, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T16:52:58.292456+00:00", + "tier": "working", + "url": "/api/datasets/spec_941030940d23f46826acaa0c6fed8bbc/cv_9362a741d742d00a0f4f5d671e0b400c/files/sha256:8fd31163adf485e022515e99d523bd1b93a1274726800598df8583981bc0984d" + }, + { + "artifact_digest": "sha256:27b4eefb8edbb7ed613cf134d8df4fba5dfeab885ed8c2f210c26e35032df8bc", + "rendering": { + "statistics": "series" + }, + "bytes": 8083, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T16:52:58.292456+00:00", + "tier": "working", + "url": "/api/datasets/spec_941030940d23f46826acaa0c6fed8bbc/cv_9362a741d742d00a0f4f5d671e0b400c/files/sha256:27b4eefb8edbb7ed613cf134d8df4fba5dfeab885ed8c2f210c26e35032df8bc" + } + ], + "series_count": 48, + "output_options": { + "capability_version": "dset_1e6cd9546fac19e9", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 48 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 8 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 48, + "covered": 48 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 48, + "covered": 47 + }, + "missing": [ + { + "ref": "country/SSD", + "label": "South Sudan" + } + ], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 48, + "covered": 48 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 48, + "covered": 48 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 48, + "covered": 48 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "financingRecipient", + "columns": "time_period", + "state": "available", + "width": 9, + "cells": 432 + }, + { + "index": "time_period", + "columns": "financingRecipient", + "state": "available", + "width": 49, + "cells": 392 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_941030940d23f46826acaa0c6fed8bbc/cv_9362a741d742d00a0f4f5d671e0b400c/files/sha256:8fd31163adf485e022515e99d523bd1b93a1274726800598df8583981bc0984d" + }, + "response": { + "status": 302, + "headers": { + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A8fd31163adf485e022515e99d523bd1b93a1274726800598df8583981bc0984d?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A8fd31163adf485e022515e99d523bd1b93a1274726800598df8583981bc0984d?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "choose-candidate-two-parts-2.parquet" + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "mixed", + "sentence": "GNI has 3 readings. Primary income for gross of fixed capital consumption in 49 places. World Bank International Debt Statistics (IDS) · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in 49 places. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in 49 places. World Development Indicators · 2015 to 2022. You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself. Germany's gross disbursements to the 48 countries in Sub-Saharan Africa for official development assistance, 2015 to 2022. Current US dollars · OECD DAC2a. You asked for sub-Saharan Africa. This shows the countries in it, each on its own.", + "complete": false, + "specs": [ + "spec_941030940d23f46826acaa0c6fed8bbc" + ], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 3 + } + ] + } + }, + { + "answer": { + "kind": "resolution", + "status": "definite", + "sentence": "Primary income for gross of fixed capital consumption in 49 places, 2015 to 2022. Current US dollars · World Bank International Debt Statistics (IDS). You asked for Germany, Eritrea, Namibia, South Sudan, and Seychelles. The data holds no values for them. Germany's gross disbursements to the 48 countries in Sub-Saharan Africa for official development assistance, 2015 to 2022. Current US dollars · OECD DAC2a. This shows the 48 countries in Sub-Saharan Africa, each on its own.", + "complete": true, + "specs": [ + "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", + "spec_941030940d23f46826acaa0c6fed8bbc" + ], + "gaps": [] + } + }, + { + "dataset": { + "rows": 720, + "columns": [ + "part", + "stat_var", + "stat_var_label", + "observationAbout", + "observationAbout_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "dac2aAidType", + "dac2aAidType_label" + ], + "part_rows": [ + { + "part": "GNI", + "rows": 348 + }, + { + "part": "ODA disbursements", + "rows": 372 + } + ], + "complete": true, + "members": [ + { + "parts": [ + "GNI" + ], + "spec_id": "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", + "content_version": "cv_18a63cb9e24a4ce6dfcd1c60f0c5a470", + "sentence": "Primary income for gross of fixed capital consumption in 49 places, 2015 to 2022. Current US dollars · World Bank International Debt Statistics (IDS)." + }, + { + "parts": [ + "ODA disbursements" + ], + "spec_id": "spec_941030940d23f46826acaa0c6fed8bbc", + "content_version": "cv_9362a741d742d00a0f4f5d671e0b400c", + "sentence": "Germany's gross disbursements to the 48 countries in Sub-Saharan Africa for official development assistance, 2015 to 2022. Current US dollars · OECD DAC2a." + } + ], + "missing": [], + "search_warning": true + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.parquet b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.parquet new file mode 100644 index 0000000000000000000000000000000000000000..6ef281866273f7980336c642de5b1441dc042e0a GIT binary patch literal 9453 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 dict[str, Any]: def dataset_outcome( - members: Sequence[Member], *, missing: Sequence[Mapping[str, Any]] = () + members: Sequence[Member], + *, + missing: Sequence[Mapping[str, Any]] = (), + search_warning: bool | None = None, ) -> dict[str, Any]: """A dataset outcome. Several members stack into one long table with a - `part` column first, then every member's columns in member order.""" + `part` column first, holding each member's `part_label`, then every + member's columns in member order.""" + summaries = [ + { + "parts": member.parts, + "spec_id": member.spec_id, + "content_version": member.content_version, + "sentence": member.sentence, + } + for member in members + ] + dataset: dict[str, Any] = {"rows": sum(member.rows for member in members)} if len(members) == 1: - columns = list(members[0].columns) + dataset["columns"] = list(members[0].columns) else: - columns = ["part", *dict.fromkeys(c for m in members for c in m.columns)] - summary = dataset_summary( - [ - { - "parts": member.parts, - "spec_id": member.spec_id, - "content_version": member.content_version, - "sentence": member.sentence, - } - for member in members - ], - missing, - ) - rows = sum(member.rows for member in members) - return {"dataset": {"rows": rows, "columns": columns, **summary}} + columns = dict.fromkeys(c for m in members for c in m.columns) + dataset["columns"] = ["part", *columns] + dataset["part_rows"] = [ + {"part": part_label(summary), "rows": member.rows} + for summary, member in zip(summaries, members, strict=True) + ] + summary = dataset_summary(summaries, missing, search_warning=search_warning) + return {"dataset": {**dataset, **summary}} def parquet_shape(data: bytes) -> tuple[int, list[str]]: @@ -490,14 +501,6 @@ def _reached[T](results: list[T], step: str) -> T: return results[0] -class StepError(Exception): - """A step ended in an error a client raises.""" - - def __init__(self, error: str, code: str | None = None) -> None: - super().__init__(f"{error} {code}") - self.outcome = error_outcome(error, code) - - class ShapeError(Exception): """The live answer no longer has the shape the scenario is named for.""" @@ -527,7 +530,7 @@ def _step(self, step: dict[str, Any], run: Callable[[], dict[str, Any]]) -> None self.call.append(step) try: outcome = run() - except StepError as refusal: + except ClientError as refusal: outcome = refusal.outcome self.expect.append(outcome) @@ -552,17 +555,13 @@ def run() -> dict[str, Any]: return _reached(answers, "the search") def choose( - self, answer: Answer, option: int | str, *, part: int | None = None - ) -> Answer: - """A choice in a one-part answer is local for candidates and posts the - option's data_query for a no_data part. In a several-part answer it - posts dataset_resubmit, with the chosen option's part as a parsed - entry, each definite part as an identity entry and each other part's - restatement as a parsed entry.""" - index = ( - part if part is not None else answer_gaps(answer, self.gap_kinds)[0]["part"] - ) - chosen = answer.parts[index] + self, answer: Answer, option: int | str, *, part: int | str | None = None + ) -> Answer | None: + """Settles a part by the rules `choice_for` and `choice_input` state, + and returns the new answer, or None when the choice refused. + + A choice among one part's candidates is local; any other choice posts + to Search.""" step: dict[str, Any] = {"op": "choose"} if part is not None: step["part"] = part @@ -570,50 +569,42 @@ def choose( answers: list[Answer] = [] def run() -> dict[str, Any]: - if chosen["status"] == "candidates": - require(len(answer.parts) == 1, "a candidates choice here is one-part") - if not isinstance(option, int): - raise ShapeError("candidates are chosen by index here") - answers.append(candidate_answer(answer, index, option)) - return self._answered(answers[0]) - options = chosen["no_data"]["options"] - picked = next( - (o for i, o in enumerate(options) if option in (i, o["label"])), None - ) - if picked is None: - raise ShapeError(f"the gap offers no option {option!r}") - if len(answer.parts) == 1: - answers.append(self._resolve(picked["data_query"])) - return self._answered(answers[0]) - entries = [ - {"entry_kind": "parsed", "part": picked["data_query"]["parts"][0]} - if i == index - else _resubmit_entry(p) - for i, p in enumerate(answer.parts) - ] - answers.append( - self._resolve({"kind": "dataset_resubmit", "entries": entries}) - ) + choice = choice_for(answer, self.gap_kinds, part, option) + posts = choice_input(answer, choice) + if posts is not None: + answers.append(self._resolve(posts)) + elif choice.candidate is not None: + answers.append(candidate_answer(answer, choice.part, choice.candidate)) return self._answered(answers[0]) self._step(step, run) - return _reached(answers, "the choice") - - def fetch_answer(self, answer: Answer, *, partial: bool = False) -> None: + return answers[0] if answers else None + + def fetch_answer( + self, answer: Answer, *, partial: bool = False, strict: bool = False + ) -> None: + """Builds the answer's readings. A declined or catalogue answer, a gap + outside a partial fetch, a partial fetch with no reading, and a strict + fetch whose readings depart from the question each raise before any + request.""" step: dict[str, Any] = {"op": "fetch"} if partial: step["partial"] = True + if strict: + step["strict"] = True def run() -> dict[str, Any]: if answer.body["kind"] != "resolution": - raise StepError("DeclinedError") + raise ClientError("DeclinedError") gaps = answer_gaps(answer, self.gap_kinds) - if gaps and not partial: - raise StepError("IncompleteAnswerError") - members = [ - self.build(parts, spec, None) for parts, spec in _members(answer) - ] - return dataset_outcome(members, missing=gaps) + readings = _members(answer) + if gaps and (not partial or not readings): + raise ClientError("IncompleteAnswerError") + warns = search_warns(answer) + if warns and strict: + raise ClientError("SearchWarning") + members = [self.build(parts, spec, None) for parts, spec in readings] + return dataset_outcome(members, missing=gaps, search_warning=warns) self._step(step, run) @@ -792,7 +783,7 @@ def _raise_problem(self, response: Response) -> None: if response.status < 400: return code = refusal_code(response.json()) - raise StepError(error_class(response.status, code, self.actions), code) + raise ClientError(error_class(response.status, code, self.actions), code) def _window(window: str | tuple[int, int]) -> dict[str, Any]: @@ -812,21 +803,6 @@ def _build_body(spec: Spec, scope: dict[str, Any] | None) -> dict[str, Any]: return {"schema_version": 1, "input": input_, "options": dict(RENDERING)} -def _resubmit_entry(part: dict[str, Any]) -> dict[str, Any]: - if part["status"] == "definite": - spec = part["spec"] - entry = { - "entry_kind": "identity", - "variable_text": part["variable_text"], - "identity": spec["definition"]["identity"], - } - groups = spec["resolved"].get("entity_groups") - if groups: - entry["entity_groups"] = groups - return entry - return {"entry_kind": "parsed", "part": part["restatement"]} - - def with_place_options(body: Any) -> Any: """`body` with each no_data `data_query` replaced by the `options` a choice refusal carries once Search serves them: per ambiguous wording and @@ -866,6 +842,14 @@ def with_place_options(body: Any) -> Any: TWO_PLACES = "Kenya's GDP, and ODA disbursements from Germany to Congo" DECLINED = "should donors give more aid to Kenya?" CATALOGUE = "what data do you have?" +TOP5 = "top 5 donors to Ethiopia in 2022" +CANDIDATES_BESIDE_GROUP = ( + "GNI of Germany from 2015 to 2022, and ODA disbursements from Germany to " + "sub-Saharan Africa" +) +TWO_CANDIDATES = "GNI of Germany and tax revenue of Kenya from 2015 to 2022" +CANDIDATES_BESIDE_UNRESTATED = "GNI of Germany and debt of Kenya from 2015 to 2022" +GROUP_DEFINITE = "GDP of the least developed countries" ASYNC = "ODA received by every recipient country from every provider (DAC2a) from 2018 to 2024" NARROW_WINDOW = (2020, 2023) SYNC_ROWS = 100_000 @@ -1039,6 +1023,60 @@ def run(s: Session, ctx: Context) -> None: return run +def _statuses(answer: Answer) -> list[str]: + return [part.get("status") for part in answer.parts] + + +def _search_warning_top5(s: Session, ctx: Context) -> None: + answer = s.search(TOP5) + require(_statuses(answer) == ["definite"], "one definite part") + operations = answer.parts[0].get("operations") or [] + require(any(o.get("verb") == "rank" for o in operations), "the rank is not done") + s.fetch_answer(answer, strict=True) + s.fetch_answer(answer) + + +def _choose_candidate_two_parts(s: Session, ctx: Context) -> None: + answer = s.search(CANDIDATES_BESIDE_GROUP) + require(_statuses(answer) == ["candidates", "definite"], "candidates, definite") + require( + bool(answer.parts[1]["spec"]["resolved"].get("entity_groups")), + "the definite part names an entity group", + ) + chosen = s.choose(answer, 0, part=0) + require( + chosen is not None and _statuses(chosen) == ["definite", "definite"], + "the choice answers both parts definite", + ) + if chosen is not None: + s.fetch_answer(chosen) + + +def _resubmit_candidates_sibling(s: Session, ctx: Context) -> None: + answer = s.search(TWO_CANDIDATES) + require(_statuses(answer) == ["candidates", "candidates"], "two candidates parts") + chosen = s.choose(answer, 0, part=0) + require( + chosen is not None and _statuses(chosen) == ["definite", "candidates"], + "the choice settles part 0 and leaves part 1's candidates", + ) + if chosen is not None: + before = [c["spec_id"] for c in answer.parts[1]["candidates"]["specs"]] + after = [c["spec_id"] for c in chosen.parts[1]["candidates"]["specs"]] + require(before == after, "the candidates keep their posted order") + + +def _resubmit_placeholder(s: Session, ctx: Context) -> None: + answer = s.search(CANDIDATES_BESIDE_UNRESTATED) + require(_statuses(answer) == ["candidates", "no_data"], "candidates, no_data") + require("restatement" not in answer.parts[1], "part 1 has no restatement") + chosen = s.choose(answer, 0, part=0) + require( + chosen is not None and _statuses(chosen)[0] == "definite", + "the choice settles part 0", + ) + + RECORDED = ( Recorded( "answer-definite-fetch", @@ -1149,6 +1187,35 @@ def run(s: Session, ctx: Context) -> None: "offer none.", _search_place(TWO_PLACES, 2), ), + Recorded( + "search-warning-top5", + "A question asking for a ranking answers one definite part that does not run the rank, " + "with a departure and two warn-severity warnings. A strict fetch raises SearchWarning " + "before any build; a fetch that is not strict builds the dataset and issues one " + "SearchWarning for all of them.", + _search_warning_top5, + ), + Recorded( + "choose-candidate-two-parts", + "Choosing candidate 0 on the candidates part of a two-part answer posts dataset_resubmit " + "with one entry per part in part order: the chosen candidate's identity, and the definite " + "part's identity with its entity_groups. Both parts answer definite, and the fetch stacks " + "two members with each member's parts as its part column value.", + _choose_candidate_two_parts, + ), + Recorded( + "resubmit-candidates-sibling", + "Choosing candidate 0 on part 0 of an answer with two candidates parts posts part 1 as a " + "candidates entry: its candidate set in the server's order, each with its identity, and " + "its ordering and truncated echoed. Part 1 answers candidates again in the same order.", + _resubmit_candidates_sibling, + ), + Recorded( + "resubmit-placeholder-without-restatement", + "Choosing candidate 0 on part 0 posts part 1, a no_data part with no restatement, as a " + "placeholder entry with its variable_text, status and reason.", + _resubmit_placeholder, + ), ) @@ -1210,11 +1277,15 @@ class Derived: @dataclass(frozen=True) class Synthetic: + """A scenario derived from a recorded one. A `live` derivation records + some of its exchanges against the base URL.""" + name: str derived_from: str edit: str description: str derive: Callable[[dict[str, Any], Context], Derived] + live: bool = False def _same(parent: dict[str, Any], exchanges: list[dict[str, Any]]) -> Derived: @@ -1288,13 +1359,8 @@ def _signed_url_refused(parent: dict[str, Any], ctx: Context) -> Derived: return _same(parent, exchanges) -def _unknown_part_status(parent: dict[str, Any], ctx: Context) -> Derived: - exchanges = copy.deepcopy(parent["exchanges"]) - body = exchanges[0]["response"]["json"] +def _deferred(body: dict[str, Any]) -> None: body["parts"][1]["status"] = "deferred" - expect = copy.deepcopy(parent["expect"]) - expect[0] = answer_outcome(answer_from_body(body), gap_kinds(ctx.actions)) - return Derived(copy.deepcopy(parent["call"]), exchanges, expect) def _unknown_enum_value(parent: dict[str, Any], ctx: Context) -> Derived: @@ -1330,20 +1396,28 @@ def _renamed_strict_field(parent: dict[str, Any], ctx: Context) -> Derived: ) -def _place_choice( - option: str, part: int | None +type BodyEdit = Callable[[Any, Context], Any] + + +def _with_options(body: Any, ctx: Context) -> Any: + return with_place_options(body) + + +def _choice( + option: int | str, + part: int | str | None = None, + *, + edit: BodyEdit | None = None, ) -> Callable[[dict[str, Any], Context], Derived]: + """The parent's search, its answer body changed by `edit`, then a choice. + A choice that posts is recorded live, its answer changed by + `with_place_options`; one that refuses makes no request.""" + def derive(parent: dict[str, Any], ctx: Context) -> Derived: - canned = [ - { - **e, - "response": { - **e["response"], - "json": with_place_options(e["response"]["json"]), - }, - } - for e in copy.deepcopy(parent["exchanges"]) - ] + canned = copy.deepcopy(parent["exchanges"][:1]) + if edit is not None: + response = canned[0]["response"] + response["json"] = edit(response["json"], ctx) session = ctx.session("synthetic", canned=canned, edit=with_place_options) answer = session.search(parent["call"][0]["question"]) session.choose(answer, option, part=part) @@ -1352,6 +1426,104 @@ def derive(parent: dict[str, Any], ctx: Context) -> Derived: return derive +def _definite_beside(body: Any, ctx: Context) -> Any: + """Part 0 becomes the definite part a live search for GROUP_DEFINITE + answers, and the other part's data_query becomes options.""" + body = with_place_options(body) + (part,) = copy.deepcopy(ctx.definite_answer(GROUP_DEFINITE).parts) + require(bool(part["spec"]["resolved"].get("entity_groups")), "a group part") + body["parts"][0] = part + body["status"] = "mixed" + return body + + +def _choice_refused( + option: int | str, part: int | str | None = None, *, options: bool = False +) -> Callable[[dict[str, Any], Context], Derived]: + choose = _choice(option, part, edit=_with_options if options else None) + + def derive(parent: dict[str, Any], ctx: Context) -> Derived: + derived = choose(parent, ctx) + require( + derived.expect[-1] == error_outcome("InvalidRequestError"), + "the choice refuses", + ) + return derived + + return derive + + +def _answer_edit( + change: Callable[[dict[str, Any]], None], +) -> Callable[[dict[str, Any], Context], Derived]: + """The parent with its first answer body changed, and that answer's + outcome derived again.""" + + def derive(parent: dict[str, Any], ctx: Context) -> Derived: + exchanges = copy.deepcopy(parent["exchanges"]) + body = exchanges[0]["response"]["json"] + change(body) + expect = copy.deepcopy(parent["expect"]) + expect[0] = answer_outcome(answer_from_body(body), gap_kinds(ctx.actions)) + return Derived(copy.deepcopy(parent["call"]), exchanges, expect) + + return derive + + +def _timed_out(body: dict[str, Any]) -> None: + body["diagnostics"]["timed_out"] = True + + +def _unsupported(body: dict[str, Any]) -> None: + part = body["parts"][1] + del part["no_data"] + part["status"] = "unsupported" + part["unsupported"] = { + "code": "scope_too_broad", + "pointer": "/definition/identity", + "detail": "the family is too broad to settle; bind a what or how slot", + } + + +def _unknown_kind(parent: dict[str, Any], ctx: Context) -> Derived: + exchanges = copy.deepcopy(parent["exchanges"]) + exchanges[0]["response"]["json"]["kind"] = "verdict" + return Derived( + copy.deepcopy(parent["call"]), exchanges, [error_outcome("ContractError")] + ) + + +def _partial_nothing_answered(parent: dict[str, Any], ctx: Context) -> Derived: + require(parent["expect"][0]["answer"]["specs"] == [], "no part has a reading") + return Derived( + [*copy.deepcopy(parent["call"]), {"op": "fetch", "partial": True}], + copy.deepcopy(parent["exchanges"]), + [*copy.deepcopy(parent["expect"]), error_outcome("IncompleteAnswerError")], + ) + + +_INFO_NOTICE = { + "code": "retrieval_score_weak", + "severity": "info", + "message": ( + "the chosen reading's match to the query is weak; treat it with less " + "confidence than a strong match." + ), +} + + +def _strict_info_notice(parent: dict[str, Any], ctx: Context) -> Derived: + exchanges = copy.deepcopy(parent["exchanges"]) + exchanges[0]["response"]["json"]["parts"][0]["warnings"].append(dict(_INFO_NOTICE)) + call = copy.deepcopy(parent["call"]) + call[1]["strict"] = True + require( + parent["expect"][1]["dataset"]["search_warning"] is False, + "the parent's fetch issues no SearchWarning", + ) + return Derived(call, exchanges, copy.deepcopy(parent["expect"])) + + SYNTHETIC = ( Synthetic( "search-retry-after-503", @@ -1402,7 +1574,7 @@ def derive(parent: dict[str, Any], ctx: Context) -> Derived: "A part status the client does not know parses as an unknown part, counts as an " "unknown gap with no options, and makes fetching the answer raise " "IncompleteAnswerError.", - _unknown_part_status, + _answer_edit(_deferred), ), Synthetic( "answer-unknown-enum-value", @@ -1436,7 +1608,8 @@ def derive(parent: dict[str, Any], ctx: Context) -> Derived: "A place refusal offers one option per candidate, so its choice gap has two options. " 'Choosing "Congo [DRC]" by label in a one-part answer posts that option\'s data_query ' "unchanged as the input of a new search, which answers definite.", - _place_choice("Congo [DRC]", None), + _choice("Congo [DRC]", edit=_with_options), + live=True, ), Synthetic( "choose-place-two-parts", @@ -1446,7 +1619,131 @@ def derive(parent: dict[str, Any], ctx: Context) -> Derived: "entry per part in part order: the chosen option's data_query part as a parsed entry, " "and part 0, still a refusal, as a parsed entry of its restatement. Part 1 answers " "definite and part 0 refuses again with its two options.", - _place_choice("Congo [DRC]", 1), + _choice("Congo [DRC]", 1, edit=_with_options), + live=True, + ), + Synthetic( + "choose-place-beside-definite", + "search-two-parts-place-ambiguous", + f"Part 0 becomes the definite part, entity groups included, of a live search for " + f'"{GROUP_DEFINITE}"; part 1\'s data_query becomes options; the choice is recorded live.', + 'Choosing "Congo [DRC]" on part 1 beside a definite part posts dataset_resubmit with the ' + "definite part's identity and entity_groups as an identity entry, and the chosen " + "option's data_query part as a parsed entry. Both parts answer definite.", + _choice("Congo [DRC]", 1, edit=_definite_beside), + live=True, + ), + Synthetic( + "choose-part-by-mention", + "search-place-ambiguous", + "The refusal's data_query becomes options, and the choice is recorded live.", + 'Naming the part by "Congo", a word its options mention, and the option by label posts ' + "that option's data_query, as naming the part by index does.", + _choice("Congo [DRC]", "Congo", edit=_with_options), + live=True, + ), + Synthetic( + "answer-timed-out", + "answer-mixed-fetch-raises", + "The answer's diagnostics.timed_out becomes true.", + "A no_data part of an answer whose diagnostics say Search timed out is a timed_out gap, " + "whatever its reason, and fetching the answer raises IncompleteAnswerError.", + _answer_edit(_timed_out), + ), + Synthetic( + "answer-unsupported-part", + "answer-mixed-fetch-raises", + "Part 1 becomes an unsupported part with code scope_too_broad.", + "An unsupported part is an unsupported gap with no options, and fetching the answer " + "raises IncompleteAnswerError.", + _answer_edit(_unsupported), + ), + Synthetic( + "answer-unknown-kind", + "search-place-ambiguous", + 'The answer\'s kind becomes "verdict", a kind no client knows.', + "A search response whose kind the client does not know raises ContractError, since the " + "client cannot read the answer.", + _unknown_kind, + ), + Synthetic( + "fetch-partial-nothing-answered", + "search-place-ambiguous", + "A partial fetch of the answer follows the search.", + "A partial fetch of an answer in which no part has a reading raises " + "IncompleteAnswerError with no request.", + _partial_nothing_answered, + ), + Synthetic( + "fetch-strict-info-notice", + "answer-definite-fetch", + "Part 0 carries an info-severity warning, and the fetch is strict.", + "An info-severity warning issues no SearchWarning, so a strict fetch of the answer " + "builds the same dataset.", + _strict_info_notice, + ), + Synthetic( + "choose-refused-no-choice", + "answer-definite-fetch", + "A choice of option 0 follows the search.", + "Choosing on an answer in which no part awaits a choice raises InvalidRequestError " + "with no request.", + _choice_refused(0), + ), + Synthetic( + "choose-refused-two-choices", + "search-two-parts-place-ambiguous", + "A choice of option 0, naming no part, follows the search.", + "Choosing without naming a part when two parts await a choice raises " + "InvalidRequestError with no request.", + _choice_refused(0), + ), + Synthetic( + "choose-refused-no-options", + "search-place-ambiguous", + "A choice of option 0 follows the search.", + "Choosing in a choice gap that offers no options raises InvalidRequestError with no " + "request.", + _choice_refused(0), + ), + Synthetic( + "choose-refused-option-out-of-range", + "answer-candidates-choose-fetch", + "A choice of candidate 3 follows the search.", + "Choosing candidate 3 of three raises InvalidRequestError with no request.", + _choice_refused(3), + ), + Synthetic( + "choose-refused-unknown-label", + "search-place-ambiguous", + 'The refusal\'s data_query becomes options, and a choice of "Congo [Nowhere]" follows.', + "Choosing an option by a label no option has raises InvalidRequestError with no " + "request.", + _choice_refused("Congo [Nowhere]", options=True), + ), + Synthetic( + "choose-refused-answered-part", + "answer-mixed-fetch-raises", + "A choice of option 0 on part 0, which has a reading, follows the search.", + "Choosing on a part that already has a reading raises InvalidRequestError with no " + "request.", + _choice_refused(0, 0), + ), + Synthetic( + "choose-refused-unknown-part", + "answer-mixed-fetch-raises", + 'A choice of option 0 on part "rainfall" follows the search.', + "Naming a part by words that are neither a part's variable text nor a word its " + "options mention raises InvalidRequestError with no request.", + _choice_refused(0, "rainfall"), + ), + Synthetic( + "choose-refused-mention-names-two-parts", + "search-two-parts-place-ambiguous", + 'Each refusal\'s data_query becomes options, and a choice on part "Congo" follows.', + 'Naming a part by "Congo", a word both parts\' options mention, raises ' + "InvalidRequestError with no request.", + _choice_refused("Congo [DRC]", "Congo", options=True), ), ) diff --git a/tools/tests/test_capture_client_contract.py b/tools/tests/test_capture_client_contract.py index 0aed3df..5b996d5 100644 --- a/tools/tests/test_capture_client_contract.py +++ b/tools/tests/test_capture_client_contract.py @@ -92,7 +92,10 @@ def _without_shapes(expect: list[dict[str, Any]]) -> list[dict[str, Any]]: expect = copy.deepcopy(expect) for outcome in expect: if "dataset" in outcome: - del outcome["dataset"]["rows"], outcome["dataset"]["columns"] + dataset = outcome["dataset"] + del dataset["rows"], dataset["columns"] + for entry in dataset.get("part_rows", []): + del entry["rows"] return expect @@ -117,7 +120,11 @@ def _drive(session: Any, call: list[dict[str, Any]]) -> None: case {"op": "fetch", "ref": ref}: session.fetch_ref(ref) case {"op": "fetch"}: - session.fetch_answer(answer, partial=step.get("partial", False)) + session.fetch_answer( + answer, + partial=step.get("partial", False), + strict=step.get("strict", False), + ) case {"op": "mint", "spec": spec}: session.mint( capture.Spec( @@ -128,9 +135,14 @@ def _drive(session: Any, call: list[dict[str, Any]]) -> None: session.result() -@pytest.mark.parametrize( - "name", [*_records("recorded"), "choose-place-one-part", "choose-place-two-parts"] -) +_LIVE = sorted(d.name for d in capture.SYNTHETIC if d.live) + + +def test_every_synthetic_record_has_a_definition() -> None: + assert sorted(d.name for d in capture.SYNTHETIC) == _records("synthetic") + + +@pytest.mark.parametrize("name", [*_records("recorded"), *_LIVE]) def test_the_recorder_reproduces_each_record_from_its_steps(name: str) -> None: record = _load(name) served = _Served(record) @@ -212,9 +224,7 @@ def test_every_absolute_url_loses_its_query(url: str, expected: str) -> None: assert capture.redact_external_url(url) == expected -@pytest.mark.parametrize( - "name", [n for n in _records("synthetic") if not n.startswith("choose-place-")] -) +@pytest.mark.parametrize("name", [n for n in _records("synthetic") if n not in _LIVE]) def test_each_derived_record_follows_from_its_parent(name: str) -> None: record = _load(name) definition = next(d for d in capture.SYNTHETIC if d.name == name) @@ -285,9 +295,17 @@ def test_several_members_stack_with_a_part_column_first() -> None: other = capture.Member( [], {"spec_id": "spec_b"}, "cv_b", "B.", "sha256:b", 3, ["y", "z"] ) - dataset = capture.dataset_outcome([member, other])["dataset"] + unnamed = capture.Member( + ["p", "q"], {"spec_id": "spec_b"}, "cv_b", "B.", "sha256:b", 3, ["y", "z"] + ) + dataset = capture.dataset_outcome([member, unnamed])["dataset"] assert dataset["columns"] == ["part", "x", "y", "z"] assert dataset["rows"] == 5 + assert dataset["part_rows"] == [ + {"part": "A.", "rows": 2}, + {"part": "p; q", "rows": 3}, + ] + assert "part_rows" not in capture.dataset_outcome([other])["dataset"] assert capture.dataset_outcome([member])["dataset"]["columns"] == ["x", "y"] diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index 0f004e3..94512b9 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -34,6 +34,15 @@ _SEARCH = "scenarios/search-place-ambiguous.json" _FETCH = "scenarios/fetch-spec-known-sentence.json" _MIXED = "scenarios/answer-mixed-fetch-raises.json" +_FOLDED = "scenarios/answer-several-readings-folded.json" +_TOP5 = "scenarios/search-warning-top5.json" + + +def _posted(index: int, change: Callable[[Any], None]) -> Callable[[Any], None]: + """Changes the input the record's second exchange posts.""" + return lambda doc: change( + doc["exchanges"][1]["request"]["json"]["input"]["entries"][index] + ) @pytest.fixture @@ -113,6 +122,14 @@ def _first_gap(**fields: Any) -> Callable[[Any], None]: return _set_outcome(0, lambda o: o["answer"]["gaps"][0].update(fields)) +def _part_rows(change: Callable[[Any], None]) -> Callable[[Any], None]: + return _set_outcome(1, lambda o: change(o["dataset"])) + + +def _set_step(index: int, **fields: Any) -> Callable[[Any], None]: + return lambda doc: doc["call"][index].update(fields) + + @pytest.mark.parametrize( ("target", "change", "expected"), [ @@ -278,6 +295,115 @@ def _first_gap(**fields: Any) -> Callable[[Any], None]: _set_outcome(1, lambda o: o["dataset"]["columns"].pop(0)), "the part column comes first", ), + ( + _FOLDED, + _part_rows(lambda d: d["part_rows"][0].update(part="health")), + "part_rows names", + ), + ( + _FOLDED, + _part_rows(lambda d: d.pop("part_rows")), + "part_rows is given exactly when", + ), + ( + _FOLDED, + _part_rows(lambda d: d["part_rows"][1].update(rows=1)), + "rows do not sum", + ), + ( + _TOP5, + _set_outcome(2, lambda o: o["dataset"].update(search_warning=False)), + "step 2 expects", + ), + ( + _TOP5, + _set_step(1, strict=False), + "the steps make a POST /datasets the record lacks", + ), + ( + "scenarios/fetch-strict-info-notice.json", + _set_body( + 0, lambda body: body["parts"][0]["warnings"][0].update(severity="warn") + ), + "the steps never make exchanges 1 to 3", + ), + ( + "scenarios/answer-timed-out.json", + _first_gap(kind="not_understood"), + "step 0 expects", + ), + ( + "scenarios/answer-unsupported-part.json", + _first_gap(kind="unknown"), + "step 0 expects", + ), + ( + "scenarios/answer-unknown-kind.json", + _set_body(0, lambda body: body.update(kind="resolution")), + "step 0 expects", + ), + ( + "scenarios/fetch-partial-nothing-answered.json", + _set_outcome(1, lambda o: o["error"].update({"class": "DeclinedError"})), + "step 1 expects", + ), + ( + "scenarios/choose-refused-option-out-of-range.json", + _set_step(1, option=2), + "step 1 expects", + ), + ( + "scenarios/choose-refused-mention-names-two-parts.json", + _set_step(1, part=1), + "the steps make a POST /search/resolve the record lacks", + ), + ( + "scenarios/choose-part-by-mention.json", + _set_step(1, part="Germany"), + "the steps never make exchanges 1 to 1", + ), + ( + "scenarios/choose-candidate-two-parts.json", + _posted(1, lambda entry: entry.pop("entity_groups")), + "where the rules post", + ), + ( + "scenarios/resubmit-candidates-sibling.json", + _posted(1, lambda entry: entry["candidates"].reverse()), + "where the rules post", + ), + ( + "scenarios/resubmit-candidates-sibling.json", + _posted(1, lambda entry: entry.update(ordering="broadest_first")), + "where the rules post", + ), + ( + "scenarios/resubmit-placeholder-without-restatement.json", + _posted(1, lambda entry: entry.update(reason="entity_ambiguous")), + "where the rules post", + ), + ( + "scenarios/choose-place-beside-definite.json", + _posted(0, lambda entry: entry.update(entry_kind="parsed")), + "where the rules post", + ), + ( + "scenarios/choose-place-two-parts.json", + _posted(0, lambda entry: entry.update(entry_kind="placeholder")), + "where the rules post", + ), + ( + "scenarios/fetch-spec-narrowed.json", + lambda doc: doc["exchanges"][1]["request"]["json"]["input"]["entries"][ + 0 + ].update(variable_text="ODA"), + "where the rules post", + ), + ( + _FETCH, + lambda doc: doc["call"].append({"op": "fetch"}), + "does not follow a step in ['choose', 'fetch_answer', 'search']", + ), ( _SEARCH, lambda doc: doc["exchanges"].append(doc["exchanges"][0]), @@ -383,6 +509,27 @@ def _first_gap(**fields: Any) -> Callable[[Any], None]: "answer-without-kind", "expect-wrong-content-version", "stacked-without-part-column", + "part-rows-wrong-part-value", + "part-rows-missing", + "part-rows-wrong-sum", + "expect-wrong-search-warning", + "strict-fetch-made-lenient", + "warn-notice-raises-on-strict", + "expect-wrong-timed-out-gap", + "expect-wrong-unsupported-gap", + "known-kind-raises-nothing", + "partial-fetch-nothing-answered", + "refusal-option-in-range", + "refusal-part-named", + "mention-names-no-part", + "definite-entry-without-groups", + "candidates-entry-reordered", + "candidates-entry-ordering-recomputed", + "placeholder-entry-wrong-reason", + "definite-part-posted-parsed", + "restated-part-posted-placeholder", + "identity-resubmit-wrong-variable-text", + "answer-fetch-after-spec-fetch", "exchange-never-made", "exchanges-unfit", "location-v2-signed", diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index 6073eaa..0693922 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -35,9 +35,12 @@ code registered with that status. - Each scenario's `expect` equals the outcomes its steps reach over its exchanges, with error classes and gap kinds from `actions.json`, as - `expected_outcomes` derives them; a dataset's rows and columns are left to - the Parquet bodies. Every absolute URL a record holds, a `url` request or a - `location` header, has the query `X-Goog-Signature=redacted`. + `expected_outcomes` derives them; a dataset's rows, columns and per-part + row counts are left to the Parquet bodies. Each Search request a record + holds posts the input the steps derive: the question, a choice's + data_query or dataset_resubmit entries, or a member's identity. Every + absolute URL a record holds, a `url` request or a `location` header, has + the query `X-Goog-Signature=redacted`. - Each ref example's file name matches its `name` and gets the verdict it states: from `dataset-ref.schema.json`, then from the rules that each member's definition carries its own `spec_id` and that members hold @@ -74,7 +77,13 @@ _OPENAPI_URI = "urn:dfo-client-contract:served-openapi" _ACTION_CHANNELS = {"problem_details", "no_data_reason"} _ANSWER_ONLY_ACTIONS = {"choose", "ask_data_question"} -_ACTS_ON_PREVIOUS = {"choose": {"search", "choose"}, "result": {"mint"}} +# The steps each step that acts on an earlier result may follow. A fetch of the +# answer acts on the last search or choice, so it may follow another such fetch. +_ACTS_ON_PREVIOUS = { + "choose": {"search", "choose"}, + "fetch_answer": {"search", "choose", "fetch_answer"}, + "result": {"mint"}, +} _STRICT_POINTER = re.compile(r"^/components/schemas/([^/]+)/properties/([^/]+)$") @@ -551,6 +560,22 @@ def error_outcome(error: str, code: str | None = None) -> dict[str, Any]: return {"error": {"class": error, "code": code}} +class ClientError(Exception): + """A step ends in `outcome`, an error a client raises.""" + + def __init__(self, error: str, code: str | None = None) -> None: + super().__init__(f"{error} {code}") + self.outcome = error_outcome(error, code) + + +# The answer kinds a client reads. Any other kind raises ContractError. +ANSWER_KINDS = ("resolution", "catalogue", "declined") +# The variable text an identity resubmit sends for a member no answer part names. +UNNAMED_VARIABLE_TEXT = "dataset" +# The warning severities a fetch reports in its SearchWarning; `info` stays quiet. +SHOWN_SEVERITIES = ("warn", "degraded") + + @dataclass(frozen=True, slots=True) class Answer: """A search answer as a client holds it: the response body, its parts, @@ -563,19 +588,23 @@ class Answer: def answer_from_body(body: dict[str, Any]) -> Answer: + """The answer a search response holds; a kind no client knows raises + ContractError.""" + if body.get("kind") not in ANSWER_KINDS: + raise ClientError("ContractError") return Answer( body, body.get("parts", []), body.get("rendered_sentence"), body.get("status") ) -def candidate_answer(answer: Answer, part: int, candidate: int) -> Answer: +def candidate_answer(answer: Answer, part: int, spec: dict[str, Any]) -> Answer: """The answer a choice among one part's candidates makes with no request: - that part definite on the chosen spec, with that spec's sentence.""" + that part definite on the chosen spec, keeping its other members, with + that spec's sentence.""" chosen = answer.parts[part] - spec = chosen["candidates"]["specs"][candidate] definite = { + **{k: v for k, v in chosen.items() if k != "candidates"}, "status": "definite", - "variable_text": chosen["variable_text"], "spec": spec, } return Answer( @@ -583,6 +612,196 @@ def candidate_answer(answer: Answer, part: int, candidate: int) -> Answer: ) +# --- choices ---------------------------------------------------------------- + + +@dataclass(frozen=True, slots=True) +class Choice: + """What a choose step settles: the part's index, and the chosen candidate + spec or no_data option.""" + + part: int + candidate: dict[str, Any] | None = None + option: dict[str, Any] | None = None + + +def _refuse() -> ClientError: + return ClientError("InvalidRequestError") + + +def choice_for( + answer: Answer, kinds: Mapping[str, str], part: int | str | None, option: int | str +) -> Choice: + """The part and option a choose step names, or InvalidRequestError. + + With no part named, exactly one gap must await a choice: a `choice` gap, + or any gap with options. A part is named by its index, its variable text, + or a word that one gap's options mention, and must be a gap. A + candidates part's options are its candidates, chosen by index; any other + gap's are its no_data options, chosen by index or label, a label scoped to + the options that mention the word the part was named by.""" + gaps = answer_gaps(answer, kinds) + gap_parts = {gap["part"] for gap in gaps} + mention = None + if part is None: + waiting = [g["part"] for g in gaps if g["kind"] == "choice" or g["options"]] + if len(waiting) != 1: + raise _refuse() + index = waiting[0] + elif isinstance(part, int): + index = part + else: + named = [ + i for i, p in enumerate(answer.parts) if p.get("variable_text") == part + ] + if not named: + mention = part + named = [ + i + for i in sorted(gap_parts) + if any(part in o.get("mentions", []) for o in _options(answer, i)) + ] + if len(named) != 1: + raise _refuse() + index = named[0] + if index not in gap_parts: + raise _refuse() + + chosen = answer.parts[index] + if chosen.get("status") == "candidates": + specs = chosen["candidates"]["specs"] + if not isinstance(option, int): + raise _UnfitError("candidates are chosen by index") + if not 0 <= option < len(specs): + raise _refuse() + return Choice(index, candidate=specs[option]) + options = _options(answer, index) + if isinstance(option, int): + found = [options[option]] if 0 <= option < len(options) else [] + else: + found = [ + o + for o in options + if o.get("label") == option + and (mention is None or mention in o.get("mentions", [])) + ] + if len(found) != 1: + raise _refuse() + return Choice(index, option=found[0]) + + +def _options(answer: Answer, index: int) -> list[dict[str, Any]]: + return answer.parts[index].get("no_data", {}).get("options", []) + + +def choice_input(answer: Answer, choice: Choice) -> dict[str, Any] | None: + """The Search input a choice posts, or None for a choice among one part's + candidates, which makes no request. In a one-part answer an option posts + its data_query; in a several-part answer the choice posts + dataset_resubmit with one entry per part, in part order.""" + if len(answer.parts) == 1: + if choice.option is None: + return None + return choice.option["data_query"] + entries = [ + resubmit_entry(part, choice if index == choice.part else None) + for index, part in enumerate(answer.parts) + ] + return {"kind": "dataset_resubmit", "entries": entries} + + +def resubmit_entry(part: dict[str, Any], choice: Choice | None) -> dict[str, Any]: + """One part's dataset_resubmit entry. The chosen candidate posts its + identity and the chosen option its one parsed part. Otherwise a definite + part posts its spec's identity, a candidates part its candidate set in the + server's order with its ordering and truncated echoed, and any other part + its restatement as a parsed entry, or a placeholder when it has none.""" + if choice is not None and choice.candidate is not None: + return _echo(part, entry_kind="identity", **_identity(choice.candidate)) + if choice is not None and choice.option is not None: + parts = choice.option["data_query"].get("parts") + if not isinstance(parts, list) or len(parts) != 1: + raise ClientError("ContractError") + return {"entry_kind": "parsed", "part": parts[0]} + match part.get("status"): + case "definite": + return _echo(part, entry_kind="identity", **_identity(part["spec"])) + case "candidates": + candidates = part["candidates"] + return _echo( + part, + entry_kind="candidates", + ordering=candidates.get("ordering"), + truncated=candidates.get("truncated") is True, + candidates=[_identity(spec) for spec in candidates["specs"]], + ) + return _restated_entry(part) + + +def _restated_entry(part: dict[str, Any]) -> dict[str, Any]: + """A part without a reading: its restatement as a parsed entry, else a + placeholder of its no_data reason or unsupported code. A part of unknown + status without a restatement cannot be posted back.""" + if isinstance(part.get("restatement"), dict): + return {"entry_kind": "parsed", "part": part["restatement"]} + match part.get("status"): + case "no_data": + reason = part["no_data"]["reason"] + return _echo( + part, entry_kind="placeholder", status="no_data", reason=reason + ) + case "unsupported": + code = part["unsupported"]["code"] + return _echo( + part, entry_kind="placeholder", status="unsupported", code=code + ) + raise _refuse() + + +def _identity(spec: dict[str, Any]) -> dict[str, Any]: + """A spec's identity, and its entity groups when it has any.""" + item: dict[str, Any] = {"identity": spec["definition"]["identity"]} + groups = spec.get("resolved", {}).get("entity_groups") + if groups: + item["entity_groups"] = groups + return item + + +def _echo(part: dict[str, Any], **members: Any) -> dict[str, Any]: + """An entry with the members every entry but a parsed one echoes from its + part: variable_text, separate when true, and operations when any.""" + if not part.get("variable_text"): + raise _refuse() + entry: dict[str, Any] = {**members, "variable_text": part["variable_text"]} + if part.get("separate") is True: + entry["separate"] = True + if part.get("operations"): + entry["operations"] = part["operations"] + return entry + + +def search_warns(answer: Answer) -> bool: + """Whether fetching `answer` issues a SearchWarning: a definite part has + an operation Search did not run, a departure, or a warning shown at + `warn` or `degraded` severity, or the answer's diagnostics carry such a + warning. An `info` warning issues nothing.""" + + def shown(warnings: Any) -> bool: + return any( + w.get("severity") in SHOWN_SEVERITIES and w.get("message") + for w in warnings or [] + ) + + for part in answer.parts: + if part.get("status") != "definite": + continue + if part.get("operations") or part.get("departures"): + return True + if shown(part.get("warnings")): + return True + return shown(answer.body.get("diagnostics", {}).get("warnings")) + + def answer_gaps(answer: Answer, kinds: Mapping[str, str]) -> list[dict[str, Any]]: """Each part without a reading: a candidates part is a choice among its specs; a no_data part takes its reason's gap kind, or `timed_out` when the @@ -637,12 +856,23 @@ def answer_outcome(answer: Answer, kinds: Mapping[str, str]) -> dict[str, Any]: return {"answer": outcome} +def part_label(member: Mapping[str, Any]) -> str: + """The `part` column's value on a member's rows in a dataset of several + members: the member's parts joined by `; `, or its sentence when it + answers no part.""" + return "; ".join(member["parts"]) or member["sentence"] + + def dataset_summary( - members: Sequence[Mapping[str, Any]], missing: Sequence[Mapping[str, Any]] + members: Sequence[Mapping[str, Any]], + missing: Sequence[Mapping[str, Any]], + *, + search_warning: bool | None = None, ) -> dict[str, Any]: - """A dataset outcome's members and gaps, without the rows and columns the - Parquet bodies hold.""" - return { + """A dataset outcome's members and gaps, and for a fetch of an answer + whether it issued a SearchWarning, without the rows, columns and per-part + row counts the Parquet bodies hold.""" + summary: dict[str, Any] = { "complete": not missing, "members": [ { @@ -655,6 +885,9 @@ def dataset_summary( ], "missing": [{"part": gap["part"], "kind": gap["kind"]} for gap in missing], } + if search_warning is not None: + summary["search_warning"] = search_warning + return summary def _strict_members(strict: dict[str, Any]) -> dict[str, list[str]]: @@ -723,14 +956,6 @@ def strict_gaps( return gaps -class _StepEndedError(Exception): - """A step ends in `outcome`, an error a client raises.""" - - def __init__(self, outcome: dict[str, Any]) -> None: - super().__init__(outcome) - self.outcome = outcome - - class _UnfitError(Exception): """The exchanges do not fit the steps, so no outcome follows from them.""" @@ -799,7 +1024,7 @@ def acted_on(self, exchange: dict[str, Any]) -> Any: if response["status"] >= 400: code = refusal_code(body) error = error_class(response["status"], code, self.actions) - raise _StepEndedError(error_outcome(error, code)) + raise ClientError(error, code) schema = self.routes.response_schema( self.base_path, exchange["request"], response["status"] ) @@ -808,7 +1033,7 @@ def acted_on(self, exchange: dict[str, Any]) -> Any: def strict(self, schema: Any, body: Any) -> None: if strict_gaps(self.routes.openapi, self.members, schema, body): - raise _StepEndedError(error_outcome("ContractError")) + raise ClientError("ContractError") def download(self) -> None: """The files route, then its signed URL; a refused signed URL asks the @@ -818,8 +1043,17 @@ def download(self) -> None: if self.call("GET", "url")["response"]["status"] < 400: return - def resolve(self) -> Answer: - return answer_from_body(self.acted_on(self.call(*_SEARCH))) + def resolve(self, posts: dict[str, Any]) -> Answer: + """A Search request whose recorded body, when it has one, posts the + input `posts`.""" + exchange = self.call(*_SEARCH) + sent = exchange["request"].get("json") + if sent is not None and sent.get("input") != posts: + raise _UnfitError( + f"exchange {self.cursor - 1} posts {json.dumps(sent.get('input'))[:300]}" + f", where the rules post {json.dumps(posts)[:300]}" + ) + return answer_from_body(self.acted_on(exchange)) def wait(self, operation: dict[str, Any]) -> dict[str, Any]: """Polls until the operation is done. The done resource's manifest is @@ -829,7 +1063,7 @@ def wait(self, operation: dict[str, Any]) -> dict[str, Any]: resource = self.acted_on(self.call(*_POLL)) operation, manifest = resource["operation"], resource.get("manifest") if not isinstance(manifest, dict): - raise _StepEndedError(error_outcome("ContractError")) + raise ClientError("ContractError") self.strict(_MANIFEST, manifest) return manifest @@ -847,7 +1081,14 @@ def member( built = manifest["definition"]["spec_id"] sentence = spec.get("sentence") if built != spec["spec_id"] or sentence is None: - (part,) = self.resolve().parts + entry = { + "entry_kind": "identity", + "variable_text": parts[0] if parts else UNNAMED_VARIABLE_TEXT, + "identity": manifest["definition"]["identity"], + } + (part,) = self.resolve( + {"kind": "dataset_resubmit", "entries": [entry]} + ).parts sentence = part["spec"]["resolved"]["rendered_sentence"] self.download() return { @@ -868,7 +1109,7 @@ def step(self, step: dict[str, Any]) -> dict[str, Any]: ) try: return getattr(self, f"_{op}")(step) - except _StepEndedError as ended: + except ClientError as ended: if op in {"search", "choose"}: self.answer = None return ended.outcome @@ -879,36 +1120,38 @@ def _answered(self) -> Answer: return self.answer def _search(self, step: dict[str, Any]) -> dict[str, Any]: - self.answer = self.resolve() + self.answer = self.resolve({"kind": "raw_text", "query": step["question"]}) return answer_outcome(self.answer, self.kinds) def _choose(self, step: dict[str, Any]) -> dict[str, Any]: answer = self._answered() - part, option = step.get("part"), step["option"] - if isinstance(part, str): - part = next( - i for i, p in enumerate(answer.parts) if p.get("variable_text") == part - ) - index = answer_gaps(answer, self.kinds)[0]["part"] if part is None else part - chosen = answer.parts[index] - if chosen.get("status") == "candidates" and len(answer.parts) == 1: - if not isinstance(option, int): - raise _UnfitError("candidates are chosen by index") - self.answer = candidate_answer(answer, index, option) + choice = choice_for(answer, self.kinds, step.get("part"), step["option"]) + posts = choice_input(answer, choice) + if posts is not None: + chosen = self.resolve(posts) + elif choice.candidate is not None: + chosen = candidate_answer(answer, choice.part, choice.candidate) else: - options = chosen.get("no_data", {}).get("options", []) - if not any(option in (i, o.get("label")) for i, o in enumerate(options)): - raise _StepEndedError(error_outcome("InvalidRequestError")) - self.answer = self.resolve() - return answer_outcome(self.answer, self.kinds) + raise _UnfitError("a choice posts unless it picks a candidate") + self.answer = chosen + return answer_outcome(chosen, self.kinds) def _fetch(self, step: dict[str, Any]) -> dict[str, Any]: + """A fetch of the answer: a declined or catalogue answer raises + DeclinedError; a gap raises IncompleteAnswerError unless the fetch is + partial and some part has a reading; a strict fetch whose readings + depart from the question raises SearchWarning; all before any + request.""" answer = self._answered() if answer.body.get("kind") != "resolution": - raise _StepEndedError(error_outcome("DeclinedError")) + raise ClientError("DeclinedError") gaps = answer_gaps(answer, self.kinds) - if gaps and not step.get("partial", False): - raise _StepEndedError(error_outcome("IncompleteAnswerError")) + readings = answer_members(answer) + if gaps and (not step.get("partial", False) or not readings): + raise ClientError("IncompleteAnswerError") + warns = search_warns(answer) + if warns and step.get("strict", False): + raise ClientError("SearchWarning") members = [ self.build( parts, @@ -917,9 +1160,9 @@ def _fetch(self, step: dict[str, Any]) -> dict[str, Any]: "sentence": spec["resolved"]["rendered_sentence"], }, ) - for parts, spec in answer_members(answer) + for parts, spec in readings ] - return {"dataset": dataset_summary(members, gaps)} + return {"dataset": dataset_summary(members, gaps, search_warning=warns)} def _fetch_spec(self, step: dict[str, Any]) -> dict[str, Any]: return {"dataset": dataset_summary([self.build([], step["spec"])], [])} @@ -1040,8 +1283,9 @@ def _check_expect( derived: list[dict[str, Any]], ) -> list[str]: """Each outcome in `expect` against the one its exchanges give. A dataset - outcome's rows and columns are the Parquet bodies' and are not derived, - except that several members put the `part` column first.""" + outcome's rows, columns and per-part row counts are the Parquet bodies' + and are not derived, except that several members put the `part` column + first and list each member's `part` value, rows summing to the dataset's.""" problems = [] for index, (stated, wanted) in enumerate( zip(record["expect"], derived, strict=False) @@ -1051,15 +1295,15 @@ def _check_expect( dataset = stated["dataset"] compared = { "dataset": { - k: v for k, v in dataset.items() if k not in {"rows", "columns"} + k: v + for k, v in dataset.items() + if k not in {"rows", "columns", "part_rows"} } } - several = len(dataset["members"]) > 1 - if (dataset["columns"][:1] == ["part"]) != several: - problems.append( - f"scenarios/{file_name}: step {index}: the part column comes " - "first exactly when the dataset has several members" - ) + problems.extend( + f"scenarios/{file_name}: step {index}: {problem}" + for problem in _part_problems(dataset, wanted["dataset"]["members"]) + ) if compared != wanted: problems.append( f"scenarios/{file_name}: step {index} expects " @@ -1069,6 +1313,38 @@ def _check_expect( return problems +def _part_problems( + dataset: dict[str, Any], members: Sequence[Mapping[str, Any]] +) -> list[str]: + """A dataset of several members has the `part` column first and a + `part_rows` entry per member, in member order, whose `part` is that + member's `part_label` and whose rows sum to the dataset's; a dataset of + one member has neither.""" + several = len(members) > 1 + problems = [] + if (dataset["columns"][:1] == ["part"]) != several: + problems.append( + "the part column comes first exactly when the dataset has several members" + ) + part_rows = dataset.get("part_rows") + if (part_rows is not None) != several: + problems.append( + "part_rows is given exactly when the dataset has several members" + ) + return problems + if part_rows is None: + return problems + labels = [part_label(member) for member in members] + if [entry["part"] for entry in part_rows] != labels: + problems.append( + f"part_rows names {[entry['part'] for entry in part_rows]}, but the " + f"members' part values are {labels}" + ) + if sum(entry["rows"] for entry in part_rows) != dataset["rows"]: + problems.append("part_rows' rows do not sum to the dataset's rows") + return problems + + def _check_scenarios( validator: jsonschema.Draft202012Validator, openapi: dict[str, Any], @@ -1168,9 +1444,8 @@ def _check_steps(file_name: str, record: dict[str, Any]) -> list[str]: for index, step in enumerate(call): op = step["op"] if op == "fetch" and "spec" not in step and "ref" not in step: - needs = {"search", "choose"} - else: - needs = _ACTS_ON_PREVIOUS.get(op) + op = "fetch_answer" + needs = _ACTS_ON_PREVIOUS.get(op) if needs is not None and previous not in needs: problems.append( f"scenarios/{file_name}: step {index} ({op}) does not follow " From 9818197a03894d1673bf8111d8714b8465cc894e Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Tue, 20 Oct 2026 22:38:51 +0200 Subject: [PATCH 13/39] feat(client-contract): name the codes a client raises itself client-codes.json lists each code a client raises when no problem document carries one, with the error class it raises. The codes are disjoint from actions.json and the codes registry, and every scenario error that no refusal in its exchanges carries names one of its class. record --offline re-derives a recorded scenario's expect from its own exchanges. --- README.md | 2 +- python/client-contract/CHANGELOG.md | 5 +- python/client-contract/README.md | 19 +- .../src/dfo_client_contract/__init__.py | 11 +- .../src/dfo_client_contract/client-codes.json | 85 ++++++ .../client-codes.schema.json | 49 ++++ .../src/dfo_client_contract/contract.py | 10 + .../dfo_client_contract/scenario.schema.json | 2 +- .../scenarios/answer-catalogue.json | 2 +- .../scenarios/answer-declined.json | 2 +- .../scenarios/answer-mixed-fetch-raises.json | 2 +- .../scenarios/answer-timed-out.json | 2 +- .../scenarios/answer-unknown-kind.json | 2 +- .../scenarios/answer-unknown-part-status.json | 2 +- .../scenarios/answer-unsupported-part.json | 2 +- .../choose-refused-answered-part.json | 2 +- ...hoose-refused-mention-names-two-parts.json | 2 +- .../scenarios/choose-refused-no-choice.json | 2 +- .../scenarios/choose-refused-no-options.json | 2 +- .../choose-refused-option-out-of-range.json | 2 +- .../scenarios/choose-refused-two-choices.json | 2 +- .../choose-refused-unknown-label.json | 2 +- .../choose-refused-unknown-part.json | 2 +- .../fetch-partial-nothing-answered.json | 2 +- .../scenarios/fetch-renamed-strict-field.json | 2 +- python/client-contract/tests/test_contract.py | 8 + tools/README.md | 4 +- tools/capture_client_contract.py | 201 +++++++++++-- tools/tests/test_capture_client_contract.py | 110 ++----- tools/tests/test_validate_client_contract.py | 106 +++++++ tools/validate_client_contract.py | 270 +++++++++++++++--- 31 files changed, 738 insertions(+), 178 deletions(-) create mode 100644 python/client-contract/src/dfo_client_contract/client-codes.json create mode 100644 python/client-contract/src/dfo_client_contract/client-codes.schema.json diff --git a/README.md b/README.md index 38349fd..d290c0e 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The **component-spec family** (the presentation catalogue, composition schema, o ## Status -Six Python distributions exist so far. `python/spec-kit/` (`dfo-spec-kit`, import `dfo_spec_kit`): `identity/` implements the spec1 identity scheme (role-slot projection, JCS canonicalisation, SHA-256 `spec_id` minting), conformance-tested against the vector suite. `units/` reads a unit ref into a typed value (`Money`, `UnpricedMoney`, `Percent`, `Count` or `Other`) from `registries/units.json`, conformance-tested against `vectors/units/`. Money whose ref leaves prices unstated cannot be compared until `complete_prices` applies the StatVar's measurement qualifier, and constant-price money with no base year cannot be compared at all. `models/` has no code yet; model extraction comes next. `python/frame-grammar/` (`dfo-spec-kit-frame-grammar`, import `dfo_frame_grammar`): the frame grammar's executable form -- canonical frame bytes and `content_version` minting for a materialised observation table -- conformance-tested against its own vector suite, and depending on `dfo-spec-kit` for the identity canonicalisation primitives it reuses. `python/dfo-spec-kit-components/` (`dfo-spec-kit-components`, import `dfo_spec_kit_components`): the presentation contract bundle as package data, holding the envelope schema, the per-member component schemas, the write-side intent grammar, and their conformance fixtures. Generated Pydantic models for the catalogue land in this same package once the catalogue freezes. `python/provenance-docs/` (`dfo-spec-kit-provenance-docs`, import `dfo_provenance_docs`): the provenance documentation grammar, which decodes the escaped Markdown documents a Provenance node carries and parses the transformations, changelog, methodology and notes templates, conformance-tested against its own vector suite. `python/descriptions/` (`dfo-spec-kit-descriptions`, import `dfo_descriptions`): the step records and descriptions contract, holding the step schema, the operation list, the description schema and a check of the structure rules a step list must meet beyond its schema, conformance-tested against its own vector suite. `python/client-contract/` (`dfo-spec-kit-client-contract`, import `dfo_client_contract`): the contract the DFO Python and TypeScript clients are built to, as package data: the served OpenAPI document of the composed dfo-apis app, the response members the clients act on, the caller's next step for each refusal code, the scenario and `DatasetRef` formats with their records, and the client rules with their vectors. dfo-apis CI checks its app against the same files. +Six Python distributions exist so far. `python/spec-kit/` (`dfo-spec-kit`, import `dfo_spec_kit`): `identity/` implements the spec1 identity scheme (role-slot projection, JCS canonicalisation, SHA-256 `spec_id` minting), conformance-tested against the vector suite. `units/` reads a unit ref into a typed value (`Money`, `UnpricedMoney`, `Percent`, `Count` or `Other`) from `registries/units.json`, conformance-tested against `vectors/units/`. Money whose ref leaves prices unstated cannot be compared until `complete_prices` applies the StatVar's measurement qualifier, and constant-price money with no base year cannot be compared at all. `models/` has no code yet; model extraction comes next. `python/frame-grammar/` (`dfo-spec-kit-frame-grammar`, import `dfo_frame_grammar`): the frame grammar's executable form -- canonical frame bytes and `content_version` minting for a materialised observation table -- conformance-tested against its own vector suite, and depending on `dfo-spec-kit` for the identity canonicalisation primitives it reuses. `python/dfo-spec-kit-components/` (`dfo-spec-kit-components`, import `dfo_spec_kit_components`): the presentation contract bundle as package data, holding the envelope schema, the per-member component schemas, the write-side intent grammar, and their conformance fixtures. Generated Pydantic models for the catalogue land in this same package once the catalogue freezes. `python/provenance-docs/` (`dfo-spec-kit-provenance-docs`, import `dfo_provenance_docs`): the provenance documentation grammar, which decodes the escaped Markdown documents a Provenance node carries and parses the transformations, changelog, methodology and notes templates, conformance-tested against its own vector suite. `python/descriptions/` (`dfo-spec-kit-descriptions`, import `dfo_descriptions`): the step records and descriptions contract, holding the step schema, the operation list, the description schema and a check of the structure rules a step list must meet beyond its schema, conformance-tested against its own vector suite. `python/client-contract/` (`dfo-spec-kit-client-contract`, import `dfo_client_contract`): the contract the DFO Python and TypeScript clients are built to, as package data: the served OpenAPI document of the composed dfo-apis app, the response members the clients act on, the caller's next step for each refusal code, the code of each error a client raises itself, the scenario and `DatasetRef` formats with their records, and the client rules with their vectors. dfo-apis CI checks its app against the same files. The Python distributions live at `python/spec-kit/`, `python/frame-grammar/`, `python/dfo-spec-kit-components/`, `python/provenance-docs/`, `python/descriptions/`, and `python/client-contract/`, each its own installable unit with its own version and dependency surface. A TypeScript package (`ts/`) opens only when the component catalogue freeze lands. diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index 4fe1214..56c5058 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -11,9 +11,10 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be - `strict-fields.json` and its schema: 25 members that stay required and non-nullable, and the answer kinds, part statuses and operation statuses the clients branch on. - `actions.json` and its schema: the caller's next step for each of the 101 active refusal codes on `problem_details` or `no_data_reason`, with the gap kind of each no_data reason. - `scenario.schema.json`, the scenario record, and 44 scenarios: 18 recorded against dfo-apis `8408f1f95` and 26 synthetic, each derived from a recorded one by a one-line edit, with 11 Parquet bodies totalling 102,956 bytes. The scenarios cover the several-part choice entries, the choice refusals, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule and the stacked dataset's `part` column. +- `client-codes.json` and its schema: the 16 codes a client sets on the errors it raises itself, each with its error class and condition, disjoint from `actions.json` and `registries/codes.json`, and the `client_codes()` and `client_codes_schema()` accessors. Every scenario error the client raises itself carries its code, and `refusal_without_code` names a refusal whose body carries no code. - `dataset-ref.schema.json`, the frozen `DatasetRef` format, with accepted and rejected examples. -- `tools/capture_client_contract.py`, which captures `served/openapi.json` from a dfo-apis checkout in process and records the scenarios against a base URL, dev by default. -- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, and checks each scenario's `expect` against the outcomes its exchanges and `actions.json` give, and each Search request against the input its steps derive. +- `tools/capture_client_contract.py`, which captures `served/openapi.json` from a dfo-apis checkout in process and records the scenarios against a base URL, dev by default, or with `record --offline` derives their outcomes again from the records with no request. +- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, checks `client-codes.json` against them, and checks each scenario's `expect` against the outcomes its exchanges, `actions.json` and `client-codes.json` give, and each Search request against the input its steps derive. - The client rules and their vectors: the credentials path and file format, the key lookup order, the key format check, and the cache directory and layout. [unreleased]: https://github.com/DevelopmentFinanceObservatory/spec-kit/commits/main/python diff --git a/python/client-contract/README.md b/python/client-contract/README.md index e1e2bea..1773986 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -40,6 +40,8 @@ uv run ty check src/dfo_client_contract | `strict-fields.schema.json` | The shape of `strict-fields.json` | | `actions.json` | The caller's next step for each refusal code, and the gap kind of each no_data reason | | `actions.schema.json` | The shape of `actions.json` | +| `client-codes.json` | The code, class and condition of each error a client raises itself | +| `client-codes.schema.json` | The shape of `client-codes.json` | | `scenario.schema.json` | One scenario record | | `scenarios/` | The scenario records, and the binary response bodies they name | | `dataset-ref.schema.json` | The frozen `DatasetRef` format | @@ -52,6 +54,7 @@ uv run ty check src/dfo_client_contract | `served_source()` | `served/SOURCE.json`, parsed | | `strict_fields()` | `strict-fields.json`, parsed | | `actions()` | `actions.json`, parsed | +| `client_codes()` | `client-codes.json`, parsed | | `scenarios()` | Every scenario record; raises `RuntimeError` when none load | | `ref_examples()` | Every `DatasetRef` example; raises `RuntimeError` when none | | `rule(name)` | The vector file for one of `RULES` | @@ -92,6 +95,10 @@ A code that maps to `no_data_reason` also carries `gap_kind`, the kind of gap a An answer's gaps follow from its parts. A candidates part is a `choice` gap, its options the candidates. A no_data part is a gap of its reason's `gap_kind`, its options the no_data `options`, and of kind `timed_out` instead when the answer's `diagnostics.timed_out` is true. An unsupported part is an `unsupported` gap. A part whose status a client does not know is an `unknown` gap. +## Client codes + +`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, and a one-line `condition`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps the server's code: the problem document's `code`, or the website proxy's `error`. A refusal whose body carries neither raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`; no other row does. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. The list holds no warning: a `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and null when they differ in several ways. + ## Scenarios A scenario is one client-level call, the HTTP exchanges it makes, and the outcome each step reaches. Each record is one file, `scenarios/.json`, validated by `scenario.schema.json`. @@ -110,9 +117,9 @@ A step that acts on an earlier result follows one: `choose` follows `search` or An exchange's request names its target in one of three ways. `path` is a path the client composes under the base URL, such as `/search/resolve`. `origin_path` is a root-relative URL the server returned, such as an artifact's `url`, which resolves against the base URL's origin and never against its path. `url` is an absolute URL outside the API, such as the signed storage URL a files route redirects to, which the client fetches with a bare request carrying no client header and no key. `json` holds the request body members that must match; a recorded scenario lists every member the client sent. The response gives `status`, the `headers` a client reads, and a `json` body or a `body_file`, a binary body in `scenarios/`. A scenario's own body files are named `.` and `-.`; a synthetic scenario may instead name a body file its parent names. -An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and the problem's `code`, or null when no problem document carries the error. +An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a `SearchWarning`'s code or null, or for any other error the client raises itself its code in `client-codes.json`. -Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry, an error's class is its code's action or else its status, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, and each Search request posts the input the rules give: the question, a choice's input, or a member's identity. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. +Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, and each Search request posts the input the rules give: the question, a choice's input, or a member's identity. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. A recorded scenario's request and response bodies validate against their route's schemas in `served/openapi.json`, with one allowance: a required member whose schema admits null may be absent, because the server leaves null members out of the bodies it serves. @@ -148,7 +155,13 @@ uv sync --directory ../dfo-apis --extra eval --extra api --extra engine --extra uv run tools/capture_client_contract.py openapi --dfo-apis ../dfo-apis ``` -Its `record` command runs every scenario against a base URL, dev's Cloud Run URL by default, checks each live answer still has the shape its scenario names, derives the synthetic scenarios from the fresh records, and then runs the validator. It fails when the validator reports a problem or the binary bodies pass 5 MB. `--only` records the scenarios it names. Each record names the commit in the responses' `x-dfo-commit` header, and the run refuses responses that name none or several. To record against a local app, run the composed app, every surface mounted, from the checkout the document came from, with `DFO_BUILD_COMMIT` set to that checkout's commit, then pass its base URL: +Its `record` command runs every scenario against a base URL, dev's Cloud Run URL by default, checks each live answer still has the shape its scenario names, derives the synthetic scenarios from the fresh records, and then runs the validator. It fails when the validator reports a problem or the binary bodies pass 5 MB. `--only` records the scenarios it names. `--offline` makes no request: each recorded scenario's steps run again over its own exchanges and rewrite its `expect`, and each synthetic scenario that records nothing live is derived again from its parent, so a change to the outcome rules or to `client-codes.json` reaches the records without a recording: + +```bash +uv run tools/capture_client_contract.py record --offline --only answer-declined choose-refused-no-choice +``` + + Each record names the commit in the responses' `x-dfo-commit` header, and the run refuses responses that name none or several. To record against a local app, run the composed app, every surface mounted, from the checkout the document came from, with `DFO_BUILD_COMMIT` set to that checkout's commit, then pass its base URL: ```bash uv run tools/capture_client_contract.py record --base-url http://127.0.0.1:8083/api diff --git a/python/client-contract/src/dfo_client_contract/__init__.py b/python/client-contract/src/dfo_client_contract/__init__.py index 676df89..b4aa34d 100644 --- a/python/client-contract/src/dfo_client_contract/__init__.py +++ b/python/client-contract/src/dfo_client_contract/__init__.py @@ -2,15 +2,18 @@ Ships, as package data, what the DFO Python and TypeScript clients generate from and replay: the served OpenAPI document, the strict fields, the caller -action for each refusal code, the scenario and DatasetRef formats with their -records, and the client rules with their vectors. Every accessor reads the -installed files through `importlib.resources`. +action for each refusal code, the code of each error a client raises itself, +the scenario and DatasetRef formats with their records, and the client rules +with their vectors. Every accessor reads the installed files through +`importlib.resources`. """ from dfo_client_contract.contract import ( RULES, actions, actions_schema, + client_codes, + client_codes_schema, contract_dir, dataset_ref_schema, openapi, @@ -28,6 +31,8 @@ "RULES", "actions", "actions_schema", + "client_codes", + "client_codes_schema", "contract_dir", "dataset_ref_schema", "openapi", diff --git a/python/client-contract/src/dfo_client_contract/client-codes.json b/python/client-contract/src/dfo_client_contract/client-codes.json new file mode 100644 index 0000000..1a02e36 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/client-codes.json @@ -0,0 +1,85 @@ +{ + "format_version": 1, + "codes": [ + { + "code": "answer_declined", + "class": "DeclinedError", + "condition": "Fetching an answer Search declined or answered with the catalogue." + }, + { + "code": "answer_incomplete", + "class": "IncompleteAnswerError", + "condition": "Fetching an answer with a part that has no reading, when the fetch is not partial or no part has a reading." + }, + { + "code": "choice_invalid", + "class": "InvalidRequestError", + "condition": "A choice whose part or option names no gap, several gaps or no option, or a choice that cannot post back a part." + }, + { + "code": "contract_violation", + "class": "ContractError", + "condition": "A response lacks a member the client acts on, or holds one that contradicts the request." + }, + { + "code": "credentials_file_invalid", + "class": "AuthenticationError", + "condition": "The credentials file breaks the credentials-file rule." + }, + { + "code": "deadline_exceeded", + "class": "DfoTimeoutError", + "condition": "The call's deadline passed before it finished." + }, + { + "code": "digest_mismatch", + "class": "ServerError", + "condition": "A downloaded file does not hash to the digest its manifest names." + }, + { + "code": "download_failed", + "class": "ServerError", + "condition": "A signed storage URL answered a status other than 2xx." + }, + { + "code": "invalid_argument", + "class": "InvalidRequestError", + "condition": "A call's arguments break a rule the client checks before any request." + }, + { + "code": "network_error", + "class": "NetworkError", + "condition": "The connection failed before a response arrived." + }, + { + "code": "offline", + "class": "NetworkError", + "condition": "DFO_OFFLINE=1 is set, and the call needs the server." + }, + { + "code": "profile_not_found", + "class": "AuthenticationError", + "condition": "DFO_PROFILE names a profile the credentials file lacks." + }, + { + "code": "profile_without_key", + "class": "AuthenticationError", + "condition": "The chosen profile in the credentials file has no key." + }, + { + "code": "refusal_without_code", + "class": "by_status", + "condition": "A refusal whose body carries no code: neither a problem document nor the website proxy's own body." + }, + { + "code": "unexpected_response", + "class": "ContractError", + "condition": "A response of a status or form the call does not act on: a redirect it does not follow, a body that is not JSON, or a status the route does not answer." + }, + { + "code": "version_unavailable", + "class": "VersionUnavailableError", + "condition": "A stored version can no longer be fetched, and no refusal names why." + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/client-codes.schema.json b/python/client-contract/src/dfo_client_contract/client-codes.schema.json new file mode 100644 index 0000000..32249a6 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/client-codes.schema.json @@ -0,0 +1,49 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/python/client-contract/src/dfo_client_contract/client-codes.schema.json", + "title": "Client codes", + "description": "Each code a client sets on an error it raises when no problem document carries one, with the error class it raises and the condition, sorted by code. A server refusal's error keeps the server's code.", + "type": "object", + "additionalProperties": false, + "required": [ + "format_version", + "codes" + ], + "properties": { + "format_version": { + "const": 1 + }, + "codes": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "code", + "class", + "condition" + ], + "properties": { + "code": { + "type": "string", + "pattern": "^[a-z][a-z0-9]*(_[a-z0-9]+)*$" + }, + "class": { + "description": "The error class the client raises, one the scenario schema names, or by_status for the class a refusal's HTTP status maps to.", + "type": "string", + "pattern": "^([A-Z][A-Za-z]*|by_status)$" + }, + "condition": { + "description": "The condition, in one line.", + "type": "string", + "minLength": 1, + "not": { + "pattern": "\\n" + } + } + } + } + } + } +} diff --git a/python/client-contract/src/dfo_client_contract/contract.py b/python/client-contract/src/dfo_client_contract/contract.py index 212c594..b200c7e 100644 --- a/python/client-contract/src/dfo_client_contract/contract.py +++ b/python/client-contract/src/dfo_client_contract/contract.py @@ -69,6 +69,16 @@ def actions_schema() -> dict[str, Any]: return _load("actions.schema.json") +def client_codes() -> dict[str, Any]: + """`client-codes.json`: the code of each error a client raises itself.""" + return _load("client-codes.json") + + +def client_codes_schema() -> dict[str, Any]: + """`client-codes.schema.json`: the shape of `client-codes.json`.""" + return _load("client-codes.schema.json") + + def scenario_schema() -> dict[str, Any]: """`scenario.schema.json`: the shape of one scenario record.""" return _load("scenario.schema.json") diff --git a/python/client-contract/src/dfo_client_contract/scenario.schema.json b/python/client-contract/src/dfo_client_contract/scenario.schema.json index f89ff93..91f63af 100644 --- a/python/client-contract/src/dfo_client_contract/scenario.schema.json +++ b/python/client-contract/src/dfo_client_contract/scenario.schema.json @@ -798,7 +798,7 @@ ] }, "code": { - "description": "The problem document's code, or null for an error no problem document carries.", + "description": "A refusal's code: the problem document's code, the website proxy's error member, or refusal_without_code for a body with neither. A SearchWarning's code is the server's warning or departure code, or null when the readings differ from the question in several ways. Any other error the client raises itself carries its code from client-codes.json.", "type": [ "string", "null" diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json index ee44b5b..4279068 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json @@ -80,7 +80,7 @@ { "error": { "class": "DeclinedError", - "code": null + "code": "answer_declined" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json index a0e48f1..ef64826 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json @@ -86,7 +86,7 @@ { "error": { "class": "DeclinedError", - "code": null + "code": "answer_declined" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json index c3aa256..5a59471 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json @@ -3568,7 +3568,7 @@ { "error": { "class": "IncompleteAnswerError", - "code": null + "code": "answer_incomplete" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json index d5e0b88..f283259 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json @@ -3567,7 +3567,7 @@ { "error": { "class": "IncompleteAnswerError", - "code": null + "code": "answer_incomplete" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json index a78a893..cfc738e 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json @@ -201,7 +201,7 @@ { "error": { "class": "ContractError", - "code": null + "code": "contract_violation" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json index 130ed6a..7fd603f 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json @@ -3567,7 +3567,7 @@ { "error": { "class": "IncompleteAnswerError", - "code": null + "code": "answer_incomplete" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json index 6c401f1..e0e082f 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json @@ -3562,7 +3562,7 @@ { "error": { "class": "IncompleteAnswerError", - "code": null + "code": "answer_incomplete" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json index 5234a35..4f6fcaf 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json @@ -3569,7 +3569,7 @@ { "error": { "class": "InvalidRequestError", - "code": null + "code": "choice_invalid" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json index 68ba74c..c2d409f 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json @@ -429,7 +429,7 @@ { "error": { "class": "InvalidRequestError", - "code": null + "code": "choice_invalid" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json index 44c0169..1a69611 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json @@ -3693,7 +3693,7 @@ { "error": { "class": "InvalidRequestError", - "code": null + "code": "choice_invalid" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json index 646a5bd..1767aff 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json @@ -221,7 +221,7 @@ { "error": { "class": "InvalidRequestError", - "code": null + "code": "choice_invalid" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json index e5068f9..2c387eb 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json @@ -2378,7 +2378,7 @@ { "error": { "class": "InvalidRequestError", - "code": null + "code": "choice_invalid" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json index d593809..05513c8 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json @@ -344,7 +344,7 @@ { "error": { "class": "InvalidRequestError", - "code": null + "code": "choice_invalid" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json index 437de68..e10d804 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json @@ -258,7 +258,7 @@ { "error": { "class": "InvalidRequestError", - "code": null + "code": "choice_invalid" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json index 10d1dfd..49d9a40 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json @@ -3569,7 +3569,7 @@ { "error": { "class": "InvalidRequestError", - "code": null + "code": "choice_invalid" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json index 19d37a1..34fc03d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json @@ -221,7 +221,7 @@ { "error": { "class": "IncompleteAnswerError", - "code": null + "code": "answer_incomplete" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json index 959cea8..083d7e4 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json @@ -4462,7 +4462,7 @@ { "error": { "class": "ContractError", - "code": null + "code": "contract_violation" } } ] diff --git a/python/client-contract/tests/test_contract.py b/python/client-contract/tests/test_contract.py index c74ed52..c99da8e 100644 --- a/python/client-contract/tests/test_contract.py +++ b/python/client-contract/tests/test_contract.py @@ -43,3 +43,11 @@ def test_an_empty_record_set_is_a_hard_failure( def test_an_unknown_rule_is_refused() -> None: with pytest.raises(ValueError, match="unknown rule"): dfo_client_contract.rule("cache") + + +def test_client_codes_are_disjoint_from_the_refusal_codes() -> None: + client = [row["code"] for row in dfo_client_contract.client_codes()["codes"]] + refusals = {row["code"] for row in dfo_client_contract.actions()["codes"]} + assert client == sorted(set(client)) + assert not refusals & set(client) + assert dfo_client_contract.client_codes_schema()["title"] == "Client codes" diff --git a/tools/README.md b/tools/README.md index d7a3ef4..23fea7d 100644 --- a/tools/README.md +++ b/tools/README.md @@ -38,13 +38,13 @@ uv run tools/validate_provenance_docs_vectors.py uv run tools/validate_descriptions_vectors.py ``` -`validate_client_contract.py` validates the client contract under `python/client-contract/src/dfo_client_contract/` against its schemas, then checks what they cannot express: every `strict-fields.json` pointer resolves in `served/openapi.json` and stays required and non-nullable, or keeps its enum values; `actions.json` holds one row, in code order, for each active refusal code in `registries/codes.json` that reaches a problem document or a no_data reason, with a gap kind exactly for the no_data reasons; each recorded scenario's requests match a served route and its JSON bodies validate against that route's schemas, a required member that admits null allowed to be absent; each scenario's `expect` equals the outcomes its steps reach over its exchanges, with error classes and gap kinds from `actions.json`, and each Search request posts the input its steps derive; every absolute URL a record holds has the redacted query; and each `DatasetRef` example gets the verdict it states. It does not import `dfo_client_contract`, whose `tests/test_rules.py` replays the rule vectors. Also a PEP 723 script: +`validate_client_contract.py` validates the client contract under `python/client-contract/src/dfo_client_contract/` against its schemas, then checks what they cannot express: every `strict-fields.json` pointer resolves in `served/openapi.json` and stays required and non-nullable, or keeps its enum values; `actions.json` holds one row, in code order, for each active refusal code in `registries/codes.json` that reaches a problem document or a no_data reason, with a gap kind exactly for the no_data reasons; `client-codes.json` lists each code a client raises itself once, in code order, none of them a code in `actions.json` or the registry, each with a class a scenario names; each recorded scenario's requests match a served route and its JSON bodies validate against that route's schemas, a required member that admits null allowed to be absent; each scenario's `expect` equals the outcomes its steps reach over its exchanges, with refusals' error classes and gap kinds from `actions.json` and each error the client raises itself carrying its code and class from `client-codes.json`, and each Search request posts the input its steps derive; every absolute URL a record holds has the redacted query; and each `DatasetRef` example gets the verdict it states. It does not import `dfo_client_contract`, whose `tests/test_rules.py` replays the rule vectors. Also a PEP 723 script: ```bash uv run tools/validate_client_contract.py ``` -`capture_client_contract.py` refreshes the client contract from dfo-apis. `openapi --dfo-apis PATH` builds the composed app in that checkout's environment, in process, and writes `served/openapi.json` and `served/SOURCE.json`, refusing a checkout with uncommitted changes or untracked files and an environment out of step with its `uv.lock`; `record` runs the contract's scenarios against a base URL, dev by default, writes the records with every absolute URL's query redacted, derives the synthetic ones and validates the result. It imports its outcome rules from `validate_client_contract.py`. `python/client-contract/README.md` has the recipe. A PEP 723 script; its tests run without network or pyarrow: +`capture_client_contract.py` refreshes the client contract from dfo-apis. `openapi --dfo-apis PATH` builds the composed app in that checkout's environment, in process, and writes `served/openapi.json` and `served/SOURCE.json`, refusing a checkout with uncommitted changes or untracked files and an environment out of step with its `uv.lock`; `record` runs the contract's scenarios against a base URL, dev by default, writes the records with every absolute URL's query redacted, derives the synthetic ones and validates the result, and `record --offline` derives the outcomes again from the records with no request. It imports its outcome rules from `validate_client_contract.py`. `python/client-contract/README.md` has the recipe. A PEP 723 script; its tests run without network or pyarrow: ```bash uv run tools/capture_client_contract.py record diff --git a/tools/capture_client_contract.py b/tools/capture_client_contract.py index 8a4232e..289821d 100644 --- a/tools/capture_client_contract.py +++ b/tools/capture_client_contract.py @@ -10,7 +10,7 @@ Usage: uv run tools/capture_client_contract.py openapi --dfo-apis PATH uv run tools/capture_client_contract.py record [--base-url URL] - [--only NAME ...] [--scenarios-dir DIR] + [--only NAME ...] [--offline] [--scenarios-dir DIR] `openapi` builds the composed dfo-apis app from the checkout at PATH, every surface flag on, by calling `dfo_apis.app.create_app()` in that checkout's @@ -25,7 +25,10 @@ URL (dev by default; a local app at `http://127.0.0.1:8083/api`), the way a client would, and writes each record and its binary bodies to `scenarios/`. Each recorded scenario checks that its live answer still has the shape the -scenario is named for and refuses to write one that does not. Synthetic +scenario is named for and refuses to write one that does not. With +`--offline` no request is made: each recorded scenario's steps run again +over its own exchanges and rewrite its `expect`, and each synthetic scenario +that records nothing live is derived again from its parent. Synthetic scenarios are derived from the recorded records after them, so a recording refreshes both, and a synthetic record names its parent's body files rather than copies. Every absolute URL a record keeps, a signed download or a @@ -74,12 +77,11 @@ choice_for, choice_input, dataset_summary, - error_class, - error_outcome, gap_kinds, owns_body_file, part_label, - refusal_code, + refusal_error, + search_warning_code, search_warns, ) from validate_client_contract import main as validate_main @@ -516,6 +518,7 @@ class Session: recorder: Recorder actions: Mapping[str, Mapping[str, Any]] + client_codes: Mapping[str, Mapping[str, Any]] read_shape: Callable[[bytes], tuple[int, list[str]]] = parquet_shape sleep: Callable[[float], None] = time.sleep call: list[dict[str, Any]] = field(default_factory=list) @@ -530,8 +533,8 @@ def _step(self, step: dict[str, Any], run: Callable[[], dict[str, Any]]) -> None self.call.append(step) try: outcome = run() - except ClientError as refusal: - outcome = refusal.outcome + except ClientError as error: + outcome = error.outcome(self.client_codes) self.expect.append(outcome) def _answered(self, answer: Answer) -> dict[str, Any]: @@ -595,14 +598,14 @@ def fetch_answer( def run() -> dict[str, Any]: if answer.body["kind"] != "resolution": - raise ClientError("DeclinedError") + raise ClientError("answer_declined") gaps = answer_gaps(answer, self.gap_kinds) readings = _members(answer) if gaps and (not partial or not readings): - raise ClientError("IncompleteAnswerError") + raise ClientError("answer_incomplete") warns = search_warns(answer) if warns and strict: - raise ClientError("SearchWarning") + raise ClientError(search_warning_code(answer), error="SearchWarning") members = [self.build(parts, spec, None) for parts, spec in readings] return dataset_outcome(members, missing=gaps, search_warning=warns) @@ -782,8 +785,7 @@ def _wait(self, operation: dict[str, Any]) -> dict[str, Any]: def _raise_problem(self, response: Response) -> None: if response.status < 400: return - code = refusal_code(response.json()) - raise ClientError(error_class(response.status, code, self.actions), code) + raise refusal_error(response.status, response.json(), self.actions) def _window(window: str | tuple[int, int]) -> dict[str, Any]: @@ -862,6 +864,7 @@ class Context: base_url: str transport: Transport actions: Mapping[str, Mapping[str, Any]] + client_codes: Mapping[str, Mapping[str, Any]] read_shape: Callable[[bytes], tuple[int, list[str]]] = parquet_shape _cache: dict[str, Any] = field(default_factory=dict) @@ -869,9 +872,14 @@ def session(self, name: str, **recorder: Any) -> Session: return Session( Recorder(name, self.base_url, self.transport, **recorder), self.actions, + self.client_codes, read_shape=self.read_shape, ) + def raised(self, code: str) -> dict[str, Any]: + """The outcome of an error the client raises with `code`.""" + return ClientError(code).outcome(self.client_codes) + def definite_answer(self, question: str) -> Answer: if question not in self._cache: answer = self.session("prerequisite").search(question) @@ -1320,8 +1328,9 @@ def _proxy_502(parent: dict[str, Any], ctx: Context) -> Derived: refused = [ _refusal(first["request"], 502, dict(_PROXY_UNAVAILABLE)) for _ in range(3) ] - code = refusal_code(_PROXY_UNAVAILABLE) - error = error_outcome(error_class(502, code, ctx.actions), code) + error = refusal_error(502, _PROXY_UNAVAILABLE, ctx.actions).outcome( + ctx.client_codes + ) return Derived(copy.deepcopy(parent["call"]), refused, [error]) @@ -1390,7 +1399,7 @@ def _renamed_strict_field(parent: dict[str, Any], ctx: Context) -> Derived: exchanges = copy.deepcopy(parent["exchanges"][: index + 1]) manifest = exchanges[index]["response"]["json"] manifest["contentVersion"] = manifest.pop("content_version") - error = error_outcome("ContractError") + error = ctx.raised("contract_violation") return Derived( copy.deepcopy(parent["call"]), exchanges, [parent["expect"][0], error] ) @@ -1445,7 +1454,7 @@ def _choice_refused( def derive(parent: dict[str, Any], ctx: Context) -> Derived: derived = choose(parent, ctx) require( - derived.expect[-1] == error_outcome("InvalidRequestError"), + derived.expect[-1] == ctx.raised("choice_invalid"), "the choice refuses", ) return derived @@ -1489,7 +1498,7 @@ def _unknown_kind(parent: dict[str, Any], ctx: Context) -> Derived: exchanges = copy.deepcopy(parent["exchanges"]) exchanges[0]["response"]["json"]["kind"] = "verdict" return Derived( - copy.deepcopy(parent["call"]), exchanges, [error_outcome("ContractError")] + copy.deepcopy(parent["call"]), exchanges, [ctx.raised("contract_violation")] ) @@ -1498,7 +1507,7 @@ def _partial_nothing_answered(parent: dict[str, Any], ctx: Context) -> Derived: return Derived( [*copy.deepcopy(parent["call"]), {"op": "fetch", "partial": True}], copy.deepcopy(parent["exchanges"]), - [*copy.deepcopy(parent["expect"]), error_outcome("IncompleteAnswerError")], + [*copy.deepcopy(parent["expect"]), ctx.raised("answer_incomplete")], ) @@ -1833,13 +1842,137 @@ def binary_total(directory: Path) -> int: ) -def load_actions(package_dir: Path) -> dict[str, dict[str, Any]]: - rows = json.loads((package_dir / "actions.json").read_text(encoding="utf-8"))[ - "codes" - ] +def _rows(path: Path) -> dict[str, dict[str, Any]]: + rows = json.loads(path.read_text(encoding="utf-8"))["codes"] return {row["code"]: row for row in rows} +def load_actions(package_dir: Path) -> dict[str, dict[str, Any]]: + return _rows(package_dir / "actions.json") + + +def load_client_codes(package_dir: Path) -> dict[str, dict[str, Any]]: + return _rows(package_dir / "client-codes.json") + + +class Served: + """A transport serving one record's exchanges in order, its binary bodies + read from `body_dir`. A request the record does not hold next raises + `ValueError`.""" + + def __init__(self, record: dict[str, Any], body_dir: Path) -> None: + self.name = record["name"] + self.base_url = record["origin"].get("base_url", DEV_BASE_URL) + self.body_dir = body_dir + self.pending = copy.deepcopy(record["exchanges"]) + + def __call__( + self, + method: str, + url: str, + *, + body: bytes | None, + headers: Mapping[str, str], + timeout: float, + ) -> Response: + if not self.pending: + raise ValueError(f"{self.name}: {method} {url} follows the last exchange") + request, response = self.pending[0]["request"], self.pending[0]["response"] + if "url" in request: + target, sent = request["url"], redact_external_url(url) + if headers: + raise ValueError(f"{self.name}: a signed download carries headers") + elif "origin_path" in request: + target, sent = _origin(self.base_url) + request["origin_path"], url + else: + target, sent = self.base_url + request["path"], url + posted = json.loads(body) if body else None + if (method, sent, posted) != (request["method"], target, request.get("json")): + raise ValueError( + f"{self.name}: {method} {sent} is not the next exchange, " + f"{request['method']} {target}" + ) + self.pending.pop(0) + if "json" in response: + data = json.dumps(response["json"]).encode() + elif "body_file" in response: + data = (self.body_dir / response["body_file"]).read_bytes() + else: + data = b"" + return Response(response["status"], dict(response.get("headers", {})), data) + + +def _offline(method: str, url: str, **_: Any) -> Response: + raise SystemExit(f"--offline makes no request, and a scenario sent {method} {url}") + + +def drive(session: Session, call: Sequence[dict[str, Any]]) -> None: + """Runs a record's steps through `session`.""" + answer = None + for step in call: + match step: + case {"op": "search", "question": question}: + answer = session.search(question) + case {"op": "choose", "option": option}: + if answer is None: + raise ValueError("a choice follows no answer") + answer = session.choose(answer, option, part=step.get("part")) + case {"op": "fetch", "spec": spec}: + window = step.get("window") + session.fetch_spec( + Spec(spec["spec_id"], spec["definition"], spec.get("sentence")), + window=tuple(window) if isinstance(window, list) else window, + facets=step.get("facets"), + ) + case {"op": "fetch", "ref": ref}: + session.fetch_ref(ref) + case {"op": "fetch"}: + if answer is None: + raise ValueError("a fetch of an answer follows no answer") + session.fetch_answer( + answer, + partial=step.get("partial", False), + strict=step.get("strict", False), + ) + case {"op": "mint", "spec": spec}: + session.mint( + Spec(spec["spec_id"], spec["definition"], spec.get("sentence")) + ) + case {"op": "result"}: + session.result() + + +def rederive_recorded(name: str, ctx: Context, directory: Path) -> None: + """Derives a recorded scenario's `expect` again from its own steps over + its own exchanges, with no request, and keeps the rest of the record.""" + path = directory / f"{name}.json" + if not path.exists(): + raise SystemExit(f"{name}: no record to derive from; record it live") + record = json.loads(path.read_text(encoding="utf-8")) + served = Served(record, directory) + session = Session( + Recorder(name, served.base_url, served), + ctx.actions, + ctx.client_codes, + read_shape=ctx.read_shape, + sleep=lambda _: None, + ) + try: + drive(session, record["call"]) + except (ValueError, ShapeError) as exc: + raise SystemExit(f"{name}: {exc}; record it live") from exc + unchanged = ( + not served.pending + and session.call == record["call"] + and session.recorder.exchanges == record["exchanges"] + ) + if not unchanged: + raise SystemExit(f"{name}: its steps no longer make its exchanges") + write_record( + directory, {**record, "expect": session.expect}, session.recorder.bodies + ) + + def run_record(args: argparse.Namespace) -> int: package_dir: Path = args.package_dir directory: Path = args.scenarios_dir or package_dir / "scenarios" @@ -1848,13 +1981,26 @@ def run_record(args: argparse.Namespace) -> int: if unknown: raise SystemExit(f"no scenario is named {sorted(unknown)}") chosen = set(args.only or names) - ctx = Context(args.base_url, urllib_transport, load_actions(package_dir)) + live = sorted(d.name for d in SYNTHETIC if d.live and d.name in chosen) + if args.offline and live: + raise SystemExit(f"--offline derives no live scenario, and {live} are live") + ctx = Context( + args.base_url, + _offline if args.offline else urllib_transport, + load_actions(package_dir), + load_client_codes(package_dir), + ) count = 0 for definition in RECORDED: - if definition.name in chosen: + if definition.name not in chosen: + continue + if args.offline: + print(f"deriving {definition.name} from its record", flush=True) + rederive_recorded(definition.name, ctx, directory) + else: print(f"recording {definition.name}", flush=True) record_recorded(definition, ctx, directory) - count += 1 + count += 1 for synthetic in SYNTHETIC: if synthetic.name in chosen: print(f"deriving {synthetic.name}", flush=True) @@ -1893,6 +2039,11 @@ def main(argv: Sequence[str] | None = None) -> int: record = commands.add_parser("record", help="record the scenarios") record.add_argument("--base-url", default=DEV_BASE_URL) record.add_argument("--only", nargs="+", metavar="NAME") + record.add_argument( + "--offline", + action="store_true", + help="derive each outcome again from the records, with no request", + ) record.add_argument( "--scenarios-dir", type=Path, diff --git a/tools/tests/test_capture_client_contract.py b/tools/tests/test_capture_client_contract.py index 5b996d5..6045a2a 100644 --- a/tools/tests/test_capture_client_contract.py +++ b/tools/tests/test_capture_client_contract.py @@ -31,6 +31,7 @@ SCENARIOS = capture.PACKAGE_DIR / "scenarios" ACTIONS = capture.load_actions(capture.PACKAGE_DIR) +CLIENT_CODES = capture.load_client_codes(capture.PACKAGE_DIR) def _load(name: str) -> dict[str, Any]: @@ -45,45 +46,6 @@ def _records(kind: str) -> list[str]: ) -class _Served: - """A transport serving one record's responses, and failing on any request - the record does not hold in that order.""" - - def __init__(self, record: dict[str, Any]) -> None: - self.base_url = record["origin"].get("base_url", capture.DEV_BASE_URL) - self.pending = copy.deepcopy(record["exchanges"]) - - def __call__( - self, - method: str, - url: str, - *, - body: bytes | None, - headers: Mapping[str, str], - timeout: float, - ) -> Any: - exchange = self.pending.pop(0) - request, response = exchange["request"], exchange["response"] - assert method == request["method"] - if "url" in request: - assert headers == {}, "a signed download carries no client header" - assert capture.redact_external_url(url) == request["url"] - elif "origin_path" in request: - assert url == capture._origin(self.base_url) + request["origin_path"] - else: - assert url == self.base_url + request["path"] - assert (json.loads(body) if body else None) == request.get("json") - if "json" in response: - data = json.dumps(response["json"]).encode() - elif "body_file" in response: - data = (SCENARIOS / response["body_file"]).read_bytes() - else: - data = b"" - return capture.Response( - response["status"], dict(response.get("headers", {})), data - ) - - def _shape(data: bytes) -> tuple[int, list[str]]: return len(data), ["column"] @@ -99,42 +61,6 @@ def _without_shapes(expect: list[dict[str, Any]]) -> list[dict[str, Any]]: return expect -def _drive(session: Any, call: list[dict[str, Any]]) -> None: - """Runs a record's steps through the recorder's client.""" - answer = None - for step in call: - match step: - case {"op": "search", "question": question}: - answer = session.search(question) - case {"op": "choose", "option": option}: - answer = session.choose(answer, option, part=step.get("part")) - case {"op": "fetch", "spec": spec}: - window = step.get("window") - session.fetch_spec( - capture.Spec( - spec["spec_id"], spec["definition"], spec.get("sentence") - ), - window=tuple(window) if isinstance(window, list) else window, - facets=step.get("facets"), - ) - case {"op": "fetch", "ref": ref}: - session.fetch_ref(ref) - case {"op": "fetch"}: - session.fetch_answer( - answer, - partial=step.get("partial", False), - strict=step.get("strict", False), - ) - case {"op": "mint", "spec": spec}: - session.mint( - capture.Spec( - spec["spec_id"], spec["definition"], spec.get("sentence") - ) - ) - case {"op": "result"}: - session.result() - - _LIVE = sorted(d.name for d in capture.SYNTHETIC if d.live) @@ -145,12 +71,12 @@ def test_every_synthetic_record_has_a_definition() -> None: @pytest.mark.parametrize("name", [*_records("recorded"), *_LIVE]) def test_the_recorder_reproduces_each_record_from_its_steps(name: str) -> None: record = _load(name) - served = _Served(record) + served = capture.Served(record, SCENARIOS) recorder = capture.Recorder(name, served.base_url, served) session = capture.Session( - recorder, ACTIONS, read_shape=_shape, sleep=lambda _: None + recorder, ACTIONS, CLIENT_CODES, read_shape=_shape, sleep=lambda _: None ) - _drive(session, record["call"]) + capture.drive(session, record["call"]) assert served.pending == [], "the client skipped a recorded exchange" assert session.call == record["call"] assert recorder.exchanges == record["exchanges"] @@ -229,7 +155,9 @@ def test_each_derived_record_follows_from_its_parent(name: str) -> None: record = _load(name) definition = next(d for d in capture.SYNTHETIC if d.name == name) parent = _load(record["origin"]["derived_from"]) - ctx = capture.Context(capture.DEV_BASE_URL, _Served(parent), ACTIONS) + ctx = capture.Context( + capture.DEV_BASE_URL, capture.Served(parent, SCENARIOS), ACTIONS, CLIENT_CODES + ) derived = definition.derive(copy.deepcopy(parent), ctx) assert record["origin"]["edit"] == definition.edit assert record["call"] == derived.call @@ -237,12 +165,34 @@ def test_each_derived_record_follows_from_its_parent(name: str) -> None: assert record["expect"] == derived.expect +def test_an_offline_rederivation_rewrites_only_the_expect(tmp_path: Path) -> None: + name = "answer-declined" + for path in SCENARIOS.glob(f"{name}*"): + (tmp_path / path.name).write_bytes(path.read_bytes()) + stale = _load(name) + stale["expect"][1]["error"]["code"] = None + capture.write_record(tmp_path, stale, {}) + ctx = capture.Context( + capture.DEV_BASE_URL, capture._offline, ACTIONS, CLIENT_CODES, read_shape=_shape + ) + capture.rederive_recorded(name, ctx, tmp_path) + fresh = (tmp_path / f"{name}.json").read_text(encoding="utf-8") + assert fresh == (SCENARIOS / f"{name}.json").read_text(encoding="utf-8") + + +def test_an_offline_run_refuses_a_live_scenario() -> None: + with pytest.raises(SystemExit, match="derives no live scenario"): + capture.main(["record", "--offline", "--only", _LIVE[0]]) + + def test_a_renamed_strict_field_ends_the_call_at_the_build() -> None: record = _load("fetch-renamed-strict-field") manifest = record["exchanges"][-1]["response"]["json"] assert "content_version" not in manifest assert "contentVersion" in manifest - assert record["expect"][-1] == {"error": {"class": "ContractError", "code": None}} + assert record["expect"][-1] == { + "error": {"class": "ContractError", "code": "contract_violation"} + } def test_place_options_pin_each_candidate_on_the_ambiguous_wording() -> None: diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index 94512b9..1ecd5fa 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -36,6 +36,9 @@ _MIXED = "scenarios/answer-mixed-fetch-raises.json" _FOLDED = "scenarios/answer-several-readings-folded.json" _TOP5 = "scenarios/search-warning-top5.json" +_NO_CHOICE = "scenarios/choose-refused-no-choice.json" +_DECLINED = "scenarios/answer-declined.json" +_REQUEST_INVALID = "scenarios/fetch-spec-request-invalid.json" def _posted(index: int, change: Callable[[Any], None]) -> Callable[[Any], None]: @@ -130,6 +133,17 @@ def _set_step(index: int, **fields: Any) -> Callable[[Any], None]: return lambda doc: doc["call"][index].update(fields) +def _error_code(index: int, code: str | None) -> Callable[[Any], None]: + return _set_outcome(index, lambda o: o["error"].update(code=code)) + + +def _one_hint(body: Any) -> None: + """Leaves the answer's one definite part a single warn warning.""" + part = body["parts"][0] + part["operations"], part["departures"] = [], [] + del part["warnings"][1:] + + @pytest.mark.parametrize( ("target", "change", "expected"), [ @@ -473,6 +487,84 @@ def _set_step(index: int, **fields: Any) -> Callable[[Any], None]: lambda doc: doc["vectors"].append(doc["vectors"][0]), "vector 'secret-key-passes' repeats", ), + ( + "client-codes.json", + _set_action("offline", condition=None), + "'condition' is a required property", + ), + ( + "client-codes.json", + lambda doc: doc["codes"].reverse(), + "codes are not sorted", + ), + ( + "client-codes.json", + lambda doc: doc["codes"].insert(1, doc["codes"][0]), + "'answer_declined' is listed twice", + ), + ( + "client-codes.json", + _add_action( + {"code": "spec_not_found", "class": "NotFoundError", "condition": "x"} + ), + "'spec_not_found' is also a code in actions.json", + ), + ( + "client-codes.json", + _add_action( + { + "code": "alternates_unevaluated", + "class": "ServerError", + "condition": "x", + } + ), + "'alternates_unevaluated' is also a code in registries/codes.json", + ), + ( + "client-codes.json", + _set_action("answer_declined", **{"class": "SearchWarning"}), + "raises 'SearchWarning', a class no scenario names", + ), + ( + "client-codes.json", + _set_action("offline", **{"class": "by_status"}), + "where 'refusal_without_code' alone does", + ), + ( + "client-codes.json", + _drop_action("answer_declined"), + "'answer_declined' is not a client code of one class", + ), + ( + "client-codes.json", + _set_action("choice_invalid", **{"class": "ContractError"}), + "client code 'choice_invalid' raises ContractError, not InvalidRequestError", + ), + ( + _NO_CHOICE, + _error_code(1, None), + "InvalidRequestError code None is neither a refusal's code", + ), + ( + _DECLINED, + _error_code(1, "choice_invalid"), + "raises InvalidRequestError, not DeclinedError", + ), + ( + _NO_CHOICE, + _error_code(1, "invalid_argument"), + '"code": "choice_invalid"}}', + ), + ( + _REQUEST_INVALID, + _set_body(0, lambda body: body.pop("code")), + '"code": "refusal_without_code"}}', + ), + ( + _TOP5, + _set_body(0, _one_hint), + '"code": "slot_defaulted"}}', + ), ( "served/SOURCE.json", lambda doc: doc.update(commit="8408f1f"), @@ -543,6 +635,20 @@ def _set_step(index: int, **fields: Any) -> Callable[[Any], None]: "ref-example-both-verdicts", "ref-example-wrong-verdict", "rule-vector-repeated", + "client-code-without-condition", + "client-codes-unsorted", + "client-code-repeated", + "client-code-is-an-action-code", + "client-code-is-a-registry-code", + "client-code-raises-a-warning", + "client-code-by-status-beside-refusal-without-code", + "client-code-the-rules-raise-missing", + "client-code-class-changed", + "client-error-without-code", + "client-error-code-of-another-class", + "client-error-code-the-rules-do-not-raise", + "refusal-without-code", + "search-warning-one-hint-code", "source-commit-short", ], ) diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index 0693922..b4b2914 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -24,6 +24,10 @@ when its code has a `no_data_reason` mapping; `choose` goes with the `choice` gap kind and only with it; and a code with a `problem_details` mapping takes an action a problem document can carry. +- `client-codes.json` lists codes in order, each once, none of them a code in + `actions.json` or `registries/codes.json`. Each row's class is one a + scenario's error may name, other than `SearchWarning`, and only + `refusal_without_code` takes the class its status maps to. - Each scenario's file name matches its `name`, names are unique, `expect` holds one outcome per step, a step that acts on an earlier result follows one, a synthetic scenario derives from a recorded one, and every body file @@ -33,9 +37,12 @@ route's request schema, each JSON response body validates against the route's schema for its status, and a problem document's `code` is an active code registered with that status. +- Each error a scenario expects, other than a `SearchWarning`, carries a + refusal's code from its exchanges or a client code of its class. - Each scenario's `expect` equals the outcomes its steps reach over its - exchanges, with error classes and gap kinds from `actions.json`, as - `expected_outcomes` derives them; a dataset's rows, columns and per-part + exchanges, with refusals' error classes and gap kinds from `actions.json` + and the class of each error the client raises itself from + `client-codes.json`, as `expected_outcomes` derives them; a dataset's rows, columns and per-part row counts are left to the Parquet bodies. Each Search request a record holds posts the input the steps derive: the question, a choice's data_query or dataset_resubmit entries, or a member's identity. Every @@ -122,6 +129,7 @@ def _contract_validators() -> dict[str, jsonschema.Draft202012Validator]: names = ( "strict-fields.schema.json", "actions.schema.json", + "client-codes.schema.json", "scenario.schema.json", "dataset-ref.schema.json", "rules/rules.schema.json", @@ -320,6 +328,53 @@ def _check_actions(document: dict[str, Any], registry: dict[str, Any]) -> list[s return problems +# --- client codes ----------------------------------------------------------- + + +def error_classes(scenario_schema: dict[str, Any]) -> list[str]: + """The error classes a scenario's error outcome may name.""" + return scenario_schema["$defs"]["error"]["properties"]["class"]["enum"] + + +def _check_client_codes( + document: dict[str, Any], + actions: dict[str, Any], + registry: dict[str, Any], + classes: Sequence[str], +) -> list[str]: + codes = [row["code"] for row in document["codes"]] + problems = [ + f"client-codes.json: code {code!r} is listed twice" + for code in sorted({c for c in codes if codes.count(c) > 1}) + ] + if codes != sorted(codes): + problems.append("client-codes.json: codes are not sorted") + taken = { + "actions.json": {row["code"] for row in actions["codes"]}, + "registries/codes.json": {entry["code"] for entry in registry["entries"]}, + } + for source, server_codes in taken.items(): + problems.extend( + f"client-codes.json: {code!r} is also a code in {source}" + for code in sorted(set(codes) & server_codes) + ) + # A SearchWarning is a warning and carries the server's code. + known = {*classes, BY_STATUS} - {"SearchWarning"} + problems.extend( + f"client-codes.json: {row['code']!r} raises {row['class']!r}, a class " + "no scenario names" + for row in document["codes"] + if row["class"] not in known + ) + by_status = [row["code"] for row in document["codes"] if row["class"] == BY_STATUS] + if by_status != [REFUSAL_WITHOUT_CODE]: + problems.append( + f"client-codes.json: {by_status} take the class {BY_STATUS}, where " + f"{REFUSAL_WITHOUT_CODE!r} alone does" + ) + return problems + + # --- scenarios -------------------------------------------------------------- @@ -556,16 +611,54 @@ def error_class( return STATUS_CLASSES.get(status, fallback) -def error_outcome(error: str, code: str | None = None) -> dict[str, Any]: +# The class of a client code that takes the class its refusal's HTTP status +# maps to, and the client code of a refusal whose body carries no code. +BY_STATUS = "by_status" +REFUSAL_WITHOUT_CODE = "refusal_without_code" + + +def error_outcome(error: str, code: str | None) -> dict[str, Any]: return {"error": {"class": error, "code": code}} class ClientError(Exception): - """A step ends in `outcome`, an error a client raises.""" - - def __init__(self, error: str, code: str | None = None) -> None: - super().__init__(f"{error} {code}") - self.outcome = error_outcome(error, code) + """A step ends in an error a client raises. A refusal names its class and + the server's code, a SearchWarning names the server's warning or + departure code, and any other error names a code from + `client-codes.json`, whose row gives its class.""" + + def __init__(self, code: str | None, *, error: str | None = None) -> None: + super().__init__(f"{error or 'client'} {code}") + self.code = code + self.error = error + + def outcome(self, client_codes: Mapping[str, Mapping[str, Any]]) -> dict[str, Any]: + """The error outcome, its class from `client_codes` when the error + names none. + + Raises: + ValueError: The code is not a client code of one class. + """ + if self.error is not None: + return error_outcome(self.error, self.code) + row = client_codes.get(self.code) if self.code is not None else None + if row is None or row["class"] == BY_STATUS: + raise ValueError( + f"{self.code!r} is not a client code of one class in client-codes.json" + ) + return error_outcome(row["class"], self.code) + + +def refusal_error( + status: int, body: Any, actions: Mapping[str, Mapping[str, Any]] +) -> ClientError: + """The error a refusal raises: its code's class and the server's code, or + for a body with no code the class its status maps to and + `refusal_without_code`.""" + code = refusal_code(body) + return ClientError( + code or REFUSAL_WITHOUT_CODE, error=error_class(status, code, actions) + ) # The answer kinds a client reads. Any other kind raises ContractError. @@ -591,7 +684,7 @@ def answer_from_body(body: dict[str, Any]) -> Answer: """The answer a search response holds; a kind no client knows raises ContractError.""" if body.get("kind") not in ANSWER_KINDS: - raise ClientError("ContractError") + raise ClientError("contract_violation") return Answer( body, body.get("parts", []), body.get("rendered_sentence"), body.get("status") ) @@ -626,7 +719,7 @@ class Choice: def _refuse() -> ClientError: - return ClientError("InvalidRequestError") + return ClientError("choice_invalid") def choice_for( @@ -721,7 +814,7 @@ def resubmit_entry(part: dict[str, Any], choice: Choice | None) -> dict[str, Any if choice is not None and choice.option is not None: parts = choice.option["data_query"].get("parts") if not isinstance(parts, list) or len(parts) != 1: - raise ClientError("ContractError") + raise ClientError("contract_violation") return {"entry_kind": "parsed", "part": parts[0]} match part.get("status"): case "definite": @@ -780,26 +873,43 @@ def _echo(part: dict[str, Any], **members: Any) -> dict[str, Any]: return entry -def search_warns(answer: Answer) -> bool: - """Whether fetching `answer` issues a SearchWarning: a definite part has - an operation Search did not run, a departure, or a warning shown at - `warn` or `degraded` severity, or the answer's diagnostics carry such a - warning. An `info` warning issues nothing.""" - - def shown(warnings: Any) -> bool: - return any( - w.get("severity") in SHOWN_SEVERITIES and w.get("message") - for w in warnings or [] - ) +def reading_hints(answer: Answer) -> dict[str, str]: + """How `answer`'s readings differ from the question, each line a client + shows once, with its code. In part order, each definite part gives each + operation Search did not run, coded by its verb, each departure, and each + warning shown at `warn` or `degraded` severity; the answer's diagnostics + warnings follow. An `info` warning gives nothing.""" + hints: dict[str, str] = {} + + def notices(warnings: Any) -> None: + for warning in warnings or []: + if warning.get("severity") in SHOWN_SEVERITIES and warning.get("message"): + hints.setdefault(f"Note: {warning['message']}", warning["code"]) for part in answer.parts: if part.get("status") != "definite": continue - if part.get("operations") or part.get("departures"): - return True - if shown(part.get("warnings")): - return True - return shown(answer.body.get("diagnostics", {}).get("warnings")) + for operation in part.get("operations") or []: + line = f"Not done: {operation['verb']} ({json.dumps(operation['phrase'])})" + hints.setdefault(line, operation["verb"]) + for departure in part.get("departures") or []: + hints.setdefault(departure["text"], departure["code"]) + notices(part.get("warnings")) + notices(answer.body.get("diagnostics", {}).get("warnings")) + return hints + + +def search_warns(answer: Answer) -> bool: + """Whether fetching `answer` issues a SearchWarning: its readings differ + from the question in some way `reading_hints` lists.""" + return bool(reading_hints(answer)) + + +def search_warning_code(answer: Answer) -> str | None: + """The code a SearchWarning on `answer` carries: the one hint's code, or + None when the readings differ in several ways.""" + codes = list(reading_hints(answer).values()) + return codes[0] if len(codes) == 1 else None def answer_gaps(answer: Answer, kinds: Mapping[str, str]) -> list[dict[str, Any]]: @@ -976,6 +1086,7 @@ class _Replay: base_path: str members: Mapping[str, Sequence[str]] actions: Mapping[str, Mapping[str, Any]] + client_codes: Mapping[str, Mapping[str, Any]] cursor: int = 0 answer: Answer | None = None minted: tuple[dict[str, Any], dict[str, Any]] | None = None @@ -1022,9 +1133,7 @@ def acted_on(self, exchange: dict[str, Any]) -> Any: response = exchange["response"] body = response.get("json") if response["status"] >= 400: - code = refusal_code(body) - error = error_class(response["status"], code, self.actions) - raise ClientError(error, code) + raise refusal_error(response["status"], body, self.actions) schema = self.routes.response_schema( self.base_path, exchange["request"], response["status"] ) @@ -1033,7 +1142,7 @@ def acted_on(self, exchange: dict[str, Any]) -> Any: def strict(self, schema: Any, body: Any) -> None: if strict_gaps(self.routes.openapi, self.members, schema, body): - raise ClientError("ContractError") + raise ClientError("contract_violation") def download(self) -> None: """The files route, then its signed URL; a refused signed URL asks the @@ -1063,7 +1172,7 @@ def wait(self, operation: dict[str, Any]) -> dict[str, Any]: resource = self.acted_on(self.call(*_POLL)) operation, manifest = resource["operation"], resource.get("manifest") if not isinstance(manifest, dict): - raise ClientError("ContractError") + raise ClientError("contract_violation") self.strict(_MANIFEST, manifest) return manifest @@ -1112,7 +1221,7 @@ def step(self, step: dict[str, Any]) -> dict[str, Any]: except ClientError as ended: if op in {"search", "choose"}: self.answer = None - return ended.outcome + return ended.outcome(self.client_codes) def _answered(self) -> Answer: if self.answer is None: @@ -1144,14 +1253,14 @@ def _fetch(self, step: dict[str, Any]) -> dict[str, Any]: request.""" answer = self._answered() if answer.body.get("kind") != "resolution": - raise ClientError("DeclinedError") + raise ClientError("answer_declined") gaps = answer_gaps(answer, self.kinds) readings = answer_members(answer) if gaps and (not step.get("partial", False) or not readings): - raise ClientError("IncompleteAnswerError") + raise ClientError("answer_incomplete") warns = search_warns(answer) if warns and step.get("strict", False): - raise ClientError("SearchWarning") + raise ClientError(search_warning_code(answer), error="SearchWarning") members = [ self.build( parts, @@ -1196,16 +1305,24 @@ def expected_outcomes( base_path: str, strict: dict[str, Any], actions: Mapping[str, Mapping[str, Any]], + client_codes: Mapping[str, Mapping[str, Any]], ) -> list[dict[str, Any]]: - """The outcome each of `record`'s steps reaches over its exchanges, and - over `actions` for error classes and gap kinds. A dataset outcome holds - what `dataset_summary` gives, without rows and columns. + """The outcome each of `record`'s steps reaches over its exchanges, over + `actions` for refusals' error classes and gap kinds, and over + `client_codes` for the class of each error the client raises itself. A + dataset outcome holds what `dataset_summary` gives, without rows and + columns. Raises: ValueError: The exchanges do not fit the steps. """ replay = _Replay( - record["exchanges"], routes, base_path, _strict_members(strict), actions + record["exchanges"], + routes, + base_path, + _strict_members(strict), + actions, + client_codes, ) try: outcomes = [replay.step(step) for step in record["call"]] @@ -1348,9 +1465,11 @@ def _part_problems( def _check_scenarios( validator: jsonschema.Draft202012Validator, openapi: dict[str, Any], + *, registry: dict[str, Any], strict: dict[str, Any], actions: Mapping[str, Mapping[str, Any]], + client_codes: Mapping[str, Mapping[str, Any]], ) -> list[str]: directory = PACKAGE_DIR / "scenarios" paths = sorted(directory.glob("*.json")) @@ -1375,6 +1494,7 @@ def _check_scenarios( problems.append(f"scenarios/{path.name}: name {name!r} repeats") records[name] = record problems.extend(_check_steps(path.name, record)) + problems.extend(_check_client_errors(path.name, record, client_codes)) for index, exchange in enumerate(record["exchanges"]): problems.extend( _check_redaction(f"scenarios/{path.name}: exchange {index}", exchange) @@ -1419,6 +1539,7 @@ def _check_scenarios( base_path=base_path, strict=strict, actions=actions, + client_codes=client_codes, ) except ValueError as exc: problems.append(f"scenarios/{file_name}: {exc}") @@ -1433,6 +1554,51 @@ def _check_scenarios( return problems +# The classes a refusal's HTTP status maps to. +_STATUS_ONLY_CLASSES = {*STATUS_CLASSES.values(), "ServerError", "InvalidRequestError"} + + +def _check_client_errors( + file_name: str, + record: dict[str, Any], + client_codes: Mapping[str, Mapping[str, Any]], +) -> list[str]: + """Each error outcome no refusal in the record carries the code of names + a client code of its class. A SearchWarning carries the server's code.""" + refused = { + refusal_code(e["response"].get("json")) + for e in record["exchanges"] + if e["response"]["status"] >= 400 + } + problems = [] + for index, outcome in enumerate(record["expect"]): + error = outcome.get("error") + if error is None or error["class"] == "SearchWarning": + continue + code = error["code"] + if code in refused: + continue + label = f"scenarios/{file_name}: step {index}" + row = client_codes.get(code) if code is not None else None + if row is None: + problems.append( + f"{label}: {error['class']} code {code!r} is neither a refusal's " + "code in the exchanges nor a client code" + ) + elif row["class"] == BY_STATUS: + if error["class"] not in _STATUS_ONLY_CLASSES: + problems.append( + f"{label}: {code!r} raises the class a status maps to, which " + f"{error['class']} is not" + ) + elif row["class"] != error["class"]: + problems.append( + f"{label}: client code {code!r} raises {row['class']}, not " + f"{error['class']}" + ) + return problems + + def _check_steps(file_name: str, record: dict[str, Any]) -> list[str]: call, expect = record["call"], record["expect"] problems = [] @@ -1553,13 +1719,27 @@ def validate() -> list[str]: ) problems.extend(errors or _check_actions(actions, registry)) + client_codes = _load(PACKAGE_DIR / "client-codes.json") + errors = _schema_problems( + "client-codes.json", validators["client-codes.schema.json"], client_codes + ) + scenario_schema = validators["scenario.schema.json"].schema + problems.extend( + errors + or _check_client_codes( + client_codes, actions, registry, error_classes(scenario_schema) + ) + ) + client_rows = [] if errors else client_codes["codes"] + problems.extend( _check_scenarios( validators["scenario.schema.json"], openapi, - registry, - strict, - {row["code"]: row for row in actions["codes"]}, + registry=registry, + strict=strict, + actions={row["code"]: row for row in actions["codes"]}, + client_codes={row["code"]: row for row in client_rows}, ) ) problems.extend(_check_refs(validators["dataset-ref.schema.json"])) @@ -1577,7 +1757,9 @@ def main() -> int: strict = _load(PACKAGE_DIR / "strict-fields.json") print( f"client contract valid: {len(_load(PACKAGE_DIR / 'actions.json')['codes'])} " - f"action rows, {len(strict['required'])} required and " + "action rows, " + f"{len(_load(PACKAGE_DIR / 'client-codes.json')['codes'])} client codes, " + f"{len(strict['required'])} required and " f"{len(strict['enums'])} enum pointers, " f"{len(list((PACKAGE_DIR / 'scenarios').glob('*.json')))} scenarios" ) From 0344f8f1c99f6cd51351deecfe75433964cd55b1 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Tue, 20 Oct 2026 23:19:07 +0200 Subject: [PATCH 14/39] feat(client-contract): add fetch, long-build and stored-version scenarios Ten scenarios cover a frame-layout build, a 504 twice, an unresolvable member, a strict data warning, a digest mismatch, a resubmit answering another spec, a frame fetch of several readings, and an expired ref that rebuilds the same version, lands on a newer one, or cannot be rebuilt. Six more are defined and wait for a served document that declares the build's 202 or the file selector. The validator derives poll waits, resubmissions, the operation id and the newest version, and a refusal with no known code maps 408 to DfoTimeoutError and 410 to NotFoundError. --- python/client-contract/CHANGELOG.md | 7 +- python/client-contract/README.md | 58 +- .../dfo_client_contract/scenario.schema.json | 106 +- .../fetch-frame-several-readings.json | 9896 +++++++++++++++++ .../fetch-ref-expired-newer-version.json | 907 ++ .../fetch-ref-expired-not-reproducible.json | 259 + ...etch-ref-expired-rebuild-same-version.json | 971 ++ .../scenarios/fetch-spec-504-twice.json | 302 + .../scenarios/fetch-spec-digest-mismatch.bin | 1 + .../scenarios/fetch-spec-digest-mismatch.json | 913 ++ .../scenarios/fetch-spec-frame-layout.json | 919 ++ .../scenarios/fetch-spec-frame-layout.parquet | Bin 0 -> 5627 bytes .../fetch-spec-member-not-resolvable.json | 200 + .../fetch-spec-resubmit-other-spec.json | 4574 ++++++++ .../scenarios/fetch-spec-strict-warning.json | 862 ++ tools/capture_client_contract.py | 970 +- tools/tests/test_capture_client_contract.py | 34 +- tools/tests/test_validate_client_contract.py | 256 +- tools/validate_client_contract.py | 727 +- 19 files changed, 21692 insertions(+), 270 deletions(-) create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-same-version.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-twice.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.bin create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.parquet create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-member-not-resolvable.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index 56c5058..b591ff4 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -10,11 +10,12 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be - `served/openapi.json`, the composed dfo-apis app's OpenAPI document, and `served/SOURCE.json`, naming dfo-apis commit `8408f1f95c622223f8fa6e9ba55826ee8e22a852`. - `strict-fields.json` and its schema: 25 members that stay required and non-nullable, and the answer kinds, part statuses and operation statuses the clients branch on. - `actions.json` and its schema: the caller's next step for each of the 101 active refusal codes on `problem_details` or `no_data_reason`, with the gap kind of each no_data reason. -- `scenario.schema.json`, the scenario record, and 44 scenarios: 18 recorded against dfo-apis `8408f1f95` and 26 synthetic, each derived from a recorded one by a one-line edit, with 11 Parquet bodies totalling 102,956 bytes. The scenarios cover the several-part choice entries, the choice refusals, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule and the stacked dataset's `part` column. +- The status fallback for a refusal whose code has no row: 400 and 422 to `InvalidRequestError`, 401 to `AuthenticationError`, 403 to `PermissionDeniedError`, 404 and 410 to `NotFoundError`, 408 to `DfoTimeoutError`, 429 to `RateLimitError`, and any other 4xx or 5xx to `InvalidRequestError` or `ServerError`. +- `scenario.schema.json`, the scenario record, and 54 scenarios: 19 recorded against dev at dfo-apis `8408f1f95`, `7175fe98e` and `687d48bf1`, and 35 synthetic, each derived from a recorded one by a one-line edit, with 13 binary bodies totalling 108,604 bytes. The scenarios cover the several-part choice entries, the choice refusals, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a twice cut-off build, a refused build, a digest mismatch, an identity resubmit answering another spec, and a ref whose stored file expired, rebuilt at the same version, at a newer one, or refused. Six more are defined and wait for a served document that declares the build's 202 or the file selector: `mint-async-build`, `operation-resume`, `fetch-spec-async-build`, `fetch-spec-poll-rate-limited`, `fetch-spec-operation-failed-resubmitted` and `fetch-ref-expired-file-selector`. - `client-codes.json` and its schema: the 16 codes a client sets on the errors it raises itself, each with its error class and condition, disjoint from `actions.json` and `registries/codes.json`, and the `client_codes()` and `client_codes_schema()` accessors. Every scenario error the client raises itself carries its code, and `refusal_without_code` names a refusal whose body carries no code. - `dataset-ref.schema.json`, the frozen `DatasetRef` format, with accepted and rejected examples. -- `tools/capture_client_contract.py`, which captures `served/openapi.json` from a dfo-apis checkout in process and records the scenarios against a base URL, dev by default, or with `record --offline` derives their outcomes again from the records with no request. -- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, checks `client-codes.json` against them, and checks each scenario's `expect` against the outcomes its exchanges, `actions.json` and `client-codes.json` give, and each Search request against the input its steps derive. +- `tools/capture_client_contract.py`, which captures `served/openapi.json` from a dfo-apis checkout in process and records the scenarios against a base URL, dev by default, or with `record --offline` derives their outcomes again from the records with no request. A scenario that needs a route or status the served document lacks waits until the document declares it. +- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, checks `client-codes.json` against them, and checks each scenario's `expect` against the outcomes its exchanges, `actions.json` and `client-codes.json` give, each Search request against the input its steps derive, each build's options against its layout, and each download against its artifact's digest. The outcomes include each long build's operation id, poll waits and resubmissions, and a `VersionUnavailableError`'s newest version. - The client rules and their vectors: the credentials path and file format, the key lookup order, the key format check, and the cache directory and layout. [unreleased]: https://github.com/DevelopmentFinanceObservatory/spec-kit/commits/main/python diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 1773986..3c9b3a9 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -91,35 +91,50 @@ The required members are each part's `status` and its payload (`spec`, `candidat | `report` | `ServerError` | Reports the trace id, after the client's retries | | `upgrade` | `ContractError` | Upgrades the client | -A code that maps to `no_data_reason` also carries `gap_kind`, the kind of gap a no_data part with that reason becomes: `choice`, `no_data`, `not_understood` or `unsupported`. `choose` goes with `choice` and only with it. `choose` and `ask_data_question` name a next step inside an answer, so a code that also reaches a problem document takes another action. A client maps a code with no row on its HTTP status: 400 and 422 to `InvalidRequestError`, 401 to `AuthenticationError`, 403 to `PermissionDeniedError`, 404 to `NotFoundError`, 429 to `RateLimitError`, any other 5xx to `ServerError` and any other 4xx to `InvalidRequestError`. The website proxy's own `{error, retry, detail}` body carries its code in `error`. A no_data reason with no row becomes a `no_data` gap. +A code that maps to `no_data_reason` also carries `gap_kind`, the kind of gap a no_data part with that reason becomes: `choice`, `no_data`, `not_understood` or `unsupported`. `choose` goes with `choice` and only with it. `choose` and `ask_data_question` name a next step inside an answer, so a code that also reaches a problem document takes another action. The website proxy's own `{error, retry, detail}` body carries its code in `error`. + +A client maps a refusal whose code has no row, or that carries no code, on its HTTP status: + +| Status | Error class | +| ------------- | ----------------------- | +| 400, 422 | `InvalidRequestError` | +| 401 | `AuthenticationError` | +| 403 | `PermissionDeniedError` | +| 404, 410 | `NotFoundError` | +| 408 | `DfoTimeoutError` | +| 429 | `RateLimitError` | +| any other 4xx | `InvalidRequestError` | +| any other 5xx | `ServerError` | + +A 408 is a timeout the caller retries, and a 410 names a resource that is gone, so the caller stops as it does on a 404. A no_data reason with no row becomes a `no_data` gap. An answer's gaps follow from its parts. A candidates part is a `choice` gap, its options the candidates. A no_data part is a gap of its reason's `gap_kind`, its options the no_data `options`, and of kind `timed_out` instead when the answer's `diagnostics.timed_out` is true. An unsupported part is an `unsupported` gap. A part whose status a client does not know is an `unknown` gap. ## Client codes -`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, and a one-line `condition`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps the server's code: the problem document's `code`, or the website proxy's `error`. A refusal whose body carries neither raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`; no other row does. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. The list holds no warning: a `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and null when they differ in several ways. +`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, and a one-line `condition`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps the server's code: the problem document's `code`, or the website proxy's `error`. A refusal whose body carries neither raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`; no other row does. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. The list holds no warning, since a warning carries the server's code. A `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and a null code when they differ in several ways. A `DataWarning` carries the manifest warning's code. ## Scenarios A scenario is one client-level call, the HTTP exchanges it makes, and the outcome each step reaches. Each record is one file, `scenarios/.json`, validated by `scenario.schema.json`. -| Member | Holds | -| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `format_version` | `1` | -| `name` | The kebab-case name, equal to the file name's stem | -| `description` | One or two sentences on what the scenario proves | -| `origin` | `recorded`, with the `base_url`, the deployed `dfo_commit` and `recorded_at`; or `synthetic`, with the recorded scenario it is `derived_from` and a one-line `edit` | -| `call` | The steps, in order: `search`; `choose`; `fetch` of the previous answer, of a `spec` with `window`, `entities` and `facets`, or of a `ref`; `mint`; `result` | -| `exchanges` | The requests the call makes, in order, each with the response to give | -| `expect` | One outcome per step: an `answer`, a `dataset`, an `operation` or an `error` | +| Member | Holds | +| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `format_version` | `1` | +| `name` | The kebab-case name, equal to the file name's stem | +| `description` | One or two sentences on what the scenario proves | +| `origin` | `recorded`, with the `base_url`, the deployed `dfo_commit` and `recorded_at`; or `synthetic`, with the recorded scenario it is `derived_from` and a one-line `edit` | +| `call` | The steps, in order: `search`; `choose`; `fetch` of the previous answer, of a `spec` with `window`, `entities` and `facets`, or of a `ref`; `mint`; `operation`, which resumes a long build by its `operation_id`; `result` | +| `exchanges` | The requests the call makes, in order, each with the response to give | +| `expect` | One outcome per step: an `answer`, a `dataset`, an `operation` or an `error` | -A step that acts on an earlier result follows one: `choose` follows `search` or `choose`, a `fetch` with no target follows `search`, `choose` or another `fetch` with no target and acts on the last answer, and `result` follows `mint`. A `spec` in a step holds `spec_id`, the server's unmodified `definition`, and the `sentence` when the client knows it. +A step that acts on an earlier result follows one: `choose` follows `search` or `choose`, a `fetch` with no target follows `search`, `choose` or another `fetch` with no target and acts on the last answer, and `result` follows `mint` or `operation`. A `fetch` of an answer or a spec, `mint` and `operation` take a `layout`, `long` by default or `frame`, and a `fetch` of an answer or a spec takes `strict`. A `spec` in a step holds `spec_id`, the server's unmodified `definition`, and the `sentence` when the client knows it. An exchange's request names its target in one of three ways. `path` is a path the client composes under the base URL, such as `/search/resolve`. `origin_path` is a root-relative URL the server returned, such as an artifact's `url`, which resolves against the base URL's origin and never against its path. `url` is an absolute URL outside the API, such as the signed storage URL a files route redirects to, which the client fetches with a bare request carrying no client header and no key. `json` holds the request body members that must match; a recorded scenario lists every member the client sent. The response gives `status`, the `headers` a client reads, and a `json` body or a `body_file`, a binary body in `scenarios/`. A scenario's own body files are named `.` and `-.`; a synthetic scenario may instead name a body file its parent names. -An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a `SearchWarning`'s code or null, or for any other error the client raises itself its code in `client-codes.json`. +An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a warning's code, which for a `SearchWarning` may be null, or for any other error the client raises itself its code in `client-codes.json`. A `VersionUnavailableError` also gives `newest_version`, the version the lookup found, or null. A dataset or error outcome of a step that made a long build gives `long_builds`, one entry per build the server ran on, in order: the `operation_id` the client polled last, the `poll_waits` in seconds before each poll, and the number of `resubmissions`. -Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, and each Search request posts the input the rules give: the question, a choice's input, or a member's identity. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. +Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry, except on a poll, where the long-build rules count retries, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, and each Search request posts the input the rules give: the question, a choice's input, or a member's identity. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. A recorded scenario's request and response bodies validate against their route's schemas in `served/openapi.json`, with one allowance: a required member whose schema admits null may be absent, because the server leaves null members out of the bodies it serves. @@ -128,7 +143,7 @@ A client replays a scenario by serving the exchanges in order: - A request matches the next exchange on its method and target, and on each listed `json` member, compared as parsed JSON values. - A request with no exchange left, or one that matches none, fails the scenario, and so does an exchange the call never makes. - `path` resolves against the base URL the replay gives the client, and `origin_path` against that base URL's origin, so a replay can run under any base URL form. -- Sleeps are not replayed: the replay injects the client's clock and sleep, and each wait the client asks for advances the clock at once. +- Sleeps are not replayed: the replay injects the client's clock and sleep, and each wait the client asks for advances the clock at once. The waits before polls are the outcome's `poll_waits`. - Every absolute URL a record holds, a `url` request or a `location` header, keeps its scheme, host and path, and its query reads `X-Goog-Signature=redacted`, whatever signed it. The records also fix these client rules: @@ -140,10 +155,17 @@ The records also fix these client rules: - A choice raises `InvalidRequestError` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is out of range or matches no label or several. - A choice among candidates in a one-part answer makes no request. A choice of a no_data option in a one-part answer posts the option's `data_query` as the input. - In a several-part answer a choice posts `dataset_resubmit`, without `raw_query`, with one entry per part in part order. The chosen candidate posts an identity entry with its identity and `entity_groups`, and the chosen option its `data_query`'s one part as a parsed entry. A definite part posts an identity entry with its spec's identity and `entity_groups`. A candidates part left alone posts a `candidates` entry: its candidate set in the server's order, each with its identity and `entity_groups`, and its `ordering` and `truncated` echoed. The server cannot recompute that order, because it rests on the first answer's bind election and availability reads, and a parsed entry would cost an LLM bind. Any other part posts its `restatement` as a parsed entry, or a placeholder entry with its no_data `reason` or unsupported `code` when it has none. Every entry but a parsed one carries the part's `variable_text`, `separate` when true and `operations` when the part has any; `entity_groups` is left out when the spec has none. +- A strict fetch raises the manifest's first warning above `info` severity as a `DataWarning` with that warning's code, before the sentence lookup and the download. +- An identity resubmit whose answer is not one definite part of the built `spec_id`, with a sentence, raises `ContractError`. +- The `frame` layout posts `{"format": "parquet", "bundle": false, "layout": "frame"}` as the build's `options` and downloads the artifact whose rendering's `layout` is `frame`; the `long` layout posts `{"format": "parquet", "bundle": false}` and downloads the bare Parquet artifact with any other layout. A fetch of an answer with several members in the `frame` layout raises `InvalidRequestError` before any build. +- A download asks the route that redirects to the signed URL: an artifact's `url`, or the file selector. A refused signed URL, or bytes that do not hash to the artifact's digest, ask the route once more, and a second failure raises `ServerError` with `download_failed` or `digest_mismatch`. - A declined or catalogue answer is not complete, and fetching it raises `DeclinedError`. - Fetching an answer with a gap raises `IncompleteAnswerError` before any request, unless the fetch is partial and some part has a reading. -- A fetch of an answer issues one `SearchWarning` when a definite part has an operation Search did not run, a departure, or a warning at severity `warn` or `degraded`, or the answer's `diagnostics.warnings` holds such a warning. An `info` warning issues nothing. A strict fetch raises the `SearchWarning` before any build. -- A ref whose version the snapshot route refuses with `snapshot_not_found` raises `NotFoundError` with no further request. +- A fetch of an answer issues one `SearchWarning` when a definite part has an operation Search did not run, a departure, or a warning at severity `warn` or `degraded`, or the answer's `diagnostics.warnings` holds such a warning. An `info` warning issues nothing. A strict fetch raises the `SearchWarning` before any build, with the code of its one hint, or a null code when the readings differ from the question in several ways. +- A ref's version is found in this order: the snapshot route and the files route at the stored digest; the file selector, `GET /datasets/{id}/{content_version}/file` with the ref's rendering as the query; and a build of the ref's spec in the ref's rendering, which must answer the same `content_version`. A snapshot refusal other than `artifact_expired` ends the lookup, so `snapshot_not_found` raises `NotFoundError` with no further request. A files route or selector refusal of `artifact_expired`, `artifact_not_found` or `not_found` takes the next step, and a selector file of another digest is not the stored file. A rebuild that answers another version, or that raises `InvalidRequestError`, `NotFoundError` or `VersionUnavailableError`, ends in `VersionUnavailableError` with the first refusal's code, or `version_unavailable` when nothing refused. Its `newest_version` is the version the rebuild answered, or else the first `GET /datasets/{id}/versions` lists, or null when that route lists none or refuses with `NotFoundError` or `PermissionDeniedError`. +- A build answers 200 with the manifest, or 202 with an operation the client polls at `/datasets/operations/{operation_id}`. Before each poll it waits the `Retry-After` of a 429 that refused the last poll, else the last operation resource's `retry_after_ms`, else the `Retry-After` of the response that carried that resource, else a backoff of 1, 2, 4 and then 8 seconds that advances only when it is used. +- A 429 poll spends no retry. Any other retryable refused poll spends one of the two retries, which a poll that answers restores, and a refusal that is not retryable raises. A poll that answers a failed operation whose error is retryable posts the same build once more and polls the operation it starts; a second failure, an error that is not retryable, and a resumed operation, whose build request the client does not hold, raise the operation's error. +- A build cut off by a retryable 504 is posted once more, and a second 504 raises. - A retry waits `Retry-After` when the response carries it. A synthetic scenario that retries assumes the default of two retries. ## Recording @@ -167,7 +189,7 @@ uv run tools/capture_client_contract.py record --offline --only answer-declined uv run tools/capture_client_contract.py record --base-url http://127.0.0.1:8083/api ``` -`mint-async-build` lands only from a server whose document declares the build's 202 response, since the validator checks each recorded body against its route's schema for that status. `--scenarios-dir` writes records outside the package, unvalidated. +A scenario that needs a route or status the served document does not declare waits, since the validator checks each recorded body against its route's schema for that status, and a synthetic scenario waits for its parent as well. `record` names each waiting scenario and what it waits for, and records it once the document declares it. `mint-async-build`, `operation-resume` and the `fetch-spec-async-build`, `fetch-spec-poll-rate-limited` and `fetch-spec-operation-failed-resubmitted` scenarios derived from `mint-async-build` wait for the build's 202, and `fetch-ref-expired-file-selector` waits for the file selector. A server answers a version it has built inline, so a long build records only from a spec the server has not built. `--scenarios-dir` writes records outside the package, unvalidated, waiting scenarios included. ## DatasetRef diff --git a/python/client-contract/src/dfo_client_contract/scenario.schema.json b/python/client-contract/src/dfo_client_contract/scenario.schema.json index 91f63af..3e9d9e5 100644 --- a/python/client-contract/src/dfo_client_contract/scenario.schema.json +++ b/python/client-contract/src/dfo_client_contract/scenario.schema.json @@ -80,6 +80,11 @@ "pattern": "^cv_[0-9a-f]{32}$", "$ref": "#/$defs/one_line" }, + "operation_id": { + "type": "string", + "pattern": "^op_[0-9a-f]{64}$", + "$ref": "#/$defs/one_line" + }, "recorded": { "type": "object", "additionalProperties": false, @@ -224,6 +229,9 @@ { "$ref": "#/$defs/mint_step" }, + { + "$ref": "#/$defs/operation_step" + }, { "$ref": "#/$defs/result_step" } @@ -388,8 +396,28 @@ "facets": true } }, + "operation_step": { + "description": "Resuming, by its id, a long build another process started.", + "type": "object", + "additionalProperties": false, + "required": [ + "op", + "operation_id" + ], + "properties": { + "op": { + "const": "operation" + }, + "operation_id": { + "$ref": "#/$defs/operation_id" + }, + "layout": { + "$ref": "#/$defs/layout" + } + } + }, "result_step": { - "description": "Waiting for the operation the previous mint step started, and taking its dataset.", + "description": "Waiting for the operation the previous mint or operation step holds, and taking its dataset.", "type": "object", "additionalProperties": false, "required": [ @@ -745,6 +773,9 @@ "search_warning": { "description": "For a fetch of an answer only: whether the fetch issued a SearchWarning.", "type": "boolean" + }, + "long_builds": { + "$ref": "#/$defs/long_builds" } } }, @@ -757,9 +788,7 @@ ], "properties": { "operation_id": { - "type": "string", - "pattern": "^op_[0-9a-f]{64}$", - "$ref": "#/$defs/one_line" + "$ref": "#/$defs/operation_id" }, "status": { "enum": [ @@ -793,16 +822,83 @@ "ServerError", "ContractError", "SearchWarning", + "DataWarning", "NetworkError", "DfoTimeoutError" ] }, "code": { - "description": "A refusal's code: the problem document's code, the website proxy's error member, or refusal_without_code for a body with neither. A SearchWarning's code is the server's warning or departure code, or null when the readings differ from the question in several ways. Any other error the client raises itself carries its code from client-codes.json.", + "description": "A refusal's code: the problem document's code, the website proxy's error member, or refusal_without_code for a body with neither. A SearchWarning's code is the server's warning or departure code, or the verb of an operation Search did not run, or null when the readings differ from the question in several ways. A DataWarning's code is the manifest warning's. Any other error the client raises itself carries its code from client-codes.json.", "type": [ "string", "null" ] + }, + "newest_version": { + "description": "For a VersionUnavailableError only: the newest version the lookup found, or null.", + "oneOf": [ + { + "$ref": "#/$defs/content_version" + }, + { + "type": "null" + } + ] + }, + "long_builds": { + "$ref": "#/$defs/long_builds" + } + }, + "if": { + "properties": { + "class": { + "const": "VersionUnavailableError" + } + } + }, + "then": { + "required": [ + "newest_version" + ] + }, + "else": { + "not": { + "required": [ + "newest_version" + ] + } + } + }, + "long_builds": { + "description": "One entry per build the step saw the server run on, in order.", + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "operation_id", + "poll_waits", + "resubmissions" + ], + "properties": { + "operation_id": { + "description": "The operation the client polled last, the one a deadline error names.", + "$ref": "#/$defs/operation_id" + }, + "poll_waits": { + "description": "The seconds the client waited before each poll, in order.", + "type": "array", + "items": { + "type": "number", + "minimum": 0 + } + }, + "resubmissions": { + "description": "How many times the client posted the build again after the operation failed.", + "type": "integer", + "minimum": 0 + } } } } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json new file mode 100644 index 0000000..989bd2f --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json @@ -0,0 +1,9896 @@ +{ + "format_version": 1, + "name": "fetch-frame-several-readings", + "description": "The frame layout holds one reading, so fetching an answer with two members in it raises InvalidRequestError before any build.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-several-readings-folded", + "edit": "The fetch of the answer asks for layout \"frame\", and the exchanges after the search go." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements for health and for education from Germany to Kenya, and GDP of Kenya" + }, + { + "op": "fetch", + "layout": "frame" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements for health and for education from Germany to Kenya, and GDP of Kenya" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements for health and for education from Germany to Kenya, and GDP of Kenya", + "normalized_query": "ODA disbursements for health and for education from Germany to Kenya, and GDP of Kenya", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "trace_id": "1c42f930c021432697eb26d2af4fb5c4", + "warnings": [], + "timing_ms": { + "total": 5, + "by_step": { + "coverage": 0, + "response_cache_layer1": 1 + } + }, + "llm_usage": { + "input_tokens": 0, + "output_tokens": 0, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "health ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 1771, + "by_step": { + "recall": 2, + "shape_arcs": 1, + "shape_probe_coverage": 183, + "shape_probe": 183, + "shape_groups": 102, + "shape_labels": 20, + "shape_admission": 0, + "shape": 599, + "bind": 39, + "materialise": 585, + "answer": 27, + "options": 519 + } + }, + "restatement": { + "variable_text": "health ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "definite", + "spec": { + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "definition": { + "schema_version": 1, + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal", + "label": "gross disbursements (official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 545, + "member_digest": "0c7508fd1997d6cdc896f2eab0f092a4915cfca9e2400eb9577bb22b527fe882", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "CRSPurposeCode110", + "label": "education" + }, + "value_kind": "enum_value" + }, + { + "ref": { + "ref": "CRSPurposeCode120", + "label": "health" + }, + "value_kind": "enum_value" + } + ] + }, + "expansion": { + "added": [ + { + "ref": "CRSPurposeCode121", + "label": "general health" + }, + { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + { + "ref": "CRSPurposeCode123", + "label": "noncommunicable disease" + }, + { + "ref": "CRSPurposeCode12110", + "label": "health policy and administrative management" + }, + { + "ref": "CRSPurposeCode12181", + "label": "medical education and training" + }, + { + "ref": "CRSPurposeCode12182", + "label": "medical research" + }, + { + "ref": "CRSPurposeCode12191", + "label": "medical service" + }, + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + }, + { + "ref": "CRSPurposeCode12230", + "label": "basic health infrastructure" + }, + { + "ref": "CRSPurposeCode12240", + "label": "basic nutrition" + }, + { + "ref": "CRSPurposeCode12250", + "label": "infectious disease control" + }, + { + "ref": "CRSPurposeCode12261", + "label": "health education" + }, + { + "ref": "CRSPurposeCode12262", + "label": "malaria control" + }, + { + "ref": "CRSPurposeCode12263", + "label": "tuberculosis control" + }, + { + "ref": "CRSPurposeCode12264", + "label": "COVID-19 control" + }, + { + "ref": "CRSPurposeCode12281", + "label": "health personnel development" + }, + { + "ref": "CRSPurposeCode12310", + "label": "general noncommunicable disease control" + }, + { + "ref": "CRSPurposeCode12320", + "label": "tobacco use control" + }, + { + "ref": "CRSPurposeCode12330", + "label": "control of harmful use of alcohol and drugs" + }, + { + "ref": "CRSPurposeCode12340", + "label": "mental health and well-being promotion" + }, + { + "ref": "CRSPurposeCode12350", + "label": "other noncommunicable disease prevention and treatment" + }, + { + "ref": "CRSPurposeCode12382", + "label": "research for noncommunicable disease prevention and control" + } + ] + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "financialObligationType" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 108, + "member_count_exact": true, + "served_count": 545, + "data_date_range": { + "start": "1997", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "breadth", + "has_data": true, + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 12 + }, + { + "label": "variables", + "count": 51 + } + ] + }, + "facets": { + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + }, + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", + "account": "provider" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode121", + "label": "general health" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 6, + "served_rows": 82, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 108, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode123", + "label": "noncommunicable disease" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 3, + "served_rows": 4, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode100", + "label": "social infrastructure and services" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "member_count": 13, + "served_rows": 1214, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode111", + "label": "unspecified-level education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 6, + "served_rows": 78, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode112", + "label": "basic education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 6, + "served_rows": 77, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode113", + "label": "upper secondary education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 5, + "served_rows": 69, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode114", + "label": "post-secondary education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 4, + "served_rows": 94, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 501, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 501, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance420", + "label": "debt instrument" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 11, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance421", + "label": "standard loan" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance420", + "member_count": 4620, + "served_rows": 11, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 512, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 104, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1606, + "served_rows": 21, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 83, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 136, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 136, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 111, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 1600, + "served_rows": 84, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 976, + "served_rows": 27, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE", + "label": "scholarship and student cost in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 38, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 819, + "served_rows": 19, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 315, + "served_rows": 19, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Kenya for education and health, 1997 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "education and health", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1997 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "CRSPurposeCode110", + "label": "education" + }, + { + "ref": "CRSPurposeCode120", + "label": "health" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "measure_elected" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [ + { + "text": "health", + "named": [ + { + "ref": "CRSPurposeCode120", + "label": "health" + } + ], + "slot": "crsPurpose", + "disposition": "bound", + "selected": [] + }, + { + "text": "ODA", + "named": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "slot": "crsTypeOfFlow", + "disposition": "bound", + "selected": [] + }, + { + "text": "education", + "named": [ + { + "ref": "CRSPurposeCode110", + "label": "education" + } + ], + "slot": "crsPurpose", + "disposition": "bound", + "selected": [] + } + ], + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_b438dc000255d174bcc13eb675e603f7", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 512, + "served_rows_exact": true + }, + { + "definition": { + "schema_version": 1, + "spec_id": "spec_e348565295de394da8ddaa23ec5fa475", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialObligation", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialObligationType", + "binding": { + "state": "value", + "ref": "Commitment" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "commitments", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialObligation", + "label": "financial obligation" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialObligationType", + "value": { + "ref": "Commitment", + "label": "commitment" + } + } + ], + "served_rows": 519, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "open_axis_facts": [ + { + "property": "crsTypeOfFinance", + "varies": true, + "distinct_count": 2, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "count": 105 + }, + { + "value": { + "ref": "CRSTypeOfFinance421", + "label": "standard loan" + }, + "count": 3 + } + ] + }, + { + "property": "crsCooperationModality", + "varies": true, + "distinct_count": 7, + "undeclared_count": 19, + "values": [ + { + "value": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "count": 27 + }, + { + "value": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "count": 21 + }, + { + "value": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "count": 16 + }, + { + "value": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "count": 15 + }, + { + "value": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "count": 8 + }, + { + "value": { + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "count": 1 + } + ] + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1991, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1985, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1986, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1991, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1992, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1973, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1994, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1986, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1987, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1989, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1987, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1961, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 1985, + "end_year": 1990 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1991, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "KES", + "origin": "EUR" + } + } + } + } + }, + { + "variable_text": "education ODA disbursements", + "warnings": [ + { + "code": "binding_folded", + "severity": "info", + "message": "'education ODA disbursements' resolved to the same shape as an earlier part; folded into that part's spec." + } + ], + "timing_ms": { + "total": 1681, + "by_step": { + "recall": 1, + "shape_arcs": 1, + "shape_probe_coverage": 16, + "shape_probe": 19, + "shape_groups": 119, + "shape_labels": 14, + "shape_admission": 1, + "shape": 237, + "bind": 24, + "materialise": 881, + "answer": 38, + "options": 500 + } + }, + "restatement": { + "variable_text": "education ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "status": "definite", + "spec": { + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "definition": { + "schema_version": 1, + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal", + "label": "gross disbursements (official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 545, + "member_digest": "0c7508fd1997d6cdc896f2eab0f092a4915cfca9e2400eb9577bb22b527fe882", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "CRSPurposeCode110", + "label": "education" + }, + "value_kind": "enum_value" + }, + { + "ref": { + "ref": "CRSPurposeCode120", + "label": "health" + }, + "value_kind": "enum_value" + } + ] + }, + "expansion": { + "added": [ + { + "ref": "CRSPurposeCode121", + "label": "general health" + }, + { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + { + "ref": "CRSPurposeCode123", + "label": "noncommunicable disease" + }, + { + "ref": "CRSPurposeCode12110", + "label": "health policy and administrative management" + }, + { + "ref": "CRSPurposeCode12181", + "label": "medical education and training" + }, + { + "ref": "CRSPurposeCode12182", + "label": "medical research" + }, + { + "ref": "CRSPurposeCode12191", + "label": "medical service" + }, + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + }, + { + "ref": "CRSPurposeCode12230", + "label": "basic health infrastructure" + }, + { + "ref": "CRSPurposeCode12240", + "label": "basic nutrition" + }, + { + "ref": "CRSPurposeCode12250", + "label": "infectious disease control" + }, + { + "ref": "CRSPurposeCode12261", + "label": "health education" + }, + { + "ref": "CRSPurposeCode12262", + "label": "malaria control" + }, + { + "ref": "CRSPurposeCode12263", + "label": "tuberculosis control" + }, + { + "ref": "CRSPurposeCode12264", + "label": "COVID-19 control" + }, + { + "ref": "CRSPurposeCode12281", + "label": "health personnel development" + }, + { + "ref": "CRSPurposeCode12310", + "label": "general noncommunicable disease control" + }, + { + "ref": "CRSPurposeCode12320", + "label": "tobacco use control" + }, + { + "ref": "CRSPurposeCode12330", + "label": "control of harmful use of alcohol and drugs" + }, + { + "ref": "CRSPurposeCode12340", + "label": "mental health and well-being promotion" + }, + { + "ref": "CRSPurposeCode12350", + "label": "other noncommunicable disease prevention and treatment" + }, + { + "ref": "CRSPurposeCode12382", + "label": "research for noncommunicable disease prevention and control" + } + ] + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "financialObligationType" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 108, + "member_count_exact": true, + "served_count": 545, + "data_date_range": { + "start": "1997", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "breadth", + "has_data": true, + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 12 + }, + { + "label": "variables", + "count": 51 + } + ] + }, + "facets": { + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + }, + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", + "account": "provider" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode121", + "label": "general health" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 6, + "served_rows": 82, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 108, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode123", + "label": "noncommunicable disease" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 3, + "served_rows": 4, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode100", + "label": "social infrastructure and services" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "member_count": 13, + "served_rows": 1214, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode111", + "label": "unspecified-level education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 6, + "served_rows": 78, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode112", + "label": "basic education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 6, + "served_rows": 77, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode113", + "label": "upper secondary education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 5, + "served_rows": 69, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode114", + "label": "post-secondary education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 4, + "served_rows": 94, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 501, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 501, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance420", + "label": "debt instrument" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 11, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance421", + "label": "standard loan" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance420", + "member_count": 4620, + "served_rows": 11, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 512, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 104, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1606, + "served_rows": 21, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 83, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 136, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 136, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 111, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 1600, + "served_rows": 84, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 976, + "served_rows": 27, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE", + "label": "scholarship and student cost in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 38, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 819, + "served_rows": 19, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 315, + "served_rows": 19, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Kenya for education and health, 1997 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "education and health", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1997 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "CRSPurposeCode110", + "label": "education" + }, + { + "ref": "CRSPurposeCode120", + "label": "health" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "measure_elected" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [ + { + "text": "health", + "named": [ + { + "ref": "CRSPurposeCode120", + "label": "health" + } + ], + "slot": "crsPurpose", + "disposition": "bound", + "selected": [] + }, + { + "text": "ODA", + "named": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "slot": "crsTypeOfFlow", + "disposition": "bound", + "selected": [] + }, + { + "text": "education", + "named": [ + { + "ref": "CRSPurposeCode110", + "label": "education" + } + ], + "slot": "crsPurpose", + "disposition": "bound", + "selected": [] + } + ], + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_b438dc000255d174bcc13eb675e603f7", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 512, + "served_rows_exact": true + }, + { + "definition": { + "schema_version": 1, + "spec_id": "spec_e348565295de394da8ddaa23ec5fa475", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialObligation", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialObligationType", + "binding": { + "state": "value", + "ref": "Commitment" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "commitments", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialObligation", + "label": "financial obligation" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialObligationType", + "value": { + "ref": "Commitment", + "label": "commitment" + } + } + ], + "served_rows": 519, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "open_axis_facts": [ + { + "property": "crsTypeOfFinance", + "varies": true, + "distinct_count": 2, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "count": 105 + }, + { + "value": { + "ref": "CRSTypeOfFinance421", + "label": "standard loan" + }, + "count": 3 + } + ] + }, + { + "property": "crsCooperationModality", + "varies": true, + "distinct_count": 7, + "undeclared_count": 19, + "values": [ + { + "value": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "count": 27 + }, + { + "value": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "count": 21 + }, + { + "value": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "count": 16 + }, + { + "value": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "count": 15 + }, + { + "value": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "count": 8 + }, + { + "value": { + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "count": 1 + } + ] + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1991, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1985, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1986, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1991, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1992, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1973, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1994, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1986, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1987, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1989, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1987, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1961, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 1985, + "end_year": 1990 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1991, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "KES", + "origin": "EUR" + } + } + } + } + }, + { + "variable_text": "GDP", + "warnings": [ + { + "code": "direction_discarded", + "severity": "warn", + "message": "Germany was named as the provider; this shape reports the place as its own subject, so the direction was dropped." + }, + { + "code": "direction_discarded", + "severity": "warn", + "message": "Kenya was named as the recipient; this shape reports the place as its own subject, so the direction was dropped." + } + ], + "timing_ms": { + "total": 2176, + "by_step": { + "recall": 1, + "shape_arcs": 3, + "shape_probe_coverage": 11, + "shape_probe": 15, + "shape_groups": 116, + "shape_labels": 14, + "shape_admission": 0, + "shape": 194, + "bind": 1952, + "materialise": 5, + "answer": 9, + "options": 15 + } + }, + "restatement": { + "variable_text": "GDP", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [ + { + "code": "direction_discarded", + "binding_ref": "where:", + "asked": "Germany", + "text": "You named Germany as a provider. This measure has no providers, so this shows the place itself." + }, + { + "code": "direction_discarded", + "binding_ref": "where:", + "asked": "Kenya", + "text": "You named Kenya as a recipient. This measure has no recipients, so this shows the place itself." + } + ], + "status": "definite", + "spec": { + "spec_id": "spec_f8dea3052d1ef6ba5667628815d1a663", + "definition": { + "schema_version": 1, + "spec_id": "spec_f8dea3052d1ef6ba5667628815d1a663", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + }, + { + "property": "economicSector", + "binding": { + "state": "unbound" + } + }, + { + "property": "naics", + "binding": { + "state": "unbound" + } + }, + { + "property": "schoolGradeLevel", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "USDollar" + } + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_nominal", + "label": "Nominal gross domestic product", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 65, + "member_digest": "73519eeb75639bdae33042fc844830cd46becc08e4f9122dfcd0886e9875f657", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "economicSector", + "naics", + "schoolGradeLevel" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 41, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 132, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 2 + }, + { + "label": "observations", + "count": 66 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 132, + "rows_exact": true, + "series": 2, + "window": { + "start_year": 1960, + "end_year": 2025 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "bound", + "ref": "USDollar", + "label": "USDollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossValueAdded", + "label": "GrossValueAdded" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NetDomesticProduction", + "label": "Net Domestic Production" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NetValueAdded", + "label": "Net Value Added" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "AgricultureForestryFishingSector", + "label": "Agriculture,Forestry and Fishing Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ConstructionSector", + "label": "Construction Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ElectricityGasSteamAirConditionSupply", + "label": "Electric Gas Steam Air Condition Supply" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinanceService", + "label": "Finance Service" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MOSPI_OtherService", + "label": "MOSPI Other Service" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ManufacturingSector", + "label": "Manufacturing Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MiningQuarrying", + "label": "Mining quarrying" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TradeSector", + "label": "Trade Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AccommodationAndFoodSector", + "label": "Accommodation and food sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AdministrativeAndSupportServices", + "label": "Administrative and support services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AgriculturalSupportActivities", + "label": "Agricultural support activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Agriculture", + "label": "Agriculture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AirTransportAndSupportServices", + "label": "Air transport and support services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AllEconomicActivities", + "label": "All economic activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AnimalProduction", + "label": "Animal production" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ArtsEntertainmentRecreation", + "label": "Arts entertainment recreation" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Education", + "label": "Education" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ElectricitySupply", + "label": "Electricity supply" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EmployerHouseholdActivities", + "label": "Employer household activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialActivities", + "label": "FinancialActivities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialAndInsuranceActivities", + "label": "Financial and insurance activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialIntermediationServicesIndirectlyMeasured", + "label": "Financial intermediation services indirectly measured" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FishingAquaculture", + "label": "Fishing aquaculture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FoodBeveragesTobaccoManufacture", + "label": "Food beverages tobacco manufacture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ForestryLogging", + "label": "Forestry logging" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "HumanHealthAndSocialWork", + "label": "Human health and social work" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "InformationAndCommunication", + "label": "Information and communication" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "InsuranceActivities", + "label": "Insurance activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "LandTransport", + "label": "Land transport" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherManufacturingAndRepair", + "label": "Other manufacturing and repair" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherServiceSector", + "label": "Other service sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherTransportPostalCourierActivities", + "label": "Other transport postal courier activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ProductTaxes", + "label": "Product taxes" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ProfessionalScientificTechnicalActivities", + "label": "Professional scientific technical activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PublicAdministrationAndDefence", + "label": "Public administration and defence" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PublishingBroadcastingInformationActivities", + "label": "Publishing Broadcasting Information Activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "RealEstate", + "label": "Real estate" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Telecommunications", + "label": "Telecommunications" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TransportStorageSector", + "label": "Transport and Storage" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "WaterSupplySewerageWasteManagement", + "label": "Water supply sewerage waste management" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "WholesaleRetailTradeAndRepair", + "label": "Wholesale retail trade and repair" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "BankingAndInsuranceSector", + "label": "Banking And Insurance Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Construction", + "label": "Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialServices", + "label": "Financial Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Industry", + "label": "Industry" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Services", + "label": "Services" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "options": [ + { + "value": { + "ref": { + "ref": "NAICS/23", + "label": "Construction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/44-45", + "label": "Retail trade" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/53", + "label": "Real estate and rental and leasing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/22", + "label": "Utilities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/55", + "label": "Management of companies and enterprises" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/48-49", + "label": "Transportation and warehousing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/61", + "label": "Educational services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/51", + "label": "Information" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/42", + "label": "Wholesale trade" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/21", + "label": "Mining, quarrying, and oil and gas extraction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/11", + "label": "Agriculture, forestry, fishing and hunting" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/72", + "label": "Accommodation and food services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/52", + "label": "Finance and insurance" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/54", + "label": "Professional, Scientific, and Technical Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/71", + "label": "Arts, entertainment, and recreation" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/311-316_322-326", + "label": "Durable Goods Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/31-33", + "label": "Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/321_327-339", + "label": "Durable Goods Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/56", + "label": "Administrative and Support and Waste Management Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/62", + "label": "Health care and social assistance" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/81", + "label": "Other services, except public administration" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/92", + "label": "Public administration" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "options": [ + { + "value": { + "ref": { + "ref": "HigherSecondaryEducation", + "label": "Higher Secondary Education" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PrePrimaryAndPrimaryEducation", + "label": "PrePrimary and Primary" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SecondaryEducation", + "label": "SecondaryEducation" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "USDollar", + "label": "USDollar" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Euro", + "label": "Euro" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NationalCurrency", + "label": "NationalCurrency" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PurchasingPowerStandard", + "label": "PurchasingPowerStandard" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "GDP in Germany and Kenya, 1960 to 2025. Current US dollars · World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Germany and Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAccommodationFoodServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSFinanceInsurance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSMiningQuarryingOilGasExtraction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSProfessionalScientificTechnicalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSWholesaleTrade_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826", + "dc/zz6gwv838v9w" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "equivalent_readings": [ + { + "spec_id": "spec_2a65bb3dc1332b16173c540e3392b139", + "definition": { + "schema_version": 1, + "spec_id": "spec_2a65bb3dc1332b16173c540e3392b139", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicProduction", + "measured_property": "valueAdded", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "currencyConversionBasis", + "binding": { + "state": "unbound" + } + }, + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + }, + { + "property": "productTaxBasis", + "binding": { + "state": "value", + "ref": "IncludingProductTaxes" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "CurrencyUSD" + } + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicproduction_valueadded_measuredvalue_nominal", + "label": "Gross domestic product (GDP)", + "population_type": { + "ref": "EconomicProduction", + "label": "economic production" + }, + "measured_property": { + "ref": "valueAdded", + "label": "value added" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 2, + "member_digest": "ef9c4356618ed98aab762248e68799d78c74ad249a6041dad0e8a345c85ee02f", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "currencyConversionBasis" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 2, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1980", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 92, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 2 + }, + { + "label": "observations", + "count": 46 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 92, + "rows_exact": true, + "series": 2, + "window": { + "start_year": 1980, + "end_year": 2025 + }, + "licence": { + "label": "IMF Copyright and Usage" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/IMFWorldEconomicOutlook", + "label": "IMF World Economic Outlook (WEO)", + "source": { + "ref": "source/InternationalMonetaryFund", + "label": "International Monetary Fund (IMF)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/IMFWorldEconomicOutlook" + }, + "unit": { + "basis": "bound", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "PurchasingPowerParityRate", + "label": "purchasing power parity rate" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "resolved_sources": [ + { + "ref": "provenance/IMFWorldEconomicOutlook", + "label": "IMF World Economic Outlook (WEO)", + "source": { + "ref": "source/InternationalMonetaryFund", + "label": "International Monetary Fund (IMF)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/IMFWorldEconomicOutlook" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_3f35867df5a65761", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAccommodationFoodServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSFinanceInsurance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSMiningQuarryingOilGasExtraction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSProfessionalScientificTechnicalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSWholesaleTrade_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826", + "dc/zz6gwv838v9w" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "measure_label_axes": [], + "measure_axis_values": [], + "related_group": { + "ref": "dc/g/EconomicActivity_ActivitySource-GrossDomesticProduction", + "label": "Economic Activity With Activity Source = Gross Domestic Production" + }, + "related_measures": [ + { + "stat_var": { + "ref": "GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "label": "Gross domestic product growth rate" + }, + "definition": { + "schema_version": 1, + "spec_id": "spec_4535d09baf2bdffef7c19c7796e96687", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "growthRate" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + } + ] + } + } + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Kenya for education and health, 1997 to 2024. Current US dollars · OECD Creditor Reporting System (CRS). GDP in Germany and Kenya, 1960 to 2025. Current US dollars · World Development Indicators. You named Germany as a provider. This measure has no providers, so this shows the place itself. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "education and health", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1997 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ], + "part_index": 2 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "Germany and Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 2 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 2 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 2 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 2 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "text", + "text": "You named Germany as a provider. This measure has no providers, so this shows the place itself.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "text", + "text": "You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 2 + } + ], + "status": "definite" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "definite", + "sentence": "Germany's gross ODA disbursements to Kenya for education and health, 1997 to 2024. Current US dollars · OECD Creditor Reporting System (CRS). GDP in Germany and Kenya, 1960 to 2025. Current US dollars · World Development Indicators. You named Germany as a provider. This measure has no providers, so this shows the place itself. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", + "complete": true, + "specs": [ + "spec_25f482395c5d012ec278118f38dff29c", + "spec_f8dea3052d1ef6ba5667628815d1a663" + ], + "gaps": [] + } + }, + { + "error": { + "class": "InvalidRequestError", + "code": "invalid_argument" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json new file mode 100644 index 0000000..e925717 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json @@ -0,0 +1,907 @@ +{ + "format_version": 1, + "name": "fetch-ref-expired-newer-version", + "description": "A rebuild that answers another content_version cannot return the stored one: the client raises VersionUnavailableError with the snapshot's artifact_expired code and the rebuilt version as the newest, and downloads nothing.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-definite-fetch", + "edit": "As fetch-ref-expired-rebuild-same-version, with the rebuild answering cv_11111111111111111111111111111111." + }, + "call": [ + { + "op": "fetch", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [ + "ODA disbursements for basic health care" + ], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + }, + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "artifact": { + "digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "rendering": { + "format": "parquet", + "bundle": false + } + } + } + ] + } + } + ], + "exchanges": [ + { + "request": { + "method": "GET", + "path": "/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756" + }, + "response": { + "status": 410, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/artifact_expired", + "title": "Gone", + "status": 410, + "detail": "Every listable artifact of this version aged out of the working tier unpinned.", + "code": "artifact_expired", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": false + } + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + }, + "content_version": "cv_11111111111111111111111111111111", + "prepared_at": "2026-10-11T20:09:36Z", + "coverage": { + "rows": 30, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 27 + } + ], + "window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1995 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS)", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-08)", + "update_cadence": "Quarterly", + "last_update": "2026-10-08", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-09-22", + "title": "Exclude donor core contributions", + "changes": [ + { + "kind": "changed", + "note": "Donor core contributions to multilateral organisations (`bi_multi = 2`) are excluded from bilateral flows, since they would otherwise double count." + } + ] + }, + { + "date": "2026-08-20", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Dataset added to the graph." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1995 + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-10T10:52:17Z", + "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", + "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-08" + } + ], + "capability_version": "dset_ac879dbf49857907", + "materialiser_build": "1f6ed6307bea979d38cc35c4e38e0da896c431ad", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 7 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 15 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261011T194155Z-80081f08", + "served_from": "head", + "confirmed_at": "2026-10-20T15:55:32.214385+00:00" + }, + "warnings": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9785, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-19T10:58:01.080848+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + }, + { + "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", + "rendering": { + "statistics": "series" + }, + "bytes": 5981, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-08T08:43:31.704442+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" + } + ], + "series_count": 5, + "output_options": { + "capability_version": "dset_1e6cd9546fac19e9", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 5 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 27 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "stat_var", + "columns": "time_period", + "state": "available", + "width": 28, + "cells": 140 + }, + { + "index": "time_period", + "columns": "stat_var", + "state": "available", + "width": 6, + "cells": 162 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + } + } + } + ], + "expect": [ + { + "error": { + "class": "VersionUnavailableError", + "code": "artifact_expired", + "newest_version": "cv_11111111111111111111111111111111" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json new file mode 100644 index 0000000..0ea58f0 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json @@ -0,0 +1,259 @@ +{ + "format_version": 1, + "name": "fetch-ref-expired-not-reproducible", + "description": "When the stored version has expired and the build is refused, the client reads the versions route for the newest version. Dev refuses the keyless recorder 403 publish_not_permitted there, so the client raises VersionUnavailableError with the snapshot's artifact_expired code and no newest version.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-ref", + "edit": "The snapshot refuses 410 artifact_expired and the rebuild 422 member_not_resolvable; the versions route is recorded live." + }, + "call": [ + { + "op": "fetch", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [ + "ODA disbursements for basic health care" + ], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + } + }, + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "artifact": { + "digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "rendering": { + "format": "parquet", + "bundle": false + } + } + } + ] + } + } + ], + "exchanges": [ + { + "request": { + "method": "GET", + "path": "/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756" + }, + "response": { + "status": 410, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/artifact_expired", + "title": "Gone", + "status": 410, + "detail": "Every listable artifact of this version aged out of the working tier unpinned.", + "code": "artifact_expired", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": false + } + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 422, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/member_not_resolvable", + "title": "Unprocessable Entity", + "status": 422, + "detail": "The spec's variable no longer resolves in the graph.", + "code": "member_not_resolvable", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": false + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/spec_774d6c001a6250aa67ca676ab067895e/versions" + }, + "response": { + "status": 403, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/publish_not_permitted", + "title": "Publish Not Permitted", + "status": 403, + "detail": "no principal header was presented; the publish permission is not granted to this caller", + "code": "publish_not_permitted", + "trace_id": "85846c77110a4f20924573e2f3654b1e", + "capability_version": "dset_1e6cd9546fac19e9", + "retryable": false + } + } + } + ], + "expect": [ + { + "error": { + "class": "VersionUnavailableError", + "code": "artifact_expired", + "newest_version": null + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-same-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-same-version.json new file mode 100644 index 0000000..73ca431 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-same-version.json @@ -0,0 +1,971 @@ +{ + "format_version": 1, + "name": "fetch-ref-expired-rebuild-same-version", + "description": "A ref whose snapshot refuses artifact_expired builds its spec again with the ref's rendering; the build answers the same content_version, so the client downloads it and returns the ref's member, its parts and sentence kept, with no Search call.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-definite-fetch", + "edit": "A ref to the fetched member, whose snapshot route refuses 410 artifact_expired; the parent's build, files and download follow." + }, + "call": [ + { + "op": "fetch", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [ + "ODA disbursements for basic health care" + ], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + }, + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "artifact": { + "digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "rendering": { + "format": "parquet", + "bundle": false + } + } + } + ] + } + } + ], + "exchanges": [ + { + "request": { + "method": "GET", + "path": "/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756" + }, + "response": { + "status": 410, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/artifact_expired", + "title": "Gone", + "status": 410, + "detail": "Every listable artifact of this version aged out of the working tier unpinned.", + "code": "artifact_expired", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": false + } + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + }, + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "prepared_at": "2026-10-11T20:09:36Z", + "coverage": { + "rows": 30, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 27 + } + ], + "window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1995 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS)", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-08)", + "update_cadence": "Quarterly", + "last_update": "2026-10-08", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-09-22", + "title": "Exclude donor core contributions", + "changes": [ + { + "kind": "changed", + "note": "Donor core contributions to multilateral organisations (`bi_multi = 2`) are excluded from bilateral flows, since they would otherwise double count." + } + ] + }, + { + "date": "2026-08-20", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Dataset added to the graph." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1995 + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-10T10:52:17Z", + "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", + "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-08" + } + ], + "capability_version": "dset_ac879dbf49857907", + "materialiser_build": "1f6ed6307bea979d38cc35c4e38e0da896c431ad", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 7 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 15 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261011T194155Z-80081f08", + "served_from": "head", + "confirmed_at": "2026-10-20T15:55:32.214385+00:00" + }, + "warnings": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9785, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-19T10:58:01.080848+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + }, + { + "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", + "rendering": { + "statistics": "series" + }, + "bytes": 5981, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-08T08:43:31.704442+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" + } + ], + "series_count": 5, + "output_options": { + "capability_version": "dset_1e6cd9546fac19e9", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 5 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 27 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "stat_var", + "columns": "time_period", + "state": "available", + "width": 28, + "cells": 140 + }, + { + "index": "time_period", + "columns": "stat_var", + "state": "available", + "width": 6, + "cells": 162 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + }, + "response": { + "status": 302, + "headers": { + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "answer-definite-fetch.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 30, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "crsCooperationModality", + "crsCooperationModality_label", + "crsPurpose", + "crsPurpose_label", + "crsTypeOfFinance", + "crsTypeOfFinance_label", + "crsTypeOfFlow", + "crsTypeOfFlow_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [ + "ODA disbursements for basic health care" + ], + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." + } + ], + "missing": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-twice.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-twice.json new file mode 100644 index 0000000..9b6bb66 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-twice.json @@ -0,0 +1,302 @@ +{ + "format_version": 1, + "name": "fetch-spec-504-twice", + "description": "A synchronous build cut off twice is retried once only: the second 504 raises the timeout code's ServerError.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "A 504 timeout with retryable true answers the build and its one retry." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 504, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/timeout", + "title": "Gateway Timeout", + "status": 504, + "detail": "The build passed its 120 s limit.", + "code": "timeout", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": true + } + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 504, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/timeout", + "title": "Gateway Timeout", + "status": 504, + "detail": "The build passed its 120 s limit.", + "code": "timeout", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": true + } + } + } + ], + "expect": [ + { + "error": { + "class": "ServerError", + "code": "timeout" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.bin b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.bin new file mode 100644 index 0000000..7941e55 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.bin @@ -0,0 +1 @@ +Not the stored file. diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json new file mode 100644 index 0000000..e231dce --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json @@ -0,0 +1,913 @@ +{ + "format_version": 1, + "name": "fetch-spec-digest-mismatch", + "description": "Bytes that do not hash to the artifact's digest ask the files route for a fresh redirect once; a second mismatch raises ServerError digest_mismatch.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "The signed download serves other bytes, and the files route is asked once more for the same." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "prepared_at": "2026-10-20T13:59:17Z", + "coverage": { + "rows": 4, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 4 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T13:18:18Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "served_from": "head", + "confirmed_at": "2026-10-20T15:55:51.543555+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal, which hold none at the observation period the other members serve in the requested years." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9541, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T13:59:18.050980+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + { + "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", + "rendering": { + "statistics": "series" + }, + "bytes": 5741, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T13:59:18.050980+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" + } + ], + "series_count": 1, + "output_options": { + "capability_version": "dset_1e6cd9546fac19e9", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 4 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + "response": { + "status": 302, + "headers": { + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "fetch-spec-digest-mismatch.bin" + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + "response": { + "status": 302, + "headers": { + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "fetch-spec-digest-mismatch.bin" + } + } + ], + "expect": [ + { + "error": { + "class": "ServerError", + "code": "digest_mismatch" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.json new file mode 100644 index 0000000..d988575 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.json @@ -0,0 +1,919 @@ +{ + "format_version": 1, + "name": "fetch-spec-frame-layout", + "description": "Fetching a spec with layout=\"frame\" posts the frame rendering as the build's options and downloads the manifest's frame artifact, matched on format, bundle and its frame layout, with no Search call.", + "origin": { + "kind": "recorded", + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "687d48bf1bbeffce437765ae950a2ba755137b98", + "recorded_at": "2026-10-20T21:01:07Z" + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." + }, + "layout": "frame" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false, + "layout": "frame" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + }, + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "prepared_at": "2026-10-11T20:09:36Z", + "coverage": { + "rows": 30, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 27 + } + ], + "window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1995 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS)", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-08)", + "update_cadence": "Quarterly", + "last_update": "2026-10-08", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-09-22", + "title": "Exclude donor core contributions", + "changes": [ + { + "kind": "changed", + "note": "Donor core contributions to multilateral organisations (`bi_multi = 2`) are excluded from bilateral flows, since they would otherwise double count." + } + ] + }, + { + "date": "2026-08-20", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Dataset added to the graph." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1995 + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-10T10:52:17Z", + "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", + "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-08" + } + ], + "capability_version": "dset_ac879dbf49857907", + "materialiser_build": "1f6ed6307bea979d38cc35c4e38e0da896c431ad", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 7 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 15 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261011T194155Z-80081f08", + "served_from": "head", + "confirmed_at": "2026-10-20T21:01:12.474481+00:00" + }, + "warnings": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:f4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": "frame" + }, + "bytes": 5627, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T20:44:10.228016+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:f4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104" + }, + { + "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", + "rendering": { + "statistics": "series" + }, + "bytes": 5981, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-08T08:43:31.704442+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" + } + ], + "series_count": 5, + "output_options": { + "capability_version": "dset_1e6cd9546fac19e9", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 5 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 27 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "stat_var", + "columns": "time_period", + "state": "available", + "width": 28, + "cells": 140 + }, + { + "index": "time_period", + "columns": "stat_var", + "state": "available", + "width": 6, + "cells": 162 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4" + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:f4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104" + }, + "response": { + "status": 302, + "headers": { + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Af4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Af4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "fetch-spec-frame-layout.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 30, + "columns": [ + "stat_var", + "financingProvider", + "financingRecipient", + "time_period", + "value", + "unit", + "measurementMethod", + "provenance", + "status", + "stat_var_crsCooperationModality", + "stat_var_crsPurpose", + "stat_var_crsTypeOfFinance", + "stat_var_crsTypeOfFlow" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." + } + ], + "missing": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.parquet b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.parquet new file mode 100644 index 0000000000000000000000000000000000000000..d0a17d0562c21183ff33c2daeb4574265fa1bc28 GIT binary patch literal 5627 zcmd^De`p)`6+g+6eRiDGc73YUiRIcRha1PSBwLA z+ug~IynjO3LI^38QrIXZ3>HSqx~v3N#^^@=*hZGotQ6Lj5JngqlrCi1=s#m2?7gon z`(#}bhf?;(4&S@`e!uU%&--=X?~~JfCdjy$_d1wAI}b7)4AnzX-*?{|JxfuPBr4K= zzNA*l=6q5q3uRFeipiq7JU_0hhB2Q|jC@5mcPs_oe zyZ2gLRW(@`OhqjpQYE3NnAKPyh!W|FuBnC`S0ymnvq zuMQ^0rXhSijHe-dTP(|7>wqA%vo!=qlzNov$#MQss$qFuH4JQ2zt_UN2}QY=*!`)) z?*hX^fnazmP3>)`U7-NH1mOn8)NZ&i|3&Mvl zdH;6lkH_B%W8iMLFt4;6gsR1?+;fb8bJXp_{~5(+di4u0@VWla?`Hc-);BO z?5m%-yJ+g)pSbBh?>E23BkK>|b^_Dr@Lji;K6CeXDE7e{K+pW)2EHHr9?+|a&w*Ah z?{kmPf7!vp`&&QT1C;*41$1&{H_$2WMWA<*{Xj46*ah^&5C7pvb)I?qP!d2Bh7YDj z-`(n_4+akp*PykUwI_~m!BjUy#7l#1D9e*K3XB@{P<=MD_R;#yo8JyxKk(yUj{N<@ zZ`hVuyrS!JS*%VUP1u#0W!byMGO#H#ih&}dNE(1L+n63pVx!koT%zDYg9D!g*8>Std<8B!C$?Md%jR)Reez?D+bxyjoqwj7G#~(bY)2} zWj3!$iVU+_C0|s;f%>#2=w?~gje?@VqEMDtT{dJv7YnRXHcZ8=n6hzZ|4Lq%4{P zCLCJr{WRpzalPwVSWw-+zhKH@p{$4?BN&Ean3 SSzdMyd;Z70kRA!-FWQyz@Rmy zHE__2=6jEc>Q~`RE%GGywj2L0W>39bnKT{`dBIRbwjc{dv%rerhfQU6H!*per)=tN z2h&#v>q%?_Fbtd|=n@NADw{S)+Zs8%8^$&mNoJys@xr<7n63q=2|Ut#QRT%n z>>G+CH>~!ot!ALoH3eL;3U4u$k~|Nsl%h)Y`3^vGFA2qpTmx`b%1VP!cS#nEicXre zL$X;|7eymG);FQLMx1U%+bf23YJ1(Cc~LiPdJ`+}(^lTq9?!b&v#zgpjkQ+G%H^@) zg5GkK#S``UeYZHu&vg32RBM-SJ>ZPf6ZKqp%JZu>?raN3|6ezRzTI$W!3l>aTNgZ{ zo?9cnRv$;qIq{9P*a{9cd?f{)9c?G zwaF`mF~I_As36N;LX>>u^nB{%ZZOX&$=73Ro@v_x3e|ZK6-|` z^30RC_PEWDXui_sdAE)G!p~jsqQC#cW}rDRpZC}X#%`k~zI^QP+;niSu-wnLqc6?J zzkNs041B-M7Wm;O0D-^i@LY3npFGFC{v5(@XbWuGgl6Dtt+v1qIaCPhkDQ*%PVVXp z+|B0^^>J;$X8MF?yMDcG%`VUV0Z){pJ!f`OKEJn<&twkI?yofw-V5{~Udw!f=lLUW zd%&7$Vh#Y%QId@_g7lPjQaBs;j&pzjpQTl7ugc%#1Q)J#6BPc(W-q+wC397}v z6#Bl=zrf^DekfKHOUZyR8>vjqMowjCPis=@6hDpnhFAK*J`fyBl2AhOaDb$CW#JK9 zk;an&X$}xmCxO2|u)!Y)T!TL(^kQmaNh-~(#X>{8{zM~QoaAR6FNUu%GdG)Dk>)0f z`PrF@G!`sM^hv}Yna0vX#?}0wk=A$;ebQ`LlW+kplBYz~N; mHX!J_y3E4Qa07oChlckA_5^&l;77)0{-~eAFWEHw+xNfBnX!ie literal 0 HcmV?d00001 diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-member-not-resolvable.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-member-not-resolvable.json new file mode 100644 index 0000000..0b7cd7a --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-member-not-resolvable.json @@ -0,0 +1,200 @@ +{ + "format_version": 1, + "name": "fetch-spec-member-not-resolvable", + "description": "A build refused because the spec no longer resolves raises InvalidRequestError with the server's code, and makes no further request.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "A 422 member_not_resolvable answers the build." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 422, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/member_not_resolvable", + "title": "Unprocessable Entity", + "status": 422, + "detail": "The spec's variable no longer resolves in the graph.", + "code": "member_not_resolvable", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": false + } + } + } + ], + "expect": [ + { + "error": { + "class": "InvalidRequestError", + "code": "member_not_resolvable" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json new file mode 100644 index 0000000..dfc532b --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json @@ -0,0 +1,4574 @@ +{ + "format_version": 1, + "name": "fetch-spec-resubmit-other-spec", + "description": "When Search answers the built identity with a spec_id other than the built one, the client raises ContractError before the download.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-narrowed", + "edit": "Search answers the built identity with the posted spec_id, and the exchanges after it go." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." + }, + "window": [ + 2020, + 2023 + ] + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "scope": { + "window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "prepared_at": "2026-10-20T13:59:17Z", + "coverage": { + "rows": 4, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 4 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T13:18:18Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "served_from": "head", + "confirmed_at": "2026-10-20T15:55:51.543555+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal, which hold none at the observation period the other members serve in the requested years." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9541, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T13:59:18.050980+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + { + "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", + "rendering": { + "statistics": "series" + }, + "bytes": 5741, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T13:59:18.050980+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" + } + ], + "series_count": 1, + "output_options": { + "capability_version": "dset_1e6cd9546fac19e9", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 4 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "dataset_resubmit", + "entries": [ + { + "entry_kind": "identity", + "variable_text": "dataset", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + ] + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "dataset_resubmit", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "trace_id": "3639b6a5b0924dad976fa2ff3a0a681e", + "warnings": [], + "timing_ms": { + "total": 1, + "by_step": { + "coverage": 0 + } + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "dataset", + "warnings": [], + "timing_ms": { + "total": 0, + "by_step": { + "response_cache_part_memo": 0 + } + }, + "operations": [], + "departures": [], + "status": "definite", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal", + "label": "gross disbursements (basic health care, official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 21, + "member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2020, + "end_year": 2023 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 21, + "data_date_range": { + "start": "2020", + "end": "2023" + } + }, + "entities": [ + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 4, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 4 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2020, + "end_year": 2023 + } + }, + "headline": { + "year": 2023, + "year_named": true, + "named_window": { + "start_year": 2020, + "end_year": 2023 + }, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2021, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + } + ] + }, + "download": { + "rows": 4, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2020, + "end_year": 2023 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 4, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 4, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 17, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 4, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 4, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 4, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Nigeria", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/NGA" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "basic health care", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2020 to 2023", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/NGA", + "label": "Nigeria" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2020, + "end_year": 2023 + }, + "capability_version": "cap_3f35867df5a65761" + }, + "confidence": "high", + "available_at_place": true, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_6b031290811d53255f1435e5983a3cc4", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 4, + "served_rows_exact": true + }, + { + "definition": { + "schema_version": 1, + "spec_id": "spec_53a50741df9d8818e3cc4fbd3d081a5f", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialObligation", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialObligationType", + "binding": { + "state": "value", + "ref": "Commitment" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + } + }, + "label": "commitments", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialObligation", + "label": "financial obligation" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialObligationType", + "value": { + "ref": "Commitment", + "label": "commitment" + } + } + ], + "served_rows": 4, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "open_axis_facts": [ + { + "property": "crsCooperationModality", + "varies": true, + "distinct_count": 14, + "undeclared_count": 2, + "values": [ + { + "value": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "count": 5 + }, + { + "value": { + "ref": "CRSCooperationModalityA02", + "label": "sector budget support" + }, + "count": 2 + }, + { + "value": { + "ref": "CRSCooperationModalityB04", + "label": "basket fund and pooled funding" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB031", + "label": "contribution to multi-donor and multi-entity funding mechanism" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB032", + "label": "contribution to multi-donor and single-entity funding mechanism" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB033", + "label": "contribution to single-donor funding mechanism or earmarked contribution to a specific funding window or geographical location" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityA01", + "label": "general budget support" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityG01", + "label": "other administrative cost" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "count": 1 + } + ] + }, + { + "property": "crsTypeOfFinance", + "varies": true, + "distinct_count": 5, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "count": 14 + }, + { + "value": { + "ref": "CRSTypeOfFinance421", + "label": "standard loan" + }, + "count": 4 + }, + { + "value": { + "ref": "CRSTypeOfFinance510", + "label": "common equity" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSTypeOfFinance210", + "label": "interest subsidy" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSTypeOfFinance520", + "label": "share in collective investment vehicle" + }, + "count": 1 + } + ] + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 2020, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2023, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1992, + "base_year_max": 2019, + "current_years": null + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 2023, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2020, + "end_year": 2020 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2010, + "current_years": null + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2020, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "NGN", + "origin": "EUR" + } + } + } + } + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Nigeria", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/NGA" + ], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "basic health care", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2020 to 2023", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "status": "definite" + } + } + } + ], + "expect": [ + { + "error": { + "class": "ContractError", + "code": "contract_violation" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json new file mode 100644 index 0000000..0b09583 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json @@ -0,0 +1,862 @@ +{ + "format_version": 1, + "name": "fetch-spec-strict-warning", + "description": "A strict fetch raises the manifest's first warning above info severity, coverage_below_scope at warn here, as DataWarning before the download.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "The fetch is strict, and the exchanges after the build go." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + }, + "strict": true + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "prepared_at": "2026-10-20T13:59:17Z", + "coverage": { + "rows": 4, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 4 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T13:18:18Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "served_from": "head", + "confirmed_at": "2026-10-20T15:55:51.543555+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal, which hold none at the observation period the other members serve in the requested years." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9541, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T13:59:18.050980+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + { + "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", + "rendering": { + "statistics": "series" + }, + "bytes": 5741, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-20T13:59:18.050980+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" + } + ], + "series_count": 1, + "output_options": { + "capability_version": "dset_1e6cd9546fac19e9", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 4 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + } + } + } + ], + "expect": [ + { + "error": { + "class": "DataWarning", + "code": "coverage_below_scope" + } + } + ] +} diff --git a/tools/capture_client_contract.py b/tools/capture_client_contract.py index 289821d..08a811c 100644 --- a/tools/capture_client_contract.py +++ b/tools/capture_client_contract.py @@ -33,13 +33,16 @@ refreshes both, and a synthetic record names its parent's body files rather than copies. Every absolute URL a record keeps, a signed download or a `location` header, keeps its path, and its query becomes -`X-Goog-Signature=redacted`. The run ends by validating the whole contract -with `tools/validate_client_contract.py`, and fails when it reports a -problem or the binary bodies pass 5 MB. - -The outcome rules, error classes and gap kinds come from -`tools/validate_client_contract.py`, so a record's `expect` is written by -the code that checks it. pyarrow loads only when a Parquet body is read, so +`X-Goog-Signature=redacted`. A scenario that needs a route or status +`served/openapi.json` does not declare, or whose parent does, waits: the +run names it and writes nothing for it, unless `--scenarios-dir` writes +outside the package. The run ends by validating the whole contract with +`tools/validate_client_contract.py`, and fails when it reports a problem or +the binary bodies pass 5 MB. + +The outcome rules, error classes, gap kinds and long-build pacing come +from `tools/validate_client_contract.py`, so a record's `expect` is written +by the code that checks it. pyarrow loads only when a Parquet body is read, so the tests run without it. """ @@ -47,7 +50,6 @@ import argparse import copy -import hashlib import io import json import os @@ -66,9 +68,15 @@ from urllib.parse import urlsplit, urlunsplit from validate_client_contract import ( + FILE_EXPIRED, + FILE_GONE, + NO_VERSIONS, + REBUILD_REFUSED, UNNAMED_VARIABLE_TEXT, + VERSION_UNAVAILABLE, Answer, ClientError, + LongBuild, answer_from_body, answer_gaps, answer_members, @@ -76,13 +84,19 @@ candidate_answer, choice_for, choice_input, + data_warning, dataset_summary, + digest_of, gap_kinds, owns_body_file, part_label, + pick_artifact, refusal_error, + rendering_for, + resubmitted_sentence, search_warning_code, search_warns, + selector_path, ) from validate_client_contract import main as validate_main @@ -442,6 +456,7 @@ class Member: digest: str rows: int columns: list[str] + rendering: dict[str, Any] = field(default_factory=lambda: dict(RENDERING)) @property def spec_id(self) -> str: @@ -453,7 +468,7 @@ def ref(self) -> dict[str, Any]: "sentence": self.sentence, "spec": {"spec_id": self.spec_id, "definition": self.definition}, "content_version": self.content_version, - "artifact": {"digest": self.digest, "rendering": dict(RENDERING)}, + "artifact": {"digest": self.digest, "rendering": dict(self.rendering)}, } @@ -512,6 +527,30 @@ def require(condition: bool, message: str) -> None: raise ShapeError(message) +@dataclass(frozen=True, slots=True) +class Minted: + """The operation a mint started or a resume read: its resource, the + headers that came with it, the build request a failed operation posts + again (None for a resumed one), the spec the client holds, and the + rendering it downloads.""" + + resource: dict[str, Any] + headers: dict[str, str] + request: dict[str, Any] | None + spec: Spec | None + rendering: dict[str, Any] + + +def _step_options( + step: dict[str, Any], *, layout: str | None, strict: bool +) -> dict[str, Any]: + if layout is not None: + step["layout"] = layout + if strict: + step["strict"] = True + return step + + @dataclass class Session: """A client over a recorder: each step appends to `call` and `expect`.""" @@ -523,7 +562,8 @@ class Session: sleep: Callable[[float], None] = time.sleep call: list[dict[str, Any]] = field(default_factory=list) expect: list[dict[str, Any]] = field(default_factory=list) - minted: tuple[Spec, dict[str, Any]] | None = None + minted: Minted | None = None + long_builds: list[dict[str, Any]] = field(default_factory=list) @property def gap_kinds(self) -> dict[str, str]: @@ -531,10 +571,14 @@ def gap_kinds(self) -> dict[str, str]: def _step(self, step: dict[str, Any], run: Callable[[], dict[str, Any]]) -> None: self.call.append(step) + self.long_builds = [] try: outcome = run() except ClientError as error: outcome = error.outcome(self.client_codes) + if self.long_builds: + (value,) = outcome.values() + value["long_builds"] = self.long_builds self.expect.append(outcome) def _answered(self, answer: Answer) -> dict[str, Any]: @@ -544,8 +588,7 @@ def _resolve(self, input_: dict[str, Any]) -> Answer: response = self.recorder.api( "POST", "/search/resolve", {"schema_version": 1, "input": input_} ) - self._raise_problem(response) - return answer_from_body(response.json()) + return answer_from_body(self._acted(response)) def search(self, question: str) -> Answer: answers: list[Answer] = [] @@ -584,17 +627,20 @@ def run() -> dict[str, Any]: return answers[0] if answers else None def fetch_answer( - self, answer: Answer, *, partial: bool = False, strict: bool = False + self, + answer: Answer, + *, + partial: bool = False, + strict: bool = False, + layout: str | None = None, ) -> None: """Builds the answer's readings. A declined or catalogue answer, a gap - outside a partial fetch, a partial fetch with no reading, and a strict - fetch whose readings depart from the question each raise before any - request.""" + outside a partial fetch, a partial fetch with no reading, a strict + fetch whose readings depart from the question, and the frame layout + with several readings each raise before any request.""" step: dict[str, Any] = {"op": "fetch"} if partial: step["partial"] = True - if strict: - step["strict"] = True def run() -> dict[str, Any]: if answer.body["kind"] != "resolution": @@ -606,10 +652,16 @@ def run() -> dict[str, Any]: warns = search_warns(answer) if warns and strict: raise ClientError(search_warning_code(answer), error="SearchWarning") - members = [self.build(parts, spec, None) for parts, spec in readings] + rendering = rendering_for(layout) + if "layout" in rendering and len(readings) > 1: + raise ClientError("invalid_argument") + members = [ + self.build(parts, spec, None, rendering, strict=strict) + for parts, spec in readings + ] return dataset_outcome(members, missing=gaps, search_warning=warns) - self._step(step, run) + self._step(_step_options(step, layout=layout, strict=strict), run) def fetch_spec( self, @@ -617,6 +669,8 @@ def fetch_spec( *, window: str | tuple[int, int] | None = None, facets: Mapping[str, str] | None = None, + layout: str | None = None, + strict: bool = False, ) -> list[Member]: step: dict[str, Any] = {"op": "fetch", "spec": spec.step()} scope: dict[str, Any] = {} @@ -629,111 +683,124 @@ def fetch_spec( built: list[Member] = [] def run() -> dict[str, Any]: - built.append(self.build([], spec, scope or None)) + rendering = rendering_for(layout) + built.append(self.build([], spec, scope or None, rendering, strict=strict)) return dataset_outcome(built) - self._step(step, run) + self._step(_step_options(step, layout=layout, strict=strict), run) return built def fetch_ref(self, ref: dict[str, Any]) -> None: - """The exact versions a ref names, through the snapshot and files routes.""" + """The exact versions a ref names, through the lookup order.""" def run() -> dict[str, Any]: - members = [] - for member in ref["members"]: - spec_id = member["spec"]["spec_id"] - cv = member["content_version"] - response = self.recorder.api("GET", f"/datasets/{spec_id}/{cv}") - self._raise_problem(response) - digest = member["artifact"]["digest"] - artifact = next( - a - for a in response.json()["artifacts"] - if a["artifact_digest"] == digest - ) - rows, columns = self.read_shape(self._download(artifact)) - members.append( - Member( - member["parts"], - member["spec"]["definition"], - cv, - member["sentence"], - digest, - rows, - columns, - ) - ) - return dataset_outcome(members) + return dataset_outcome([self._stored(member) for member in ref["members"]]) self._step({"op": "fetch", "ref": ref}, run) - def mint(self, spec: Spec) -> str: - operation: list[dict[str, Any]] = [] + def mint(self, spec: Spec, *, layout: str | None = None) -> str: + operation: list[str] = [] def run() -> dict[str, Any]: - response = self.recorder.api("POST", "/datasets", _build_body(spec, None)) - self._raise_problem(response) + rendering = rendering_for(layout) + body = _build_body(spec, None, rendering) + response = self.recorder.api("POST", "/datasets", body) + resource = self._acted(response) require( response.status == 202, f"the build answered {response.status}, not 202" ) - operation.append(response.json()["operation"]) - return { - "operation": { - "operation_id": operation[0]["operation_id"], - "status": operation[0]["status"], - } - } + self.minted = Minted(resource, response.headers, body, spec, rendering) + operation.append(resource["operation"]["operation_id"]) + return _operation_outcome(resource) + + self._step( + _step_options( + {"op": "mint", "spec": spec.step()}, layout=layout, strict=False + ), + run, + ) + return _reached(operation, "the mint") + + def resume(self, operation_id: str, *, layout: str | None = None) -> None: + """Reads a build another process started, by its operation id.""" + + def run() -> dict[str, Any]: + path = POLL_PATH.format(operation_id=operation_id) + response = self.recorder.api("GET", path) + resource = self._acted(response) + self.minted = Minted( + resource, response.headers, None, None, rendering_for(layout) + ) + return _operation_outcome(resource) - self._step({"op": "mint", "spec": spec.step()}, run) - self.minted = (spec, _reached(operation, "the mint")) - return self.minted[1]["operation_id"] + step = {"op": "operation", "operation_id": operation_id} + self._step(_step_options(step, layout=layout, strict=False), run) def result(self) -> None: - """Waits for the operation the last mint started.""" + """Waits for the operation the last mint or operation step holds.""" if self.minted is None: - raise ValueError("result follows mint") - spec, operation = self.minted + raise ValueError("result follows mint or operation") + minted = self.minted def run() -> dict[str, Any]: - manifest = self._wait(operation) - return dataset_outcome([self._member([], spec, manifest)]) + manifest = self._wait(minted.resource, minted.headers, minted.request) + member = self._member([], minted.spec, manifest, minted.rendering, False) + return dataset_outcome([member]) self._step({"op": "result"}, run) # -- building -- def build( - self, parts: list[str], spec: Spec, scope: dict[str, Any] | None + self, + parts: list[str], + spec: Spec, + scope: dict[str, Any] | None, + rendering: dict[str, Any], + *, + strict: bool = False, ) -> Member: """Builds one member: the build, the sentence when the client lacks it, then the file.""" - response = self.recorder.api("POST", "/datasets", _build_body(spec, scope)) - self._raise_problem(response) - body = response.json() - manifest = self._wait(body["operation"]) if response.status == 202 else body - return self._member(parts, spec, manifest) - - def _member(self, parts: list[str], spec: Spec, manifest: dict[str, Any]) -> Member: + manifest = self._built(_build_body(spec, scope, rendering)) + return self._member(parts, spec, manifest, rendering, strict) + + def _built(self, body: dict[str, Any]) -> dict[str, Any]: + """The manifest a build answers, through a long build on a 202.""" + response = self.recorder.api("POST", "/datasets", body) + reply = self._acted(response) + if response.status != 202: + return reply + return self._wait(reply, response.headers, body) + + def _member( + self, + parts: list[str], + spec: Spec | None, + manifest: dict[str, Any], + rendering: dict[str, Any], + strict: bool, + ) -> Member: + if strict and (warning := data_warning(manifest)) is not None: + raise warning + artifact = pick_artifact(manifest, rendering) + if artifact is None: + raise ClientError("contract_violation") definition = manifest["definition"] - sentence = spec.sentence - if definition["spec_id"] != spec.spec_id or sentence is None: + sentence = None if spec is None else spec.sentence + if spec is None or definition["spec_id"] != spec.spec_id or sentence is None: sentence = self._identity_sentence(parts, definition) - artifact = next( - a - for a in manifest["artifacts"] - if a["rendering"].get("format") == "parquet" - and a["rendering"].get("bundle") is False - and a["rendering"].get("layout") != "frame" - ) - rows, columns = self.read_shape(self._download(artifact)) + digest = artifact["artifact_digest"] + rows, columns = self.read_shape(self._download(artifact["url"], digest)) return Member( parts, definition, manifest["content_version"], sentence, - artifact["artifact_digest"], + digest, rows, columns, + dict(rendering), ) def _identity_sentence(self, parts: list[str], definition: dict[str, Any]) -> str: @@ -743,49 +810,166 @@ def _identity_sentence(self, parts: list[str], definition: dict[str, Any]) -> st "identity": definition["identity"], } answer = self._resolve({"kind": "dataset_resubmit", "entries": [entry]}) - (part,) = answer.parts - require(part["status"] == "definite", "the identity resubmit is definite") - require( - part["spec"]["spec_id"] == definition["spec_id"], - "the resubmit keeps the id", + return resubmitted_sentence(answer, definition["spec_id"]) + + def _download(self, target: str, digest: str, *, origin: bool = True) -> bytes: + """A file through the route that redirects to it: an artifact's + root-relative url, or a path under the base URL. A refused signed URL + or bytes of another digest ask the route once more.""" + failure = ClientError("download_failed") + for _ in range(2): + files = ( + self.recorder.origin("GET", target) + if origin + else self.recorder.api("GET", target) + ) + self._raise_problem(files) + require(files.status == 302, f"the files route answered {files.status}") + data = self.recorder.external(files.headers["location"]) + if data.status >= 400: + failure = ClientError("download_failed") + continue + if digest_of(data.body) == digest: + return data.body + failure = ClientError("digest_mismatch") + raise failure + + def _wait( + self, + resource: dict[str, Any], + headers: Mapping[str, str], + request: dict[str, Any] | None, + ) -> dict[str, Any]: + """Polls as `LongBuild` rules, sleeping each wait, for at most 30 + minutes.""" + build = LongBuild(resource, headers, request, self.actions) + self.long_builds.append(build.entry) + deadline = time.monotonic() + 1800 + while build.result is None: + if time.monotonic() >= deadline: + raise SystemExit(f"{build.entry['operation_id']} ran past 30 minutes") + self.sleep(build.next_wait()) + path = POLL_PATH.format(operation_id=build.entry["operation_id"]) + response = self.recorder.api("GET", path) + if build.polled(response.status, response.headers, _json(response)): + again = self.recorder.api("POST", "/datasets", request) + build.reposted(again.status, again.headers, _json(again)) + return build.result + + # -- stored versions -- + + def _stored(self, member: dict[str, Any]) -> Member: + """One version a ref names, through the lookup order + `validate_client_contract._Replay.stored_version` states.""" + spec = member["spec"] + spec_id, version = spec["spec_id"], member["content_version"] + rendering = member["artifact"]["rendering"] + held = Spec(spec_id, spec["definition"], member["sentence"]) + refusal: ClientError | None = None + manifest = None + try: + manifest = self._acted( + self.recorder.api("GET", f"/datasets/{spec_id}/{version}") + ) + except ClientError as error: + if error.code != FILE_EXPIRED: + raise + refusal = error + if manifest is not None: + built = (manifest["definition"]["spec_id"], manifest["content_version"]) + if built != (spec_id, version): + raise ClientError("contract_violation") + data, refusal = self._stored_file(member, manifest) + if data is not None: + rows, columns = self.read_shape(data) + return Member( + member["parts"], + spec["definition"], + version, + member["sentence"], + member["artifact"]["digest"], + rows, + columns, + dict(rendering), + ) + try: + manifest = self._built(_build_body(held, None, rendering)) + except ClientError as error: + if error.error_class(self.client_codes) not in REBUILD_REFUSED: + raise + refusal = refusal if refusal is not None else error + newest = self._newest(spec_id) + else: + if manifest["content_version"] == version: + return self._member(member["parts"], held, manifest, rendering, False) + newest = manifest["content_version"] + raise ClientError( + refusal.code if refusal is not None else "version_unavailable", + error=VERSION_UNAVAILABLE, + newest_version=newest, ) - return part["spec"]["resolved"]["rendered_sentence"] - - def _download(self, artifact: dict[str, Any]) -> bytes: - files = self.recorder.origin("GET", artifact["url"]) - self._raise_problem(files) - require(files.status == 302, f"the files route answered {files.status}") - data = self.recorder.external(files.headers["location"]) - require(data.status == 200, f"the signed download answered {data.status}") - digest = "sha256:" + hashlib.sha256(data.body).hexdigest() - require( - digest == artifact["artifact_digest"], "the download matches its digest" + + def _stored_file( + self, member: dict[str, Any], manifest: dict[str, Any] + ) -> tuple[bytes | None, ClientError | None]: + digest = member["artifact"]["digest"] + refusal = None + artifact = next( + (a for a in manifest["artifacts"] if a["artifact_digest"] == digest), None + ) + if artifact is not None: + try: + return self._download(artifact["url"], digest), None + except ClientError as error: + if error.code not in FILE_GONE: + raise + refusal = error + path = selector_path( + member["spec"]["spec_id"], + member["content_version"], + member["artifact"]["rendering"], ) - return data.body + try: + return self._download(path, digest, origin=False), None + except ClientError as error: + if error.code == "digest_mismatch": + return None, refusal + if error.code in FILE_GONE: + return None, refusal if refusal is not None else error + raise - def _wait(self, operation: dict[str, Any]) -> dict[str, Any]: - """Polls at the server's pacing, else backs off from 1 to 8 seconds.""" - backoff = 1.0 - deadline = time.monotonic() + 1800 - while time.monotonic() < deadline: - if "retry_after_ms" in operation: - self.sleep(operation["retry_after_ms"] / 1000) - else: - self.sleep(backoff) - backoff = min(backoff * 2, 8.0) - path = POLL_PATH.format(operation_id=operation["operation_id"]) - response = self.recorder.api("GET", path) - self._raise_problem(response) - resource = response.json() - operation = resource["operation"] - if operation["status"] == "done": - return resource["manifest"] - raise SystemExit(f"{operation['operation_id']} did not finish in 30 minutes") + def _newest(self, spec_id: str) -> str | None: + try: + body = self._acted( + self.recorder.api("GET", f"/datasets/{spec_id}/versions") + ) + except ClientError as error: + if error.error_class(self.client_codes) in NO_VERSIONS: + return None + raise + versions = body.get("versions") if isinstance(body, dict) else None + first = versions[0] if isinstance(versions, list) and versions else None + newest = first.get("content_version") if isinstance(first, dict) else None + return newest if isinstance(newest, str) else None + + def _acted(self, response: Response) -> Any: + self._raise_problem(response) + return response.json() def _raise_problem(self, response: Response) -> None: if response.status < 400: return - raise refusal_error(response.status, response.json(), self.actions) + raise refusal_error(response.status, _json(response), self.actions) + + +def _json(response: Response) -> Any: + """A response's JSON body, or None for an empty one.""" + return response.json() if response.body else None + + +def _operation_outcome(resource: dict[str, Any]) -> dict[str, Any]: + operation = resource["operation"] + return {"operation": {k: operation[k] for k in ("operation_id", "status")}} def _window(window: str | tuple[int, int]) -> dict[str, Any]: @@ -794,7 +978,9 @@ def _window(window: str | tuple[int, int]) -> dict[str, Any]: return {"kind": window} -def _build_body(spec: Spec, scope: dict[str, Any] | None) -> dict[str, Any]: +def _build_body( + spec: Spec, scope: dict[str, Any] | None, rendering: Mapping[str, Any] +) -> dict[str, Any]: input_: dict[str, Any] = { "kind": "spec_id", "spec_id": spec.spec_id, @@ -802,7 +988,7 @@ def _build_body(spec: Spec, scope: dict[str, Any] | None) -> dict[str, Any]: } if scope: input_["scope"] = scope - return {"schema_version": 1, "input": input_, "options": dict(RENDERING)} + return {"schema_version": 1, "input": input_, "options": dict(rendering)} def with_place_options(body: Any) -> Any: @@ -907,16 +1093,56 @@ def definite_ref(self) -> dict[str, Any]: answer = self.definite_answer(DEFINITE) session = self.session("prerequisite") ((parts, spec),) = _members(answer) - member = session.build(parts, spec, None) + member = session.build(parts, spec, None, dict(RENDERING)) self._cache["ref"] = {"format_version": 1, "members": [member.ref()]} return self._cache["ref"] + def async_spec(self) -> Spec: + """The spec whose estimate is just above the sync budget.""" + (part,) = self.definite_answer(ASYNC).parts + rows = part["spec"]["resolved"].get("download", {}).get("rows") or 0 + require( + SYNC_ROWS < rows < 2 * SYNC_ROWS, + f"{rows} rows is just above the sync budget", + ) + return _part_spec(part["spec"]) + + def running_operation(self) -> str: + """The id of a long build another process started.""" + if "operation" not in self._cache: + self._cache["operation"] = self.session("prerequisite").mint( + self.async_spec() + ) + return self._cache["operation"] + + +# A route and status the served document must declare before a scenario that +# needs them is recorded: the method, the route template as the served +# document names it, and the status. +type Need = tuple[str, str, str] +ASYNC_BUILD: Need = ("POST", "/api/datasets", "202") +FILE_SELECTOR: Need = ("GET", "/api/datasets/{id}/{content_version}/file", "302") + + +def unmet(needs: Sequence[Need], openapi: Mapping[str, Any]) -> list[Need]: + """The needs the served document does not declare.""" + return [ + (method, path, status) + for method, path, status in needs + if status + not in openapi["paths"] + .get(path, {}) + .get(method.lower(), {}) + .get("responses", {}) + ] + @dataclass(frozen=True) class Recorded: name: str description: str run: Callable[[Session, Context], None] + needs: tuple[Need, ...] = () def _answer_definite_fetch(s: Session, ctx: Context) -> None: @@ -1001,15 +1227,20 @@ def _fetch_ref_unknown_version(s: Session, ctx: Context) -> None: def _mint_async(s: Session, ctx: Context) -> None: - (part,) = ctx.definite_answer(ASYNC).parts - rows = part["spec"]["resolved"].get("download", {}).get("rows") or 0 - require( - SYNC_ROWS < rows < 2 * SYNC_ROWS, f"{rows} rows is just above the sync budget" - ) - s.mint(_part_spec(part["spec"])) + s.mint(ctx.async_spec()) + s.result() + + +def _operation_resume(s: Session, ctx: Context) -> None: + s.resume(ctx.running_operation()) s.result() +def _fetch_spec_frame(s: Session, ctx: Context) -> None: + (member,) = s.fetch_spec(ctx.definite_spec(DEFINITE), layout="frame") + require(member.rendering.get("layout") == "frame", "the frame artifact is fetched") + + def _answer_kind(question: str, kind: str) -> Callable[[Session, Context], None]: def run(s: Session, ctx: Context) -> None: answer = s.search(question) @@ -1168,6 +1399,24 @@ def _resubmit_placeholder(s: Session, ctx: Context) -> None: "backing off from 1 to 8 seconds otherwise, until done; the done manifest's file is " "then downloaded.", _mint_async, + needs=(ASYNC_BUILD,), + ), + Recorded( + "operation-resume", + "Resuming a long build another process started reads its operation by id, and the " + "operation is pending or running. Waiting polls it at the server's pacing until done; " + "the client holds no spec, so it takes the sentence from Search by posting the built " + 'identity with variable_text "dataset", then downloads the file. A resumed build holds ' + "no request, so a failed operation is not posted again.", + _operation_resume, + needs=(ASYNC_BUILD,), + ), + Recorded( + "fetch-spec-frame-layout", + 'Fetching a spec with layout="frame" posts the frame rendering as the build\'s options ' + "and downloads the manifest's frame artifact, matched on format, bundle and its frame " + "layout, with no Search call.", + _fetch_spec_frame, ), Recorded( "answer-declined", @@ -1281,12 +1530,14 @@ class Derived: call: list[dict[str, Any]] exchanges: list[dict[str, Any]] expect: list[dict[str, Any]] + bodies: dict[str, bytes] = field(default_factory=dict) @dataclass(frozen=True) class Synthetic: """A scenario derived from a recorded one. A `live` derivation records - some of its exchanges against the base URL.""" + some of its exchanges against the base URL. A synthetic scenario waits + for its own needs and its parent's.""" name: str derived_from: str @@ -1294,6 +1545,7 @@ class Synthetic: description: str derive: Callable[[dict[str, Any], Context], Derived] live: bool = False + needs: tuple[Need, ...] = () def _same(parent: dict[str, Any], exchanges: list[dict[str, Any]]) -> Derived: @@ -1342,20 +1594,314 @@ def _build_index(parent: dict[str, Any]) -> int: ) +_TIMEOUT = _problem( + "timeout", + 504, + "Gateway Timeout", + "The build passed its 120 s limit.", + retryable=True, +) +_EXPIRED = _problem( + "artifact_expired", + 410, + "Gone", + "Every listable artifact of this version aged out of the working tier unpinned.", + retryable=False, +) +_NOT_RESOLVABLE = _problem( + "member_not_resolvable", + 422, + "Unprocessable Entity", + "The spec's variable no longer resolves in the graph.", + retryable=False, +) +_OPERATION_FAILED = _problem( + "operation_failed", + 500, + "Internal Server Error", + "The build's worker stopped before it finished.", + retryable=True, +) +# The content version a rebuild answers when the data moved on. +NEWER_VERSION = "cv_" + "1" * 32 + + def _retry_after_504(parent: dict[str, Any], ctx: Context) -> Derived: exchanges = copy.deepcopy(parent["exchanges"]) index = _build_index(parent) - problem = _problem( - "timeout", - 504, - "Gateway Timeout", - "The build passed its 120 s limit.", - retryable=True, + exchanges.insert(index, _refusal(exchanges[index]["request"], 504, _TIMEOUT)) + return _same(parent, exchanges) + + +def _ends_at_build( + response: Callable[ + [dict[str, Any], Context], tuple[dict[str, Any], dict[str, Any]] + ], +) -> Callable[[dict[str, Any], Context], Derived]: + """The parent's exchanges up to its first build, which `response` turns + into the exchanges the build makes and the outcome the last step reaches.""" + + def derive(parent: dict[str, Any], ctx: Context) -> Derived: + index = _build_index(parent) + exchanges = copy.deepcopy(parent["exchanges"][:index]) + made, outcome = response(copy.deepcopy(parent["exchanges"][index]), ctx) + return Derived( + copy.deepcopy(parent["call"]), + [*exchanges, *made], + [*copy.deepcopy(parent["expect"][:-1]), outcome], + ) + + return derive + + +def _cut_off_twice( + build: dict[str, Any], ctx: Context +) -> tuple[list[dict[str, Any]], dict[str, Any]]: + refused = _refusal(build["request"], 504, _TIMEOUT) + error = refusal_error(504, _TIMEOUT, ctx.actions).outcome(ctx.client_codes) + return [refused, copy.deepcopy(refused)], error + + +def _not_resolvable( + build: dict[str, Any], ctx: Context +) -> tuple[list[dict[str, Any]], dict[str, Any]]: + error = refusal_error(422, _NOT_RESOLVABLE, ctx.actions).outcome(ctx.client_codes) + return [_refusal(build["request"], 422, _NOT_RESOLVABLE)], error + + +def _strict_warning(parent: dict[str, Any], ctx: Context) -> Derived: + index = _build_index(parent) + manifest = parent["exchanges"][index]["response"]["json"] + warning = data_warning(manifest) + require(warning is not None, "the manifest carries a warning above info") + call = copy.deepcopy(parent["call"]) + call[-1]["strict"] = True + return Derived( + call, + copy.deepcopy(parent["exchanges"][: index + 1]), + [*copy.deepcopy(parent["expect"][:-1]), warning.outcome(ctx.client_codes)], + ) + + +def _digest_mismatch(name: str) -> Callable[[dict[str, Any], Context], Derived]: + """The signed URL serves the scenario's own bytes, of another digest, on + both downloads.""" + + def derive(parent: dict[str, Any], ctx: Context) -> Derived: + exchanges = copy.deepcopy(parent["exchanges"]) + index = next(i for i, e in enumerate(exchanges) if "url" in e["request"]) + files, signed = exchanges[index - 1], exchanges[index] + body_file = f"{name}.bin" + signed["response"]["body_file"] = body_file + exchanges[index + 1 : index + 1] = [copy.deepcopy(files), copy.deepcopy(signed)] + return Derived( + copy.deepcopy(parent["call"]), + exchanges[: index + 3], + [*copy.deepcopy(parent["expect"][:-1]), ctx.raised("digest_mismatch")], + {body_file: b"Not the stored file.\n"}, + ) + + return derive + + +def _resubmit_other_spec(parent: dict[str, Any], ctx: Context) -> Derived: + """Search answers the built identity with the spec the fetch posted + rather than the one the build answered.""" + index = next( + i + for i, e in enumerate(parent["exchanges"]) + if e["request"].get("path") == "/search/resolve" + ) + exchanges = copy.deepcopy(parent["exchanges"][: index + 1]) + spec = exchanges[index]["response"]["json"]["parts"][0]["spec"] + posted = parent["call"][-1]["spec"]["spec_id"] + require(spec["spec_id"] != posted, "the build answered another spec_id") + spec["spec_id"] = spec["definition"]["spec_id"] = posted + return Derived( + copy.deepcopy(parent["call"]), + exchanges, + [*copy.deepcopy(parent["expect"][:-1]), ctx.raised("contract_violation")], + ) + + +def _frame_several(parent: dict[str, Any], ctx: Context) -> Derived: + require(len(parent["expect"][-1]["dataset"]["members"]) > 1, "several members") + return Derived( + [copy.deepcopy(parent["call"][0]), {"op": "fetch", "layout": "frame"}], + copy.deepcopy(parent["exchanges"][:1]), + [copy.deepcopy(parent["expect"][0]), ctx.raised("invalid_argument")], + ) + + +def _answer_ref(parent: dict[str, Any]) -> dict[str, Any]: + """The ref the parent's fetch of a one-member answer writes.""" + build = parent["exchanges"][_build_index(parent)] + manifest = build["response"]["json"] + (member,) = parent["expect"][-1]["dataset"]["members"] + artifact = pick_artifact(manifest, RENDERING) + require(artifact is not None, "the manifest lists the long Parquet artifact") + assert artifact is not None + return { + "format_version": 1, + "members": [ + { + "parts": member["parts"], + "sentence": member["sentence"], + "spec": { + "spec_id": member["spec_id"], + "definition": build["request"]["json"]["input"]["definition"], + }, + "content_version": member["content_version"], + "artifact": { + "digest": artifact["artifact_digest"], + "rendering": dict(RENDERING), + }, + } + ], + } + + +def _snapshot_expired(ref: dict[str, Any]) -> dict[str, Any]: + (member,) = ref["members"] + path = f"/datasets/{member['spec']['spec_id']}/{member['content_version']}" + return _refusal({"method": "GET", "path": path}, 410, _EXPIRED) + + +def _expired_rebuilt(parent: dict[str, Any], ctx: Context) -> Derived: + """The ref the parent's fetch writes, its snapshot expired, and the + parent's build, files and download as the rebuild.""" + ref = _answer_ref(parent) + index = _build_index(parent) + dataset = copy.deepcopy(parent["expect"][-1]["dataset"]) + del dataset["search_warning"] + return Derived( + [{"op": "fetch", "ref": ref}], + [_snapshot_expired(ref), *copy.deepcopy(parent["exchanges"][index:])], + [{"dataset": dataset}], ) - exchanges.insert(index, _refusal(exchanges[index]["request"], 504, problem)) + + +def _expired_newer(parent: dict[str, Any], ctx: Context) -> Derived: + """As `_expired_rebuilt`, with the rebuild answering a newer version.""" + ref = _answer_ref(parent) + build = copy.deepcopy(parent["exchanges"][_build_index(parent)]) + build["response"]["json"]["content_version"] = NEWER_VERSION + error = ClientError( + FILE_EXPIRED, error=VERSION_UNAVAILABLE, newest_version=NEWER_VERSION + ) + return Derived( + [{"op": "fetch", "ref": ref}], + [_snapshot_expired(ref), build], + [error.outcome(ctx.client_codes)], + ) + + +def _expired_not_reproducible(parent: dict[str, Any], ctx: Context) -> Derived: + """The parent's ref, its snapshot expired and its rebuild refused; the + versions route is recorded live.""" + ref = copy.deepcopy(parent["call"][0]["ref"]) + (member,) = ref["members"] + spec = Spec(member["spec"]["spec_id"], member["spec"]["definition"]) + body = _build_body(spec, None, member["artifact"]["rendering"]) + canned = [ + _snapshot_expired(ref), + _refusal( + {"method": "POST", "path": "/datasets", "json": body}, 422, _NOT_RESOLVABLE + ), + ] + session = ctx.session("synthetic", canned=canned) + session.fetch_ref(ref) + require( + session.expect[-1].get("error", {}).get("class") == VERSION_UNAVAILABLE, + "the lookup raises VersionUnavailableError", + ) + return Derived(session.call, session.recorder.exchanges, session.expect) + + +def _expired_file_selector(parent: dict[str, Any], ctx: Context) -> Derived: + """The files route refuses artifact_expired, and the file selector + redirects to the parent's signed download.""" + exchanges = copy.deepcopy(parent["exchanges"]) + (member,) = parent["call"][0]["ref"]["members"] + index = next(i for i, e in enumerate(exchanges) if "origin_path" in e["request"]) + files = exchanges[index] + path = selector_path( + member["spec"]["spec_id"], + member["content_version"], + member["artifact"]["rendering"], + ) + selector = { + "request": {"method": "GET", "path": path}, + "response": copy.deepcopy(files["response"]), + } + exchanges[index : index + 1] = [_refusal(files["request"], 410, _EXPIRED), selector] return _same(parent, exchanges) +def _poll_index(exchanges: Sequence[dict[str, Any]]) -> int: + return next( + i + for i, e in enumerate(exchanges) + if e["request"].get("path", "").startswith("/datasets/operations/") + ) + + +def _async_fetch( + change: Callable[[list[dict[str, Any]], dict[str, Any]], None] | None = None, +) -> Callable[[dict[str, Any], Context], Derived]: + """The parent's mint and result as one fetch of its spec, which makes the + same exchanges; `change` edits the exchanges and the fetch's outcome.""" + + def derive(parent: dict[str, Any], ctx: Context) -> Derived: + mint, result = parent["call"] + require( + mint["op"] == "mint" and result["op"] == "result", "a mint, then result" + ) + require( + "retry_after_ms" in parent["exchanges"][0]["response"]["json"]["operation"], + "the build's operation carries its pacing", + ) + exchanges = copy.deepcopy(parent["exchanges"]) + outcome = copy.deepcopy(parent["expect"][1]) + if change is not None: + change(exchanges, outcome["dataset"]["long_builds"][0]) + return Derived( + [{"op": "fetch", "spec": copy.deepcopy(mint["spec"])}], exchanges, [outcome] + ) + + return derive + + +def _poll_rate_limited(exchanges: list[dict[str, Any]], build: dict[str, Any]) -> None: + """A 429 with Retry-After 3 and no body answers the first poll.""" + index = _poll_index(exchanges) + refused = { + "request": copy.deepcopy(exchanges[index]["request"]), + "response": {"status": 429, "headers": {"retry-after": "3"}}, + } + exchanges.insert(index, refused) + build["poll_waits"].insert(1, 3.0) + + +def _operation_failed(exchanges: list[dict[str, Any]], build: dict[str, Any]) -> None: + """The first poll answers the operation failed with a retryable + operation_failed, and the build is posted again and runs as recorded. The + second build's operation is paced as the first's, so the waits repeat the + first wait.""" + index = _poll_index(exchanges) + failed = copy.deepcopy(exchanges[index]) + operation = failed["response"]["json"]["operation"] + operation["status"] = "failed" + operation.pop("progress", None) + failed["response"]["json"] = { + "operation": operation, + "error": dict(_OPERATION_FAILED), + } + exchanges[index:index] = [failed, copy.deepcopy(exchanges[0])] + build["poll_waits"].insert(0, build["poll_waits"][0]) + build["resubmissions"] = 1 + + def _signed_url_refused(parent: dict[str, Any], ctx: Context) -> Derived: exchanges = copy.deepcopy(parent["exchanges"]) index = next(i for i, e in enumerate(exchanges) if "url" in e["request"]) @@ -1568,6 +2114,118 @@ def _strict_info_notice(parent: dict[str, Any], ctx: Context) -> Derived: "client builds once more and reaches the same dataset.", _retry_after_504, ), + Synthetic( + "fetch-spec-504-twice", + "fetch-spec-known-sentence", + "A 504 timeout with retryable true answers the build and its one retry.", + "A synchronous build cut off twice is retried once only: the second 504 raises the " + "timeout code's ServerError.", + _ends_at_build(_cut_off_twice), + ), + Synthetic( + "fetch-spec-member-not-resolvable", + "fetch-spec-known-sentence", + "A 422 member_not_resolvable answers the build.", + "A build refused because the spec no longer resolves raises InvalidRequestError with " + "the server's code, and makes no further request.", + _ends_at_build(_not_resolvable), + ), + Synthetic( + "fetch-spec-strict-warning", + "fetch-spec-known-sentence", + "The fetch is strict, and the exchanges after the build go.", + "A strict fetch raises the manifest's first warning above info severity, " + "coverage_below_scope at warn here, as DataWarning before the download.", + _strict_warning, + ), + Synthetic( + "fetch-spec-digest-mismatch", + "fetch-spec-known-sentence", + "The signed download serves other bytes, and the files route is asked once more for the same.", + "Bytes that do not hash to the artifact's digest ask the files route for a fresh " + "redirect once; a second mismatch raises ServerError digest_mismatch.", + _digest_mismatch("fetch-spec-digest-mismatch"), + ), + Synthetic( + "fetch-spec-resubmit-other-spec", + "fetch-spec-narrowed", + "Search answers the built identity with the posted spec_id, and the exchanges after it go.", + "When Search answers the built identity with a spec_id other than the built one, the " + "client raises ContractError before the download.", + _resubmit_other_spec, + ), + Synthetic( + "fetch-frame-several-readings", + "answer-several-readings-folded", + 'The fetch of the answer asks for layout "frame", and the exchanges after the search go.', + "The frame layout holds one reading, so fetching an answer with two members in it " + "raises InvalidRequestError before any build.", + _frame_several, + ), + Synthetic( + "fetch-ref-expired-rebuild-same-version", + "answer-definite-fetch", + "A ref to the fetched member, whose snapshot route refuses 410 artifact_expired; the parent's build, files and download follow.", + "A ref whose snapshot refuses artifact_expired builds its spec again with the ref's " + "rendering; the build answers the same content_version, so the client downloads it " + "and returns the ref's member, its parts and sentence kept, with no Search call.", + _expired_rebuilt, + ), + Synthetic( + "fetch-ref-expired-newer-version", + "answer-definite-fetch", + f"As fetch-ref-expired-rebuild-same-version, with the rebuild answering {NEWER_VERSION}.", + "A rebuild that answers another content_version cannot return the stored one: the " + "client raises VersionUnavailableError with the snapshot's artifact_expired code and " + "the rebuilt version as the newest, and downloads nothing.", + _expired_newer, + ), + Synthetic( + "fetch-ref-expired-not-reproducible", + "fetch-ref", + "The snapshot refuses 410 artifact_expired and the rebuild 422 member_not_resolvable; the versions route is recorded live.", + "When the stored version has expired and the build is refused, the client reads the " + "versions route for the newest version. Dev refuses the keyless recorder 403 " + "publish_not_permitted there, so the client raises VersionUnavailableError with the " + "snapshot's artifact_expired code and no newest version.", + _expired_not_reproducible, + live=True, + ), + Synthetic( + "fetch-ref-expired-file-selector", + "fetch-ref", + "The files route refuses 410 artifact_expired, and the file selector redirects to the parent's signed download.", + "When the files route refuses artifact_expired, the client asks the file selector for " + "the stored version in the ref's rendering and downloads the file it redirects to, " + "which hashes to the stored digest.", + _expired_file_selector, + needs=(FILE_SELECTOR,), + ), + Synthetic( + "fetch-spec-async-build", + "mint-async-build", + "The mint and result steps become one fetch of the spec, which makes the same exchanges.", + "Fetching a spec whose build answers 202 polls the operation: it waits the 202's " + "retry_after_ms, then each poll's, backing off from 1 to 8 seconds when a poll gives " + "none, and downloads the done manifest's file.", + _async_fetch(), + ), + Synthetic( + "fetch-spec-poll-rate-limited", + "mint-async-build", + "As fetch-spec-async-build, with a bodiless 429 and Retry-After 3 answering the first poll.", + "A 429 on a poll spends no retry: the client waits the Retry-After seconds, polls " + "again and keeps the server's pacing after it.", + _async_fetch(_poll_rate_limited), + ), + Synthetic( + "fetch-spec-operation-failed-resubmitted", + "mint-async-build", + "As fetch-spec-async-build, with the first poll answering failed with a retryable operation_failed, and the build posted again.", + "A poll that answers a failed operation whose error is retryable posts the same build " + "once more and polls the operation it starts; long_builds counts one resubmission.", + _async_fetch(_operation_failed), + ), Synthetic( "fetch-ref-signed-url-refused", "fetch-ref", @@ -1830,7 +2488,7 @@ def record_synthetic(definition: Synthetic, ctx: Context, directory: Path) -> No write_record( directory, _record(definition.name, definition.description, origin, derived), - {}, + derived.bodies, ) @@ -1923,6 +2581,8 @@ def drive(session: Session, call: Sequence[dict[str, Any]]) -> None: Spec(spec["spec_id"], spec["definition"], spec.get("sentence")), window=tuple(window) if isinstance(window, list) else window, facets=step.get("facets"), + layout=step.get("layout"), + strict=step.get("strict", False), ) case {"op": "fetch", "ref": ref}: session.fetch_ref(ref) @@ -1933,11 +2593,15 @@ def drive(session: Session, call: Sequence[dict[str, Any]]) -> None: answer, partial=step.get("partial", False), strict=step.get("strict", False), + layout=step.get("layout"), ) case {"op": "mint", "spec": spec}: session.mint( - Spec(spec["spec_id"], spec["definition"], spec.get("sentence")) + Spec(spec["spec_id"], spec["definition"], spec.get("sentence")), + layout=step.get("layout"), ) + case {"op": "operation", "operation_id": operation_id}: + session.resume(operation_id, layout=step.get("layout")) case {"op": "result"}: session.result() @@ -1973,6 +2637,20 @@ def rederive_recorded(name: str, ctx: Context, directory: Path) -> None: ) +def waiting(openapi: Mapping[str, Any]) -> dict[str, list[str]]: + """Each scenario that waits for a route or status `openapi` does not + declare, its own or its parent's, with what it waits for.""" + recorded = {d.name: d.needs for d in RECORDED} + found = {} + for definition in (*RECORDED, *SYNTHETIC): + needs = definition.needs + if isinstance(definition, Synthetic): + needs = (*needs, *recorded.get(definition.derived_from, ())) + if missing := unmet(needs, openapi): + found[definition.name] = [" ".join(need) for need in missing] + return found + + def run_record(args: argparse.Namespace) -> int: package_dir: Path = args.package_dir directory: Path = args.scenarios_dir or package_dir / "scenarios" @@ -1980,7 +2658,17 @@ def run_record(args: argparse.Namespace) -> int: unknown = set(args.only or ()) - names if unknown: raise SystemExit(f"no scenario is named {sorted(unknown)}") + served = json.loads( + (package_dir / "served" / "openapi.json").read_text(encoding="utf-8") + ) chosen = set(args.only or names) + # A record outside the package is not validated, so it waits for nothing. + for name, needs in waiting(served).items() if args.scenarios_dir is None else (): + if name in chosen: + print( + f"waiting {name}: the served document declares no {needs}", flush=True + ) + chosen.discard(name) live = sorted(d.name for d in SYNTHETIC if d.live and d.name in chosen) if args.offline and live: raise SystemExit(f"--offline derives no live scenario, and {live} are live") diff --git a/tools/tests/test_capture_client_contract.py b/tools/tests/test_capture_client_contract.py index 6045a2a..611d931 100644 --- a/tools/tests/test_capture_client_contract.py +++ b/tools/tests/test_capture_client_contract.py @@ -62,10 +62,36 @@ def _without_shapes(expect: list[dict[str, Any]]) -> list[dict[str, Any]]: _LIVE = sorted(d.name for d in capture.SYNTHETIC if d.live) - - -def test_every_synthetic_record_has_a_definition() -> None: - assert sorted(d.name for d in capture.SYNTHETIC) == _records("synthetic") +_SERVED = json.loads( + (capture.PACKAGE_DIR / "served" / "openapi.json").read_text(encoding="utf-8") +) +_WAITING = capture.waiting(_SERVED) + + +def test_every_record_has_a_definition_and_every_definition_a_record() -> None: + """Each definition has its record unless it waits for the served document.""" + for kind, definitions in ( + ("recorded", capture.RECORDED), + ("synthetic", capture.SYNTHETIC), + ): + landed = sorted(d.name for d in definitions if d.name not in _WAITING) + assert landed == _records(kind) + + +def test_a_scenario_waits_for_its_own_needs_and_its_parents() -> None: + assert _WAITING == { + "mint-async-build": ["POST /api/datasets 202"], + "operation-resume": ["POST /api/datasets 202"], + "fetch-spec-async-build": ["POST /api/datasets 202"], + "fetch-spec-poll-rate-limited": ["POST /api/datasets 202"], + "fetch-spec-operation-failed-resubmitted": ["POST /api/datasets 202"], + "fetch-ref-expired-file-selector": [ + "GET /api/datasets/{id}/{content_version}/file 302" + ], + } + served = copy.deepcopy(_SERVED) + served["paths"]["/api/datasets"]["post"]["responses"]["202"] = {} + assert sorted(capture.waiting(served)) == ["fetch-ref-expired-file-selector"] @pytest.mark.parametrize("name", [*_records("recorded"), *_LIVE]) diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index 1ecd5fa..353b9fb 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -15,6 +15,7 @@ from __future__ import annotations +import copy import importlib.util import json import shutil @@ -39,6 +40,8 @@ _NO_CHOICE = "scenarios/choose-refused-no-choice.json" _DECLINED = "scenarios/answer-declined.json" _REQUEST_INVALID = "scenarios/fetch-spec-request-invalid.json" +_UNKNOWN_VERSION = "scenarios/fetch-ref-unknown-version.json" +_NEWER = "scenarios/fetch-ref-expired-newer-version.json" def _posted(index: int, change: Callable[[Any], None]) -> Callable[[Any], None]: @@ -144,6 +147,31 @@ def _one_hint(body: Any) -> None: del part["warnings"][1:] +def _refused_without_code(status: int) -> Callable[[Any], None]: + """The snapshot refuses at `status` with a body that carries no code, + and the record expects the 4xx fallback, InvalidRequestError.""" + + def change(doc: Any) -> None: + response = doc["exchanges"][0]["response"] + response["status"] = response["json"]["status"] = status + del response["json"]["code"] + doc["expect"][0] = { + "error": {"class": "InvalidRequestError", "code": "refusal_without_code"} + } + + return change + + +def _resubmit_answers_built(doc: Any) -> None: + """Search answers the identity resubmit with the built spec_id.""" + built = doc["exchanges"][0]["response"]["json"]["definition"]["spec_id"] + doc["exchanges"][1]["response"]["json"]["parts"][0]["spec"]["spec_id"] = built + + +def _last_response(change: Callable[[Any], None]) -> Callable[[Any], None]: + return lambda doc: change(doc["exchanges"][-1]["response"]) + + @pytest.mark.parametrize( ("target", "change", "expected"), [ @@ -453,7 +481,7 @@ def _one_hint(body: Any) -> None: ( _SEARCH, lambda doc: doc["call"].insert(0, {"op": "result"}), - "does not follow a step in ['mint']", + "does not follow a step in ['mint', 'operation']", ), ( _SEARCH, @@ -570,6 +598,73 @@ def _one_hint(body: Any) -> None: lambda doc: doc.update(commit="8408f1f"), "commit is not a 40-character sha", ), + ( + _UNKNOWN_VERSION, + _refused_without_code(408), + '"class": "DfoTimeoutError"', + ), + ( + _UNKNOWN_VERSION, + _refused_without_code(410), + '"class": "NotFoundError"', + ), + ( + _NEWER, + _set_outcome( + 0, lambda o: o["error"].update(newest_version="cv_" + "2" * 32) + ), + "step 0 expects", + ), + ( + _NEWER, + _set_outcome(0, lambda o: o["error"].pop("newest_version")), + ( + "expect/0: {'error': {'class': 'VersionUnavailableError', 'code': " + "'artifact_expired'}} is not valid" + ), + ), + ( + "scenarios/fetch-ref-expired-not-reproducible.json", + _last_response( + lambda r: r.update( + status=200, + json={"versions": [{"content_version": "cv_" + "3" * 32}]}, + ) + ), + "step 0 expects", + ), + ( + "scenarios/fetch-ref-expired-rebuild-same-version.json", + _set_body(0, lambda body: body.update(code="snapshot_not_found")), + "the steps never make exchanges 1 to 3", + ), + ( + "scenarios/fetch-spec-strict-warning.json", + _set_body(0, lambda body: body["warnings"][0].update(severity="info")), + "the steps make a GET origin the record lacks", + ), + ( + "scenarios/fetch-spec-digest-mismatch.json", + _last_response( + lambda r: r.update(body_file="fetch-spec-known-sentence.parquet") + ), + "step 0 expects", + ), + ( + "scenarios/fetch-spec-frame-layout.json", + lambda doc: doc["exchanges"][0]["request"]["json"]["options"].pop("layout"), + "where the rules post", + ), + ( + "scenarios/fetch-spec-resubmit-other-spec.json", + _resubmit_answers_built, + "the steps make a GET origin the record lacks", + ), + ( + "scenarios/fetch-frame-several-readings.json", + lambda doc: doc["call"][1].pop("layout"), + "the steps make a POST /datasets the record lacks", + ), ], ids=[ "strict-pointer-unresolved", @@ -650,6 +745,17 @@ def _one_hint(body: Any) -> None: "refusal-without-code", "search-warning-one-hint-code", "source-commit-short", + "status-408-without-code", + "status-410-without-code", + "expect-wrong-newest-version", + "version-unavailable-without-newest-version", + "newest-version-from-the-versions-route", + "unknown-version-ends-the-lookup", + "info-warning-raises-on-strict", + "digest-match-raises", + "frame-build-posts-long-options", + "resubmit-answering-another-spec", + "several-readings-fetched-long", ], ) def test_a_broken_contract_is_reported( @@ -686,3 +792,151 @@ def test_no_scenarios_is_a_hard_failure(package_dir: Path) -> None: for path in (package_dir / "scenarios").iterdir(): path.unlink() assert "scenarios: no scenario records found" in validator.validate() + + +_OPERATION_ID = "op_" + "a" * 64 + + +def _write_long_build(package_dir: Path, kind: str) -> Path: + """A synthetic record in which fetch-spec-known-sentence's build answers + 202 and two polls finish it, the first after the 202's 1.5 s pacing and + the second after a 1 s backoff. `rate_limited` adds a 429 with + Retry-After 3 before the first poll; `resubmitted` has the first poll + answer a retryable failed operation and the build posted again.""" + scenarios = package_dir / "scenarios" + parent = json.loads( + (scenarios / "fetch-spec-known-sentence.json").read_text(encoding="utf-8") + ) + build, files, signed = parent["exchanges"] + operation = { + "operation_id": _OPERATION_ID, + "status": "pending", + "poll": f"/api/datasets/operations/{_OPERATION_ID}", + "retry_after_ms": 1500, + } + poll = {"method": "GET", "path": f"/datasets/operations/{_OPERATION_ID}"} + + def polled(status: str, **members: Any) -> dict[str, Any]: + resource = { + "operation": {**operation, "status": status, "retry_after_ms": None} + } + return { + "request": poll, + "response": {"status": 200, "json": resource | members}, + } + + started = { + "request": build["request"], + "response": {"status": 202, "json": {"operation": operation}}, + } + polls = [polled("running"), polled("done", manifest=build["response"]["json"])] + waits = [1.5, 1.0] + resubmissions = 0 + if kind == "rate_limited": + polls.insert( + 0, + { + "request": poll, + "response": {"status": 429, "headers": {"retry-after": "3"}}, + }, + ) + waits = [1.5, 3.0, 1.0] + elif kind == "resubmitted": + error = { + "type": "/codes/operation_failed", + "title": "Internal Server Error", + "status": 500, + "detail": "The build's worker stopped.", + "code": "operation_failed", + "trace_id": "0" * 32, + "capability_version": "synthetic", + "retryable": True, + } + polls[:0] = [polled("failed", error=error), started] + waits = [1.5, 1.5, 1.0] + resubmissions = 1 + outcome = copy.deepcopy(parent["expect"][0]) + outcome["dataset"]["long_builds"] = [ + { + "operation_id": _OPERATION_ID, + "poll_waits": waits, + "resubmissions": resubmissions, + } + ] + record = { + "format_version": 1, + "name": "fetch-spec-long-build", + "description": "The parent's build runs on as an operation.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "The build answers 202, and polls finish it.", + }, + "call": parent["call"], + "exchanges": [started, *polls, files, signed], + "expect": [outcome], + } + path = scenarios / "fetch-spec-long-build.json" + path.write_text(json.dumps(record), encoding="utf-8") + return path + + +def _long_builds(change: Callable[[Any], None]) -> Callable[[Any], None]: + return _set_outcome(0, lambda o: change(o["dataset"]["long_builds"][0])) + + +@pytest.mark.parametrize("kind", ["plain", "rate_limited", "resubmitted"]) +def test_a_long_build_record_is_valid(package_dir: Path, kind: str) -> None: + _write_long_build(package_dir, kind) + assert validator.validate() == [] + + +@pytest.mark.parametrize( + ("kind", "change", "expected"), + [ + ( + "plain", + _long_builds(lambda b: b.update(poll_waits=[1.5, 2.0])), + "step 0 expects", + ), + ( + "plain", + _long_builds(lambda b: b.update(operation_id="op_" + "b" * 64)), + "step 0 expects", + ), + ( + "plain", + _set_outcome(0, lambda o: o["dataset"].pop("long_builds")), + "step 0 expects", + ), + ( + "rate_limited", + _long_builds(lambda b: b.update(poll_waits=[1.5, 1.5, 1.0])), + "step 0 expects", + ), + ( + "resubmitted", + _long_builds(lambda b: b.update(resubmissions=0)), + "step 0 expects", + ), + ( + "resubmitted", + _set_body(1, lambda body: body["error"].update(retryable=False)), + "the steps never make exchanges 2 to 6", + ), + ], + ids=[ + "poll-waits-without-backoff", + "long-build-other-operation", + "long-build-unnamed", + "rate-limited-poll-without-its-wait", + "resubmission-uncounted", + "failed-operation-not-retryable", + ], +) +def test_a_broken_long_build_is_reported( + package_dir: Path, kind: str, change: Callable[[Any], None], expected: str +) -> None: + _edit(_write_long_build(package_dir, kind), change) + problems = validator.validate() + assert any(expected in problem for problem in problems), problems diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index b4b2914..2d1173a 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -26,7 +26,7 @@ mapping takes an action a problem document can carry. - `client-codes.json` lists codes in order, each once, none of them a code in `actions.json` or `registries/codes.json`. Each row's class is one a - scenario's error may name, other than `SearchWarning`, and only + scenario's error may name, other than a warning's, and only `refusal_without_code` takes the class its status maps to. - Each scenario's file name matches its `name`, names are unique, `expect` holds one outcome per step, a step that acts on an earlier result follows @@ -37,15 +37,19 @@ route's request schema, each JSON response body validates against the route's schema for its status, and a problem document's `code` is an active code registered with that status. -- Each error a scenario expects, other than a `SearchWarning`, carries a - refusal's code from its exchanges or a client code of its class. +- Each error a scenario expects, other than a `SearchWarning` or + `DataWarning`, carries a refusal's code from its exchanges, a failed + operation's included, or a client code of its class. - Each scenario's `expect` equals the outcomes its steps reach over its exchanges, with refusals' error classes and gap kinds from `actions.json` and the class of each error the client raises itself from - `client-codes.json`, as `expected_outcomes` derives them; a dataset's rows, columns and per-part - row counts are left to the Parquet bodies. Each Search request a record - holds posts the input the steps derive: the question, a choice's - data_query or dataset_resubmit entries, or a member's identity. Every + `client-codes.json`, as `expected_outcomes` derives them, the waits + before each poll included; a dataset's rows, columns and per-part row + counts are left to the Parquet bodies, and each download hashes to its + artifact's digest or the outcome says it does not. Each Search request a + record holds posts the input the steps derive: the question, a choice's + data_query or dataset_resubmit entries, or a member's identity, and each + build posts the options its layout gives. Every absolute URL a record holds, a `url` request or a `location` header, has the query `X-Goog-Signature=redacted`. - Each ref example's file name matches its `name` and gets the verdict it @@ -64,11 +68,12 @@ from __future__ import annotations +import hashlib import json import re import sys from collections.abc import Iterator, Mapping, Sequence -from dataclasses import dataclass +from dataclasses import dataclass, field from pathlib import Path from typing import Any from urllib.parse import urlsplit @@ -89,7 +94,7 @@ _ACTS_ON_PREVIOUS = { "choose": {"search", "choose"}, "fetch_answer": {"search", "choose", "fetch_answer"}, - "result": {"mint"}, + "result": {"mint", "operation"}, } _STRICT_POINTER = re.compile(r"^/components/schemas/([^/]+)/properties/([^/]+)$") @@ -358,8 +363,8 @@ def _check_client_codes( f"client-codes.json: {code!r} is also a code in {source}" for code in sorted(set(codes) & server_codes) ) - # A SearchWarning is a warning and carries the server's code. - known = {*classes, BY_STATUS} - {"SearchWarning"} + # A warning raised under strict carries the server's code. + known = {*classes, BY_STATUS} - set(WARNING_CLASSES) problems.extend( f"client-codes.json: {row['code']!r} raises {row['class']!r}, a class " "no scenario names" @@ -545,8 +550,10 @@ def _check_problem_code( } if entry["lifecycle"] != "active" or response["status"] not in statuses: return [ - f"{label}: problem code {body['code']!r} is not an active code " - f"registered with status {response['status']}" + ( + f"{label}: problem code {body['code']!r} is not an active code " + f"registered with status {response['status']}" + ) ] return [] return [f"{label}: problem code {body['code']!r} is not in the registry"] @@ -580,9 +587,17 @@ def _check_problem_code( 401: "AuthenticationError", 403: "PermissionDeniedError", 404: "NotFoundError", + 408: "DfoTimeoutError", + 410: "NotFoundError", 422: "InvalidRequestError", 429: "RateLimitError", } +# The statuses a refusal is retried on when its body does not say. +RETRYABLE_STATUSES = frozenset({408, 429, 500, 502, 503, 504}) +# The website proxy's `retry` value that makes its refusal retryable. +_PROXY_RETRY = "retry_after_delay" +# The retries a client makes by default after a retryable refusal. +MAX_RETRIES = 2 def gap_kinds(actions: Mapping[str, Mapping[str, Any]]) -> dict[str, str]: @@ -611,42 +626,128 @@ def error_class( return STATUS_CLASSES.get(status, fallback) +def retryable(status: int, body: Any) -> bool: + """Whether a client retries a refusal: as a problem document's `retryable` + says, or the website proxy's `retry`, and otherwise by its status.""" + if isinstance(body, dict): + if "code" not in body and "error" in body: + return body.get("retry") == _PROXY_RETRY + if isinstance(body.get("retryable"), bool): + return body["retryable"] + return status in RETRYABLE_STATUSES + + +def retry_after(headers: Mapping[str, str]) -> float | None: + """The seconds a `Retry-After` header asks for, or None.""" + try: + wait = float(headers.get("retry-after", "")) + except ValueError: + return None + return wait if wait >= 0 else None + + +POLL_BACKOFF_FIRST = 1.0 +POLL_BACKOFF_CAP = 8.0 + + +@dataclass +class PollPacing: + """The wait before each poll of one long build: the `Retry-After` of a 429 + that refused the last poll, else the last operation resource's + `retry_after_ms`, else the `Retry-After` of the response that carried that + resource, else a backoff that doubles from 1 to 8 seconds and advances + only when it is used.""" + + paced: float | None = None + header: float | None = None + refused: float | None = None + backoff_step: int = 0 + + def took(self, operation: Mapping[str, Any], headers: Mapping[str, str]) -> None: + """An operation resource arrived, with its response's headers.""" + ms = operation.get("retry_after_ms") + number = isinstance(ms, int | float) and not isinstance(ms, bool) + self.paced = ms / 1000 if number and ms >= 0 else None + self.header = retry_after(headers) + + def rate_limited(self, headers: Mapping[str, str]) -> None: + """A 429 refused the last poll; it spends no retry.""" + self.refused = retry_after(headers) + + def next_wait(self) -> float: + if self.refused is not None: + wait, self.refused = self.refused, None + return wait + if self.paced is not None: + return self.paced + if self.header is not None: + return self.header + wait = min(POLL_BACKOFF_FIRST * 2**self.backoff_step, POLL_BACKOFF_CAP) + self.backoff_step += 1 + return wait + + # The class of a client code that takes the class its refusal's HTTP status # maps to, and the client code of a refusal whose body carries no code. BY_STATUS = "by_status" REFUSAL_WITHOUT_CODE = "refusal_without_code" -def error_outcome(error: str, code: str | None) -> dict[str, Any]: - return {"error": {"class": error, "code": code}} +def error_outcome(error: str, code: str | None, **members: Any) -> dict[str, Any]: + return {"error": {"class": error, "code": code, **members}} + + +# The warnings a client raises as errors under strict, which carry the +# server's code rather than a client code. +WARNING_CLASSES = ("SearchWarning", "DataWarning") +VERSION_UNAVAILABLE = "VersionUnavailableError" class ClientError(Exception): """A step ends in an error a client raises. A refusal names its class and - the server's code, a SearchWarning names the server's warning or - departure code, and any other error names a code from - `client-codes.json`, whose row gives its class.""" - - def __init__(self, code: str | None, *, error: str | None = None) -> None: + the server's code, a SearchWarning or DataWarning names the server's + warning, departure or operation code, and any other error names a code + from `client-codes.json`, whose row gives its class. A + VersionUnavailableError also names the newest version, or None.""" + + def __init__( + self, + code: str | None, + *, + error: str | None = None, + newest_version: str | None = None, + ) -> None: super().__init__(f"{error or 'client'} {code}") self.code = code self.error = error + self.newest_version = newest_version - def outcome(self, client_codes: Mapping[str, Mapping[str, Any]]) -> dict[str, Any]: - """The error outcome, its class from `client_codes` when the error - names none. + def error_class(self, client_codes: Mapping[str, Mapping[str, Any]]) -> str: + """The error class: the one it names, else its client code's. Raises: ValueError: The code is not a client code of one class. """ if self.error is not None: - return error_outcome(self.error, self.code) + return self.error row = client_codes.get(self.code) if self.code is not None else None if row is None or row["class"] == BY_STATUS: raise ValueError( f"{self.code!r} is not a client code of one class in client-codes.json" ) - return error_outcome(row["class"], self.code) + return row["class"] + + def outcome(self, client_codes: Mapping[str, Mapping[str, Any]]) -> dict[str, Any]: + """The error outcome, its class from `client_codes` when the error + names none. + + Raises: + ValueError: The code is not a client code of one class. + """ + error = self.error_class(client_codes) + if error == VERSION_UNAVAILABLE: + return error_outcome(error, self.code, newest_version=self.newest_version) + return error_outcome(error, self.code) def refusal_error( @@ -1074,6 +1175,199 @@ class _UnfitError(Exception): _BUILD = ("POST", "/datasets") _POLL = ("GET", "/datasets/operations/") _MANIFEST = {"$ref": "#/components/schemas/Manifest"} +_OPERATION = {"$ref": "#/components/schemas/OperationResource"} +# The bare Parquet rendering a fetch asks for, by layout. +LAYOUT_RENDERINGS = { + "long": {"format": "parquet", "bundle": False}, + "frame": {"format": "parquet", "bundle": False, "layout": "frame"}, +} +# The snapshot refusal after which a stored version's lookup builds it again: +# the version exists, but its file has expired. Any other refusal ends it. +FILE_EXPIRED = "artifact_expired" +# The file route refusals after which the lookup takes its next step. +FILE_GONE = frozenset({FILE_EXPIRED, "artifact_not_found", "not_found"}) +# The classes of a rebuild refusal after which the lookup reads the newest +# version, and of a versions refusal that leaves the newest version unknown. +REBUILD_REFUSED = frozenset( + {"InvalidRequestError", "NotFoundError", VERSION_UNAVAILABLE} +) +NO_VERSIONS = frozenset({"NotFoundError", "PermissionDeniedError"}) +OPERATION_FAILED = "operation_failed" + + +def rendering_for(layout: str | None) -> dict[str, Any]: + """The build request's `options` for a fetch's `layout`, long by default.""" + return dict(LAYOUT_RENDERINGS[layout or "long"]) + + +def pick_artifact( + manifest: Mapping[str, Any], rendering: Mapping[str, Any] +) -> dict[str, Any] | None: + """The artifact a manifest lists for `rendering`, matched on format, + bundle and whether its layout is the frame.""" + frame = rendering.get("layout") == "frame" + for artifact in manifest["artifacts"]: + found = artifact.get("rendering") + if ( + isinstance(found, dict) + and found.get("format") == rendering["format"] + and found.get("bundle") is rendering["bundle"] + and (found.get("layout") == "frame") == frame + ): + return artifact + return None + + +def digest_of(data: bytes) -> str: + """The `sha256:` digest the server names a stored file by.""" + return "sha256:" + hashlib.sha256(data).hexdigest() + + +def selector_path( + spec_id: str, content_version: str, rendering: Mapping[str, Any] +) -> str: + """The file selector's path for a stored version, its rendering as the + query.""" + query = "&".join( + f"{name}={str(value).lower() if isinstance(value, bool) else value}" + for name, value in rendering.items() + ) + return f"/datasets/{spec_id}/{content_version}/file?{query}" + + +def data_warning(manifest: Mapping[str, Any]) -> ClientError | None: + """The DataWarning a strict fetch raises for a manifest: its first warning + above `info` severity, with that warning's code; None when it has none.""" + for warning in manifest.get("warnings") or []: + if isinstance(warning, dict) and warning.get("severity") != "info": + return ClientError(warning.get("code"), error="DataWarning") + return None + + +def resubmitted_sentence(answer: Answer, spec_id: str) -> str: + """The sentence Search gives a built identity it was posted: the answer + must be one definite part of `spec_id`, with a sentence, or the client + raises ContractError.""" + found = answer.parts[0] if len(answer.parts) == 1 else {} + spec = found.get("spec") if found.get("status") == "definite" else None + if answer.body.get("kind") != "resolution" or not isinstance(spec, dict): + raise ClientError("contract_violation") + resolved = spec.get("resolved") + sentence = resolved.get("rendered_sentence") if isinstance(resolved, dict) else None + if spec.get("spec_id") != spec_id or not isinstance(sentence, str) or not sentence: + raise ClientError("contract_violation") + return sentence + + +def failed_operation( + resource: Mapping[str, Any], actions: Mapping[str, Mapping[str, Any]] +) -> tuple[ClientError, bool]: + """A failed operation's error, the refusal its problem document states at + that document's status or else 500, and whether it is retryable.""" + problem = resource.get("error") + status = problem.get("status") if isinstance(problem, dict) else None + status = status if isinstance(status, int) else 500 + return refusal_error(status, problem, actions), retryable(status, problem) + + +class LongBuild: + """A build the server runs on, followed the way a client polls it. Each + wait before a poll is `PollPacing`'s. A 429 poll spends no retry, any + other retryable refused poll one of MAX_RETRIES, and any other refused + poll raises. A poll answering a failed operation, retryable by its + error, posts the build again once when the client holds its request; + otherwise, and for an operation that failed before the client polled + it, the operation's error raises. `entry` is the build's `long_builds` + entry, and `result` its manifest once it is done.""" + + def __init__( + self, + resource: Mapping[str, Any], + headers: Mapping[str, str], + request: Any, + actions: Mapping[str, Mapping[str, Any]], + ) -> None: + self.request = request + self.actions = actions + self.pacing = PollPacing() + self.retries = 0 + self.result: dict[str, Any] | None = None + self.entry: dict[str, Any] = { + "operation_id": resource["operation"]["operation_id"], + "poll_waits": [], + "resubmissions": 0, + } + self._take(resource, headers) + + def _take(self, resource: Mapping[str, Any], headers: Mapping[str, str]) -> None: + self.resource = resource + self.pacing.took(resource["operation"], headers) + if resource["operation"]["status"] == "done": + manifest = resource.get("manifest") + if not isinstance(manifest, dict): + raise ClientError("contract_violation") + self.result = manifest + + def next_wait(self) -> float: + """The wait before the next poll, kept in `entry`.""" + if self.resource["operation"]["status"] == "failed": + raise failed_operation(self.resource, self.actions)[0] + wait = self.pacing.next_wait() + self.entry["poll_waits"].append(wait) + return wait + + def polled(self, status: int, headers: Mapping[str, str], body: Any) -> bool: + """Takes a poll's response, and says whether to post the build again. + + Raises: + ClientError: The error that ends the build. + """ + if status < 400: + self.retries = 0 + self._take(body, headers) + if body["operation"]["status"] != "failed": + return False + error, again = failed_operation(body, self.actions) + else: + error = refusal_error(status, body, self.actions) + again = retryable(status, body) + if error.code != OPERATION_FAILED: + if status == 429: + self.pacing.rate_limited(headers) + elif again and self.retries < MAX_RETRIES: + self.retries += 1 + else: + raise error + return False + if not again or self.request is None or self.entry["resubmissions"]: + raise error + self.entry["resubmissions"] += 1 + return True + + def reposted(self, status: int, headers: Mapping[str, str], body: Any) -> None: + """Takes the answer to the build posted again: a refusal raises, a + 202 starts the operation the client polls next, and a 200 is done.""" + if status >= 400: + raise refusal_error(status, body, self.actions) + if status != 202: + self.result = body + return + self.entry["operation_id"] = body["operation"]["operation_id"] + self._take(body, headers) + + +@dataclass +class _Minted: + """An operation a mint started or a resume read, for the result step: + its resource, the headers that came with it, the build request a failed + operation resubmits (None for a resumed one), the spec the client holds, + and the rendering it downloads.""" + + resource: dict[str, Any] + headers: dict[str, str] + request: dict[str, Any] | None + spec: dict[str, Any] | None + rendering: dict[str, Any] @dataclass @@ -1087,9 +1381,11 @@ class _Replay: members: Mapping[str, Sequence[str]] actions: Mapping[str, Mapping[str, Any]] client_codes: Mapping[str, Mapping[str, Any]] + body_dir: Path cursor: int = 0 answer: Answer | None = None - minted: tuple[dict[str, Any], dict[str, Any]] | None = None + minted: _Minted | None = None + long_builds: list[dict[str, Any]] = field(default_factory=list) @property def kinds(self) -> dict[str, str]: @@ -1097,11 +1393,11 @@ def kinds(self) -> dict[str, str]: # -- exchanges -- - def call(self, method: str, target: str) -> dict[str, Any]: - """The exchange a client acts on for its next request: the last of a - run that repeats one request, each refusal before it a retry. - `target` is a path under the base URL, a path prefix ending in `/`, - `origin` for a root-relative URL or `url` for an absolute one.""" + def call(self, method: str, target: str, *, retries: bool = True) -> dict[str, Any]: + """The exchange a client acts on for its next request: with `retries`, + the last of a run that repeats one request, each refusal before it a + retry. `target` is a path under the base URL, a path prefix ending in + `/`, `origin` for a root-relative URL or `url` for an absolute one.""" if self.cursor >= len(self.exchanges): raise _UnfitError(f"the steps make a {method} {target} the record lacks") exchange = self.exchanges[self.cursor] @@ -1119,7 +1415,8 @@ def call(self, method: str, target: str) -> dict[str, Any]: ) self.cursor += 1 while ( - exchange["response"]["status"] >= 400 + retries + and exchange["response"]["status"] >= 400 and self.cursor < len(self.exchanges) and self.exchanges[self.cursor]["request"] == request ): @@ -1127,16 +1424,18 @@ def call(self, method: str, target: str) -> dict[str, Any]: self.cursor += 1 return exchange - def acted_on(self, exchange: dict[str, Any]) -> Any: - """The JSON body a client acts on. A refusal raises its error, and a - body without a strict member raises ContractError.""" + def acted_on(self, exchange: dict[str, Any], schema: Any = None) -> Any: + """The JSON body a client acts on, read through `schema` or else its + route's schema for its status. A refusal raises its error, and a body + without a strict member raises ContractError.""" response = exchange["response"] body = response.get("json") if response["status"] >= 400: raise refusal_error(response["status"], body, self.actions) - schema = self.routes.response_schema( - self.base_path, exchange["request"], response["status"] - ) + if schema is None: + schema = self.routes.response_schema( + self.base_path, exchange["request"], response["status"] + ) self.strict(schema, body) return body @@ -1144,13 +1443,38 @@ def strict(self, schema: Any, body: Any) -> None: if strict_gaps(self.routes.openapi, self.members, schema, body): raise ClientError("contract_violation") - def download(self) -> None: - """The files route, then its signed URL; a refused signed URL asks the - files route again.""" - while True: - self.acted_on(self.call("GET", "origin")) - if self.call("GET", "url")["response"]["status"] < 400: + def body(self, response: dict[str, Any]) -> bytes: + if "body_file" in response: + path = self.body_dir / response["body_file"] + if not path.is_file(): + raise _UnfitError(f"body file {response['body_file']!r} is missing") + return path.read_bytes() + if "json" in response: + return json.dumps(response["json"]).encode() + return b"" + + def download(self, target: str, digest: str, *, origin: bool) -> None: + """A file through the route that redirects to its signed URL: an + artifact's root-relative `url` when `origin`, else a path under the + base URL. A refused signed URL, or bytes that do not hash to `digest`, + ask the route once more, and a second failure raises.""" + failure = ClientError("download_failed") + for _ in range(2): + exchange = self.call("GET", "origin" if origin else target) + asked = exchange["request"].get("origin_path", target) + if asked != target: + raise _UnfitError( + f"the record asks {asked}, where the rules ask {target}" + ) + self.acted_on(exchange) + signed = self.call("GET", "url", retries=False)["response"] + if signed["status"] >= 400: + failure = ClientError("download_failed") + continue + if digest_of(self.body(signed)) == digest: return + failure = ClientError("digest_mismatch") + raise failure def resolve(self, posts: dict[str, Any]) -> Answer: """A Search request whose recorded body, when it has one, posts the @@ -1164,42 +1488,89 @@ def resolve(self, posts: dict[str, Any]) -> Answer: ) return answer_from_body(self.acted_on(exchange)) - def wait(self, operation: dict[str, Any]) -> dict[str, Any]: - """Polls until the operation is done. The done resource's manifest is - untyped in the served document, so it is checked as a Manifest.""" - manifest = None - while operation["status"] != "done": - resource = self.acted_on(self.call(*_POLL)) - operation, manifest = resource["operation"], resource.get("manifest") - if not isinstance(manifest, dict): - raise ClientError("contract_violation") - self.strict(_MANIFEST, manifest) - return manifest + # -- builds -- - def build(self, parts: list[str], spec: dict[str, Any]) -> dict[str, Any]: + def build(self, rendering: dict[str, Any]) -> dict[str, Any]: + """A build of the latest version, posting `rendering` as its options: + the manifest it answers, through a long build when it answers 202.""" + exchange = self.call(*_BUILD) + sent = exchange["request"].get("json") + if sent is not None and sent.get("options") != rendering: + raise _UnfitError( + f"exchange {self.cursor - 1} posts options {sent.get('options')}, " + f"where the rules post {rendering}" + ) + if exchange["response"]["status"] != 202: + return self.acted_on(exchange) + resource = self.acted_on(exchange, _OPERATION) + headers = exchange["response"].get("headers", {}) + return self.long_build(resource, headers, exchange["request"]) + + def long_build( + self, + resource: dict[str, Any], + headers: Mapping[str, str], + request: dict[str, Any] | None, + ) -> dict[str, Any]: + """Polls an operation as `LongBuild` rules until it is done and + returns its manifest. A build posted again posts the same request.""" + build = LongBuild(resource, headers, request, self.actions) + self.long_builds.append(build.entry) + while build.result is None: + build.next_wait() + response = self.call(*_POLL, retries=False)["response"] + body = response.get("json") + if response["status"] < 400: + self.strict(_OPERATION, body) + if not build.polled(response["status"], response.get("headers", {}), body): + continue + again = self.call(*_BUILD) + if again["request"] != request: + raise _UnfitError("the build posted again posts another request") + reply = again["response"] + if reply["status"] < 400: + self.strict( + _OPERATION if reply["status"] == 202 else _MANIFEST, + reply.get("json"), + ) + build.reposted(reply["status"], reply.get("headers", {}), reply.get("json")) + self.strict(_MANIFEST, build.result) + return build.result + + def note_warnings(self, manifest: dict[str, Any], strict: bool) -> None: + if strict and (warning := data_warning(manifest)) is not None: + raise warning + + def fetched( + self, + parts: list[str], + spec: dict[str, Any], + rendering: dict[str, Any], + strict: bool, + ) -> dict[str, Any]: """One member: the build, then the member's files.""" - body = self.acted_on(self.call(*_BUILD)) - manifest = self.wait(body["operation"]) if "operation" in body else body - return self.member(parts, spec, manifest) + return self.member(parts, spec, self.build(rendering), rendering, strict) def member( - self, parts: list[str], spec: dict[str, Any], manifest: dict[str, Any] + self, + parts: list[str], + spec: dict[str, Any] | None, + manifest: dict[str, Any], + rendering: dict[str, Any], + strict: bool, ) -> dict[str, Any]: - """A built member: its sentence from Search when the build changed the - spec_id or the client lacks it, then the download.""" + """A built member: its warnings under strict, its sentence from + Search when the build changed the spec_id or the client lacks it, + then the download. `spec` is None for a resumed operation.""" + self.note_warnings(manifest, strict) + artifact = pick_artifact(manifest, rendering) + if artifact is None: + raise ClientError("contract_violation") built = manifest["definition"]["spec_id"] - sentence = spec.get("sentence") - if built != spec["spec_id"] or sentence is None: - entry = { - "entry_kind": "identity", - "variable_text": parts[0] if parts else UNNAMED_VARIABLE_TEXT, - "identity": manifest["definition"]["identity"], - } - (part,) = self.resolve( - {"kind": "dataset_resubmit", "entries": [entry]} - ).parts - sentence = part["spec"]["resolved"]["rendered_sentence"] - self.download() + sentence = None if spec is None else spec.get("sentence") + if spec is None or built != spec["spec_id"] or sentence is None: + sentence = self.sentence(parts, manifest["definition"]) + self.download(artifact["url"], artifact["artifact_digest"], origin=True) return { "parts": parts, "spec_id": built, @@ -1207,21 +1578,141 @@ def member( "sentence": sentence, } + def sentence(self, parts: list[str], definition: dict[str, Any]) -> str: + """Search's sentence for a built identity. An answer that is not one + definite part of the built spec_id, with a sentence, raises + ContractError.""" + entry = { + "entry_kind": "identity", + "variable_text": parts[0] if parts else UNNAMED_VARIABLE_TEXT, + "identity": definition["identity"], + } + answer = self.resolve({"kind": "dataset_resubmit", "entries": [entry]}) + return resubmitted_sentence(answer, definition["spec_id"]) + + # -- stored versions -- + + def stored_version(self, member: dict[str, Any]) -> dict[str, Any]: + """One version a ref names, through the lookup order: the snapshot + route and the files route at the stored digest, then the file + selector, then a build that must answer the same version. A snapshot + refusal other than artifact_expired ends the lookup; otherwise a + lookup that finds no file raises VersionUnavailableError with the + first refusal's code, or version_unavailable, and the newest version: + the one the build answered, or the versions route's first.""" + spec = member["spec"] + spec_id, version = spec["spec_id"], member["content_version"] + rendering = member["artifact"]["rendering"] + stored = { + "parts": member["parts"], + "spec_id": spec_id, + "content_version": version, + "sentence": member["sentence"], + } + refusal: ClientError | None = None + try: + manifest = self.acted_on(self.call("GET", f"/datasets/{spec_id}/{version}")) + except ClientError as error: + if error.code != FILE_EXPIRED: + raise + refusal, manifest = error, None + if manifest is not None: + built = (manifest["definition"]["spec_id"], manifest["content_version"]) + if built != (spec_id, version): + raise ClientError("contract_violation") + found, refusal = self.stored_file(member, manifest) + if found: + return stored + + try: + manifest = self.build(rendering) + except ClientError as error: + if error.error_class(self.client_codes) not in REBUILD_REFUSED: + raise + refusal = refusal if refusal is not None else error + newest = self.newest(spec_id) + else: + if manifest["content_version"] == version: + held = {"spec_id": spec_id, "sentence": member["sentence"]} + return self.member(member["parts"], held, manifest, rendering, False) + newest = manifest["content_version"] + raise ClientError( + refusal.code if refusal is not None else "version_unavailable", + error=VERSION_UNAVAILABLE, + newest_version=newest, + ) + + def stored_file( + self, member: dict[str, Any], manifest: dict[str, Any] + ) -> tuple[bool, ClientError | None]: + """Whether the files route at the stored digest, or else the file + selector, served the stored file, and the files route's refusal when + it refused. A selector refusal outside FILE_GONE, and a files route + one, raise; a selector file of another digest is not the stored one.""" + digest = member["artifact"]["digest"] + refusal = None + artifact = next( + (a for a in manifest["artifacts"] if a["artifact_digest"] == digest), None + ) + if artifact is not None: + try: + self.download(artifact["url"], digest, origin=True) + except ClientError as error: + if error.code not in FILE_GONE: + raise + refusal = error + else: + return True, None + path = selector_path( + member["spec"]["spec_id"], + member["content_version"], + member["artifact"]["rendering"], + ) + try: + self.download(path, digest, origin=False) + except ClientError as error: + if error.code == "digest_mismatch": + return False, refusal + if error.code in FILE_GONE: + return False, refusal or error + raise + return True, None + + def newest(self, spec_id: str) -> str | None: + """The newest stored version the versions route lists first, or None + when it lists none or refuses as unknown or forbidden.""" + try: + body = self.acted_on(self.call("GET", f"/datasets/{spec_id}/versions")) + except ClientError as error: + if error.error_class(self.client_codes) in NO_VERSIONS: + return None + raise + versions = body.get("versions") if isinstance(body, dict) else None + first = versions[0] if isinstance(versions, list) and versions else None + newest = first.get("content_version") if isinstance(first, dict) else None + return newest if isinstance(newest, str) else None + # -- steps -- def step(self, step: dict[str, Any]) -> dict[str, Any]: - """The outcome `step` reaches.""" + """The outcome `step` reaches. A step that made a long build names + each in `long_builds`, whatever its outcome.""" + self.long_builds = [] op = step["op"] if op == "fetch": op = ( "fetch_ref" if "ref" in step else "fetch_spec" if "spec" in step else op ) try: - return getattr(self, f"_{op}")(step) + outcome = getattr(self, f"_{op}")(step) except ClientError as ended: if op in {"search", "choose"}: self.answer = None - return ended.outcome(self.client_codes) + outcome = ended.outcome(self.client_codes) + if self.long_builds: + (value,) = outcome.values() + value["long_builds"] = self.long_builds + return outcome def _answered(self) -> Answer: if self.answer is None: @@ -1249,8 +1740,8 @@ def _fetch(self, step: dict[str, Any]) -> dict[str, Any]: """A fetch of the answer: a declined or catalogue answer raises DeclinedError; a gap raises IncompleteAnswerError unless the fetch is partial and some part has a reading; a strict fetch whose readings - depart from the question raises SearchWarning; all before any - request.""" + depart from the question raises SearchWarning; the frame layout with + several members raises InvalidRequestError; all before any request.""" answer = self._answered() if answer.body.get("kind") != "resolution": raise ClientError("answer_declined") @@ -1259,45 +1750,69 @@ def _fetch(self, step: dict[str, Any]) -> dict[str, Any]: if gaps and (not step.get("partial", False) or not readings): raise ClientError("answer_incomplete") warns = search_warns(answer) - if warns and step.get("strict", False): + strict = step.get("strict", False) + if warns and strict: raise ClientError(search_warning_code(answer), error="SearchWarning") + rendering = rendering_for(step.get("layout")) + if "layout" in rendering and len(readings) > 1: + raise ClientError("invalid_argument") members = [ - self.build( + self.fetched( parts, { "spec_id": spec["spec_id"], "sentence": spec["resolved"]["rendered_sentence"], }, + rendering, + strict, ) for parts, spec in readings ] return {"dataset": dataset_summary(members, gaps, search_warning=warns)} def _fetch_spec(self, step: dict[str, Any]) -> dict[str, Any]: - return {"dataset": dataset_summary([self.build([], step["spec"])], [])} + rendering = rendering_for(step.get("layout")) + member = self.fetched([], step["spec"], rendering, step.get("strict", False)) + return {"dataset": dataset_summary([member], [])} def _fetch_ref(self, step: dict[str, Any]) -> dict[str, Any]: - members = [] - for member in step["ref"]["members"]: - spec_id, version = member["spec"]["spec_id"], member["content_version"] - self.acted_on(self.call("GET", f"/datasets/{spec_id}/{version}")) - self.download() - members.append({**member, "spec_id": spec_id}) + members = [self.stored_version(member) for member in step["ref"]["members"]] return {"dataset": dataset_summary(members, [])} def _mint(self, step: dict[str, Any]) -> dict[str, Any]: - operation = self.acted_on(self.call(*_BUILD))["operation"] - self.minted = (step["spec"], operation) - return {"operation": {k: operation[k] for k in ("operation_id", "status")}} + rendering = rendering_for(step.get("layout")) + exchange = self.call(*_BUILD) + if exchange["response"]["status"] == 200: + raise _UnfitError("a mint step's build answers an operation") + resource = self.acted_on(exchange, _OPERATION) + headers = exchange["response"].get("headers", {}) + self.minted = _Minted( + resource, headers, exchange["request"], step["spec"], rendering + ) + return _operation_outcome(resource) + + def _operation(self, step: dict[str, Any]) -> dict[str, Any]: + exchange = self.call("GET", f"/datasets/operations/{step['operation_id']}") + resource = self.acted_on(exchange, _OPERATION) + headers = exchange["response"].get("headers", {}) + rendering = rendering_for(step.get("layout")) + self.minted = _Minted(resource, headers, None, None, rendering) + return _operation_outcome(resource) def _result(self, step: dict[str, Any]) -> dict[str, Any]: if self.minted is None: - raise _UnfitError("result follows no mint") - spec, operation = self.minted - member = self.member([], spec, self.wait(operation)) + raise _UnfitError("result follows no mint or operation") + minted = self.minted + manifest = self.long_build(minted.resource, minted.headers, minted.request) + member = self.member([], minted.spec, manifest, minted.rendering, False) return {"dataset": dataset_summary([member], [])} +def _operation_outcome(resource: dict[str, Any]) -> dict[str, Any]: + operation = resource["operation"] + return {"operation": {k: operation[k] for k in ("operation_id", "status")}} + + def expected_outcomes( record: dict[str, Any], *, @@ -1306,8 +1821,10 @@ def expected_outcomes( strict: dict[str, Any], actions: Mapping[str, Mapping[str, Any]], client_codes: Mapping[str, Mapping[str, Any]], + body_dir: Path, ) -> list[dict[str, Any]]: - """The outcome each of `record`'s steps reaches over its exchanges, over + """The outcome each of `record`'s steps reaches over its exchanges, its + binary bodies read from `body_dir`, over `actions` for refusals' error classes and gap kinds, and over `client_codes` for the class of each error the client raises itself. A dataset outcome holds what `dataset_summary` gives, without rows and @@ -1323,6 +1840,7 @@ def expected_outcomes( _strict_members(strict), actions, client_codes, + body_dir, ) try: outcomes = [replay.step(step) for step in record["call"]] @@ -1540,6 +2058,7 @@ def _check_scenarios( strict=strict, actions=actions, client_codes=client_codes, + body_dir=directory, ) except ValueError as exc: problems.append(f"scenarios/{file_name}: {exc}") @@ -1564,16 +2083,18 @@ def _check_client_errors( client_codes: Mapping[str, Mapping[str, Any]], ) -> list[str]: """Each error outcome no refusal in the record carries the code of names - a client code of its class. A SearchWarning carries the server's code.""" + a client code of its class. A refusal is a response of status 400 or + more, or a failed operation's error. A SearchWarning or DataWarning + carries the server's code.""" refused = { refusal_code(e["response"].get("json")) for e in record["exchanges"] if e["response"]["status"] >= 400 - } + } | {refusal_code(body.get("error")) for body in _failed_operations(record)} problems = [] for index, outcome in enumerate(record["expect"]): error = outcome.get("error") - if error is None or error["class"] == "SearchWarning": + if error is None or error["class"] in WARNING_CLASSES: continue code = error["code"] if code in refused: @@ -1599,6 +2120,16 @@ def _check_client_errors( return problems +def _failed_operations(record: dict[str, Any]) -> Iterator[dict[str, Any]]: + """Each operation resource in the record's responses whose status is + failed.""" + for exchange in record["exchanges"]: + body = exchange["response"].get("json") + operation = body.get("operation") if isinstance(body, dict) else None + if isinstance(operation, dict) and operation.get("status") == "failed": + yield body + + def _check_steps(file_name: str, record: dict[str, Any]) -> list[str]: call, expect = record["call"], record["expect"] problems = [] From a2d1a8c3bdcea6ae36fd18f90dcca7f56000de4b Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Wed, 21 Oct 2026 08:56:13 +0200 Subject: [PATCH 15/39] feat(client-contract): pin how entities become a build's scope The server's scope replaces the spec's entity binding whole, so a client starts from the spec's bound roles, replaces the roles the caller names, drops a role bound to null, and posts the whole map. The validator checks every build's input.scope against that rule, and two dev recordings rebind and drop the origin of a two-role spec. --- python/client-contract/CHANGELOG.md | 4 +- python/client-contract/README.md | 3 +- .../dfo_client_contract/scenario.schema.json | 6 +- .../scenarios/fetch-spec-entity-dropped.json | 4902 +++++++++++++++++ .../fetch-spec-entity-dropped.parquet | Bin 0 -> 13341 bytes .../scenarios/fetch-spec-entity-rebound.json | 4672 ++++++++++++++++ .../fetch-spec-entity-rebound.parquet | Bin 0 -> 9059 bytes tools/README.md | 2 +- tools/capture_client_contract.py | 56 +- tools/tests/test_validate_client_contract.py | 31 + tools/validate_client_contract.py | 60 +- 11 files changed, 9715 insertions(+), 21 deletions(-) create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.parquet create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.parquet diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index b591ff4..ca1a925 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -11,11 +11,11 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be - `strict-fields.json` and its schema: 25 members that stay required and non-nullable, and the answer kinds, part statuses and operation statuses the clients branch on. - `actions.json` and its schema: the caller's next step for each of the 101 active refusal codes on `problem_details` or `no_data_reason`, with the gap kind of each no_data reason. - The status fallback for a refusal whose code has no row: 400 and 422 to `InvalidRequestError`, 401 to `AuthenticationError`, 403 to `PermissionDeniedError`, 404 and 410 to `NotFoundError`, 408 to `DfoTimeoutError`, 429 to `RateLimitError`, and any other 4xx or 5xx to `InvalidRequestError` or `ServerError`. -- `scenario.schema.json`, the scenario record, and 54 scenarios: 19 recorded against dev at dfo-apis `8408f1f95`, `7175fe98e` and `687d48bf1`, and 35 synthetic, each derived from a recorded one by a one-line edit, with 13 binary bodies totalling 108,604 bytes. The scenarios cover the several-part choice entries, the choice refusals, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a twice cut-off build, a refused build, a digest mismatch, an identity resubmit answering another spec, and a ref whose stored file expired, rebuilt at the same version, at a newer one, or refused. Six more are defined and wait for a served document that declares the build's 202 or the file selector: `mint-async-build`, `operation-resume`, `fetch-spec-async-build`, `fetch-spec-poll-rate-limited`, `fetch-spec-operation-failed-resubmitted` and `fetch-ref-expired-file-selector`. +- `scenario.schema.json`, the scenario record, and 56 scenarios: 21 recorded against dev at dfo-apis `8408f1f95`, `7175fe98e` and `687d48bf1`, and 35 synthetic, each derived from a recorded one by a one-line edit, with 15 binary bodies totalling 131,004 bytes. The scenarios cover the several-part choice entries, the choice refusals, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a twice cut-off build, a refused build, a digest mismatch, an identity resubmit answering another spec, and a ref whose stored file expired, rebuilt at the same version, at a newer one, or refused. Six more are defined and wait for a served document that declares the build's 202 or the file selector: `mint-async-build`, `operation-resume`, `fetch-spec-async-build`, `fetch-spec-poll-rate-limited`, `fetch-spec-operation-failed-resubmitted` and `fetch-ref-expired-file-selector`. - `client-codes.json` and its schema: the 16 codes a client sets on the errors it raises itself, each with its error class and condition, disjoint from `actions.json` and `registries/codes.json`, and the `client_codes()` and `client_codes_schema()` accessors. Every scenario error the client raises itself carries its code, and `refusal_without_code` names a refusal whose body carries no code. - `dataset-ref.schema.json`, the frozen `DatasetRef` format, with accepted and rejected examples. - `tools/capture_client_contract.py`, which captures `served/openapi.json` from a dfo-apis checkout in process and records the scenarios against a base URL, dev by default, or with `record --offline` derives their outcomes again from the records with no request. A scenario that needs a route or status the served document lacks waits until the document declares it. -- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, checks `client-codes.json` against them, and checks each scenario's `expect` against the outcomes its exchanges, `actions.json` and `client-codes.json` give, each Search request against the input its steps derive, each build's options against its layout, and each download against its artifact's digest. The outcomes include each long build's operation id, poll waits and resubmissions, and a `VersionUnavailableError`'s newest version. +- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, checks `client-codes.json` against them, and checks each scenario's `expect` against the outcomes its exchanges, `actions.json` and `client-codes.json` give, each Search request against the input its steps derive, each build's `input.scope` against the narrowing its step names over the spec's bound roles, each build's options against its layout, and each download against its artifact's digest. The outcomes include each long build's operation id, poll waits and resubmissions, and a `VersionUnavailableError`'s newest version. - The client rules and their vectors: the credentials path and file format, the key lookup order, the key format check, and the cache directory and layout. [unreleased]: https://github.com/DevelopmentFinanceObservatory/spec-kit/commits/main/python diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 3c9b3a9..af4c418 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -134,7 +134,7 @@ An exchange's request names its target in one of three ways. `path` is a path th An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a warning's code, which for a `SearchWarning` may be null, or for any other error the client raises itself its code in `client-codes.json`. A `VersionUnavailableError` also gives `newest_version`, the version the lookup found, or null. A dataset or error outcome of a step that made a long build gives `long_builds`, one entry per build the server ran on, in order: the `operation_id` the client polled last, the `poll_waits` in seconds before each poll, and the number of `resubmissions`. -Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry, except on a poll, where the long-build rules count retries, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, and each Search request posts the input the rules give: the question, a choice's input, or a member's identity. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. +Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry, except on a poll, where the long-build rules count retries, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, each build posts the `scope` the rules give, and each Search request posts the input the rules give: the question, a choice's input, or a member's identity. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. A recorded scenario's request and response bodies validate against their route's schemas in `served/openapi.json`, with one allowance: a required member whose schema admits null may be absent, because the server leaves null members out of the bodies it serves. @@ -149,6 +149,7 @@ A client replays a scenario by serving the exchanges in order: The records also fix these client rules: - A fetch builds each distinct `spec_id` once, in part order, and finishes one member (build, the sentence when the client lacks it, files, download) before the next. +- A fetch or mint of a spec posts its narrowing as the build's `input.scope`, and posts no `scope` when it narrows nothing. `window` posts `{"kind": "range", "start_year", "end_year"}` for a pair of years, or `{"kind": "all"}` or `{"kind": "latest"}`, and `facets` posts each axis as `{"ref": ...}`. The server's `scope.entities` replaces the spec's whole entity binding, so `entities` posts a whole map: the roles the spec's `definition.identity.entities` binds, with each role the caller names replaced by its refs and each role the caller binds to null dropped. Naming `origin` alone on a spec bound to `origin` and `destination` keeps `destination`. A fetch that names no role posts no `entities`. - A built `spec_id` that differs from the posted one, or a spec with no sentence, takes its sentence from Search: the client posts the built definition's `identity` as one `dataset_resubmit` identity entry, with the member's first part as `variable_text`, or `"dataset"` when no answer part names it, and checks the answer's `spec_id` equals the built one. - A dataset of several members puts the `part` column first, then each member's columns in member order, each column once. The `part` value on a member's rows is the member's `parts` joined by `"; "`, so a member that answers two folded parts reads `"health ODA disbursements; education ODA disbursements"`, or the member's sentence when `parts` is empty. - A choice names its part by index, by variable text, or by a word that one gap's options mention, and its option by index or label; a candidate is named by index. A label is matched among the options that mention the word the part was named by. With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. diff --git a/python/client-contract/src/dfo_client_contract/scenario.schema.json b/python/client-contract/src/dfo_client_contract/scenario.schema.json index 3e9d9e5..c978946 100644 --- a/python/client-contract/src/dfo_client_contract/scenario.schema.json +++ b/python/client-contract/src/dfo_client_contract/scenario.schema.json @@ -188,9 +188,13 @@ "$ref": "#/$defs/window" }, "entities": { + "description": "The roles the caller rebinds. A role holds its new refs, or null to drop it; a role left out keeps the spec's binding.", "type": "object", "additionalProperties": { - "type": "array", + "type": [ + "array", + "null" + ], "minItems": 1, "items": { "type": "string", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json new file mode 100644 index 0000000..94753ef --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json @@ -0,0 +1,4902 @@ +{ + "format_version": 1, + "name": "fetch-spec-entity-dropped", + "description": "Fetching a two-role spec with entities binding origin to null posts input.scope.entities with origin dropped and destination kept, and the build answers a new spec_id bound to destination alone.", + "origin": { + "kind": "recorded", + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "687d48bf1bbeffce437765ae950a2ba755137b98", + "recorded_at": "2026-10-21T06:52:59Z" + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." + }, + "entities": { + "origin": null + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "scope": { + "entities": { + "destination": [ + "country/NGA" + ] + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_4c228c73be6c18efd0939eabb3b3c456", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + }, + "content_version": "cv_1868d697e8e7d56da6a83740a940c2e5", + "prepared_at": "2026-10-21T06:50:59Z", + "coverage": { + "rows": 309, + "dimensions": [ + { + "label": "financingProvider", + "count": 25, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 30 + } + ], + "window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1995 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1995 + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00260-6xk", + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "687d48bf1bbeffce437765ae950a2ba755137b98", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 33 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 3 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 19 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 149 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 12 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 65 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 23 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261020T170016Z-691bf0da", + "served_from": "head", + "confirmed_at": "2026-10-21T06:50:59.928161+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:da9aa46394801d54e23b886528b98b609d8fda2ed46a2eb9e365575ee73ddf3a", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 13341, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T06:50:59.873948+00:00", + "tier": "working", + "url": "/api/datasets/spec_4c228c73be6c18efd0939eabb3b3c456/cv_1868d697e8e7d56da6a83740a940c2e5/files/sha256:da9aa46394801d54e23b886528b98b609d8fda2ed46a2eb9e365575ee73ddf3a" + }, + { + "artifact_digest": "sha256:ffd0e9eaabfc35d3113188c82648ce0bf809307a01a024b52b0baa133ef63d18", + "rendering": { + "statistics": "series" + }, + "bytes": 9074, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T06:50:59.873948+00:00", + "tier": "working", + "url": "/api/datasets/spec_4c228c73be6c18efd0939eabb3b3c456/cv_1868d697e8e7d56da6a83740a940c2e5/files/sha256:ffd0e9eaabfc35d3113188c82648ce0bf809307a01a024b52b0baa133ef63d18" + } + ], + "series_count": 58, + "output_options": { + "capability_version": "dset_1e6cd9546fac19e9", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 10 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 25 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 30 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 25, + "covered": 18 + }, + "missing": [ + { + "ref": "EuropeanUnionInstitutions", + "label": "European Union institutions" + }, + { + "ref": "Gavi", + "label": "Gavi, the Vaccine Alliance" + }, + { + "ref": "GlobalFund", + "label": "Global Fund" + }, + { + "ref": "InternationalDevelopmentAssociation", + "label": "International Development Association" + }, + { + "ref": "UnitedNationsChildrensFund", + "label": "United Nations Children's Fund" + }, + { + "ref": "UnitedNationsDevelopmentProgramme", + "label": "United Nations Development Programme" + }, + { + "ref": "WorldHealthOrganization", + "label": "World Health Organization" + } + ], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 25, + "covered": 18 + }, + "missing": [ + { + "ref": "EuropeanUnionInstitutions", + "label": "European Union institutions" + }, + { + "ref": "Gavi", + "label": "Gavi, the Vaccine Alliance" + }, + { + "ref": "GlobalFund", + "label": "Global Fund" + }, + { + "ref": "InternationalDevelopmentAssociation", + "label": "International Development Association" + }, + { + "ref": "UnitedNationsChildrensFund", + "label": "United Nations Children's Fund" + }, + { + "ref": "UnitedNationsDevelopmentProgramme", + "label": "United Nations Development Programme" + }, + { + "ref": "WorldHealthOrganization", + "label": "World Health Organization" + } + ], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 25, + "covered": 25 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 25, + "covered": 25 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 25, + "covered": 25 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "stat_var", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 30 + } + ] + }, + { + "index": "stat_var", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 25 + } + ] + }, + { + "index": "financingProvider", + "columns": "stat_var", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 30 + } + ] + }, + { + "index": "financingProvider", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "stat_var", + "distinct": 10 + } + ] + }, + { + "index": "time_period", + "columns": "stat_var", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 25 + } + ] + }, + { + "index": "time_period", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "stat_var", + "distinct": 10 + } + ] + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "dataset_resubmit", + "entries": [ + { + "entry_kind": "identity", + "variable_text": "dataset", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + } + ] + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "dataset_resubmit", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "687d48bf1bbeffce437765ae950a2ba755137b98", + "trace_id": "7d611a2ae07b416194eac78b2d77f22b", + "warnings": [], + "timing_ms": { + "total": 505, + "by_step": { + "coverage": 0 + } + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "dataset", + "warnings": [ + { + "code": "role_scope_defaulted", + "severity": "warn", + "message": "no provider was named; the answer was resolved across every provider with data." + } + ], + "timing_ms": { + "total": 339, + "by_step": { + "validate": 4, + "walk": 222, + "reread_arcs": 1, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 4, + "bind": 1, + "where_places": 1, + "materialise": 57, + "answer": 21, + "options": 28 + } + }, + "operations": [], + "departures": [], + "status": "definite", + "spec": { + "spec_id": "spec_4c228c73be6c18efd0939eabb3b3c456", + "definition": { + "schema_version": 1, + "spec_id": "spec_4c228c73be6c18efd0939eabb3b3c456", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal", + "label": "gross disbursements (basic health care, official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 21, + "member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 10, + "member_count_exact": true, + "served_count": 21, + "data_date_range": { + "start": "1995", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "destination" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 309, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 23 + }, + { + "label": "variables", + "count": 10 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 20, + "series": 20, + "role_counts": { + "financingProvider": 16, + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2024, + "observations": 20, + "series": 20, + "role_counts": { + "financingProvider": 16, + "financingRecipient": 1 + } + }, + { + "year": 2023, + "observations": 18, + "series": 18, + "role_counts": { + "financingProvider": 16, + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 17, + "series": 17, + "role_counts": { + "financingProvider": 15, + "financingRecipient": 1 + } + } + ] + }, + "download": { + "rows": 309, + "rows_exact": true, + "series": 58, + "window": { + "start_year": 1995, + "end_year": 2024 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 56, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1606, + "served_rows": 22, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 33, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB04", + "label": "basket fund and pooled funding" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 709, + "served_rows": 1, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 172, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 172, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 14, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 1600, + "served_rows": 12, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 976, + "served_rows": 2, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE", + "label": "scholarship and student cost in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 2, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 819, + "served_rows": 2, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 1321, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 286, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 286, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance420", + "label": "debt instrument" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 23, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance421", + "label": "standard loan" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance420", + "member_count": 4620, + "served_rows": 23, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 309, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow21", + "label": "non-export credit official flow" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 3798, + "served_rows": 12, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow30", + "label": "private development finance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 2711, + "served_rows": 42, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [ + { + "role": "origin", + "options": [], + "truncated": true, + "source": "observed" + } + ], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Gross ODA disbursements to Nigeria from 25 providers for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Nigeria", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/NGA" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " from ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "25 providers", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "basic health care", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1995 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/NGA", + "label": "Nigeria" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/NGA", + "label": "Nigeria" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_3f35867df5a65761" + }, + "confidence": "high", + "available_at_place": true, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_b7f316e86e3564e5bd58d7dbf04e411a", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 310, + "served_rows_exact": true + }, + { + "definition": { + "schema_version": 1, + "spec_id": "spec_4344b54b17658b054f6af7db6eeabb46", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialObligation", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialObligationType", + "binding": { + "state": "value", + "ref": "Commitment" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "commitments", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialObligation", + "label": "financial obligation" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialObligationType", + "value": { + "ref": "Commitment", + "label": "commitment" + } + } + ], + "served_rows": 284, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "open_axis_facts": [ + { + "property": "crsCooperationModality", + "varies": true, + "distinct_count": 14, + "undeclared_count": 2, + "values": [ + { + "value": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "count": 5 + }, + { + "value": { + "ref": "CRSCooperationModalityA02", + "label": "sector budget support" + }, + "count": 2 + }, + { + "value": { + "ref": "CRSCooperationModalityB04", + "label": "basket fund and pooled funding" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB031", + "label": "contribution to multi-donor and multi-entity funding mechanism" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB032", + "label": "contribution to multi-donor and single-entity funding mechanism" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB033", + "label": "contribution to single-donor funding mechanism or earmarked contribution to a specific funding window or geographical location" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityA01", + "label": "general budget support" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityG01", + "label": "other administrative cost" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "count": 1 + } + ] + }, + { + "property": "crsTypeOfFinance", + "varies": true, + "distinct_count": 5, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "count": 14 + }, + { + "value": { + "ref": "CRSTypeOfFinance421", + "label": "standard loan" + }, + "count": 4 + }, + { + "value": { + "ref": "CRSTypeOfFinance510", + "label": "common equity" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSTypeOfFinance210", + "label": "interest subsidy" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSTypeOfFinance520", + "label": "share in collective investment vehicle" + }, + "count": 1 + } + ] + } + ], + "role_axis_facts": [ + { + "role": "origin", + "member_count": 25, + "members_available": true + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1995, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 2023, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1995, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "NGN" + } + } + } + } + } + ], + "rendered_sentence": "Gross ODA disbursements to Nigeria from 25 providers for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Nigeria", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/NGA" + ], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " from ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "25 providers", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [], + "states": [ + "origin:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "basic health care", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1995 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "status": "definite" + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_4c228c73be6c18efd0939eabb3b3c456/cv_1868d697e8e7d56da6a83740a940c2e5/files/sha256:da9aa46394801d54e23b886528b98b609d8fda2ed46a2eb9e365575ee73ddf3a" + }, + "response": { + "status": 302, + "headers": { + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ada9aa46394801d54e23b886528b98b609d8fda2ed46a2eb9e365575ee73ddf3a?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ada9aa46394801d54e23b886528b98b609d8fda2ed46a2eb9e365575ee73ddf3a?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "fetch-spec-entity-dropped.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 309, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "crsCooperationModality", + "crsCooperationModality_label", + "crsPurpose", + "crsPurpose_label", + "crsTypeOfFinance", + "crsTypeOfFinance_label", + "crsTypeOfFlow", + "crsTypeOfFlow_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_4c228c73be6c18efd0939eabb3b3c456", + "content_version": "cv_1868d697e8e7d56da6a83740a940c2e5", + "sentence": "Gross ODA disbursements to Nigeria from 25 providers for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." + } + ], + "missing": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.parquet b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.parquet new file mode 100644 index 0000000000000000000000000000000000000000..bc5adcd90c1f0974ebf0182a188d2b156a1bdf57 GIT binary patch literal 13341 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 literal 0 HcmV?d00001 diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json new file mode 100644 index 0000000..133d325 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json @@ -0,0 +1,4672 @@ +{ + "format_version": 1, + "name": "fetch-spec-entity-rebound", + "description": "Fetching a two-role spec with entities naming only origin posts input.scope.entities with origin replaced and destination kept from the spec's definition, because the server's scope.entities replaces the spec's whole entity binding. The build answers a new spec_id bound to both roles.", + "origin": { + "kind": "recorded", + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "687d48bf1bbeffce437765ae950a2ba755137b98", + "recorded_at": "2026-10-21T06:52:57Z" + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." + }, + "entities": { + "origin": [ + "country/FRA" + ] + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "scope": { + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/FRA" + ] + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_1ee5f6648c9e46ddcc806fa0034bb6a8", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/FRA" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + }, + "content_version": "cv_7947f7ed828c0b23b8df4c601d463c09", + "prepared_at": "2026-10-21T06:50:58Z", + "coverage": { + "rows": 2, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 2 + } + ], + "window": { + "kind": "all", + "origin": "default", + "end_year": 2021, + "start_year": 2019 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "all", + "origin": "default", + "end_year": 2021, + "start_year": 2019 + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00260-6xk", + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "687d48bf1bbeffce437765ae950a2ba755137b98", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261020T170016Z-691bf0da", + "served_from": "head", + "confirmed_at": "2026-10-21T06:50:59.135638+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:3f42e71fd7f6c7dde3c7294e7eb1eb6525ab0748650d41948ba054114025b297", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9059, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T06:50:59.083645+00:00", + "tier": "working", + "url": "/api/datasets/spec_1ee5f6648c9e46ddcc806fa0034bb6a8/cv_7947f7ed828c0b23b8df4c601d463c09/files/sha256:3f42e71fd7f6c7dde3c7294e7eb1eb6525ab0748650d41948ba054114025b297" + }, + { + "artifact_digest": "sha256:36616ef68df33904cc9dfa37fb145d8fd1563b1b3701710dcd8d9e04ed50d79a", + "rendering": { + "statistics": "series" + }, + "bytes": 5628, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T06:50:59.083645+00:00", + "tier": "working", + "url": "/api/datasets/spec_1ee5f6648c9e46ddcc806fa0034bb6a8/cv_7947f7ed828c0b23b8df4c601d463c09/files/sha256:36616ef68df33904cc9dfa37fb145d8fd1563b1b3701710dcd8d9e04ed50d79a" + } + ], + "series_count": 2, + "output_options": { + "capability_version": "dset_1e6cd9546fac19e9", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 2 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 2 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "stat_var", + "columns": "time_period", + "state": "available", + "width": 3, + "cells": 6 + }, + { + "index": "time_period", + "columns": "stat_var", + "state": "available", + "width": 3, + "cells": 6 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "dataset_resubmit", + "entries": [ + { + "entry_kind": "identity", + "variable_text": "dataset", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/FRA" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + } + ] + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "dataset_resubmit", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "687d48bf1bbeffce437765ae950a2ba755137b98", + "trace_id": "a4fd321a6db64e49b724fb75dac0193b", + "warnings": [], + "timing_ms": { + "total": 398, + "by_step": { + "coverage": 0 + } + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "dataset", + "warnings": [], + "timing_ms": { + "total": 293, + "by_step": { + "validate": 5, + "walk": 242, + "reread_arcs": 1, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 3, + "bind": 1, + "where_places": 0, + "materialise": 16, + "answer": 21, + "options": 4 + } + }, + "operations": [], + "departures": [], + "status": "definite", + "spec": { + "spec_id": "spec_1ee5f6648c9e46ddcc806fa0034bb6a8", + "definition": { + "schema_version": 1, + "spec_id": "spec_1ee5f6648c9e46ddcc806fa0034bb6a8", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/FRA" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal", + "label": "gross disbursements (basic health care, official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 21, + "member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 2, + "member_count_exact": true, + "served_count": 21, + "data_date_range": { + "start": "2019", + "end": "2021" + } + }, + "entities": [ + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/FRA", + "label": "France", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 2, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 1 + }, + { + "label": "variables", + "count": 2 + } + ] + }, + "headline": { + "year": 2021, + "year_named": false, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2021, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2020, + "observations": 0, + "series": 0, + "role_counts": {} + }, + { + "year": 2019, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + } + ] + }, + "download": { + "rows": 2, + "rows_exact": true, + "series": 2, + "window": { + "start_year": 2019, + "end_year": 2021 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 1, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 1, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 1, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 976, + "served_rows": 1, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 14, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 2, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 2, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 2, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow21", + "label": "non-export credit official flow" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 3798, + "served_rows": 1, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "France's gross ODA disbursements to Nigeria for basic health care, 2019 to 2021. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "France", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/FRA" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Nigeria", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/NGA" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "basic health care", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2019 to 2021", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/FRA", + "label": "France" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/NGA", + "label": "Nigeria" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_3f35867df5a65761" + }, + "confidence": "high", + "available_at_place": true, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_f7d465ce303ba2d1d4b15ebf98faa7a7", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/FRA" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 2, + "served_rows_exact": true + }, + { + "definition": { + "schema_version": 1, + "spec_id": "spec_d93d68e62c537fb8b05cc0add6ce5f9d", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialObligation", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialObligationType", + "binding": { + "state": "value", + "ref": "Commitment" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/FRA" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "commitments", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialObligation", + "label": "financial obligation" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialObligationType", + "value": { + "ref": "Commitment", + "label": "commitment" + } + } + ], + "served_rows": 2, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "open_axis_facts": [ + { + "property": "crsCooperationModality", + "varies": true, + "distinct_count": 14, + "undeclared_count": 2, + "values": [ + { + "value": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "count": 5 + }, + { + "value": { + "ref": "CRSCooperationModalityA02", + "label": "sector budget support" + }, + "count": 2 + }, + { + "value": { + "ref": "CRSCooperationModalityB04", + "label": "basket fund and pooled funding" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB031", + "label": "contribution to multi-donor and multi-entity funding mechanism" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB032", + "label": "contribution to multi-donor and single-entity funding mechanism" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB033", + "label": "contribution to single-donor funding mechanism or earmarked contribution to a specific funding window or geographical location" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityA01", + "label": "general budget support" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityG01", + "label": "other administrative cost" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "count": 1 + } + ] + }, + { + "property": "crsTypeOfFinance", + "varies": true, + "distinct_count": 5, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "count": 14 + }, + { + "value": { + "ref": "CRSTypeOfFinance421", + "label": "standard loan" + }, + "count": 4 + }, + { + "value": { + "ref": "CRSTypeOfFinance510", + "label": "common equity" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSTypeOfFinance210", + "label": "interest subsidy" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSTypeOfFinance520", + "label": "share in collective investment vehicle" + }, + "count": 1 + } + ] + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2019, + "end_year": 2019 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 2019, + "end_year": 2019 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 2020, + "end_year": 2020 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2019, + "end_year": 2020 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2010, + "current_years": null + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 2019, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2019, + "end_year": 2021 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "NGN", + "origin": "EUR" + } + } + } + } + } + ], + "rendered_sentence": "France's gross ODA disbursements to Nigeria for basic health care, 2019 to 2021. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "France", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/FRA" + ], + "states": [ + "origin:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Nigeria", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/NGA" + ], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "basic health care", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2019 to 2021", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "status": "definite" + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_1ee5f6648c9e46ddcc806fa0034bb6a8/cv_7947f7ed828c0b23b8df4c601d463c09/files/sha256:3f42e71fd7f6c7dde3c7294e7eb1eb6525ab0748650d41948ba054114025b297" + }, + "response": { + "status": 302, + "headers": { + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A3f42e71fd7f6c7dde3c7294e7eb1eb6525ab0748650d41948ba054114025b297?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A3f42e71fd7f6c7dde3c7294e7eb1eb6525ab0748650d41948ba054114025b297?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "fetch-spec-entity-rebound.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 2, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "crsCooperationModality", + "crsCooperationModality_label", + "crsPurpose", + "crsPurpose_label", + "crsTypeOfFinance", + "crsTypeOfFinance_label", + "crsTypeOfFlow", + "crsTypeOfFlow_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_1ee5f6648c9e46ddcc806fa0034bb6a8", + "content_version": "cv_7947f7ed828c0b23b8df4c601d463c09", + "sentence": "France's gross ODA disbursements to Nigeria for basic health care, 2019 to 2021. Current US dollars · OECD Creditor Reporting System (CRS)." + } + ], + "missing": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.parquet b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.parquet new file mode 100644 index 0000000000000000000000000000000000000000..bd415ce58a6b791fce03022f96894472feb55e0c GIT binary patch literal 9059 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 ZLYG4DOC$V@{x$yNeg=Q(PQm|P^B>NkY*YXM literal 0 HcmV?d00001 diff --git a/tools/README.md b/tools/README.md index 23fea7d..7362495 100644 --- a/tools/README.md +++ b/tools/README.md @@ -38,7 +38,7 @@ uv run tools/validate_provenance_docs_vectors.py uv run tools/validate_descriptions_vectors.py ``` -`validate_client_contract.py` validates the client contract under `python/client-contract/src/dfo_client_contract/` against its schemas, then checks what they cannot express: every `strict-fields.json` pointer resolves in `served/openapi.json` and stays required and non-nullable, or keeps its enum values; `actions.json` holds one row, in code order, for each active refusal code in `registries/codes.json` that reaches a problem document or a no_data reason, with a gap kind exactly for the no_data reasons; `client-codes.json` lists each code a client raises itself once, in code order, none of them a code in `actions.json` or the registry, each with a class a scenario names; each recorded scenario's requests match a served route and its JSON bodies validate against that route's schemas, a required member that admits null allowed to be absent; each scenario's `expect` equals the outcomes its steps reach over its exchanges, with refusals' error classes and gap kinds from `actions.json` and each error the client raises itself carrying its code and class from `client-codes.json`, and each Search request posts the input its steps derive; every absolute URL a record holds has the redacted query; and each `DatasetRef` example gets the verdict it states. It does not import `dfo_client_contract`, whose `tests/test_rules.py` replays the rule vectors. Also a PEP 723 script: +`validate_client_contract.py` validates the client contract under `python/client-contract/src/dfo_client_contract/` against its schemas, then checks what they cannot express: every `strict-fields.json` pointer resolves in `served/openapi.json` and stays required and non-nullable, or keeps its enum values; `actions.json` holds one row, in code order, for each active refusal code in `registries/codes.json` that reaches a problem document or a no_data reason, with a gap kind exactly for the no_data reasons; `client-codes.json` lists each code a client raises itself once, in code order, none of them a code in `actions.json` or the registry, each with a class a scenario names; each recorded scenario's requests match a served route and its JSON bodies validate against that route's schemas, a required member that admits null allowed to be absent; each scenario's `expect` equals the outcomes its steps reach over its exchanges, with refusals' error classes and gap kinds from `actions.json` and each error the client raises itself carrying its code and class from `client-codes.json`, each build posts the `input.scope` its step's narrowing derives over the spec's bound roles, and each Search request posts the input its steps derive; every absolute URL a record holds has the redacted query; and each `DatasetRef` example gets the verdict it states. It does not import `dfo_client_contract`, whose `tests/test_rules.py` replays the rule vectors. Also a PEP 723 script: ```bash uv run tools/validate_client_contract.py diff --git a/tools/capture_client_contract.py b/tools/capture_client_contract.py index 08a811c..8c4e499 100644 --- a/tools/capture_client_contract.py +++ b/tools/capture_client_contract.py @@ -91,6 +91,7 @@ owns_body_file, part_label, pick_artifact, + posted_scope, refusal_error, rendering_for, resubmitted_sentence, @@ -668,23 +669,30 @@ def fetch_spec( spec: Spec, *, window: str | tuple[int, int] | None = None, + entities: Mapping[str, Sequence[str] | None] | None = None, facets: Mapping[str, str] | None = None, layout: str | None = None, strict: bool = False, ) -> list[Member]: + """Builds `spec` narrowed by `window`, `entities` and `facets`. A + role in `entities` replaces the spec's binding of it, or drops it + when null.""" step: dict[str, Any] = {"op": "fetch", "spec": spec.step()} - scope: dict[str, Any] = {} if window is not None: step["window"] = list(window) if isinstance(window, tuple) else window - scope["window"] = _window(window) + if entities is not None: + step["entities"] = { + role: None if refs is None else list(refs) + for role, refs in entities.items() + } if facets is not None: step["facets"] = dict(facets) - scope["facets"] = {name: {"ref": ref} for name, ref in facets.items()} + scope = posted_scope(step) built: list[Member] = [] def run() -> dict[str, Any]: rendering = rendering_for(layout) - built.append(self.build([], spec, scope or None, rendering, strict=strict)) + built.append(self.build([], spec, scope, rendering, strict=strict)) return dataset_outcome(built) self._step(_step_options(step, layout=layout, strict=strict), run) @@ -972,12 +980,6 @@ def _operation_outcome(resource: dict[str, Any]) -> dict[str, Any]: return {"operation": {k: operation[k] for k in ("operation_id", "status")}} -def _window(window: str | tuple[int, int]) -> dict[str, Any]: - if isinstance(window, tuple): - return {"kind": "range", "start_year": window[0], "end_year": window[1]} - return {"kind": window} - - def _build_body( spec: Spec, scope: dict[str, Any] | None, rendering: Mapping[str, Any] ) -> dict[str, Any]: @@ -1040,6 +1042,7 @@ def with_place_options(body: Any) -> Any: GROUP_DEFINITE = "GDP of the least developed countries" ASYNC = "ODA received by every recipient country from every provider (DAC2a) from 2018 to 2024" NARROW_WINDOW = (2020, 2023) +REBOUND_ORIGIN = "country/FRA" SYNC_ROWS = 100_000 @@ -1197,6 +1200,23 @@ def _fetch_spec_narrowed(s: Session, ctx: Context) -> None: require("2020 to 2023" in member.sentence, "the sentence names the window") +def _fetch_spec_entities( + rebinds: Mapping[str, list[str] | None], +) -> Callable[[Session, Context], None]: + """Fetches the definite spec with `rebinds` as `entities`, and checks the + build binds the entities the client posts.""" + + def run(s: Session, ctx: Context) -> None: + spec = ctx.definite_spec(DEFINITE) + (member,) = s.fetch_spec(spec, entities=rebinds) + posted = s.recorder.exchanges[0]["request"]["json"]["input"]["scope"] + bound = member.definition["identity"]["entities"] + require(member.spec_id != spec.spec_id, "the entities give a new spec_id") + require(bound == posted["entities"], "the build binds the posted entities") + + return run + + def _fetch_spec_known_sentence(s: Session, ctx: Context) -> None: spec = ctx.narrowed_spec() (member,) = s.fetch_spec(spec) @@ -1364,6 +1384,21 @@ def _resubmit_placeholder(s: Session, ctx: Context) -> None: "answer's spec_id equals the built one, then downloads the file.", _fetch_spec_narrowed, ), + Recorded( + "fetch-spec-entity-rebound", + "Fetching a two-role spec with entities naming only origin posts input.scope.entities " + "with origin replaced and destination kept from the spec's definition, because the " + "server's scope.entities replaces the spec's whole entity binding. The build answers a " + "new spec_id bound to both roles.", + _fetch_spec_entities({"origin": [REBOUND_ORIGIN]}), + ), + Recorded( + "fetch-spec-entity-dropped", + "Fetching a two-role spec with entities binding origin to null posts " + "input.scope.entities with origin dropped and destination kept, and the build answers " + "a new spec_id bound to destination alone.", + _fetch_spec_entities({"origin": None}), + ), Recorded( "fetch-spec-known-sentence", "Fetching a spec whose sentence the client holds builds bare Parquet, follows the files " @@ -2580,6 +2615,7 @@ def drive(session: Session, call: Sequence[dict[str, Any]]) -> None: session.fetch_spec( Spec(spec["spec_id"], spec["definition"], spec.get("sentence")), window=tuple(window) if isinstance(window, list) else window, + entities=step.get("entities"), facets=step.get("facets"), layout=step.get("layout"), strict=step.get("strict", False), diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index 353b9fb..9a94c0a 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -42,6 +42,8 @@ _REQUEST_INVALID = "scenarios/fetch-spec-request-invalid.json" _UNKNOWN_VERSION = "scenarios/fetch-ref-unknown-version.json" _NEWER = "scenarios/fetch-ref-expired-newer-version.json" +_REBOUND = "scenarios/fetch-spec-entity-rebound.json" +_DROPPED = "scenarios/fetch-spec-entity-dropped.json" def _posted(index: int, change: Callable[[Any], None]) -> Callable[[Any], None]: @@ -168,6 +170,13 @@ def _resubmit_answers_built(doc: Any) -> None: doc["exchanges"][1]["response"]["json"]["parts"][0]["spec"]["spec_id"] = built +def _posted_entities(change: Callable[[Any], None]) -> Callable[[Any], None]: + """Changes the entities the record's build posts.""" + return lambda doc: change( + doc["exchanges"][0]["request"]["json"]["input"]["scope"]["entities"] + ) + + def _last_response(change: Callable[[Any], None]) -> Callable[[Any], None]: return lambda doc: change(doc["exchanges"][-1]["response"]) @@ -441,6 +450,24 @@ def _last_response(change: Callable[[Any], None]) -> Callable[[Any], None]: ].update(variable_text="ODA"), "where the rules post", ), + ( + _REBOUND, + _posted_entities(lambda entities: entities.pop("destination")), + "where the rules post", + ), + ( + _DROPPED, + _posted_entities(lambda entities: entities.update(origin=["country/DEU"])), + "where the rules post", + ), + ( + _REBOUND, + _posted_entities( + lambda entities: entities.update(origin=["country/DEU", "country/FRA"]) + ), + "where the rules post", + ), + (_REBOUND, _set_step(0, entities={}), "where the rules post"), ( _FETCH, lambda doc: doc["call"].append({"op": "fetch"}), @@ -716,6 +743,10 @@ def _last_response(change: Callable[[Any], None]) -> Callable[[Any], None]: "definite-part-posted-parsed", "restated-part-posted-placeholder", "identity-resubmit-wrong-variable-text", + "unnamed-role-dropped", + "null-role-kept", + "named-role-merged", + "no-role-named-posts-entities", "answer-fetch-after-spec-fetch", "exchange-never-made", "exchanges-unfit", diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index 2d1173a..2e4e6c2 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -1200,6 +1200,33 @@ def rendering_for(layout: str | None) -> dict[str, Any]: return dict(LAYOUT_RENDERINGS[layout or "long"]) +def posted_scope(step: Mapping[str, Any]) -> dict[str, Any] | None: + """The `input.scope` a fetch or mint of a spec posts for the step's + narrowing, or None when it narrows nothing. The server's + `scope.entities` replaces the spec's whole entity binding, so the + client posts the spec's bound roles with each role the step names + replaced, and a role named with null dropped. A step that names no + role posts no `entities`.""" + scope: dict[str, Any] = {} + window = step.get("window") + if isinstance(window, list): + start, end = window + scope["window"] = {"kind": "range", "start_year": start, "end_year": end} + elif window is not None: + scope["window"] = {"kind": window} + if named := step.get("entities"): + bound = dict(step["spec"]["definition"]["identity"].get("entities", {})) + for role, refs in named.items(): + if refs is None: + bound.pop(role, None) + else: + bound[role] = list(refs) + scope["entities"] = bound + if (facets := step.get("facets")) is not None: + scope["facets"] = {name: {"ref": ref} for name, ref in facets.items()} + return scope or None + + def pick_artifact( manifest: Mapping[str, Any], rendering: Mapping[str, Any] ) -> dict[str, Any] | None: @@ -1490,16 +1517,35 @@ def resolve(self, posts: dict[str, Any]) -> Answer: # -- builds -- - def build(self, rendering: dict[str, Any]) -> dict[str, Any]: - """A build of the latest version, posting `rendering` as its options: - the manifest it answers, through a long build when it answers 202.""" + def posted_build( + self, rendering: dict[str, Any], scope: dict[str, Any] | None + ) -> dict[str, Any]: + """A build request whose recorded body, when it has one, posts + `rendering` as its options and `scope` as its input's scope.""" exchange = self.call(*_BUILD) sent = exchange["request"].get("json") - if sent is not None and sent.get("options") != rendering: + if sent is None: + return exchange + if sent.get("options") != rendering: raise _UnfitError( f"exchange {self.cursor - 1} posts options {sent.get('options')}, " f"where the rules post {rendering}" ) + if "input" in sent and sent["input"].get("scope") != scope: + raise _UnfitError( + f"exchange {self.cursor - 1} posts scope " + f"{json.dumps(sent['input'].get('scope'))}, where the rules post " + f"{json.dumps(scope)}" + ) + return exchange + + def build( + self, rendering: dict[str, Any], scope: dict[str, Any] | None = None + ) -> dict[str, Any]: + """A build of the latest version, posting `rendering` as its options + and `scope` as its input's scope: the manifest it answers, through a + long build when it answers 202.""" + exchange = self.posted_build(rendering, scope) if exchange["response"]["status"] != 202: return self.acted_on(exchange) resource = self.acted_on(exchange, _OPERATION) @@ -1772,7 +1818,9 @@ def _fetch(self, step: dict[str, Any]) -> dict[str, Any]: def _fetch_spec(self, step: dict[str, Any]) -> dict[str, Any]: rendering = rendering_for(step.get("layout")) - member = self.fetched([], step["spec"], rendering, step.get("strict", False)) + manifest = self.build(rendering, posted_scope(step)) + strict = step.get("strict", False) + member = self.member([], step["spec"], manifest, rendering, strict) return {"dataset": dataset_summary([member], [])} def _fetch_ref(self, step: dict[str, Any]) -> dict[str, Any]: @@ -1781,7 +1829,7 @@ def _fetch_ref(self, step: dict[str, Any]) -> dict[str, Any]: def _mint(self, step: dict[str, Any]) -> dict[str, Any]: rendering = rendering_for(step.get("layout")) - exchange = self.call(*_BUILD) + exchange = self.posted_build(rendering, posted_scope(step)) if exchange["response"]["status"] == 200: raise _UnfitError("a mint step's build answers an operation") resource = self.acted_on(exchange, _OPERATION) From 4dd8a12c59a2110fbeea125583b151afd4d0cfaa Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Wed, 21 Oct 2026 09:14:56 +0200 Subject: [PATCH 16/39] feat(client-contract): pin which groups a built identity keeps The identity entry a client posts to name a built spec carries the spec's entity_groups for each role the build binds to the same entities as the spec's definition. A window or facets narrowing keeps every group, and a role the narrowing rebound or dropped loses its group, so the sentence names "the 44 Least Developed Countries" where the group still holds and lists recipients where it does not. validate_client_contract.py derives the kept groups from the held spec and checks every posted identity entry against them. Two new recordings cover a narrowed build and a rebound origin, bringing the contract to 58 scenarios. --- python/client-contract/CHANGELOG.md | 4 +- python/client-contract/README.md | 4 +- .../dfo_client_contract/scenario.schema.json | 10 +- .../scenarios/fetch-spec-group-narrowed.json | 5314 +++++++++++++++++ .../fetch-spec-group-narrowed.parquet | Bin 0 -> 8716 bytes .../fetch-spec-group-origin-rebound.json | 5313 ++++++++++++++++ .../fetch-spec-group-origin-rebound.parquet | Bin 0 -> 21027 bytes tools/capture_client_contract.py | 77 +- tools/tests/test_validate_client_contract.py | 19 + tools/validate_client_contract.py | 79 +- 10 files changed, 10789 insertions(+), 31 deletions(-) create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.parquet create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.parquet diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index ca1a925..b85256a 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -11,11 +11,11 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be - `strict-fields.json` and its schema: 25 members that stay required and non-nullable, and the answer kinds, part statuses and operation statuses the clients branch on. - `actions.json` and its schema: the caller's next step for each of the 101 active refusal codes on `problem_details` or `no_data_reason`, with the gap kind of each no_data reason. - The status fallback for a refusal whose code has no row: 400 and 422 to `InvalidRequestError`, 401 to `AuthenticationError`, 403 to `PermissionDeniedError`, 404 and 410 to `NotFoundError`, 408 to `DfoTimeoutError`, 429 to `RateLimitError`, and any other 4xx or 5xx to `InvalidRequestError` or `ServerError`. -- `scenario.schema.json`, the scenario record, and 56 scenarios: 21 recorded against dev at dfo-apis `8408f1f95`, `7175fe98e` and `687d48bf1`, and 35 synthetic, each derived from a recorded one by a one-line edit, with 15 binary bodies totalling 131,004 bytes. The scenarios cover the several-part choice entries, the choice refusals, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a twice cut-off build, a refused build, a digest mismatch, an identity resubmit answering another spec, and a ref whose stored file expired, rebuilt at the same version, at a newer one, or refused. Six more are defined and wait for a served document that declares the build's 202 or the file selector: `mint-async-build`, `operation-resume`, `fetch-spec-async-build`, `fetch-spec-poll-rate-limited`, `fetch-spec-operation-failed-resubmitted` and `fetch-ref-expired-file-selector`. +- `scenario.schema.json`, the scenario record, and 58 scenarios: 23 recorded against dev at dfo-apis `8408f1f95`, `7175fe98e`, `687d48bf1` and `36b9f48d8`, and 35 synthetic, each derived from a recorded one by a one-line edit, with 17 binary bodies totalling 160,747 bytes. The scenarios cover the several-part choice entries, the choice refusals, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a refused build, a digest mismatch, an identity resubmit answering another spec, and a ref whose stored file expired, rebuilt at the same version, at a newer one, or refused. Six more are defined and wait for a served document that declares the build's 202 or the file selector: `mint-async-build`, `operation-resume`, `fetch-spec-async-build`, `fetch-spec-poll-rate-limited`, `fetch-spec-operation-failed-resubmitted` and `fetch-ref-expired-file-selector`. - `client-codes.json` and its schema: the 16 codes a client sets on the errors it raises itself, each with its error class and condition, disjoint from `actions.json` and `registries/codes.json`, and the `client_codes()` and `client_codes_schema()` accessors. Every scenario error the client raises itself carries its code, and `refusal_without_code` names a refusal whose body carries no code. - `dataset-ref.schema.json`, the frozen `DatasetRef` format, with accepted and rejected examples. - `tools/capture_client_contract.py`, which captures `served/openapi.json` from a dfo-apis checkout in process and records the scenarios against a base URL, dev by default, or with `record --offline` derives their outcomes again from the records with no request. A scenario that needs a route or status the served document lacks waits until the document declares it. -- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, checks `client-codes.json` against them, and checks each scenario's `expect` against the outcomes its exchanges, `actions.json` and `client-codes.json` give, each Search request against the input its steps derive, each build's `input.scope` against the narrowing its step names over the spec's bound roles, each build's options against its layout, and each download against its artifact's digest. The outcomes include each long build's operation id, poll waits and resubmissions, and a `VersionUnavailableError`'s newest version. +- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, checks `client-codes.json` against them, and checks each scenario's `expect` against the outcomes its exchanges, `actions.json` and `client-codes.json` give, each Search request against the input its steps derive, a sentence lookup's `entity_groups` included, each build's `input.scope` against the narrowing its step names over the spec's bound roles, each build's options against its layout, and each download against its artifact's digest. The outcomes include each long build's operation id, poll waits and resubmissions, and a `VersionUnavailableError`'s newest version. - The client rules and their vectors: the credentials path and file format, the key lookup order, the key format check, and the cache directory and layout. [unreleased]: https://github.com/DevelopmentFinanceObservatory/spec-kit/commits/main/python diff --git a/python/client-contract/README.md b/python/client-contract/README.md index af4c418..3fa45ec 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -128,7 +128,7 @@ A scenario is one client-level call, the HTTP exchanges it makes, and the outcom | `exchanges` | The requests the call makes, in order, each with the response to give | | `expect` | One outcome per step: an `answer`, a `dataset`, an `operation` or an `error` | -A step that acts on an earlier result follows one: `choose` follows `search` or `choose`, a `fetch` with no target follows `search`, `choose` or another `fetch` with no target and acts on the last answer, and `result` follows `mint` or `operation`. A `fetch` of an answer or a spec, `mint` and `operation` take a `layout`, `long` by default or `frame`, and a `fetch` of an answer or a spec takes `strict`. A `spec` in a step holds `spec_id`, the server's unmodified `definition`, and the `sentence` when the client knows it. +A step that acts on an earlier result follows one: `choose` follows `search` or `choose`, a `fetch` with no target follows `search`, `choose` or another `fetch` with no target and acts on the last answer, and `result` follows `mint` or `operation`. A `fetch` of an answer or a spec, `mint` and `operation` take a `layout`, `long` by default or `frame`, and a `fetch` of an answer or a spec takes `strict`. A `spec` in a step holds `spec_id`, the server's unmodified `definition`, the `sentence` when the client knows it, and the server's `resolved.entity_groups` as `entity_groups` when it names any. An exchange's request names its target in one of three ways. `path` is a path the client composes under the base URL, such as `/search/resolve`. `origin_path` is a root-relative URL the server returned, such as an artifact's `url`, which resolves against the base URL's origin and never against its path. `url` is an absolute URL outside the API, such as the signed storage URL a files route redirects to, which the client fetches with a bare request carrying no client header and no key. `json` holds the request body members that must match; a recorded scenario lists every member the client sent. The response gives `status`, the `headers` a client reads, and a `json` body or a `body_file`, a binary body in `scenarios/`. A scenario's own body files are named `.` and `-.`; a synthetic scenario may instead name a body file its parent names. @@ -150,7 +150,7 @@ The records also fix these client rules: - A fetch builds each distinct `spec_id` once, in part order, and finishes one member (build, the sentence when the client lacks it, files, download) before the next. - A fetch or mint of a spec posts its narrowing as the build's `input.scope`, and posts no `scope` when it narrows nothing. `window` posts `{"kind": "range", "start_year", "end_year"}` for a pair of years, or `{"kind": "all"}` or `{"kind": "latest"}`, and `facets` posts each axis as `{"ref": ...}`. The server's `scope.entities` replaces the spec's whole entity binding, so `entities` posts a whole map: the roles the spec's `definition.identity.entities` binds, with each role the caller names replaced by its refs and each role the caller binds to null dropped. Naming `origin` alone on a spec bound to `origin` and `destination` keeps `destination`. A fetch that names no role posts no `entities`. -- A built `spec_id` that differs from the posted one, or a spec with no sentence, takes its sentence from Search: the client posts the built definition's `identity` as one `dataset_resubmit` identity entry, with the member's first part as `variable_text`, or `"dataset"` when no answer part names it, and checks the answer's `spec_id` equals the built one. +- A built `spec_id` that differs from the posted one, or a spec with no sentence, takes its sentence from Search: the client posts the built definition's `identity` as one `dataset_resubmit` identity entry, with the member's first part as `variable_text`, or `"dataset"` when no answer part names it, and checks the answer's `spec_id` equals the built one. The entry's `entity_groups` holds the spec's `resolved.entity_groups` for each role the built identity binds to the same entities as the spec's definition, so a window or facets narrowing keeps every group and a role the narrowing rebound or dropped loses its group. The entry leaves `entity_groups` out when it keeps no group, as for a resumed operation, whose spec the client does not hold. The server reads a role posted without its group as its members, so a narrowed spec of flows to the least developed countries would read "44 recipients" in place of "the 44 Least Developed Countries". - A dataset of several members puts the `part` column first, then each member's columns in member order, each column once. The `part` value on a member's rows is the member's `parts` joined by `"; "`, so a member that answers two folded parts reads `"health ODA disbursements; education ODA disbursements"`, or the member's sentence when `parts` is empty. - A choice names its part by index, by variable text, or by a word that one gap's options mention, and its option by index or label; a candidate is named by index. A label is matched among the options that mention the word the part was named by. With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. - A choice raises `InvalidRequestError` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is out of range or matches no label or several. diff --git a/python/client-contract/src/dfo_client_contract/scenario.schema.json b/python/client-contract/src/dfo_client_contract/scenario.schema.json index c978946..a47445a 100644 --- a/python/client-contract/src/dfo_client_contract/scenario.schema.json +++ b/python/client-contract/src/dfo_client_contract/scenario.schema.json @@ -138,7 +138,7 @@ } }, "spec": { - "description": "A Spec as a client holds it: the server's spec_id and unmodified definition, and the sentence when the client knows it.", + "description": "A Spec as a client holds it: the server's spec_id and unmodified definition, the sentence when the client knows it, and the entity groups the server's resolved.entity_groups names, when it names any.", "type": "object", "additionalProperties": false, "required": [ @@ -155,6 +155,14 @@ "sentence": { "type": "string", "minLength": 1 + }, + "entity_groups": { + "description": "The server's resolved.entity_groups: each grouped role's EntityGroup, keyed by role.", + "type": "object", + "minProperties": 1, + "additionalProperties": { + "type": "object" + } } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.json new file mode 100644 index 0000000..209ed01 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.json @@ -0,0 +1,5314 @@ +{ + "format_version": 1, + "name": "fetch-spec-group-narrowed", + "description": "Fetching a spec whose destination is the least developed countries group with window=(2020, 2023) answers a new spec_id. The identity entry that asks Search for its sentence carries the spec's entity_groups whole, since a window leaves every role's binding as it was, and the sentence names the group.", + "origin": { + "kind": "recorded", + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "36b9f48d83282bcd5d99cb8f67b83e57a00216fd", + "recorded_at": "2026-10-21T07:08:47Z" + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_17a33486ccfd93f1a75c2070bab68b8c", + "definition": { + "schema_version": 1, + "spec_id": "spec_17a33486ccfd93f1a75c2070bab68b8c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/CAF", + "country/COD", + "country/COM", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GIN", + "country/GMB", + "country/GNB", + "country/HTI", + "country/KHM", + "country/KIR", + "country/LAO", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MMR", + "country/MOZ", + "country/MRT", + "country/MWI", + "country/NER", + "country/NPL", + "country/RWA", + "country/SDN", + "country/SEN", + "country/SLB", + "country/SLE", + "country/SOM", + "country/SSD", + "country/TCD", + "country/TGO", + "country/TLS", + "country/TUV", + "country/TZA", + "country/UGA", + "country/YEM", + "country/ZMB" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "sentence": "Germany's gross disbursements to the 44 Least Developed Countries for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", + "entity_groups": { + "destination": { + "label": "Least Developed Countries", + "group_id": "groups/UN.LDC" + } + } + }, + "window": [ + 2020, + 2023 + ] + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_17a33486ccfd93f1a75c2070bab68b8c", + "definition": { + "schema_version": 1, + "spec_id": "spec_17a33486ccfd93f1a75c2070bab68b8c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/CAF", + "country/COD", + "country/COM", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GIN", + "country/GMB", + "country/GNB", + "country/HTI", + "country/KHM", + "country/KIR", + "country/LAO", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MMR", + "country/MOZ", + "country/MRT", + "country/MWI", + "country/NER", + "country/NPL", + "country/RWA", + "country/SDN", + "country/SEN", + "country/SLB", + "country/SLE", + "country/SOM", + "country/SSD", + "country/TCD", + "country/TGO", + "country/TLS", + "country/TUV", + "country/TZA", + "country/UGA", + "country/YEM", + "country/ZMB" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "scope": { + "window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_f04936b8378cde70bc6289ac1e45ee9b", + "identity": { + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/CAF", + "country/COD", + "country/COM", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GIN", + "country/GMB", + "country/GNB", + "country/HTI", + "country/KHM", + "country/KIR", + "country/LAO", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MMR", + "country/MOZ", + "country/MRT", + "country/MWI", + "country/NER", + "country/NPL", + "country/RWA", + "country/SDN", + "country/SEN", + "country/SLB", + "country/SLE", + "country/SOM", + "country/SSD", + "country/TCD", + "country/TGO", + "country/TLS", + "country/TUV", + "country/TZA", + "country/UGA", + "country/YEM", + "country/ZMB" + ], + "origin": [ + "country/DEU" + ] + }, + "identity_version": "spec1", + "requested_window": { + "end_year": 2023, + "kind": "range", + "start_year": 2020 + }, + "shape": { + "kind": "statvar_schema", + "measured_property": "amount", + "measurement_qualifier": "Nominal", + "population_type": "FinancialFlow", + "stat_type": "measuredValue" + }, + "slots": [ + { + "binding": { + "ref": "DAC2aAidType206", + "state": "value" + }, + "property": "dac2aAidType" + }, + { + "binding": { + "state": "unbound" + }, + "property": "dacTypeOfFinance" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ] + } + }, + "content_version": "cv_daec84e443d4e1b37291242d90fc8fa8", + "prepared_at": "2026-10-21T07:08:48Z", + "coverage": { + "rows": 170, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 43, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 4 + } + ], + "window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023, + "origin": "query" + } + }, + "citation": { + "text": "OECD DAC2A (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=dac2a&pg=0&snb=1&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_DAC2%40DF_DAC2A&df[ag]=OECD.DCD.FSD&df[vs]=1.6&dq=.DPGC.206.USD.Q&lom=LASTNPERIODS&lo=5&to[TIME_PERIOD]=false&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "DAC2A is the OECD Development Assistance Committee's table of ODA disbursements by donor and recipient country or region. It covers bilateral donors and multilateral agencies reporting their own outflows, and includes the OECD's estimate of each donor's core multilateral contributions attributed to recipients.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip", + "attribution": "OECD (2026), OECD DAC2A, OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip (accessed on 2026-10-12)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1960-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The OECD publishes DAC2A in April, June, September and December. The complete table is downloaded from the OECD each time it is republished, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets. The totals DAC2A reports for groups of providers, such as all DAC countries, and for groups of recipients, such as regions and income groups, are included as providers and recipients of their own. Where two provider codes name the same organisation and report the same figures, the figures are counted once. Where two recipient codes name the same organisation, such as IDA and IDA's Multilateral Debt Relief Initiative, their flows are added." + }, + { + "transformation": "Select figures", + "description": "Only figures in current US dollars are included, not constant US dollars. Only flows to recipients on Part I of the DAC List are included: the developing countries, and the multilateral organisations DAC2A reports as recipients, such as development banks and UN agencies. Flows to Part II recipients, the countries in transition, are excluded." + }, + { + "transformation": "Convert to whole units", + "description": "DAC2A reports amounts in millions, which are converted to whole units. ODA per person and ODA as a share of GNI are kept as reported." + }, + { + "transformation": "Select dimensions", + "description": "Each figure is reported by year, provider, recipient and type of aid, such as grants, repayments, interest received, or debt forgiven or rescheduled. DAC2A is a table of disbursements, so every figure, repayments and interest included, is recorded as a disbursement. Figures are marked as gross or net, except where DAC2A does not say which, and as grants or non-grants where the type of aid is wholly one or the other. Imputed multilateral ODA, the OECD's estimate of each provider's share of multilateral organisations' ODA, is marked as modelled. ODA as a share of GNI records the recipient's GNI as its denominator, and ODA per person records the recipient's population." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "ODA disbursements by donor and recipient country or region, including the OECD's imputed multilateral contributions, and ODA per person and as a share of recipient GNI." + } + ] + } + ] + } + } + ] + }, + "trace": { + "applied_window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023, + "origin": "query" + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00260-6xk", + "code_index_stamp": { + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", + "graph_endpoint": "graph_release" + }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "source_revisions": [ + { + "source": "provenance/OECDDAC2A", + "revision": "2026-10-15" + } + ], + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 170 + } + ], + "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "family_member_count": 1, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDDAC2A", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253" + }, + { + "axis": "measurementMethod", + "ref": null, + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "1962969911839422253" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253" + } + ], + "normalisations": [], + "frame_grammar_version": "1.1.0", + "materialiser_build": "36b9f48d83282bcd5d99cb8f67b83e57a00216fd", + "capability_version": "dset_1e6cd9546fac19e9", + "served_from": "materialise", + "confirmed_at": "2026-10-21T07:08:48.876767+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for country/TUV." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:5674a67518081e6d1d436a9ba9ebd4cfe59bb8aec561571b3264522dda1d72b0", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 8716, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T07:08:48.809260+00:00", + "tier": "working", + "url": "/api/datasets/spec_f04936b8378cde70bc6289ac1e45ee9b/cv_daec84e443d4e1b37291242d90fc8fa8/files/sha256:5674a67518081e6d1d436a9ba9ebd4cfe59bb8aec561571b3264522dda1d72b0" + }, + { + "artifact_digest": "sha256:78ad78b09dcc0d40e50f5804d66f3399fa6b851ae4b4ac48b27ce5a6f2124ef0", + "rendering": { + "statistics": "series" + }, + "bytes": 7768, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T07:08:48.809260+00:00", + "tier": "working", + "url": "/api/datasets/spec_f04936b8378cde70bc6289ac1e45ee9b/cv_daec84e443d4e1b37291242d90fc8fa8/files/sha256:78ad78b09dcc0d40e50f5804d66f3399fa6b851ae4b4ac48b27ce5a6f2124ef0" + } + ], + "series_count": 43, + "output_options": { + "capability_version": "dset_1e6cd9546fac19e9", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 43 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 4 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 43, + "covered": 43 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 43, + "covered": 42 + }, + "missing": [ + { + "ref": "country/SSD", + "label": "South Sudan" + } + ], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 43, + "covered": 43 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 43, + "covered": 43 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 43, + "covered": 43 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "financingRecipient", + "columns": "time_period", + "state": "available", + "width": 5, + "cells": 215 + }, + { + "index": "time_period", + "columns": "financingRecipient", + "state": "available", + "width": 44, + "cells": 176 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "dataset_resubmit", + "entries": [ + { + "entry_kind": "identity", + "variable_text": "dataset", + "identity": { + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/CAF", + "country/COD", + "country/COM", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GIN", + "country/GMB", + "country/GNB", + "country/HTI", + "country/KHM", + "country/KIR", + "country/LAO", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MMR", + "country/MOZ", + "country/MRT", + "country/MWI", + "country/NER", + "country/NPL", + "country/RWA", + "country/SDN", + "country/SEN", + "country/SLB", + "country/SLE", + "country/SOM", + "country/SSD", + "country/TCD", + "country/TGO", + "country/TLS", + "country/TUV", + "country/TZA", + "country/UGA", + "country/YEM", + "country/ZMB" + ], + "origin": [ + "country/DEU" + ] + }, + "identity_version": "spec1", + "requested_window": { + "end_year": 2023, + "kind": "range", + "start_year": 2020 + }, + "shape": { + "kind": "statvar_schema", + "measured_property": "amount", + "measurement_qualifier": "Nominal", + "population_type": "FinancialFlow", + "stat_type": "measuredValue" + }, + "slots": [ + { + "binding": { + "ref": "DAC2aAidType206", + "state": "value" + }, + "property": "dac2aAidType" + }, + { + "binding": { + "state": "unbound" + }, + "property": "dacTypeOfFinance" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ] + }, + "entity_groups": { + "destination": { + "label": "Least Developed Countries", + "group_id": "groups/UN.LDC" + } + } + } + ] + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "dataset_resubmit", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "36b9f48d83282bcd5d99cb8f67b83e57a00216fd", + "trace_id": "573e457b43fd4b7f8275c71ef3fb1ce7", + "warnings": [], + "timing_ms": { + "total": 1722, + "by_step": { + "coverage": 0 + } + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "dataset", + "warnings": [], + "timing_ms": { + "total": 1644, + "by_step": { + "validate": 1, + "walk": 14, + "reread_arcs": 0, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 1577, + "bind": 0, + "where_places": 1, + "materialise": 31, + "answer": 17, + "options": 3 + } + }, + "operations": [], + "departures": [ + { + "code": "entity_unavailable", + "binding_ref": "where:", + "text": "The data holds no values for 1 of the 44 Least Developed Countries." + }, + { + "code": "group_read_as_members", + "binding_ref": "where:", + "text": "This shows the 44 Least Developed Countries, each on its own." + } + ], + "status": "definite", + "spec": { + "spec_id": "spec_f04936b8378cde70bc6289ac1e45ee9b", + "definition": { + "schema_version": 1, + "spec_id": "spec_f04936b8378cde70bc6289ac1e45ee9b", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/CAF", + "country/COD", + "country/COM", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GIN", + "country/GMB", + "country/GNB", + "country/HTI", + "country/KHM", + "country/KIR", + "country/LAO", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MMR", + "country/MOZ", + "country/MRT", + "country/MWI", + "country/NER", + "country/NPL", + "country/RWA", + "country/SDN", + "country/SEN", + "country/SLB", + "country/SLE", + "country/SOM", + "country/SSD", + "country/TCD", + "country/TGO", + "country/TLS", + "country/TUV", + "country/TZA", + "country/UGA", + "country/YEM", + "country/ZMB" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal_family_f096b1ba", + "label": "gross disbursements (official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "DAC2aAidType206", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AFG", + "label": "Afghanistan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BGD", + "label": "Bangladesh" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/HTI", + "label": "Haiti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KHM", + "label": "Cambodia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KIR", + "label": "Kiribati" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LAO", + "label": "Laos" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MMR", + "label": "Myanmar [Burma]" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NPL", + "label": "Nepal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SDN", + "label": "Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLB", + "label": "Solomon Islands" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TLS", + "label": "Timor-Leste" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TUV", + "label": "Tuvalu" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/YEM", + "label": "Yemen" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2020, + "end_year": 2023 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "dacTypeOfFinance" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "2020", + "end": "2023" + } + }, + "entities": [ + { + "ref": "country/AFG", + "label": "Afghanistan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BGD", + "label": "Bangladesh", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/HTI", + "label": "Haiti", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/KHM", + "label": "Cambodia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/KIR", + "label": "Kiribati", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LAO", + "label": "Laos", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MMR", + "label": "Myanmar [Burma]", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NPL", + "label": "Nepal", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SDN", + "label": "Sudan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SLB", + "label": "Solomon Islands", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TLS", + "label": "Timor-Leste", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TUV", + "label": "Tuvalu", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/YEM", + "label": "Yemen", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "entity_groups": { + "destination": { + "label": "Least Developed Countries", + "group_id": "groups/UN.LDC" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 170, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 4 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2020, + "end_year": 2023 + } + }, + "headline": { + "year": 2023, + "year_named": true, + "named_window": { + "start_year": 2020, + "end_year": 2023 + }, + "observations": 43, + "series": 43, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 43 + }, + "recent_years": [ + { + "year": 2023, + "observations": 43, + "series": 43, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 43 + } + }, + { + "year": 2022, + "observations": 43, + "series": 43, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 43 + } + }, + { + "year": 2021, + "observations": 42, + "series": 42, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 42 + } + } + ] + }, + "download": { + "rows": 170, + "rows_exact": true, + "series": 43, + "window": { + "start_year": 2020, + "end_year": 2023 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "DAC2aAidType218", + "label": "ODA loans and other long-term capital" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 2, + "served_rows": 19, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType201", + "label": "ODA grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 1, + "served_rows": 170, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType207", + "label": "free-standing technical co-operation" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 170, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType213", + "label": "developmental food aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 74, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType216", + "label": "humanitarian aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 101, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross disbursements to the 44 Least Developed Countries for official development assistance, 2020 to 2023. Current US dollars · OECD DAC2a.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "the 44 Least Developed Countries", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/AFG", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/CAF", + "country/COD", + "country/COM", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GIN", + "country/GMB", + "country/GNB", + "country/HTI", + "country/KHM", + "country/KIR", + "country/LAO", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MMR", + "country/MOZ", + "country/MRT", + "country/MWI", + "country/NER", + "country/NPL", + "country/RWA", + "country/SDN", + "country/SEN", + "country/SLB", + "country/SLE", + "country/SOM", + "country/SSD", + "country/TCD", + "country/TGO", + "country/TLS", + "country/TUV", + "country/TZA", + "country/UGA", + "country/YEM", + "country/ZMB" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2020 to 2023", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/AFG", + "label": "Afghanistan" + }, + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BGD", + "label": "Bangladesh" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/HTI", + "label": "Haiti" + }, + { + "ref": "country/KHM", + "label": "Cambodia" + }, + { + "ref": "country/KIR", + "label": "Kiribati" + }, + { + "ref": "country/LAO", + "label": "Laos" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MMR", + "label": "Myanmar [Burma]" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NPL", + "label": "Nepal" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SDN", + "label": "Sudan" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLB", + "label": "Solomon Islands" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TLS", + "label": "Timor-Leste" + }, + { + "ref": "country/TUV", + "label": "Tuvalu" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/YEM", + "label": "Yemen" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2a", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "DAC2aAidType206", + "label": "official development assistance" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AFG", + "label": "Afghanistan" + }, + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BGD", + "label": "Bangladesh" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/HTI", + "label": "Haiti" + }, + { + "ref": "country/KHM", + "label": "Cambodia" + }, + { + "ref": "country/KIR", + "label": "Kiribati" + }, + { + "ref": "country/LAO", + "label": "Laos" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MMR", + "label": "Myanmar [Burma]" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NPL", + "label": "Nepal" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SDN", + "label": "Sudan" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLB", + "label": "Solomon Islands" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TLS", + "label": "Timor-Leste" + }, + { + "ref": "country/TUV", + "label": "Tuvalu" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/YEM", + "label": "Yemen" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2020, + "end_year": 2023 + }, + "capability_version": "cap_3f35867df5a65761" + }, + "confidence": "high", + "available_at_place": true, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_53102a787c202df65dcbb4d112c7bf33", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/CAF", + "country/COD", + "country/COM", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GIN", + "country/GMB", + "country/GNB", + "country/HTI", + "country/KHM", + "country/KIR", + "country/LAO", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MMR", + "country/MOZ", + "country/MRT", + "country/MWI", + "country/NER", + "country/NPL", + "country/RWA", + "country/SDN", + "country/SEN", + "country/SLB", + "country/SLE", + "country/SOM", + "country/SSD", + "country/TCD", + "country/TGO", + "country/TLS", + "country/TUV", + "country/TZA", + "country/UGA", + "country/YEM", + "country/ZMB" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 170, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 2020, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2023, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1992, + "base_year_max": 2019, + "current_years": null + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 2023, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2020, + "end_year": 2020 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2010, + "current_years": null + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2020, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 2020, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2020, + "end_year": 2023 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "origin": "EUR" + } + } + } + } + } + ], + "rendered_sentence": "Germany's gross disbursements to the 44 Least Developed Countries for official development assistance, 2020 to 2023. Current US dollars · OECD DAC2a. The data holds no values for 1 of the 44 Least Developed Countries. This shows the 44 Least Developed Countries, each on its own.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "the 44 Least Developed Countries", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/AFG", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/CAF", + "country/COD", + "country/COM", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GIN", + "country/GMB", + "country/GNB", + "country/HTI", + "country/KHM", + "country/KIR", + "country/LAO", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MMR", + "country/MOZ", + "country/MRT", + "country/MWI", + "country/NER", + "country/NPL", + "country/RWA", + "country/SDN", + "country/SEN", + "country/SLB", + "country/SLE", + "country/SOM", + "country/SSD", + "country/TCD", + "country/TGO", + "country/TLS", + "country/TUV", + "country/TZA", + "country/UGA", + "country/YEM", + "country/ZMB" + ], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2020 to 2023", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "The data holds no values for 1 of the 44 Least Developed Countries.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "This shows the 44 Least Developed Countries, each on its own.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "definite" + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_f04936b8378cde70bc6289ac1e45ee9b/cv_daec84e443d4e1b37291242d90fc8fa8/files/sha256:5674a67518081e6d1d436a9ba9ebd4cfe59bb8aec561571b3264522dda1d72b0" + }, + "response": { + "status": 302, + "headers": { + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A5674a67518081e6d1d436a9ba9ebd4cfe59bb8aec561571b3264522dda1d72b0?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A5674a67518081e6d1d436a9ba9ebd4cfe59bb8aec561571b3264522dda1d72b0?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "fetch-spec-group-narrowed.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 170, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "dac2aAidType", + "dac2aAidType_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_f04936b8378cde70bc6289ac1e45ee9b", + "content_version": "cv_daec84e443d4e1b37291242d90fc8fa8", + "sentence": "Germany's gross disbursements to the 44 Least Developed Countries for official development assistance, 2020 to 2023. Current US dollars · OECD DAC2a." + } + ], + "missing": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.parquet b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.parquet new file mode 100644 index 0000000000000000000000000000000000000000..7b8da91d2c90a671a7307d152beae37a3dd6481a GIT binary patch literal 8716 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

(pFnE{W9~V|Zz<@>;6;ZAv{N2FYC~N_@~sW}D54 zvnGca=QA0~OX=#-h3cF0kyW$Y(Ua*$XldiVKFuV0^4E*hql^A;o}8AcV%XPk<#k;B z1%4EztsnVEwwYNw5XyOeF}o8{`O<+r$`A)%I*`PkX;oHH@ zwwF(Vp4zD1zwz6FCT#vOoR4wk?{W3T`_&%;5|%G{Or7=cn(UgPQt25?I$gxre~c?H z;_4?@^^FR|o^XDhah6SHdTr4ZlXBPw=MXii+^@%Sav6$sI5st}i=A_s<5V$vN?8-j zvUTtmJ=HAR%j!E>Gs||ehEB0fuV-01`ek6*N>oBUUP472+6!%L84|1RH9}(mV4w!| zS~ScM1~`^S!%V0S57c)c>S_e1??oEap}HQ`jUw}QBxeC2mervb;$V$NU2!q0n#@RX z)*$kWKT$O%r0;e6)@ohNrCsg58gGlXugmFc3XA=QZWzCITXAi1F_P9h#8x+Yi}+#{ z`GIBK)~X(luPN$mF70*!O;ha-@YhU!QPl)~1f`F-n$0^rEmhw3=BB8}RO0nmx_VsZ zwP9y7w6O*|;_pXz$h^8n(TFNUdUq-O5DCCz%11?G&gBD%i3*7vKNgn z-Z9-D;7WL=^kI>xUH}Yl%PKEmp{X;55r1{pw9*oU5ApLGP$@m8dT3Kzyr>Fg{`alJpG#slKG$=haNjo4yzEg=Xk$ zLFy*xE6$&_Day5o?qq#Per-dX&nP-2iLVjyX`Rh|B{0VT*@@ym1}%ns!^%m04dVEj z@y4RC(rdWp67a9y>-KqjT;lrZMS%`372^Xb8e1tQV;pam_(iVMZ*w-=`<;#Epv&wi zbz7P`+AU_m)eIA2?1u4cHN`#C{4bIu#ILwsT^4h<-DlQw&5lOCMejvQuog6a<+d5) z#h^(T??Iw2pI3~1uDR6T=xgfcTJ%8_gJ5Tu+wUlC(ME#pKICgd0O6I^u9+53HUyF| zKcZ7DE*N8uIcWiN-;$lbMp#u!EYDj`O{c6}hLXTw8XXnaWnyb|IKvJ*U0 z>qCqOy$@_exdL?a)S=t~KJ&W0YkQq7RT{o&Z3y~fL2T{@yp@gcO3WW9XcO~C3#w1^ zpO{O$+gvSGcjs~&(ocuhaDsj_<4ccJokc%nzg@Ji4n-Hl8@SlbiYCHj-ZgSEzle)6 zVLm_}BD6;1Y;kmWeCB>sMe`LOiZLqqS^)nP87XuJgN0lu6zEm;@S(5(|Ej26U8E_} Wzy%mSj{Mnwu$}O~AZp?Nf&4G5SA%*0 literal 0 HcmV?d00001 diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json new file mode 100644 index 0000000..89d6fd5 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json @@ -0,0 +1,5313 @@ +{ + "format_version": 1, + "name": "fetch-spec-group-origin-rebound", + "description": "Fetching a spec of Germany's flows to the least developed countries group with entities naming only origin rebinds origin to France. The identity entry that asks Search for the built sentence carries the destination's group, whose binding the build kept, and the sentence names the group.", + "origin": { + "kind": "recorded", + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "36b9f48d83282bcd5d99cb8f67b83e57a00216fd", + "recorded_at": "2026-10-21T07:08:52Z" + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_17a33486ccfd93f1a75c2070bab68b8c", + "definition": { + "schema_version": 1, + "spec_id": "spec_17a33486ccfd93f1a75c2070bab68b8c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/CAF", + "country/COD", + "country/COM", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GIN", + "country/GMB", + "country/GNB", + "country/HTI", + "country/KHM", + "country/KIR", + "country/LAO", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MMR", + "country/MOZ", + "country/MRT", + "country/MWI", + "country/NER", + "country/NPL", + "country/RWA", + "country/SDN", + "country/SEN", + "country/SLB", + "country/SLE", + "country/SOM", + "country/SSD", + "country/TCD", + "country/TGO", + "country/TLS", + "country/TUV", + "country/TZA", + "country/UGA", + "country/YEM", + "country/ZMB" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "sentence": "Germany's gross disbursements to the 44 Least Developed Countries for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", + "entity_groups": { + "destination": { + "label": "Least Developed Countries", + "group_id": "groups/UN.LDC" + } + } + }, + "entities": { + "origin": [ + "country/FRA" + ] + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_17a33486ccfd93f1a75c2070bab68b8c", + "definition": { + "schema_version": 1, + "spec_id": "spec_17a33486ccfd93f1a75c2070bab68b8c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/CAF", + "country/COD", + "country/COM", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GIN", + "country/GMB", + "country/GNB", + "country/HTI", + "country/KHM", + "country/KIR", + "country/LAO", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MMR", + "country/MOZ", + "country/MRT", + "country/MWI", + "country/NER", + "country/NPL", + "country/RWA", + "country/SDN", + "country/SEN", + "country/SLB", + "country/SLE", + "country/SOM", + "country/SSD", + "country/TCD", + "country/TGO", + "country/TLS", + "country/TUV", + "country/TZA", + "country/UGA", + "country/YEM", + "country/ZMB" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "scope": { + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/CAF", + "country/COD", + "country/COM", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GIN", + "country/GMB", + "country/GNB", + "country/HTI", + "country/KHM", + "country/KIR", + "country/LAO", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MMR", + "country/MOZ", + "country/MRT", + "country/MWI", + "country/NER", + "country/NPL", + "country/RWA", + "country/SDN", + "country/SEN", + "country/SLB", + "country/SLE", + "country/SOM", + "country/SSD", + "country/TCD", + "country/TGO", + "country/TLS", + "country/TUV", + "country/TZA", + "country/UGA", + "country/YEM", + "country/ZMB" + ], + "origin": [ + "country/FRA" + ] + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_c2f21170dfa9f31705e47ed60c8fa305", + "identity": { + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/CAF", + "country/COD", + "country/COM", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GIN", + "country/GMB", + "country/GNB", + "country/HTI", + "country/KHM", + "country/KIR", + "country/LAO", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MMR", + "country/MOZ", + "country/MRT", + "country/MWI", + "country/NER", + "country/NPL", + "country/RWA", + "country/SDN", + "country/SEN", + "country/SLB", + "country/SLE", + "country/SOM", + "country/SSD", + "country/TCD", + "country/TGO", + "country/TLS", + "country/TUV", + "country/TZA", + "country/UGA", + "country/YEM", + "country/ZMB" + ], + "origin": [ + "country/FRA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + }, + "shape": { + "kind": "statvar_schema", + "measured_property": "amount", + "measurement_qualifier": "Nominal", + "population_type": "FinancialFlow", + "stat_type": "measuredValue" + }, + "slots": [ + { + "binding": { + "ref": "DAC2aAidType206", + "state": "value" + }, + "property": "dac2aAidType" + }, + { + "binding": { + "state": "unbound" + }, + "property": "dacTypeOfFinance" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ] + } + }, + "content_version": "cv_66a0a4a0331d59b519aa1629dade3d99", + "prepared_at": "2026-10-21T07:08:52Z", + "coverage": { + "rows": 2114, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 44, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 63 + } + ], + "window": { + "kind": "all", + "start_year": 1960, + "end_year": 2024, + "origin": "default" + } + }, + "citation": { + "text": "OECD DAC2A (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=dac2a&pg=0&snb=1&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_DAC2%40DF_DAC2A&df[ag]=OECD.DCD.FSD&df[vs]=1.6&dq=.DPGC.206.USD.Q&lom=LASTNPERIODS&lo=5&to[TIME_PERIOD]=false&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "DAC2A is the OECD Development Assistance Committee's table of ODA disbursements by donor and recipient country or region. It covers bilateral donors and multilateral agencies reporting their own outflows, and includes the OECD's estimate of each donor's core multilateral contributions attributed to recipients.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip", + "attribution": "OECD (2026), OECD DAC2A, OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip (accessed on 2026-10-12)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1960-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The OECD publishes DAC2A in April, June, September and December. The complete table is downloaded from the OECD each time it is republished, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets. The totals DAC2A reports for groups of providers, such as all DAC countries, and for groups of recipients, such as regions and income groups, are included as providers and recipients of their own. Where two provider codes name the same organisation and report the same figures, the figures are counted once. Where two recipient codes name the same organisation, such as IDA and IDA's Multilateral Debt Relief Initiative, their flows are added." + }, + { + "transformation": "Select figures", + "description": "Only figures in current US dollars are included, not constant US dollars. Only flows to recipients on Part I of the DAC List are included: the developing countries, and the multilateral organisations DAC2A reports as recipients, such as development banks and UN agencies. Flows to Part II recipients, the countries in transition, are excluded." + }, + { + "transformation": "Convert to whole units", + "description": "DAC2A reports amounts in millions, which are converted to whole units. ODA per person and ODA as a share of GNI are kept as reported." + }, + { + "transformation": "Select dimensions", + "description": "Each figure is reported by year, provider, recipient and type of aid, such as grants, repayments, interest received, or debt forgiven or rescheduled. DAC2A is a table of disbursements, so every figure, repayments and interest included, is recorded as a disbursement. Figures are marked as gross or net, except where DAC2A does not say which, and as grants or non-grants where the type of aid is wholly one or the other. Imputed multilateral ODA, the OECD's estimate of each provider's share of multilateral organisations' ODA, is marked as modelled. ODA as a share of GNI records the recipient's GNI as its denominator, and ODA per person records the recipient's population." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "ODA disbursements by donor and recipient country or region, including the OECD's imputed multilateral contributions, and ODA per person and as a share of recipient GNI." + } + ] + } + ] + } + } + ] + }, + "trace": { + "applied_window": { + "kind": "all", + "start_year": 1960, + "end_year": 2024, + "origin": "default" + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00260-6xk", + "code_index_stamp": { + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", + "graph_endpoint": "graph_release" + }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "source_revisions": [ + { + "source": "provenance/OECDDAC2A", + "revision": "2026-10-15" + } + ], + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2114 + } + ], + "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "family_member_count": 1, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDDAC2A", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253" + }, + { + "axis": "measurementMethod", + "ref": null, + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "1962969911839422253" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253" + } + ], + "normalisations": [], + "frame_grammar_version": "1.1.0", + "materialiser_build": "36b9f48d83282bcd5d99cb8f67b83e57a00216fd", + "capability_version": "dset_1e6cd9546fac19e9", + "served_from": "materialise", + "confirmed_at": "2026-10-21T07:08:52.918932+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:1ea84fd402e660f640baf08b43a6ef4ed031c01b7dc8a781237c1c3006a3f934", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 21027, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T07:08:52.857494+00:00", + "tier": "working", + "url": "/api/datasets/spec_c2f21170dfa9f31705e47ed60c8fa305/cv_66a0a4a0331d59b519aa1629dade3d99/files/sha256:1ea84fd402e660f640baf08b43a6ef4ed031c01b7dc8a781237c1c3006a3f934" + }, + { + "artifact_digest": "sha256:b1f80f2d3df16b6cda3831730ee4749b13e1eb3fff82cdf2f479e71f087bfe2b", + "rendering": { + "statistics": "series" + }, + "bytes": 8093, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T07:08:52.857494+00:00", + "tier": "working", + "url": "/api/datasets/spec_c2f21170dfa9f31705e47ed60c8fa305/cv_66a0a4a0331d59b519aa1629dade3d99/files/sha256:b1f80f2d3df16b6cda3831730ee4749b13e1eb3fff82cdf2f479e71f087bfe2b" + } + ], + "series_count": 44, + "output_options": { + "capability_version": "dset_1e6cd9546fac19e9", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 44 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 63 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 44, + "covered": 44 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 44, + "covered": 43 + }, + "missing": [ + { + "ref": "country/SSD", + "label": "South Sudan" + } + ], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 44, + "covered": 44 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 44, + "covered": 44 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 44, + "covered": 44 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "financingRecipient", + "columns": "time_period", + "state": "available", + "width": 64, + "cells": 2816 + }, + { + "index": "time_period", + "columns": "financingRecipient", + "state": "available", + "width": 45, + "cells": 2835 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "dataset_resubmit", + "entries": [ + { + "entry_kind": "identity", + "variable_text": "dataset", + "identity": { + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/CAF", + "country/COD", + "country/COM", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GIN", + "country/GMB", + "country/GNB", + "country/HTI", + "country/KHM", + "country/KIR", + "country/LAO", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MMR", + "country/MOZ", + "country/MRT", + "country/MWI", + "country/NER", + "country/NPL", + "country/RWA", + "country/SDN", + "country/SEN", + "country/SLB", + "country/SLE", + "country/SOM", + "country/SSD", + "country/TCD", + "country/TGO", + "country/TLS", + "country/TUV", + "country/TZA", + "country/UGA", + "country/YEM", + "country/ZMB" + ], + "origin": [ + "country/FRA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + }, + "shape": { + "kind": "statvar_schema", + "measured_property": "amount", + "measurement_qualifier": "Nominal", + "population_type": "FinancialFlow", + "stat_type": "measuredValue" + }, + "slots": [ + { + "binding": { + "ref": "DAC2aAidType206", + "state": "value" + }, + "property": "dac2aAidType" + }, + { + "binding": { + "state": "unbound" + }, + "property": "dacTypeOfFinance" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ] + }, + "entity_groups": { + "destination": { + "label": "Least Developed Countries", + "group_id": "groups/UN.LDC" + } + } + } + ] + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "dataset_resubmit", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "36b9f48d83282bcd5d99cb8f67b83e57a00216fd", + "trace_id": "51c7ccf406404774860a36e433d3d603", + "warnings": [], + "timing_ms": { + "total": 1733, + "by_step": { + "coverage": 0 + } + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "dataset", + "warnings": [], + "timing_ms": { + "total": 1665, + "by_step": { + "validate": 1, + "walk": 14, + "reread_arcs": 0, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 1617, + "bind": 0, + "where_places": 1, + "materialise": 19, + "answer": 10, + "options": 3 + } + }, + "operations": [], + "departures": [ + { + "code": "group_read_as_members", + "binding_ref": "where:", + "text": "This shows the 44 Least Developed Countries, each on its own." + } + ], + "status": "definite", + "spec": { + "spec_id": "spec_c2f21170dfa9f31705e47ed60c8fa305", + "definition": { + "schema_version": 1, + "spec_id": "spec_c2f21170dfa9f31705e47ed60c8fa305", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/CAF", + "country/COD", + "country/COM", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GIN", + "country/GMB", + "country/GNB", + "country/HTI", + "country/KHM", + "country/KIR", + "country/LAO", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MMR", + "country/MOZ", + "country/MRT", + "country/MWI", + "country/NER", + "country/NPL", + "country/RWA", + "country/SDN", + "country/SEN", + "country/SLB", + "country/SLE", + "country/SOM", + "country/SSD", + "country/TCD", + "country/TGO", + "country/TLS", + "country/TUV", + "country/TZA", + "country/UGA", + "country/YEM", + "country/ZMB" + ], + "origin": [ + "country/FRA" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal_family_f096b1ba", + "label": "gross disbursements (official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "DAC2aAidType206", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AFG", + "label": "Afghanistan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BGD", + "label": "Bangladesh" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/HTI", + "label": "Haiti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KHM", + "label": "Cambodia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KIR", + "label": "Kiribati" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LAO", + "label": "Laos" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MMR", + "label": "Myanmar [Burma]" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NPL", + "label": "Nepal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SDN", + "label": "Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLB", + "label": "Solomon Islands" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TLS", + "label": "Timor-Leste" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TUV", + "label": "Tuvalu" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/YEM", + "label": "Yemen" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "dacTypeOfFinance" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/AFG", + "label": "Afghanistan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BGD", + "label": "Bangladesh", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/HTI", + "label": "Haiti", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/KHM", + "label": "Cambodia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/KIR", + "label": "Kiribati", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LAO", + "label": "Laos", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MMR", + "label": "Myanmar [Burma]", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NPL", + "label": "Nepal", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SDN", + "label": "Sudan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SLB", + "label": "Solomon Islands", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TLS", + "label": "Timor-Leste", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TUV", + "label": "Tuvalu", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/YEM", + "label": "Yemen", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/FRA", + "label": "France", + "entity_type": "Country", + "role": "origin" + } + ], + "entity_groups": { + "destination": { + "label": "Least Developed Countries", + "group_id": "groups/UN.LDC" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 2114, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 61 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 41, + "series": 41, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 41 + }, + "recent_years": [ + { + "year": 2024, + "observations": 41, + "series": 41, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 41 + } + }, + { + "year": 2023, + "observations": 42, + "series": 42, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 42 + } + }, + { + "year": 2022, + "observations": 42, + "series": 42, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 42 + } + } + ] + }, + "download": { + "rows": 2114, + "rows_exact": true, + "series": 44, + "window": { + "start_year": 1960, + "end_year": 2024 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "DAC2aAidType218", + "label": "ODA loans and other long-term capital" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 2, + "served_rows": 1091, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType201", + "label": "ODA grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 1, + "served_rows": 2095, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType207", + "label": "free-standing technical co-operation" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 2021, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType213", + "label": "developmental food aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 845, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType216", + "label": "humanitarian aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 545, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "France's gross disbursements to the 44 Least Developed Countries for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", + "sentence_plan": [ + { + "kind": "slot", + "text": "France", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/FRA" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "the 44 Least Developed Countries", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/AFG", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/CAF", + "country/COD", + "country/COM", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GIN", + "country/GMB", + "country/GNB", + "country/HTI", + "country/KHM", + "country/KIR", + "country/LAO", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MMR", + "country/MOZ", + "country/MRT", + "country/MWI", + "country/NER", + "country/NPL", + "country/RWA", + "country/SDN", + "country/SEN", + "country/SLB", + "country/SLE", + "country/SOM", + "country/SSD", + "country/TCD", + "country/TGO", + "country/TLS", + "country/TUV", + "country/TZA", + "country/UGA", + "country/YEM", + "country/ZMB" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/AFG", + "label": "Afghanistan" + }, + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BGD", + "label": "Bangladesh" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/HTI", + "label": "Haiti" + }, + { + "ref": "country/KHM", + "label": "Cambodia" + }, + { + "ref": "country/KIR", + "label": "Kiribati" + }, + { + "ref": "country/LAO", + "label": "Laos" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MMR", + "label": "Myanmar [Burma]" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NPL", + "label": "Nepal" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SDN", + "label": "Sudan" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLB", + "label": "Solomon Islands" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TLS", + "label": "Timor-Leste" + }, + { + "ref": "country/TUV", + "label": "Tuvalu" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/YEM", + "label": "Yemen" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/FRA", + "label": "France" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2a", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "DAC2aAidType206", + "label": "official development assistance" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AFG", + "label": "Afghanistan" + }, + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BGD", + "label": "Bangladesh" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/HTI", + "label": "Haiti" + }, + { + "ref": "country/KHM", + "label": "Cambodia" + }, + { + "ref": "country/KIR", + "label": "Kiribati" + }, + { + "ref": "country/LAO", + "label": "Laos" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MMR", + "label": "Myanmar [Burma]" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NPL", + "label": "Nepal" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SDN", + "label": "Sudan" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLB", + "label": "Solomon Islands" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TLS", + "label": "Timor-Leste" + }, + { + "ref": "country/TUV", + "label": "Tuvalu" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/YEM", + "label": "Yemen" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_3f35867df5a65761" + }, + "confidence": "high", + "available_at_place": true, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_d0fa2dd4c5ba67436b13a12bb98547d4", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/CAF", + "country/COD", + "country/COM", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GIN", + "country/GMB", + "country/GNB", + "country/HTI", + "country/KHM", + "country/KIR", + "country/LAO", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MMR", + "country/MOZ", + "country/MRT", + "country/MWI", + "country/NER", + "country/NPL", + "country/RWA", + "country/SDN", + "country/SEN", + "country/SLB", + "country/SLE", + "country/SOM", + "country/SSD", + "country/TCD", + "country/TGO", + "country/TLS", + "country/TUV", + "country/TZA", + "country/UGA", + "country/YEM", + "country/ZMB" + ], + "origin": [ + "country/FRA" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 2128, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1985, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1992, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1973, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1994, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1987, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1989, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1987, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1961, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 1985, + "end_year": 1990 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "origin": "EUR" + } + } + } + } + } + ], + "rendered_sentence": "France's gross disbursements to the 44 Least Developed Countries for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a. This shows the 44 Least Developed Countries, each on its own.", + "sentence_plan": [ + { + "kind": "slot", + "text": "France", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/FRA" + ], + "states": [ + "origin:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "the 44 Least Developed Countries", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/AFG", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/CAF", + "country/COD", + "country/COM", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GIN", + "country/GMB", + "country/GNB", + "country/HTI", + "country/KHM", + "country/KIR", + "country/LAO", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MMR", + "country/MOZ", + "country/MRT", + "country/MWI", + "country/NER", + "country/NPL", + "country/RWA", + "country/SDN", + "country/SEN", + "country/SLB", + "country/SLE", + "country/SOM", + "country/SSD", + "country/TCD", + "country/TGO", + "country/TLS", + "country/TUV", + "country/TZA", + "country/UGA", + "country/YEM", + "country/ZMB" + ], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "This shows the 44 Least Developed Countries, each on its own.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "definite" + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_c2f21170dfa9f31705e47ed60c8fa305/cv_66a0a4a0331d59b519aa1629dade3d99/files/sha256:1ea84fd402e660f640baf08b43a6ef4ed031c01b7dc8a781237c1c3006a3f934" + }, + "response": { + "status": 302, + "headers": { + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A1ea84fd402e660f640baf08b43a6ef4ed031c01b7dc8a781237c1c3006a3f934?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A1ea84fd402e660f640baf08b43a6ef4ed031c01b7dc8a781237c1c3006a3f934?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "fetch-spec-group-origin-rebound.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 2114, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "dac2aAidType", + "dac2aAidType_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_c2f21170dfa9f31705e47ed60c8fa305", + "content_version": "cv_66a0a4a0331d59b519aa1629dade3d99", + "sentence": "France's gross disbursements to the 44 Least Developed Countries for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a." + } + ], + "missing": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.parquet b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.parquet new file mode 100644 index 0000000000000000000000000000000000000000..7ef63db695671fde6c755c03768f477e526359bd GIT binary patch literal 21027 zcmd7430zaxw?BGed}QT6)U~>f8V?BeV!lpA!iS3t-bbI-?jEW zIf;-&de|fTa)$j7e>UQ?LkJK$)Is)~eEYPgFJ;EJ7H1YoW+b%h-J^7Iwi_ZjdT2)rgl=i4G zTU&S^{MuqLqX!+B1YeAu`Vb z0*A;W2Mi-nsKoOXI%5d|GlSfJ-n1_}$MsfC4k4kK{b$oK&o_!Aio0uZrKg~FwD zLwH0e%_lO}GoOK?0zGXQM3m1)_!tTwaa5>uKnQ`OMuySDqCBA?Isl~eak9YCp;5pb zN5_n&+u}Vd2^7;h?>H$fTYQ*5Xx7NEKhF5nr2n(((Bp3t0G+k!S=l`PFAM9KK*Te0 zEDAdmqEu#K$GlE?IFB{la-7u!cD%LHWRBEnYaTZ+t&6+ZEV;bEl81_YE3GTdrin#1vJA zCOb!!(UH+voG~#oP1OnN{d2Q&Gm7+_e)Tpcp!rG44-(QoR zt;%Ioa%3tE3?0G?fYwY9G-z0eCQFm3%F!U85~|9~W~l8#HHqph4f8H9RGpoflak3e z=@O<&R!vl8C#kX+?l?@9#$3P)o1)4{S7kAsQDz}y8lIf1X4>#nxge7&gSCzWomBaP zew=X4M0FNpJ||qQRi!Zw*+u57GLlt{E}W>`WK{-ZMoN@ALp@QI26jP2Wv0PIGx+lC zH0YGgW^{4asI#(E{7`jfhPo4jW0#q(O4F#EgY2R}2Pu4}%!!seAVrnTz&JW{BJ-Gw zRF$2>kJf;~7*o8WbMsVbxwM9&RT+i0TTskI+xfn6G`7+h5#Oq$_HD1@hen=No5lYB z(Cq#<0m#+9??*7}BBK@kkEqfftabiJAKpJJ+J(9x`w<^G^)BrRoH8d&(9rRXpRCSP zr)6sCpvG5aXSe!J`|#ZJzZt{(?>e+AS#u}*g#f}|w}Nm>2mDhnwcc_rie$xe4VK6f=}xpxlOX2g+S2_n_Q|@&HOBlV1J@x8`$OH#=jbQ_+xjH zaBHWwRnJG+&9gqD@N_Ys9jJ1Wt#=Q-Gc3X-ELuHQu_-;_!8E1YykyOql+D}Iy5SC^ zc%2ryS)KRoY$xv$6W4XArrYHyJ$Z9_$F1nIVspQ1`v*Fm95lAW@83Kq5^+i<^L4vK z-~1+C;5BMVu4?(d$*W%#t@B-2Ic0tI{$1OCIPli$r{|%UscCnn@Y#i55nfw<9q|6h z&SB@hmA49d;IC&BhBG3!X% zhbQ*EdHQ^y)B2qR=j4xC_n%k96Wg~Foc+^*!5S8W_+xZ91NGO=c}n2n*Yal#V-Ou@ z_%P8~(h@d3ig^3m@oj>cW1u^~W5DWb9z{$<8 z7{r_Hqb%4@Laz<}vz*~vzAKlQWzX0*sl%*+7R1x|8_;(|A|h7KIc~8liNQGwS{hYU z$L}<&RXy9&X4qTIDJH(}vadg5Uzi0uTCG~{qaYj?yQZ> zS^X_Ibhx6kuksrV`|YbC7d_Xl)dlJ@oah#FH#Z4Dr!hgm#9)$rSr~QoU|}Ma#m5RP zV{y=-p3tIi7Q$8R;sRIWj$urU45ciLm3MrY9Bi8D4a0)Jgf^!iBj9Q-8vzx50r0WB z-Vd&&eI;;>2=Rh}=FO}MoEV)51JT+EQ0@5RM7ZAEoCeneceHTbdV3OFXRObH?w8*( zF`J4s&W8Tl$8#BQ!_&@(KjI#qm0Xh(_-X+kX`S*IJmTg>pArHnH=3bagHxa2AcvHna;A*ZDfds}v zn2dHgs~Hzxj%D(&TW%<{armR5Ejo~uf)agLEhtZ*Xo!g{6|+})Gqi%#8OwqRm?GmD4aW0RO7 zz~lYnSb9pMrY0?Xk=L^1f7a#;)Wrtonl#Ww0) z6$~CO-!)iZ!sauZ1u5)ikLanOispxRz5)@>@0EU`6ycg5;be35txYH%W^|Yl(f3`o?^-H zjF%dQ2oo!23C$=lPMCu0j;mn2Ib%Ew+_Y3!io_jR4XC=a)C3q?Eu}EA;TL%UG8_YK zwG0KT5pR!K$rPh$D_C{-M0f@W_xo01Gu~K`$>3n|lSKl!UNH(QQ0K+;ti$7lV&s1v ztm#edIAEXLFq!uPdcl1s zvYJuFAT&3L=7WR=Au#KkZ zB`_yyUxvWUrlvnD1+_+@dGwO*EBc1^5>q9U$0i2$rJx(}WQ!E4;=hMk8?A?dsMOmW zrW>Y&-g003Ksw7>1b#u~lXJi?jOhI$AV7o(N{nnGpSuu92X-%`X)5}bG-87N2yF7} z`9Ohh!*dmt>>p|XC-|hoI#YAYOyaMqrfkH)PLL;bF*n+O->WrxPGSofpCp4gp??58~ zSJWVW;$op2%AKih#zeLV+LI@h0F9fuEIu0Q1VU04x0ub?m_!QPF!8W~cC}|mKw|2L z29^j_&K5LaYHS9x0dVi4#uxK$=om(9Oz9y|u*G}FE(JA+gBWW-JY(VMwIH5&UK6c5 zuB%$c7Dr!P4R%g;1H~98!~+K^S1TyT;^T{;hKSw7jDYw*j#Y&&vcP`DD4eCm@n0=t z$S}2KB-4#eW#+GgRS}1W(T3vjRFHy=o(lm-jGHDheK8UD8t71uC(-o#USxvtlm`R% zV?C3B+}5sEVCgl7Uo2-RpbGGWeelA=RUk2yx@ZGPoY13(9wZ*HZxxF|nWqGN?3Py} z1;HY&HtA7x=V}F*WwjW6{Z`nBwi6l?dhP;h-bR52sj?zL6(%@$H7Q8;USmY&ZaN<7 zHC0oNELj=~tvmr^{PU}M_-e0wMg^ww&IxPKvyFl}O!Sk{`h9Z-y!Yu@Fz1C%O+54> zPVS51@iq?eTGx!+#5xZ8VifHv9@D_YDGyllH^0aYh`RtBt5~KhN9+Vx&a@eTAs4KK z1TvSwryOUfqde-BNbFJzOF8_khJ*IJ7W(41_Q4DjHayD*$BP(d0(+}+wU+WQK6kK0 zfz3k<>I(J=!>US#h&^m@{btb148~f4fvp(&)ecY@Q8zdl{L%cbT8r*R2r1<5Csd-+ zz5sj$)%9ZZ+s0}h+J21Hh|YwAFl9`7!M-pH3($afLK%7}2fU!dtJM+M_~&9~6%se; zC`@e@mlR;4=TB-GCPF&VYx$i7)G*gh3KozstwfB82|A`28*c`|ybfj zZkXb8pjTh(N{oq>Czv&mr3Qnxw{H@1&=CvT!oIR%DbS)-5Mb5^K+Ct9N+mWP z=?;d=3AO>rMC&$#IGi{;m~YC-0Ir)Q)`wPAw&3#RPOy5ucpx*M5!876GZ@1-&JxRdNznQoqN0J z$%niE7$Lgn&}#dx9A-}d4mO}OGeNynV=awWt1SUACyXfdxb z{hk3gZ0Z2>s5`zMz<_dnz^uaBF?nhZZkcr%R&mN@CZDbCI%p~QZOz$BAnU;iH^Ddv z1?JXSVq#-}rUkj(Cu=ZDI0fSOT?FAl-wYN;Ed3Mi-)e<*kfscP;Y7qiZUN+M`sum~ z)H6pYLV-h}#|nF(Q0JhjL++b}V)RootnbauKt(c(R-5rOD5?4&%!Rw41SC(@%SDKN zTJDC1>}QD)EPM+%#2@L*a&$WadLa%=ili0-15bJ7w3Wq@BLnEnkJWDE9JKzE13V5XE) zB&hc3*GzzoE*rsBDgJEWGyX706;U_=G*%<}0kBOr1Oumv=!;O}wqyl-Zod8_T*d4b zsRHwh4Ybh4L8rK-R#?{877}jRdw+<;;>IsPHksE*xQZf%f(FYx0PxE5NRADT=r4y9 z=|T;+zy=dJW2J$j9(uk&}lN3fuhP(mwctJ*3q10qph|sG|&FJb*xfxkjKw74Ht}&zS zw^=;o7!L8qMXakrlo4*%(0rmP(6Q(ps{m=oY8p`EM0qm`KgiOe=}!RrsF7+tn~Key z!K_2R{WJ>XhG5JS8YM&-QUX&!&ZL_)@>vODYMUZ ze6^OsZlX$cBX&=%s4c~Y`Q}OrzdbUa>o8&$tyBi93@9D>w;Y0wsOWlX^W$F@u7| zwd>UoKduety0I}~^(}3~9vAA3$h$Y#-0Cv|f=y%u6*Ki{<|1h$rk+`-p@&yA%_++r zuxoc;YYx#2xdBnF;nrATD!HEP3m`-~s8bLzLdeI|mB|7~zDwuQ=w7r4e5Enz27DG1 z<&aGkEaxyI*wna|d5ltQ6itIErhGjXl(lDhkwAg>FnbG1+1Kk2tYEm|x@%Qj85{N* zYG*p+QeB*&H}P5uSH2K-F@#!3A+L$@6o4&KWQD4R$?K3fAJ#)u256Ho20k@5u*A5o zDu_w%hPYx-iHS=#+G6ABKEPDm*dMg3cZaNn2xW0FKiCz_jbowXBV`s@V~2>Y)&{}| zs-Zk!qd|3X2ctG7*ux;VBuHitddOusp~{xQ!<4c1o*q+QOanOU{|hAUrQZ)^@L|>! z5bKQJeZ|FW#9!@LXA9d7oe}ZqC{5^XARBGj3h3Kd0vM)Og)(HAaF2yZla@?lm48RM z0oBa`pniLl)UqMh04FbfDpa6j$DxyA8CWte4JON z2U%O*L*fB2ScO`;!>6a#8ZiWjY6bF@lckmjOTpr)E+i(=xGb{48Yz896GnI+ON0zr z&}~2rD0*HspjR{k7%e;p{(0=G0BqvgOd11>9;+Z&*iPa`kXS6sg4k=i1Y%Za-qjU!eY*@6?wgV(NML-pCQD2e z>`{Y_H!rD$>#S+eD0V3kV`A_Y62qqWI86VtkrYFyZEVsai9JgJ$zU}P-7f(ro^=`E zskbAjt?O6!2u$=)!}yWIXoJ2&l!!1jZ=br3t(+B74bfbD=2i(rNt@y72242Ks4T@I zza*{!Ja!qqn=$ohU{Js^F`4{|;op7`j(R8mAD**s9OERy8#*hJ}3u}wJ- z5+OkgZ1x&7Zm^6t3_Y6=yV${Ma`>c@2L{{~FxXs1*6>in&kzgH00sEN-}6k^ z^0RmX0#kzv9XXanCDR1QlNW2jq<+m5)}R?($O=o^=r~~Lpb-7^+EPg07eLHBmJRnu ze*@$qY?B3MO!eF&5MxSrigv!``Lx;k_7l`#qGJ+(qVO`z!*@TZT(G{DhoeI(AS0~m z_>L)NH|&U8#xUZRpPDNvcIt>wxzlpHafs>Bx zQHO~Z@bwn0P7Jn1y0OvXQMyv3td*NlmZh))6@O3r(W)!lW&jX;fz)Dj{5ZD-PCeJ} zfz`Nmxv2`VSsD(?tO6!Qy&&#WzC73y5-O>%{KF0D* z0KSA`Z0_bOppY^eq7e~F8Z1%y5S;-MW3rir^ePBNfJ@jB6m&x%LlFn%jcBnG6WoHc zgKPwosjG&wgW>cz+uwi%HL_OEHuhv~WfssOO@#PDO%)O^f#mCWP^}&g8(4r;`U5YR zT6E}jy%>aj3#(+b7+G(`2L~z`5ttHpl@e^@$urSlZjo;wl_WynF+^b5yYGRmQtMfO zazsQ(eI2TJMd~5qUKIKwg)7Sh%yfKIlOz;D_70)iq?W@%FaWlQt}F!rRClI=4%J#@ zN&w6cws0F*m`WW4 zYfmivrUbk!ekE67g~fxLN&xcFI&KvU8^5~FZLtSPvEw$7SYPbJmD$10?K^IbC070j z+a$Jl#*uZ5W~_{HCPkKzw!@UokY(}M<-ecXLu+-yb*2&%-JEG(T&O4kpGzuaHi9pf zgF4T=2Ol%VE z8-G+bV=BKALd6vNXoEUBic7Gu*y0APg>kTuMykv>XduF83wW4X{+pl*8>{4ibK~tG zV2RI_07{zuxG6AbT{)ddH}XJV#G7AW*VafMFDtw4E=j@0xgEeL!V2iNi*#MrTW=Y3YnJ(4Y+Rg88GPNccg)h?=oJ%qM;{wkSS@;ZG)+A zpCd40b6}Z3iBqQbqcP63jucx$4A2z-0Mt|96@VXv)=d|IBGy3Vbp$?TcbD|FM5Y%c z&l3MoktmU|iLFuNKpp_M8cPK3hiMShqvGNwKGL77Zw6olFzZ7rw}w;chKVv0i$cvx zvd#)kom-uPw%%rzvQ0}i9cHE=OjN>Lt8F1Xi}%4PG^Xy&tAqq`#x&5rGVT_9rZOC) zdbs{3h4@%865!i-;C!tC6DeVU|N7P7=r##WVt_9x=<1NJqykg58(|^DNtfgVI#3Hy zOl)_brag9pv=mcE&XN(9X#54xGEvpU6+!mM$%a5fEZePyX1@e(IaKxWxTnX&??X!( z*qn+R`p(o7aW}U_jl3=a~T+iXFraB~b2h&g1!D4kYl$hXP{1(^=l&D!?<%gj2PSyopy#V%Axtx#>kHw&;-p$PoMc==fN0GnY}0 zi9x$yOw$%As47WHyKM)F0Ia+>eF&2^y;_9)3TcaUiU8FR7p&AG44JORfF7MLX~e|9 zr$Q~dpH$80*o%&!hcY@(CT89*WmcfDP67<)Lu{59l`Nx)b)nDu zh~wF`d9Qs8L*!g=%Tw#PJlFv|*(T>B+fm?ZM5qQV*qAs#Aj5_`cce-zO8XJ?CKBJQ zZNd8dK$ua5-Da>2rRPXcaIG&>jJ4(~_mr5oCzVd`tG1C9HmE_Yp&+QxAY8GLxyK(4CMqqN^30ovLFu=VkNkY>*Szyp(-YXVWtbz~`vJ`Y!-W*4%Gg^UR# z-ww_KAiGxj(AmUEjRXCb#dt{%d9)qAo6 zFm&{9F#Upn&WsvNWp9D>(`zKR4m1?<5OVWP14$zbaws{4roILGHAR38e^v_3aBxQ| zS!jNV8YVU-RSE{Vfs~eGY6>aPVnVoHV8TS!SiloPcNn~baQBn*&|zD!TzYFHLY-~t zTp_a&=yiM!2cKUI(qXiCi<-jX1o{CArOSeRQ>=QS)??$&16-mDoFZUp9i~_hYRj>* zC83sJi&tz~;!I%im>aP2#?F;3n7T8dwiJ@*QdkWtTMH>baaY*XQSV-;o3Z)ucBYK2 zx0znWkYVE}Yw!hK26U$e7O~3FAeANp?Ft2(rkV;NWqIqR1{Y0!Q%hlE-7?tpAWzy& zre(r(T9mG^x{95lV5xks6lOVg3fT&ukEsSj{o{AGwNq{rPJg_WOz*)I4I@1uo(?9L7*gNc&ITZ0=shyV6*vtDVYMW^?SV-cFN#9i?`I5 zqLdl6ZuGedM1KAB!2n1RYvf|2rEM0Ta)4iEd_-+@LDElBY*f&J^tGj*Y>6SM z1Jk4yvB0?QogyP_Q8B%dBo389+l?l$c=>3uz#i$ZaP@3B`FF3^qr9uN&6sF913>_i zF0&JaEmCHKhJ6jn`27ULGFc?ps|CFmZ0ME2G@$&MLP+G60I@mKs>_kq4NQilH(X%T z7%kmc4K}%?UV-9DrM{Su9R(6@&x9#(W(rFoSPy3L_*XE95ndWC+B}TZ+n{mV0ai}k zfXY=VFwJ2~a3pH+4rv{msCljcmYf}6vNdaUzL2GY%h)+^l^7d;(9p>HL?Eccl-bPX zKrEU>@1BWAa6o_yzS#^`<#e3|P+hg(f>nn$+>?TN$P(x-DSFyXmmUFjZaa05NxQ%f z5gv^|*nZPp2RpH2)xOx}=P|&1;SetF3;}r%Y|u*C5bh85iG>x2=*+CaM8Qu&J*+Z_ z-m;b66%l_Ph4c%aZM7bQxS{RdkVF0K3_`!01)1r>KS2>G10fU;mVE%TPRtQ1P*nlo znlhR+v5;vUc)ivQE-IUP0wvxe3s~q;GwAhfGQiD&Kcy5lPwoTRhM|XJZ5`IGdao|W zVkPF5!wJC7hqZb{Ja&Xw(qW98N0g@5pdm_d$%Jw+3*zCbYF~OuAtL)ghSOZVAYLYbEfx{I(=I>wBMPO*`E3l0sleq-4%_H>XFJsCxX6Flt2{L2~KDlXP` zd=2*Z+qaPRi8`GCx(UOrxy@{R3YS+Z@l9esx6}q-x|7N@n-2ag8g+uqE+; zM<=NCtz!#^$Op$QJ4Nc9&@9*$!QPn-uG_eXY;eNi!~MWczCI2Q*^wWYtmC4G=gAa% zcyL|M0|e5E(2Vuq-8Ko3Ybt$o98~v*rUFtAO(`6<*NegJAyKQCr7MRGS0#Z7c=QDO zXm?g4a_dD0LA{C;b%6(yLSK{?#Db^IuVL3!J_NR}oCV-qcL$SZE~>~TE4riG^adob zGii1}myW}ZE$eK}eg=e z@lLX#3o6 z8uqKM1rAqBK>zw?T{Ap&t`?zDlXVp8HvwQUeoO)V;NS-qmw=O)HFI=YIMRX4K01*s zwMLhI))~-X1z^a6{VZRAeR_*AP6A5qRa2`#Mh{ZU!Qu%cOG>eE`);7g%`TzX#-iVr zFd*=Jvyh8nBNY~0QjU$iA3^#?-LC}^w3dJ<3mWLm_uG&rEjlr@lETF3^Q74d`Ta=} z)@X8fSUbw*Ytqa@tOvBQjX6YP|BHM8r^$bSo9EALB2X_OtO@IlfRAgOHOz9H((e`+ zdt-1tpqZloH}@*AF>Nl4&iVNSvl+X)4`-TDf{?^qoc!)kWdVLMiI5YJk~E3n2urSq zb69|1FjM+!OpsT>K^E!8MdyM6@{ZjF=NM*9@@!D-F<^V{lE8ooc{2#q?MtBv?Y{uv zsdy-GgOjY?_2p>BWvJY=l-Yo(!X^Qr#*g$yo;v)Epn%RW=)+aw;#|0)gqs8aN6LjT zWn%9aV9}MM0aK}>L@+J$JBYVKjm6D`n#8csa>%U?ZpcMp@X4b1OT8M9mg$a zW4?htxG{P8)9}>$8eChJH~=y?AD?~?(uSI)_ad;t)C9>8L5QVzV6x9; z+)|i@@e%a%T~*D4@CnPgbu#_LiRilseE()FON+v<3V`nIvT8G&>w%i6Z|fiqi>HkM zSK|kJsVN-s#Wko`p43Z0uPcT#Ax+I351#yHanwCHX}MBZqQnhhbGbZtpkfLpYv9r6 z4OS@<-D-j?a5w-vVerDn5Xi`~U)q-42-66$3{8SB2SN4j2{8JO>3?Yznnm(&t z_0_j|9*3~uQtfC9xs=wC2eAj8HhJHT8Gr9uKN zHiPx9a&I!wkLg=b2&cXVExyie02GZ_;D^>RxIy+9;6LVQTIvsR1ke-hyFK zD~<`ly!(IqcUlW$h>RyWC=kK;^XCG=@%Ky{p}z2|Ktmm z&`3X6mVo&5KV`O<{zB#FwXI*MY$ji1TK)BnN~`GvrihMWim)>hoy1}bI|I?t%gE?V ziIIzlVHs_-=xP*q^fEAPa*Q2%5)vFJvfwT@qCR4YWwgP9++$?23mEJ~{!9mxzN1eK z!zN2VvwO3?)9@AsX9mC6nX?WD`C4!n>Wc-Ub*%6L3%m9F5@EzT%h5F!B;;KE5Av9M**w-0q^sC2m2I zIgu5&?W$xYeMcXjGrH!sy`i+keS&0ee8X+Brmkc_-r>39T5fkW;#s0ulCnhJ9bTPm zmgmyL>|n2>4nI>tUK>5EQ=^YMUN#2#?Ad9Zk#n@$Eh59PRPS7(D#N&dy)IINI|)Arm7{&J4R_{5W6i&wY+d+>4#9C)Wk= zxwg8{;$HSU>!hNEw%?=`_wN3zE?CUvE+{K@5qQ+gBNlR(Y%Lb_pIjfJ@)Ni`N*lyyXcYBEx>uisIn}(jV@AQh-yUCs^@l9fzrNF>qf+E&9dK` zEbTYuml3fCpW7RXrS3`2A#ta&$UPgS{U@nH#$10+)*O=#$X*vR_F>|(0}af9Q_h|o z*K)4wk8hcxBHOZY9Rn(k@a~IB3bb{Azhch|H z2d!m-^cI7l;c?yGiTlRec)%(**I(*)cs-fPeU#r4$s@OyZh6e zKHTXyU)vOT+4gu=Hhb7TkDsTQ7WH_!b@mreCjb1Exl7O2r)Cd-x%1~~&5L@zdp!Hg zch7#FPT27o)}>;mr>Tgun9uBADzVNo&E(rTv%*UK?RS|T zt_(!{Q96P{ahEp+x{X*cXY{f4>{|Ql!vA+T(kyNy2&*oqBk#Gvc0&{U84!fVG+yrU$7WBjTO3= zwW#8F;3m)IO`$0x7Ol8+Y?IITO<~$Oi&ota{C3C{jdlK!s5LM4^cnuLe&lqEXg%_F z^S3_{G21_S{WyJ92lqLnzFA+iVVrVVu%vI~!WDLvebv<=s=iScrVE>VFA8lB8>7}* z#8d@(_l;a~BKlkZn9b39`;OjwB4!|Qc8jIaO;I~y^zQXB+tThW8uLrv*!@@ScNE^+ zGM>>-am10_IY+%U$+=(LiFk5%qRD;Y7gq6S7hc*^71MvxSgSEt&XMW+YPV%fc{Iix z>0fiqdqCEblL-&}WA|U!J0NfG$+5rAh&_1Mdtl+kljB~^=<>t!${q0K+VSt6U;dFG zMMc(SO6H)3!+R)0u`o?_QmHtaVm8c{oC>mC)Nssgw8z}B>?DWt4aa>idCZ^2PIm5c zrA{{5bJ1$HS{QZZgyNFtvP0|%9*eG=N*O(97F@pp&H&6#WJsp+tT`fquHfdaemExPL(t)HENOL z#my7;Zc+806#wYxrJ76LJG}2qQd+HSI3Bcb*YYQ6DIqJbjx+e|J4{)mZ=kMu<#=!o zS!YaMS#h1?GuXnkEh8`L+6_nQyMs;XnNuHKvv~XaU?VeJJF|DfFYJ8ZV|)3Nr|Tva z-6p&CKJNW=z`U=V?)K{QeZ9lntTlZ{-6Pe0mgS9E6-S+_$R*#O(ws?Lc_-n)uvdPj zlJJ}jy~j3%<`2108J@c(Y3!qfS3??V!}E4;82cnGf9Uml;rR#djQw@$tD$D*$bzH2 z$2}{{A9hzTa>~i1alfs4HLOuOvhe(daW6AehaRa0es%R)k5~I29Qw6r;MCjQ)*h)_ zrh7i+e!KOa;E5SF z*LNYWv2I%8fmiNbaqX4#+z@ zcRWhs)mG^|`j&CU%7%@u(&L^ho|UDf1v*}AT!N4uT`BG~!ZgG2g&v1h`FA~GnlKV*B~t zRnQlGBNuJ%_gt7;eKIjMYW17ws-T$7QI)AN+X`d0PKenu=3Z*-p*JyxSutCa1e4-U z7mnVuDQ4Rw^`tR39Dn-mi1+ra)&0gkO1*sGw)c+08~w)r@$mAG7Cwd<-Q87IlNyfp z^4U3Otb0g26IC*1D(=evQ_X-6d^ zL~TR^3`L#G%&1?%VRnXLW>5AnIHcf+-F8FCoop5RPQRm$H$}6DKK`ZiOy6U@dU)u% zk4~Juyyci%_)cBSTYM=nz1BTr=iKq^JG_$x$Gv)JzDb{&U%AB;jy?guBj~M5#hU{KZ3D9z z(iaL|EJ?6??FDgA&Yr--M(^oB(eH+`TDVgec;e=&wpY-Bxqw;%|EIQCoB_Ep_ zwbt=sx9ZU^H^<#bjs5ZJe#5-ITZj5iir>vi+}6}t6=QRaYt9o zKKJtFjw0*tl~zN!?#>U>XNNsb?Dj`PUHHCT%TA|R@RW%tC9i5#Sj3MW<{w^M{cZQU z?&(yokgMl61rNjP$~oinR9ONdlz#WCwbFLNhhHGbm>2=G)+DPxY3=%1>-aQP zqB^ZD1*gyZw7wBP9^QLSZrhRjpN^60B#l-BZ-TaM=6&A$IkWEVbZVa)J6Vv}Bc|Nmq~8!VA!u$%MTn)G+B+h}9p|g>o}ApGa*f7U9HN_&1(G_h%hz0hW&{$yMEUCxe%6r+h<#L zoWH9-8ABF3J2*MKwR0t$?AZ?9L`ROp-!@}!0nOw*L{=cz9~iFq|9?L?;ouG+4p{L4 zQ!I#KWchJhhmH=e@DmhZ?QLiExzT@^-W~>dkl}h0x#|%;zyJLD0Q^A3-@iTpH{f!g zbKCmJqJ3`v=0qQOE@hBw7_Q|VU9U4~o}d3V#pj$Vjx*Zl^k2H-2X^HQvV!5dwUg_c z*53^I=Z{x>&TMhzzc6dZojW|MC_x|-Rp3tO$^KU!?(Hyl1^_pe&~S9tiqw84^m z%5rTWUFUUfRb%@v?|;tk&5VCpwf`Dv+A4FqgX>!!&Gi3)GCx7955!L~$O{bDtB$UV z9ckkKeEq(?_whfU-oalxv~Mcypx_6#Tj9{q!u5=kYhyQ>?SJ>K{r}0!_@9gQ_I;;M z#X^7KOF$hy_)_RSK%jEVEGrv59t0EuQChr$SH#;?jxYK29OWjKA_F2SAaObGiY76O(Or9QGQ0A{8vwD6OukKy2&8# zGhFYtFkDx(v@&WZgZ!7Q@^iLz=g_B1_i<+UW61l!w3tDbFf+7sHOxBp0WKWA2T zq78zR$8OMxiYq3Yi!2BSCmvf8896d`$cIdrr)LkO|9MNK5{YCK6#8F?M3OJ@pC}2E zNG3`GCbri3`%5HY^rrxcL{9&O`;UL&rgdmO)Jc5kZXx-BP?-s2;12F1=wSibKu)5j zhe_#s_y_leH0uzWoPRzo!6^FPpS}-lSTSaZdpC;v>6CWE?n5-C)mKZxaH(BbD zmK>at7a!!89Ty9Al7KLp{}h@YJ-tyet&l(EsBmE zEm8&hO`?0|)8hvgeyR^pCH(ta9tqvmUjsDK6ob-$7QJ+V*);!-U+w znZVTFBQZTq^!K{?=hOVM{vmHLEp8imTh~uEI#;D=Ri`AK?(Y}P`~4+vKLK zkp_SBRkV-%$2aIPfvxh%!AAc}|Db36Z}jLUdb~$8T-w+hpcDN2+do?E!9N}5NMi-a zmOP5a4$xUzQkq|WoMMDXJ=!k|+CLa^P%6;t7Xz2J_(2c7ZG&p)hnexqpX0(%1$CrMhT2#fijN&bZ|txnlyJ)l2W zXt*d&5ji0_J!lGjORv|*p#+Z)=Lzs*W;y+nwA%ivtgOs@ex5ojTLZsK=IJ#+G(ZGf VWH>(gzx|(B3qOt+0Y4A dict[str, Any]: step: dict[str, Any] = {"spec_id": self.spec_id, "definition": self.definition} if self.sentence is not None: step["sentence"] = self.sentence + if self.entity_groups: + step["entity_groups"] = self.entity_groups return step -def _part_spec(spec: dict[str, Any]) -> Spec: +def _step_spec(step: Mapping[str, Any]) -> Spec: + """The Spec a step's `spec`, or `held_spec`'s shape, holds.""" return Spec( - spec["spec_id"], spec["definition"], spec["resolved"]["rendered_sentence"] + step["spec_id"], + step["definition"], + step.get("sentence"), + step.get("entity_groups"), ) +def _part_spec(spec: dict[str, Any]) -> Spec: + return _step_spec(held_spec(spec)) + + def _members(answer: Answer) -> list[tuple[list[str], Spec]]: return [(parts, _part_spec(spec)) for parts, spec in answer_members(answer)] @@ -797,7 +809,8 @@ def _member( definition = manifest["definition"] sentence = None if spec is None else spec.sentence if spec is None or definition["spec_id"] != spec.spec_id or sentence is None: - sentence = self._identity_sentence(parts, definition) + held = None if spec is None else spec.step() + sentence = self._identity_sentence(parts, definition, held) digest = artifact["artifact_digest"] rows, columns = self.read_shape(self._download(artifact["url"], digest)) return Member( @@ -811,12 +824,13 @@ def _member( dict(rendering), ) - def _identity_sentence(self, parts: list[str], definition: dict[str, Any]) -> str: - entry = { - "entry_kind": "identity", - "variable_text": parts[0] if parts else UNNAMED_VARIABLE_TEXT, - "identity": definition["identity"], - } + def _identity_sentence( + self, + parts: list[str], + definition: dict[str, Any], + held: dict[str, Any] | None, + ) -> str: + entry = sentence_entry(parts, definition, held) answer = self._resolve({"kind": "dataset_resubmit", "entries": [entry]}) return resubmitted_sentence(answer, definition["spec_id"]) @@ -1040,6 +1054,7 @@ def with_place_options(body: Any) -> Any: TWO_CANDIDATES = "GNI of Germany and tax revenue of Kenya from 2015 to 2022" CANDIDATES_BESIDE_UNRESTATED = "GNI of Germany and debt of Kenya from 2015 to 2022" GROUP_DEFINITE = "GDP of the least developed countries" +GROUPED_FLOW = "Germany's ODA to the least developed countries" ASYNC = "ODA received by every recipient country from every provider (DAC2a) from 2018 to 2024" NARROW_WINDOW = (2020, 2023) REBOUND_ORIGIN = "country/FRA" @@ -1217,6 +1232,28 @@ def run(s: Session, ctx: Context) -> None: return run +def _fetch_spec_grouped( + *, + window: tuple[int, int] | None = None, + entities: Mapping[str, list[str] | None] | None = None, +) -> Callable[[Session, Context], None]: + """Fetches the GROUPED_FLOW spec, whose destination is a named group, with + the narrowing given, and checks the built sentence still names the group.""" + + def run(s: Session, ctx: Context) -> None: + spec = ctx.definite_spec(GROUPED_FLOW) + groups = spec.entity_groups or {} + require("destination" in groups, "the destination is a named group") + (member,) = s.fetch_spec(spec, window=window, entities=entities) + require(member.spec_id != spec.spec_id, "the narrowing gives a new spec_id") + require( + groups["destination"]["label"] in member.sentence, + "the built sentence names the destination's group", + ) + + return run + + def _fetch_spec_known_sentence(s: Session, ctx: Context) -> None: spec = ctx.narrowed_spec() (member,) = s.fetch_spec(spec) @@ -1399,6 +1436,22 @@ def _resubmit_placeholder(s: Session, ctx: Context) -> None: "a new spec_id bound to destination alone.", _fetch_spec_entities({"origin": None}), ), + Recorded( + "fetch-spec-group-narrowed", + "Fetching a spec whose destination is the least developed countries group with " + "window=(2020, 2023) answers a new spec_id. The identity entry that asks Search for its " + "sentence carries the spec's entity_groups whole, since a window leaves every role's " + "binding as it was, and the sentence names the group.", + _fetch_spec_grouped(window=NARROW_WINDOW), + ), + Recorded( + "fetch-spec-group-origin-rebound", + "Fetching a spec of Germany's flows to the least developed countries group with " + "entities naming only origin rebinds origin to France. The identity entry that asks " + "Search for the built sentence carries the destination's group, whose binding the " + "build kept, and the sentence names the group.", + _fetch_spec_grouped(entities={"origin": [REBOUND_ORIGIN]}), + ), Recorded( "fetch-spec-known-sentence", "Fetching a spec whose sentence the client holds builds bare Parquet, follows the files " @@ -2613,7 +2666,7 @@ def drive(session: Session, call: Sequence[dict[str, Any]]) -> None: case {"op": "fetch", "spec": spec}: window = step.get("window") session.fetch_spec( - Spec(spec["spec_id"], spec["definition"], spec.get("sentence")), + _step_spec(spec), window=tuple(window) if isinstance(window, list) else window, entities=step.get("entities"), facets=step.get("facets"), @@ -2633,7 +2686,7 @@ def drive(session: Session, call: Sequence[dict[str, Any]]) -> None: ) case {"op": "mint", "spec": spec}: session.mint( - Spec(spec["spec_id"], spec["definition"], spec.get("sentence")), + _step_spec(spec), layout=step.get("layout"), ) case {"op": "operation", "operation_id": operation_id}: diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index 9a94c0a..ca586a4 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -44,6 +44,9 @@ _NEWER = "scenarios/fetch-ref-expired-newer-version.json" _REBOUND = "scenarios/fetch-spec-entity-rebound.json" _DROPPED = "scenarios/fetch-spec-entity-dropped.json" +_GROUP_NARROWED = "scenarios/fetch-spec-group-narrowed.json" +_GROUP_REBOUND = "scenarios/fetch-spec-group-origin-rebound.json" +_ORIGIN_GROUP = {"label": "G7", "group_id": "groups/G7"} def _posted(index: int, change: Callable[[Any], None]) -> Callable[[Any], None]: @@ -177,6 +180,14 @@ def _posted_entities(change: Callable[[Any], None]) -> Callable[[Any], None]: ) +def _rebound_group_kept(doc: Any) -> None: + """The held spec groups origin as well, and the resubmit keeps that group + though the fetch rebinds origin.""" + doc["call"][0]["spec"]["entity_groups"]["origin"] = _ORIGIN_GROUP + entry = doc["exchanges"][1]["request"]["json"]["input"]["entries"][0] + entry["entity_groups"]["origin"] = _ORIGIN_GROUP + + def _last_response(change: Callable[[Any], None]) -> Callable[[Any], None]: return lambda doc: change(doc["exchanges"][-1]["response"]) @@ -450,6 +461,12 @@ def _last_response(change: Callable[[Any], None]) -> Callable[[Any], None]: ].update(variable_text="ODA"), "where the rules post", ), + ( + _GROUP_NARROWED, + _posted(0, lambda entry: entry.pop("entity_groups")), + "where the rules post", + ), + (_GROUP_REBOUND, _rebound_group_kept, "where the rules post"), ( _REBOUND, _posted_entities(lambda entities: entities.pop("destination")), @@ -743,6 +760,8 @@ def _last_response(change: Callable[[Any], None]) -> Callable[[Any], None]: "definite-part-posted-parsed", "restated-part-posted-placeholder", "identity-resubmit-wrong-variable-text", + "kept-group-dropped", + "rebound-role-group-kept", "unnamed-role-dropped", "null-role-kept", "named-role-merged", diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index 2e4e6c2..e5ba433 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -48,7 +48,8 @@ counts are left to the Parquet bodies, and each download hashes to its artifact's digest or the outcome says it does not. Each Search request a record holds posts the input the steps derive: the question, a choice's - data_query or dataset_resubmit entries, or a member's identity, and each + data_query or dataset_resubmit entries, or a member's identity with the + entity groups of the roles its build left bound as they were, and each build posts the options its layout gives. Every absolute URL a record holds, a `url` request or a `location` header, has the query `X-Goog-Signature=redacted`. @@ -1054,6 +1055,21 @@ def answer_members(answer: Answer) -> list[tuple[list[str], dict[str, Any]]]: return list(members.values()) +def held_spec(spec: Mapping[str, Any]) -> dict[str, Any]: + """A served spec as a client holds it, the shape of a step's `spec`: its + spec_id, definition and sentence, and the entity groups its `resolved` + names, when it names any.""" + resolved = spec["resolved"] + held = { + "spec_id": spec["spec_id"], + "definition": spec["definition"], + "sentence": resolved["rendered_sentence"], + } + if groups := resolved.get("entity_groups"): + held["entity_groups"] = groups + return held + + def answer_outcome(answer: Answer, kinds: Mapping[str, str]) -> dict[str, Any]: """An answer outcome. A declined or catalogue answer is never complete.""" gaps = answer_gaps(answer, kinds) @@ -1286,6 +1302,42 @@ def resubmitted_sentence(answer: Answer, spec_id: str) -> str: return sentence +def kept_entity_groups( + held: Mapping[str, Any] | None, built: Mapping[str, Any] +) -> dict[str, Any]: + """The held spec's entity groups a built definition keeps: the group of + each role the built identity binds to the same entities the held + definition binds it to. A role the narrowing rebound or dropped loses its + group; a window or facets narrowing keeps every group.""" + if held is None or not (groups := held.get("entity_groups")): + return {} + before = held["definition"]["identity"].get("entities", {}) + after = built["identity"].get("entities", {}) + return { + role: group + for role, group in groups.items() + if role in after and set(after[role]) == set(before.get(role, ())) + } + + +def sentence_entry( + parts: list[str], built: Mapping[str, Any], held: Mapping[str, Any] | None +) -> dict[str, Any]: + """The dataset_resubmit identity entry that asks Search for a built + definition's sentence: the built identity, the member's first part or + UNNAMED_VARIABLE_TEXT, and the entity groups `kept_entity_groups` gives, + left out when it gives none. `held` is the spec the client built from, + None for a resumed operation.""" + entry: dict[str, Any] = { + "entry_kind": "identity", + "variable_text": parts[0] if parts else UNNAMED_VARIABLE_TEXT, + "identity": built["identity"], + } + if groups := kept_entity_groups(held, built): + entry["entity_groups"] = groups + return entry + + def failed_operation( resource: Mapping[str, Any], actions: Mapping[str, Mapping[str, Any]] ) -> tuple[ClientError, bool]: @@ -1615,7 +1667,7 @@ def member( built = manifest["definition"]["spec_id"] sentence = None if spec is None else spec.get("sentence") if spec is None or built != spec["spec_id"] or sentence is None: - sentence = self.sentence(parts, manifest["definition"]) + sentence = self.sentence(parts, manifest["definition"], spec) self.download(artifact["url"], artifact["artifact_digest"], origin=True) return { "parts": parts, @@ -1624,15 +1676,17 @@ def member( "sentence": sentence, } - def sentence(self, parts: list[str], definition: dict[str, Any]) -> str: - """Search's sentence for a built identity. An answer that is not one + def sentence( + self, + parts: list[str], + definition: dict[str, Any], + held: dict[str, Any] | None, + ) -> str: + """Search's sentence for a built identity, posted with the entity + groups of `held` that the build keeps. An answer that is not one definite part of the built spec_id, with a sentence, raises ContractError.""" - entry = { - "entry_kind": "identity", - "variable_text": parts[0] if parts else UNNAMED_VARIABLE_TEXT, - "identity": definition["identity"], - } + entry = sentence_entry(parts, definition, held) answer = self.resolve({"kind": "dataset_resubmit", "entries": [entry]}) return resubmitted_sentence(answer, definition["spec_id"]) @@ -1679,7 +1733,7 @@ def stored_version(self, member: dict[str, Any]) -> dict[str, Any]: newest = self.newest(spec_id) else: if manifest["content_version"] == version: - held = {"spec_id": spec_id, "sentence": member["sentence"]} + held = {**spec, "sentence": member["sentence"]} return self.member(member["parts"], held, manifest, rendering, False) newest = manifest["content_version"] raise ClientError( @@ -1805,10 +1859,7 @@ def _fetch(self, step: dict[str, Any]) -> dict[str, Any]: members = [ self.fetched( parts, - { - "spec_id": spec["spec_id"], - "sentence": spec["resolved"]["rendered_sentence"], - }, + held_spec(spec), rendering, strict, ) From 6148139d5c40116c13224305f00ea22918a37714 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Wed, 21 Oct 2026 11:03:05 +0200 Subject: [PATCH 17/39] feat(client-contract): record the contract against the composed server Every recorded scenario and the served OpenAPI document now come from one dfo-apis commit, 635943e03, which composes dev with the search choice options, answer statements and datasets client contract branches. The served document lists the four deployed surfaces: Search, Datasets, Graph and Presentation. The contract holds 67 scenarios, 29 recorded and 38 synthetic. The long builds record against the composed app: mint-async-build, operation-resume and their synthetic children, and the expired file redirected through the file selector. Signed download URLs read as storage.googleapis.com URLs with the signature redacted, since a production download is cross-origin; origin.base_url states the base URL the client was given. The rules the recording pins: - Every candidate pick, in a one-part answer too, posts the reading's identity to Search as a dataset_resubmit entry echoing reading_assumptions[spec_id] as its assumptions, and the picked answer and its sentence come from Search's response. - A client asks for the newest stored version with GET /datasets/{id}/versions?limit=1; only not-found reads as none. - A mint takes only a layout. - A required member that admits null must be present. - capability_unavailable keeps the fix_request action, pinned by fetch-spec-capability-unavailable. --- python/client-contract/CHANGELOG.md | 6 +- python/client-contract/README.md | 19 +- .../dfo_client_contract/scenario.schema.json | 7 +- .../answer-candidates-choose-fetch.json | 897 +- .../scenarios/answer-catalogue.json | 24 +- .../scenarios/answer-declined.json | 22 +- .../scenarios/answer-definite-fetch.json | 450 +- .../scenarios/answer-mixed-fetch-partial.json | 241 +- .../scenarios/answer-mixed-fetch-raises.json | 120 +- .../answer-several-readings-folded.json | 1218 ++- .../scenarios/answer-timed-out.json | 114 +- .../scenarios/answer-unknown-enum-value.json | 94 +- .../scenarios/answer-unknown-kind.json | 92 +- .../scenarios/answer-unknown-part-status.json | 114 +- .../scenarios/answer-unsupported-part.json | 111 +- .../choose-candidate-assumed-reading.json | 3190 ++++++ .../choose-candidate-echoes-assumptions.json | 8990 +++++++++++++++++ .../scenarios/choose-candidate-two-parts.json | 197 +- .../scenarios/choose-part-by-mention.json | 67 +- .../choose-place-beside-definite.json | 112 +- .../scenarios/choose-place-one-part.json | 68 +- .../scenarios/choose-place-two-parts.json | 93 +- .../choose-refused-answered-part.json | 114 +- ...hoose-refused-mention-names-two-parts.json | 24 +- .../scenarios/choose-refused-no-choice.json | 323 +- .../scenarios/choose-refused-no-options.json | 46 +- .../choose-refused-option-out-of-range.json | 52 +- .../scenarios/choose-refused-two-choices.json | 198 +- .../choose-refused-unknown-label.json | 23 +- .../choose-refused-unknown-part.json | 114 +- .../fetch-frame-several-readings.json | 1014 +- .../scenarios/fetch-null-member.json | 446 +- .../fetch-partial-nothing-answered.json | 94 +- .../fetch-ref-expired-file-selector.json | 903 ++ .../fetch-ref-expired-newer-version.json | 116 +- .../fetch-ref-expired-not-reproducible.json | 32 +- ...etch-ref-expired-rebuild-same-version.json | 123 +- .../fetch-ref-signed-url-refused.json | 167 +- .../scenarios/fetch-ref-unknown-version.json | 12 +- .../scenarios/fetch-ref.json | 168 +- .../scenarios/fetch-renamed-strict-field.json | 437 +- .../scenarios/fetch-retry-after-504.json | 444 +- .../scenarios/fetch-spec-async-build.json | 1208 +++ .../fetch-spec-capability-unavailable.json | 198 + .../scenarios/fetch-spec-digest-mismatch.json | 34 +- .../scenarios/fetch-spec-entity-dropped.json | 211 +- .../scenarios/fetch-spec-entity-rebound.json | 184 +- .../scenarios/fetch-spec-frame-layout.json | 71 +- .../scenarios/fetch-spec-group-narrowed.json | 58 +- .../fetch-spec-group-origin-rebound.json | 58 +- .../scenarios/fetch-spec-known-sentence.json | 35 +- .../scenarios/fetch-spec-narrowed.json | 186 +- ...tch-spec-operation-failed-resubmitted.json | 1328 +++ .../fetch-spec-poll-rate-limited.json | 1221 +++ .../scenarios/fetch-spec-request-invalid.json | 10 +- .../fetch-spec-resubmit-other-spec.json | 175 +- .../scenarios/fetch-spec-strict-warning.json | 24 +- .../scenarios/fetch-strict-info-notice.json | 444 +- .../scenarios/mint-async-build.json | 1218 +++ .../scenarios/mint-async-build.parquet | Bin 0 -> 913395 bytes .../scenarios/operation-resume.json | 5834 +++++++++++ .../scenarios/operation-resume.parquet | Bin 0 -> 1031059 bytes .../resubmit-candidates-sibling.json | 144 +- ...ubmit-placeholder-without-restatement.json | 179 +- .../scenarios/search-place-ambiguous.json | 102 +- .../scenarios/search-proxy-rate-limited.json | 94 +- .../scenarios/search-retry-after-503.json | 94 +- .../search-two-parts-place-ambiguous.json | 206 +- .../scenarios/search-warning-top5.json | 123 +- .../dfo_client_contract/served/SOURCE.json | 2 +- .../dfo_client_contract/served/openapi.json | 1620 +-- tools/README.md | 2 +- tools/capture_client_contract.py | 490 +- tools/tests/test_capture_client_contract.py | 85 +- tools/tests/test_validate_client_contract.py | 90 +- tools/validate_client_contract.py | 120 +- 76 files changed, 31493 insertions(+), 5451 deletions(-) create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-assumed-reading.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-echoes-assumptions.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-file-selector.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-async-build.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-capability-unavailable.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-operation-failed-resubmitted.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.parquet create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/operation-resume.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/operation-resume.parquet diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index b85256a..8baaa8c 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -7,14 +7,14 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be ### Added - Package scaffolding (uv, ruff, ty, pytest). -- `served/openapi.json`, the composed dfo-apis app's OpenAPI document, and `served/SOURCE.json`, naming dfo-apis commit `8408f1f95c622223f8fa6e9ba55826ee8e22a852`. +- `served/openapi.json`, the composed dfo-apis app's OpenAPI document, and `served/SOURCE.json`, naming dfo-apis commit `635943e03a297f686ca5af32f6d027181d1971d4`. - `strict-fields.json` and its schema: 25 members that stay required and non-nullable, and the answer kinds, part statuses and operation statuses the clients branch on. - `actions.json` and its schema: the caller's next step for each of the 101 active refusal codes on `problem_details` or `no_data_reason`, with the gap kind of each no_data reason. - The status fallback for a refusal whose code has no row: 400 and 422 to `InvalidRequestError`, 401 to `AuthenticationError`, 403 to `PermissionDeniedError`, 404 and 410 to `NotFoundError`, 408 to `DfoTimeoutError`, 429 to `RateLimitError`, and any other 4xx or 5xx to `InvalidRequestError` or `ServerError`. -- `scenario.schema.json`, the scenario record, and 58 scenarios: 23 recorded against dev at dfo-apis `8408f1f95`, `7175fe98e`, `687d48bf1` and `36b9f48d8`, and 35 synthetic, each derived from a recorded one by a one-line edit, with 17 binary bodies totalling 160,747 bytes. The scenarios cover the several-part choice entries, the choice refusals, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a refused build, a digest mismatch, an identity resubmit answering another spec, and a ref whose stored file expired, rebuilt at the same version, at a newer one, or refused. Six more are defined and wait for a served document that declares the build's 202 or the file selector: `mint-async-build`, `operation-resume`, `fetch-spec-async-build`, `fetch-spec-poll-rate-limited`, `fetch-spec-operation-failed-resubmitted` and `fetch-ref-expired-file-selector`. +- `scenario.schema.json`, the scenario record, and 67 scenarios: 29 recorded against the composed dfo-apis app at `635943e03`, and 38 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 2,105,201 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, an identity resubmit answering another spec, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, a failed operation posted again, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route. - `client-codes.json` and its schema: the 16 codes a client sets on the errors it raises itself, each with its error class and condition, disjoint from `actions.json` and `registries/codes.json`, and the `client_codes()` and `client_codes_schema()` accessors. Every scenario error the client raises itself carries its code, and `refusal_without_code` names a refusal whose body carries no code. - `dataset-ref.schema.json`, the frozen `DatasetRef` format, with accepted and rejected examples. -- `tools/capture_client_contract.py`, which captures `served/openapi.json` from a dfo-apis checkout in process and records the scenarios against a base URL, dev by default, or with `record --offline` derives their outcomes again from the records with no request. A scenario that needs a route or status the served document lacks waits until the document declares it. +- `tools/capture_client_contract.py`, which captures `served/openapi.json` from a dfo-apis checkout in process and records the scenarios against a base URL, dev by default, or with `record --offline` derives their outcomes again from the records with no request. A local app's signed URLs are written as the storage URLs a deployment signs. - `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, checks `client-codes.json` against them, and checks each scenario's `expect` against the outcomes its exchanges, `actions.json` and `client-codes.json` give, each Search request against the input its steps derive, a sentence lookup's `entity_groups` included, each build's `input.scope` against the narrowing its step names over the spec's bound roles, each build's options against its layout, and each download against its artifact's digest. The outcomes include each long build's operation id, poll waits and resubmissions, and a `VersionUnavailableError`'s newest version. - The client rules and their vectors: the credentials path and file format, the key lookup order, the key format check, and the cache directory and layout. diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 3fa45ec..821a034 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -63,7 +63,7 @@ uv run ty check src/dfo_client_contract ## Served document -`served/openapi.json` is `app.openapi()` of the composed dfo-apis app, every surface mounted. `served/SOURCE.json` names the commit it came from as `{format_version, repository, commit, captured_from}`. It names the closed runtime models, `Manifest`, `ArtifactEntryModel`, every Search part model and `ProblemDetails` among them, which the per-surface schema routes leave open. Both clients generate wire types from it and parse tolerantly regardless of its `additionalProperties: false`: an unknown member or enum value passes through. +`served/openapi.json` is `app.openapi()` of the composed dfo-apis app as deployed, with the Search, Datasets, Graph and Presentation surfaces mounted. `served/SOURCE.json` names the commit it came from as `{format_version, repository, commit, captured_from}`. It names the closed runtime models, `Manifest`, `ArtifactEntryModel`, every Search part model and `ProblemDetails` among them, which the per-surface schema routes leave open. Both clients generate wire types from it and parse tolerantly regardless of its `additionalProperties: false`: an unknown member or enum value passes through. ## Strict fields @@ -91,7 +91,7 @@ The required members are each part's `status` and its payload (`spec`, `candidat | `report` | `ServerError` | Reports the trace id, after the client's retries | | `upgrade` | `ContractError` | Upgrades the client | -A code that maps to `no_data_reason` also carries `gap_kind`, the kind of gap a no_data part with that reason becomes: `choice`, `no_data`, `not_understood` or `unsupported`. `choose` goes with `choice` and only with it. `choose` and `ask_data_question` name a next step inside an answer, so a code that also reaches a problem document takes another action. The website proxy's own `{error, retry, detail}` body carries its code in `error`. +A code that maps to `no_data_reason` also carries `gap_kind`, the kind of gap a no_data part with that reason becomes: `choice`, `no_data`, `not_understood` or `unsupported`. `choose` goes with `choice` and only with it. `choose` and `ask_data_question` name a next step inside an answer, so a code that also reaches a problem document takes another action. The website proxy's own `{error, retry, detail}` body carries its code in `error`. `capability_unavailable` is a well-formed request for a format, reshape or conversion class the deployment does not enable, answered 501; its action is `fix_request`, since the caller asks for another one, and `fetch-spec-capability-unavailable` pins it. A client maps a refusal whose code has no row, or that carries no code, on its HTTP status: @@ -136,7 +136,7 @@ An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct ` Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry, except on a poll, where the long-build rules count retries, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, each build posts the `scope` the rules give, and each Search request posts the input the rules give: the question, a choice's input, or a member's identity. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. -A recorded scenario's request and response bodies validate against their route's schemas in `served/openapi.json`, with one allowance: a required member whose schema admits null may be absent, because the server leaves null members out of the bodies it serves. +A recorded scenario's request and response bodies validate against their route's schemas in `served/openapi.json`. A required member stays required when its schema admits null: the body carries it, as null or a value. A member the schema leaves optional may be absent or null, and a client reads both as null. A client replays a scenario by serving the exchanges in order: @@ -149,13 +149,14 @@ A client replays a scenario by serving the exchanges in order: The records also fix these client rules: - A fetch builds each distinct `spec_id` once, in part order, and finishes one member (build, the sentence when the client lacks it, files, download) before the next. -- A fetch or mint of a spec posts its narrowing as the build's `input.scope`, and posts no `scope` when it narrows nothing. `window` posts `{"kind": "range", "start_year", "end_year"}` for a pair of years, or `{"kind": "all"}` or `{"kind": "latest"}`, and `facets` posts each axis as `{"ref": ...}`. The server's `scope.entities` replaces the spec's whole entity binding, so `entities` posts a whole map: the roles the spec's `definition.identity.entities` binds, with each role the caller names replaced by its refs and each role the caller binds to null dropped. Naming `origin` alone on a spec bound to `origin` and `destination` keeps `destination`. A fetch that names no role posts no `entities`. +- A fetch of a spec posts its narrowing as the build's `input.scope`, and posts no `scope` when it narrows nothing. A mint takes a layout and no narrowing, so it posts no `scope`. `window` posts `{"kind": "range", "start_year", "end_year"}` for a pair of years, or `{"kind": "all"}` or `{"kind": "latest"}`, and `facets` posts each axis as `{"ref": ...}`. The server's `scope.entities` replaces the spec's whole entity binding, so `entities` posts a whole map: the roles the spec's `definition.identity.entities` binds, with each role the caller names replaced by its refs and each role the caller binds to null dropped. Naming `origin` alone on a spec bound to `origin` and `destination` keeps `destination`. A fetch that names no role posts no `entities`. - A built `spec_id` that differs from the posted one, or a spec with no sentence, takes its sentence from Search: the client posts the built definition's `identity` as one `dataset_resubmit` identity entry, with the member's first part as `variable_text`, or `"dataset"` when no answer part names it, and checks the answer's `spec_id` equals the built one. The entry's `entity_groups` holds the spec's `resolved.entity_groups` for each role the built identity binds to the same entities as the spec's definition, so a window or facets narrowing keeps every group and a role the narrowing rebound or dropped loses its group. The entry leaves `entity_groups` out when it keeps no group, as for a resumed operation, whose spec the client does not hold. The server reads a role posted without its group as its members, so a narrowed spec of flows to the least developed countries would read "44 recipients" in place of "the 44 Least Developed Countries". - A dataset of several members puts the `part` column first, then each member's columns in member order, each column once. The `part` value on a member's rows is the member's `parts` joined by `"; "`, so a member that answers two folded parts reads `"health ODA disbursements; education ODA disbursements"`, or the member's sentence when `parts` is empty. - A choice names its part by index, by variable text, or by a word that one gap's options mention, and its option by index or label; a candidate is named by index. A label is matched among the options that mention the word the part was named by. With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. - A choice raises `InvalidRequestError` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is out of range or matches no label or several. -- A choice among candidates in a one-part answer makes no request. A choice of a no_data option in a one-part answer posts the option's `data_query` as the input. +- Every pick of a candidate asks Search for the picked answer, and no client builds it locally. In a one-part answer the pick posts `dataset_resubmit`, without `raw_query`, with one identity entry: the candidate's identity and `entity_groups`, and the part's `variable_text`, `separate` and `operations` as below. The picked answer, its sentence with any "Assumed: …" clause, and its assumptions are Search's response. A choice of a no_data option in a one-part answer posts the option's `data_query` as the input. - In a several-part answer a choice posts `dataset_resubmit`, without `raw_query`, with one entry per part in part order. The chosen candidate posts an identity entry with its identity and `entity_groups`, and the chosen option its `data_query`'s one part as a parsed entry. A definite part posts an identity entry with its spec's identity and `entity_groups`. A candidates part left alone posts a `candidates` entry: its candidate set in the server's order, each with its identity and `entity_groups`, and its `ordering` and `truncated` echoed. The server cannot recompute that order, because it rests on the first answer's bind election and availability reads, and a parsed entry would cost an LLM bind. Any other part posts its `restatement` as a parsed entry, or a placeholder entry with its no_data `reason` or unsupported `code` when it has none. Every entry but a parsed one carries the part's `variable_text`, `separate` when true and `operations` when the part has any; `entity_groups` is left out when the spec has none. +- Each identity a choice posts echoes its reading's assumptions as `assumptions`: the chosen candidate's entry carries its part's `reading_assumptions` under the candidate's `spec_id`, a definite part's entry carries the part's `assumptions`, and each candidate of a `candidates` entry carries its own `reading_assumptions` entry. Search then states the echoed items that still hold, so the picked answer states what that reading assumed. `[]` states none. An identity with no `assumptions` reads as a fresh request, so a client that holds no list for a reading, from a part that carries no `assumptions` or `reading_assumptions`, posts none. The identity entry that asks for a built sentence posts no `assumptions`, since it reads only the spec's own `rendered_sentence`. - A strict fetch raises the manifest's first warning above `info` severity as a `DataWarning` with that warning's code, before the sentence lookup and the download. - An identity resubmit whose answer is not one definite part of the built `spec_id`, with a sentence, raises `ContractError`. - The `frame` layout posts `{"format": "parquet", "bundle": false, "layout": "frame"}` as the build's `options` and downloads the artifact whose rendering's `layout` is `frame`; the `long` layout posts `{"format": "parquet", "bundle": false}` and downloads the bare Parquet artifact with any other layout. A fetch of an answer with several members in the `frame` layout raises `InvalidRequestError` before any build. @@ -163,7 +164,7 @@ The records also fix these client rules: - A declined or catalogue answer is not complete, and fetching it raises `DeclinedError`. - Fetching an answer with a gap raises `IncompleteAnswerError` before any request, unless the fetch is partial and some part has a reading. - A fetch of an answer issues one `SearchWarning` when a definite part has an operation Search did not run, a departure, or a warning at severity `warn` or `degraded`, or the answer's `diagnostics.warnings` holds such a warning. An `info` warning issues nothing. A strict fetch raises the `SearchWarning` before any build, with the code of its one hint, or a null code when the readings differ from the question in several ways. -- A ref's version is found in this order: the snapshot route and the files route at the stored digest; the file selector, `GET /datasets/{id}/{content_version}/file` with the ref's rendering as the query; and a build of the ref's spec in the ref's rendering, which must answer the same `content_version`. A snapshot refusal other than `artifact_expired` ends the lookup, so `snapshot_not_found` raises `NotFoundError` with no further request. A files route or selector refusal of `artifact_expired`, `artifact_not_found` or `not_found` takes the next step, and a selector file of another digest is not the stored file. A rebuild that answers another version, or that raises `InvalidRequestError`, `NotFoundError` or `VersionUnavailableError`, ends in `VersionUnavailableError` with the first refusal's code, or `version_unavailable` when nothing refused. Its `newest_version` is the version the rebuild answered, or else the first `GET /datasets/{id}/versions` lists, or null when that route lists none or refuses with `NotFoundError` or `PermissionDeniedError`. +- A ref's version is found in this order: the snapshot route and the files route at the stored digest; the file selector, `GET /datasets/{id}/{content_version}/file` with the ref's rendering as the query; and a build of the ref's spec in the ref's rendering, which must answer the same `content_version`. A snapshot refusal other than `artifact_expired` ends the lookup, so `snapshot_not_found` raises `NotFoundError` with no further request. A files route or selector refusal of `artifact_expired`, `artifact_not_found` or `not_found` takes the next step, and a selector file of another digest is not the stored file. A rebuild that answers another version, or that raises `InvalidRequestError`, `NotFoundError` or `VersionUnavailableError`, ends in `VersionUnavailableError` with the first refusal's code, or `version_unavailable` when nothing refused. Its `newest_version` is the version the rebuild answered, or else the newest stored version, which `GET /datasets/{id}/versions?limit=1` lists alone, since the route lists versions newest first and needs no key; or null when that route lists none or refuses with `NotFoundError`. Any other refusal of the versions route raises. - A build answers 200 with the manifest, or 202 with an operation the client polls at `/datasets/operations/{operation_id}`. Before each poll it waits the `Retry-After` of a 429 that refused the last poll, else the last operation resource's `retry_after_ms`, else the `Retry-After` of the response that carried that resource, else a backoff of 1, 2, 4 and then 8 seconds that advances only when it is used. - A 429 poll spends no retry. Any other retryable refused poll spends one of the two retries, which a poll that answers restores, and a refusal that is not retryable raises. A poll that answers a failed operation whose error is retryable posts the same build once more and polls the operation it starts; a second failure, an error that is not retryable, and a resumed operation, whose build request the client does not hold, raise the operation's error. - A build cut off by a retryable 504 is posted once more, and a second 504 raises. @@ -171,7 +172,7 @@ The records also fix these client rules: ## Recording -`tools/capture_client_contract.py` refreshes the served document and the scenarios. Its `openapi` command calls `dfo_apis.app.create_app()` in process, every surface flag on, in a dfo-apis checkout with no uncommitted changes and no untracked files, and writes `served/openapi.json` and `served/SOURCE.json`. It refuses an environment that `uv sync --frozen --check` with the five extras below finds out of step with the checkout's `uv.lock`, so the checkout needs its environment first. From the repository root, with the checkout at `../dfo-apis`: +`tools/capture_client_contract.py` refreshes the served document and the scenarios. Its `openapi` command calls `dfo_apis.app.create_app()` in process, with the deployed surface flags (Datasets, Graph and Presentation beside Search), in a dfo-apis checkout with no uncommitted changes and no untracked files, over the checkout's own test origin catalogue and test graph release published into a temporary directory, and writes `served/openapi.json` and `served/SOURCE.json`. It refuses an environment that `uv sync --frozen --check` with the five extras below finds out of step with the checkout's `uv.lock`, so the checkout needs its environment first. From the repository root, with the checkout at `../dfo-apis`: ```bash uv sync --directory ../dfo-apis --extra eval --extra api --extra engine --extra datasets --extra graph @@ -184,13 +185,13 @@ Its `record` command runs every scenario against a base URL, dev's Cloud Run URL uv run tools/capture_client_contract.py record --offline --only answer-declined choose-refused-no-choice ``` - Each record names the commit in the responses' `x-dfo-commit` header, and the run refuses responses that name none or several. To record against a local app, run the composed app, every surface mounted, from the checkout the document came from, with `DFO_BUILD_COMMIT` set to that checkout's commit, then pass its base URL: +Each record names the commit in the responses' `x-dfo-commit` header, and the run refuses responses that name none or several. To record against a local app, run the composed app, with the same four surfaces mounted, from the checkout the document came from, with `DFO_BUILD_COMMIT` set to that checkout's commit, then pass its base URL: ```bash uv run tools/capture_client_contract.py record --base-url http://127.0.0.1:8083/api ``` -A scenario that needs a route or status the served document does not declare waits, since the validator checks each recorded body against its route's schema for that status, and a synthetic scenario waits for its parent as well. `record` names each waiting scenario and what it waits for, and records it once the document declares it. `mint-async-build`, `operation-resume` and the `fetch-spec-async-build`, `fetch-spec-poll-rate-limited` and `fetch-spec-operation-failed-resubmitted` scenarios derived from `mint-async-build` wait for the build's 202, and `fetch-ref-expired-file-selector` waits for the file selector. A server answers a version it has built inline, so a long build records only from a spec the server has not built. `--scenarios-dir` writes records outside the package, unvalidated, waiting scenarios included. +A record's `origin.base_url` is the base URL the run was given, a local app's included. A local app's signed URL, which its launcher serves at `/__e2e__/blob/{bucket}/{object}` on the API's origin, is written as `https://storage.googleapis.com/{bucket}/{object}` with its query redacted, as a deployment signs it, because a production download is cross-origin and the client sends no key there; the run refuses a record whose signed URL or `location` header still names the base URL's host. A server answers a version it has built inline, so `mint-async-build` and `operation-resume` each need a spec just above the 100,000-row sync budget that the server has not built: the DAC2a recipient flows from 2018 to 2024 for the mint, and from 2017 to 2024 for the resumed operation. A local recording therefore starts on a fresh datasets database with `DATASETS_SYNC_BUDGET_ROWS=100000`. `--scenarios-dir` writes records outside the package, unvalidated. ## DatasetRef diff --git a/python/client-contract/src/dfo_client_contract/scenario.schema.json b/python/client-contract/src/dfo_client_contract/scenario.schema.json index a47445a..476973a 100644 --- a/python/client-contract/src/dfo_client_contract/scenario.schema.json +++ b/python/client-contract/src/dfo_client_contract/scenario.schema.json @@ -386,13 +386,13 @@ } }, "mint_step": { + "description": "A mint of a spec, which starts its build and answers the operation; it takes a layout and no narrowing.", "type": "object", "additionalProperties": false, "required": [ "op", "spec" ], - "$ref": "#/$defs/narrowing", "properties": { "op": { "const": "mint" @@ -402,10 +402,7 @@ }, "layout": { "$ref": "#/$defs/layout" - }, - "window": true, - "entities": true, - "facets": true + } } }, "operation_step": { diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json index 8f0ec7c..ee9d38f 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json @@ -1,12 +1,12 @@ { "format_version": 1, "name": "answer-candidates-choose-fetch", - "description": "A question with three readings answers one candidates part, a choice gap with three options. Choosing option 0 makes no request: the new answer is definite, its sentence is that candidate's spec.resolved.rendered_sentence, and fetching it builds that candidate's spec.", + "description": "A question with three readings answers one candidates part, a choice gap with three options. Choosing option 0 posts that candidate's identity to Search as the one dataset_resubmit identity entry, echoing the part's reading_assumptions under its spec_id as assumptions. Search answers that reading definite with its own sentence, and fetching the answer builds that candidate's spec.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "recorded_at": "2026-10-20T16:03:53Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:57:19Z" }, "call": [ { @@ -45,23 +45,23 @@ "entry_path": "raw_text", "raw_query": "GNI of Germany from 2015 to 2022", "normalized_query": "GNI of Germany from 2015 to 2022", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "b018f4db7a8e41cbac1f24b9e43abab8", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "8a56f4a56757466094a49079c6a116c4", "warnings": [], "timing_ms": { - "total": 2, + "total": 4642, "by_step": { "coverage": 0, - "response_cache_layer1": 0 + "extract": 1227 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 7300, + "output_tokens": 300, + "cached_tokens": 861 }, "timed_out": false }, @@ -71,19 +71,19 @@ "variable_text": "GNI", "warnings": [], "timing_ms": { - "total": 4620, + "total": 3202, "by_step": { - "recall": 478, - "shape_arcs": 3, - "shape_probe_coverage": 13, - "shape_probe": 108, - "shape_groups": 200, - "shape_labels": 12, - "shape_admission": 10, - "shape": 1457, - "bind": 2338, - "materialise": 186, - "answer": 161 + "recall": 421, + "shape_arcs": 4, + "shape_probe_coverage": 2, + "shape_probe": 211, + "shape_groups": 29, + "shape_labels": 15, + "shape_admission": 0, + "shape": 1184, + "bind": 1000, + "materialise": 429, + "answer": 168 } }, "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", @@ -396,6 +396,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "candidates", "candidates": { "ordering": "intent_rank", @@ -899,7 +900,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -1433,7 +1434,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -1975,7 +1976,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -2015,6 +2016,11 @@ } ], "truncated": false + }, + "reading_assumptions": { + "spec_c0f61f3ca3558aac184973441a67601e": [], + "spec_403a96317ee8b97f1d8569c71015e5ce": [], + "spec_d94656e5d53b7b6c6b0c683145a1cd98": [] } } ], @@ -2361,6 +2367,740 @@ } } }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "dataset_resubmit", + "entries": [ + { + "entry_kind": "identity", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + }, + "assumptions": [], + "variable_text": "GNI" + } + ] + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "dataset_resubmit", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "2841fbd5b3f24a44b79d2e01ed6faf58", + "warnings": [], + "timing_ms": { + "total": 6, + "by_step": { + "coverage": 0 + } + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GNI", + "warnings": [], + "timing_ms": { + "total": 6, + "by_step": { + "validate": 1, + "walk": 3, + "reread_arcs": 0, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 0, + "bind": 0, + "where_places": 0, + "materialise": 1, + "answer": 0, + "options": 1 + } + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "definition": { + "schema_version": 1, + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicunit_primaryincome_measuredvalue_nominal", + "label": "Gross national income", + "population_type": { + "ref": "EconomicUnit", + "label": "economic unit" + }, + "measured_property": { + "ref": "primaryIncome", + "label": "primary income" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_347a470e04c97eec" + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [], + "related_measures": [] + } + } + } + ], + "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "status": "definite" + } + } + }, { "request": { "method": "POST", @@ -2451,7 +3191,7 @@ } }, "content_version": "cv_3cae36487750f272df16f77858171e89", - "prepared_at": "2026-10-20T15:55:37Z", + "prepared_at": "2026-10-21T08:57:25Z", "coverage": { "rows": 8, "dimensions": [ @@ -2466,9 +3206,9 @@ ], "window": { "kind": "range", - "origin": "query", + "start_year": 2015, "end_year": 2022, - "start_year": 2015 + "origin": "query" } }, "citation": { @@ -2540,56 +3280,25 @@ ] }, "trace": { - "facets": [ - { - "ref": "provenance/OECDDAC1", - "axis": "provenance", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "8223167158242641624", - "default_policy_version": "1" - }, - { - "ref": null, - "axis": "measurementMethod", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "absent_on_selected_facet", - "dispatch_facet_id": "8223167158242641624", - "default_policy_version": "1" - }, - { - "ref": "CurrencyUSD", - "axis": "unit", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "8223167158242641624", - "default_policy_version": "1" - } - ], "applied_window": { "kind": "range", - "origin": "query", + "start_year": 2015, "end_year": 2022, - "start_year": 2015 + "origin": "query" }, - "graph_revision": "dfo-dev-dc-datacommons-service-00259-rpx", - "normalisations": [], + "graph_revision": null, "code_index_stamp": { - "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", "graph_endpoint": "graph_release" }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDDAC1", "revision": "2026-10-12" } ], - "capability_version": "dset_1e6cd9546fac19e9", - "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:PrimaryIncome_EconomicUnit_GrossOfFixedCapitalConsumption_Nominal", @@ -2599,12 +3308,43 @@ "observation_count": 8 } ], - "family_member_count": 1, "family_member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", + "family_member_count": 1, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDDAC1", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "8223167158242641624" + }, + { + "axis": "measurementMethod", + "ref": null, + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "8223167158242641624" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "8223167158242641624" + } + ], + "normalisations": [], "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", - "served_from": "head", - "confirmed_at": "2026-10-20T15:55:38.402563+00:00" + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:57:25.351460+00:00" }, "warnings": [], "diagnostics": [ @@ -2624,7 +3364,7 @@ }, "bytes": 4800, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T15:55:38.338535+00:00", + "created_at": "2026-10-21T08:57:25.321163+00:00", "tier": "working", "url": "/api/datasets/spec_c0f61f3ca3558aac184973441a67601e/cv_3cae36487750f272df16f77858171e89/files/sha256:9086e741fcbfa1fe56a9d8af57c54ae3784744b50a03086d9e715623d9c71766" }, @@ -2635,14 +3375,14 @@ }, "bytes": 5294, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T15:55:38.338535+00:00", + "created_at": "2026-10-21T08:57:25.321163+00:00", "tier": "working", "url": "/api/datasets/spec_c0f61f3ca3558aac184973441a67601e/cv_3cae36487750f272df16f77858171e89/files/sha256:d822d05c709d2d1ca448023a433f936b28403893dede278e2b2696eca3587d1c" } ], "series_count": 1, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -2781,7 +3521,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:25.321231Z" + } } } }, @@ -2793,15 +3537,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9086e741fcbfa1fe56a9d8af57c54ae3784744b50a03086d9e715623d9c71766?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A9086e741fcbfa1fe56a9d8af57c54ae3784744b50a03086d9e715623d9c71766?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9086e741fcbfa1fe56a9d8af57c54ae3784744b50a03086d9e715623d9c71766?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3A9086e741fcbfa1fe56a9d8af57c54ae3784744b50a03086d9e715623d9c71766?X-Goog-Signature=redacted" }, "response": { "status": 200, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json index 4279068..93ba6dd 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json @@ -4,9 +4,9 @@ "description": "A question about what data exists answers catalogue, with no parts and no sentence, and is not complete. Fetching it raises DeclinedError with no request.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "recorded_at": "2026-10-20T16:04:09Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:58:54Z" }, "call": [ { @@ -41,23 +41,23 @@ "entry_path": "raw_text", "raw_query": "what data do you have?", "normalized_query": "what data do you have?", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "a0dc5b26977c494a945c88be3342ca62", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "b189cd826f684905bbf71384dbcf93cb", "warnings": [], "timing_ms": { - "total": 1, + "total": 746, "by_step": { - "coverage": 0, - "response_cache_layer1": 1 + "coverage": 1, + "extract": 745 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 2249, + "output_tokens": 45, + "cached_tokens": 859 }, "timed_out": false }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json index ef64826..8d4a5ff 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json @@ -4,9 +4,9 @@ "description": "A question that asks for analysis answers declined, with no parts and no sentence, and is not complete. Fetching it raises DeclinedError with no request.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "recorded_at": "2026-10-20T16:04:09Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:58:51Z" }, "call": [ { @@ -41,23 +41,23 @@ "entry_path": "raw_text", "raw_query": "should donors give more aid to Kenya?", "normalized_query": "should donors give more aid to Kenya?", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "df97a30a410b494ab7f4eeeed9958aa0", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "cfa01996ace144f3900e03b7e31189db", "warnings": [], "timing_ms": { - "total": 2, + "total": 2072, "by_step": { "coverage": 0, - "response_cache_layer1": 2 + "extract": 2071 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 2251, + "output_tokens": 97, + "cached_tokens": 859 }, "timed_out": false }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-definite-fetch.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-definite-fetch.json index f408299..402b415 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-definite-fetch.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-definite-fetch.json @@ -4,9 +4,9 @@ "description": "A question with one reading answers definite, and fetching the answer builds the part's spec as bare Parquet, follows the files route's redirect with a bare request, and returns one member whose parts hold the part's variable text and whose sentence is the part's spec.resolved.rendered_sentence, with no Search call after the first.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "recorded_at": "2026-10-20T16:03:50Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:57:13Z" }, "call": [ { @@ -41,22 +41,22 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements from Germany to Nigeria for basic health care", "normalized_query": "ODA disbursements from Germany to Nigeria for basic health care", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "c37510c195ea4f928cd9dc72e7adf6b9", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", "warnings": [], "timing_ms": { - "total": 4, + "total": 4556, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 889 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, + "input_tokens": 6116, + "output_tokens": 408, "cached_tokens": 0 }, "timed_out": false @@ -64,27 +64,27 @@ "kind": "resolution", "parts": [ { - "variable_text": "ODA disbursements for basic health care", + "variable_text": "basic health care ODA disbursements", "warnings": [], "timing_ms": { - "total": 4815, + "total": 3505, "by_step": { - "recall": 549, + "recall": 628, "shape_arcs": 1, - "shape_probe_coverage": 80, - "shape_probe": 238, - "shape_groups": 142, - "shape_labels": 0, + "shape_probe_coverage": 5, + "shape_probe": 477, + "shape_groups": 22, + "shape_labels": 1, "shape_admission": 1, - "shape": 1269, - "bind": 2396, - "materialise": 226, - "answer": 227, - "options": 148 + "shape": 1283, + "bind": 1188, + "materialise": 11, + "answer": 381, + "options": 14 } }, "restatement": { - "variable_text": "ODA disbursements for basic health care", + "variable_text": "basic health care ODA disbursements", "entities": [ { "text": "Germany", @@ -100,6 +100,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", @@ -192,14 +193,6 @@ }, "measurement_denominator_unresolved": false, "slot_keys": [ - { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, { "axis": "how", "property": { @@ -240,6 +233,14 @@ }, "label": "netting basis" }, + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, { "axis": "where", "label": "place" @@ -264,20 +265,6 @@ ] }, "slots": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding": { - "kind": "unbound" - }, - "summable": true - }, { "key": { "axis": "how", @@ -376,6 +363,20 @@ }, "summable": false }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, { "key": { "axis": "where", @@ -512,7 +513,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -537,6 +538,102 @@ } }, "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 88, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 30, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, { "key": { "axis": "how", @@ -645,102 +742,6 @@ ], "truncated": false, "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsPurpose", - "label": "CRS purpose" - }, - "label": "sector" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSPurposeCode122", - "label": "basic health" - }, - "value_kind": "enum_value" - }, - "relation": "parent", - "parent": "CRSPurposeCode120", - "member_count": 4, - "served_rows": 88, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFinance", - "label": "CRS type of finance" - }, - "label": "instrument" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance100", - "label": "grant" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 30, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance110", - "label": "standard grant" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSTypeOfFinance100", - "member_count": 12672, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFlow", - "label": "CRS type of flow" - }, - "label": "flow" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 14098, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" } ], "entity_options": [], @@ -1008,19 +1009,6 @@ } ], "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "how", @@ -1106,6 +1094,19 @@ ], "provenance": "measure_elected" }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "where", @@ -1141,31 +1142,31 @@ ], "query_qualifiers": [ { - "text": "ODA", + "text": "basic health care", "named": [ { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode12220", + "label": "basic health care" } ], - "slot": "crsTypeOfFlow", + "slot": "crsPurpose", "disposition": "bound", "selected": [] }, { - "text": "basic health care", + "text": "ODA", "named": [ { - "ref": "CRSPurposeCode12220", - "label": "basic health care" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" } ], - "slot": "crsPurpose", + "slot": "crsTypeOfFlow", "disposition": "bound", "selected": [] } ], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3834,7 +3835,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-11T20:09:36Z", + "prepared_at": "2026-10-21T08:57:19Z", "coverage": { "rows": 30, "dimensions": [ @@ -3863,13 +3864,13 @@ ], "window": { "kind": "all", - "origin": "default", + "start_year": 1995, "end_year": 2024, - "start_year": 1995 + "origin": "default" } }, "citation": { - "text": "OECD Creditor Reporting System (CRS)", + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", "sources": [ { "ref": "provenance/OECDCreditorReportingSystem", @@ -3890,9 +3891,9 @@ "publisher": "Organisation for Economic Co-operation and Development (OECD)", "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", - "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-08)", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", "update_cadence": "Quarterly", - "last_update": "2026-10-08", + "last_update": "2026-10-15", "years_covered": "1973-2024", "granularity": "Annual, by provider and recipient", "currencies": [ @@ -3903,6 +3904,10 @@ "transformation": "Download the source data", "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, { "transformation": "Exclude donor core contributions to multilaterals", "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." @@ -3922,22 +3927,22 @@ ], "version_history": [ { - "date": "2026-09-22", - "title": "Exclude donor core contributions", + "date": "2026-10-15", + "title": "Partial preliminary year excluded", "changes": [ { "kind": "changed", - "note": "Donor core contributions to multilateral organisations (`bi_multi = 2`) are excluded from bilateral flows, since they would otherwise double count." + "note": "The partial preliminary year published ahead of the next full release is excluded." } ] }, { - "date": "2026-08-20", + "date": "2026-10-14", "title": "First release", "changes": [ { "kind": "added", - "note": "Dataset added to the graph." + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." } ] } @@ -3947,47 +3952,25 @@ ] }, "trace": { - "facets": [ - { - "ref": "provenance/OECDCreditorReportingSystem", - "axis": "provenance", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - }, - { - "ref": "CurrencyUSD", - "axis": "unit", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - } - ], "applied_window": { "kind": "all", - "origin": "default", + "start_year": 1995, "end_year": 2024, - "start_year": 1995 + "origin": "default" }, - "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", - "normalisations": [], + "graph_revision": null, "code_index_stamp": { - "exported_at": "2026-10-10T10:52:17Z", - "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", - "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", + "graph_endpoint": "graph_release" }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", - "revision": "2026-10-08" + "revision": "2026-10-15" } ], - "capability_version": "dset_ac879dbf49857907", - "materialiser_build": "1f6ed6307bea979d38cc35c4e38e0da896c431ad", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -4158,20 +4141,36 @@ "observation_count": 0 } ], - "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "family_member_count": 21, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDCreditorReportingSystem", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + } + ], + "normalisations": [], "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261011T194155Z-80081f08", - "served_from": "head", - "confirmed_at": "2026-10-20T15:55:32.214385+00:00" + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:57:19.628756+00:00" }, - "warnings": [ - { - "code": "processing_level_undeclared", - "severity": "info", - "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." - } - ], + "warnings": [], "diagnostics": [ { "code": "processing_level_undeclared", @@ -4189,7 +4188,7 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-19T10:58:01.080848+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, @@ -4200,14 +4199,14 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-08T08:43:31.704442+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } ], "series_count": 5, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -4442,7 +4441,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:19.589587Z" + } } } }, @@ -4454,15 +4457,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" }, "response": { "status": 200, @@ -4521,7 +4523,7 @@ "members": [ { "parts": [ - "ODA disbursements for basic health care" + "basic health care ODA disbursements" ], "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json index 7f5e5ec..e76bef6 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json @@ -4,9 +4,9 @@ "description": "Fetching the mixed answer with partial=True builds only the answered part and returns a dataset that is not complete, with part 1's not_understood gap in missing.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "recorded_at": "2026-10-20T16:03:55Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:57:30Z" }, "call": [ { @@ -45,20 +45,20 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "5a61d16265664051af3fadd803379c1d", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "dcf1ce440fc24b248c5237bb149d73ef", "warnings": [], "timing_ms": { - "total": 155, + "total": 3081, "by_step": { "coverage": 0, - "extract": 0 + "extract": 930 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 5885, + "output_tokens": 606, + "cached_tokens": 2304 }, "timed_out": false }, @@ -68,20 +68,20 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 55, + "total": 2113, "by_step": { "recall": 1, "shape_arcs": 2, - "shape_probe_coverage": 14, - "shape_probe": 15, - "shape_groups": 5, - "shape_labels": 9, + "shape_probe_coverage": 8, + "shape_probe": 8, + "shape_groups": 4, + "shape_labels": 5, "shape_admission": 0, - "shape": 35, - "bind": 1, - "materialise": 9, - "answer": 3, - "options": 6 + "shape": 603, + "bind": 1503, + "materialise": 3, + "answer": 0, + "options": 3 } }, "restatement": { @@ -96,6 +96,14 @@ }, "operations": [], "departures": [], + "assumptions": [ + { + "kind": "open_role", + "binding_ref": "origin:", + "text": "every creditor", + "refs": [] + } + ], "status": "definite", "spec": { "spec_id": "spec_78d04fefc3b3f1ef71acd622957e4995", @@ -539,7 +547,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -1257,7 +1265,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3242,15 +3250,15 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 14, + "total": 7, "by_step": { - "recall": 1, + "recall": 2, "shape_arcs": 1, "shape_probe": 2, - "shape_groups": 1, + "shape_groups": 0, "shape_labels": 0, - "shape_admission": 1, - "shape": 13 + "shape_admission": 0, + "shape": 5 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", @@ -3265,6 +3273,7 @@ ], "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "variable_not_resolved", @@ -3274,12 +3283,27 @@ "ambiguous_entities": [], "source_terms": [], "ambiguous_sources": [], - "unbound_qualifiers": [] + "unbound_qualifiers": [], + "options": [] } } ], - "rendered_sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "rendered_sentence": "Answered 1 of 2 parts. Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). Assumed: every creditor. No match for price of tea. Try a different wording or a related indicator.", "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, { "kind": "slot", "text": "Kenya", @@ -3509,6 +3533,38 @@ "states": [], "part_index": 0 }, + { + "kind": "text", + "text": " ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Assumed: ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "every creditor", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, { "kind": "text", "text": " ", @@ -3716,7 +3772,7 @@ } }, "content_version": "cv_2c981b422e8f8bdf5dee6067837cff13", - "prepared_at": "2026-10-12T03:03:22Z", + "prepared_at": "2026-10-21T08:57:34Z", "coverage": { "rows": 55, "dimensions": [ @@ -3736,13 +3792,13 @@ ], "window": { "kind": "all", - "origin": "default", + "start_year": 1970, "end_year": 2024, - "start_year": 1970 + "origin": "default" } }, "citation": { - "text": "World Bank International Debt Statistics (IDS)", + "text": "World Bank International Debt Statistics (IDS) (2026), via the Development Finance Observatory", "sources": [ { "ref": "provenance/WorldBankInternationalDebtStatistics", @@ -3765,7 +3821,7 @@ "source_data_url": "https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092201/A_D.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092202/E_K.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092203/L_M.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0093225/N_Q.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092204/R_U.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092205/V_Z.xlsx", "attribution": "International Debt Statistics by the World Bank, https://datacatalog.worldbank.org/search/dataset/0038015/international-debt-statistics, licensed under CC BY 4.0. Modified by The ONE Campaign.", "update_cadence": "Annual", - "last_update": "2026-09-29", + "last_update": "2026-10-13", "years_covered": "1970-2032", "granularity": "Annual, by provider and recipient", "currencies": [ @@ -3799,12 +3855,12 @@ ], "version_history": [ { - "date": "2026-09-29", + "date": "2026-10-14", "title": "First release", "changes": [ { "kind": "added", - "note": "Dataset added to the graph." + "note": "External debt stocks, flows and debt service of low- and middle-income countries by borrower and creditor, with related ratios and gross national income." } ] } @@ -3814,56 +3870,25 @@ ] }, "trace": { - "facets": [ - { - "ref": "provenance/WorldBankInternationalDebtStatistics", - "axis": "provenance", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "most_observations", - "dispatch_facet_id": "2052749850102211920", - "default_policy_version": "1" - }, - { - "ref": null, - "axis": "measurementMethod", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "absent_on_selected_facet", - "dispatch_facet_id": "2052749850102211920", - "default_policy_version": "1" - }, - { - "ref": "CurrencyUSD", - "axis": "unit", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "most_observations", - "dispatch_facet_id": "2052749850102211920", - "default_policy_version": "1" - } - ], "applied_window": { "kind": "all", - "origin": "default", + "start_year": 1970, "end_year": 2024, - "start_year": 1970 + "origin": "default" }, - "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", - "normalisations": [], + "graph_revision": null, "code_index_stamp": { - "exported_at": "2026-10-10T10:52:17Z", - "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", - "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", + "graph_endpoint": "graph_release" }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/WorldBankInternationalDebtStatistics", - "revision": "2026-09-29" + "revision": "2026-10-13" } ], - "capability_version": "dset_ac879dbf49857907", - "materialiser_build": "3c49570945bd107f0484c1a16044d714410b1e25", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_ServicingPayment_Nominal", @@ -3873,20 +3898,45 @@ "observation_count": 55 } ], + "family_member_digest": "b66541c53125ee32113e51b4f52a3a428043b5506e15f96277f37b89547fc1c4", "family_member_count": 65, - "family_member_digest": "ef0365e0d7395767fee6210ec02c809839d0e28516031bf225d2cef2acc5e6d5", + "facets": [ + { + "axis": "provenance", + "ref": "provenance/WorldBankInternationalDebtStatistics", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "most_observations", + "dispatch_facet_id": "2052749850102211920" + }, + { + "axis": "measurementMethod", + "ref": null, + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "2052749850102211920" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "most_observations", + "dispatch_facet_id": "2052749850102211920" + } + ], + "normalisations": [], "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261012T000033Z-84777283", - "served_from": "head", - "confirmed_at": "2026-10-20T15:55:43.675067+00:00" + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:57:34.243265+00:00" }, - "warnings": [ - { - "code": "processing_level_undeclared", - "severity": "info", - "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." - } - ], + "warnings": [], "diagnostics": [ { "code": "processing_level_undeclared", @@ -3904,7 +3954,7 @@ }, "bytes": 6025, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T15:55:43.599626+00:00", + "created_at": "2026-10-21T08:57:34.203372+00:00", "tier": "working", "url": "/api/datasets/spec_78d04fefc3b3f1ef71acd622957e4995/cv_2c981b422e8f8bdf5dee6067837cff13/files/sha256:674d9a4ab33eabc631aba510ed88f9d45ddeef43d11d2aee7b267bd1e3546143" }, @@ -3915,14 +3965,14 @@ }, "bytes": 5343, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-05T21:15:15.844014+00:00", + "created_at": "2026-10-21T08:57:34.203372+00:00", "tier": "working", "url": "/api/datasets/spec_78d04fefc3b3f1ef71acd622957e4995/cv_2c981b422e8f8bdf5dee6067837cff13/files/sha256:8da8a5b081cc06acba677ac2c668e4bcafb796bf040bede5de00740acda9c9ee" } ], "series_count": 1, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -4074,7 +4124,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:34.203386Z" + } } } }, @@ -4086,15 +4140,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A674d9a4ab33eabc631aba510ed88f9d45ddeef43d11d2aee7b267bd1e3546143?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A674d9a4ab33eabc631aba510ed88f9d45ddeef43d11d2aee7b267bd1e3546143?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A674d9a4ab33eabc631aba510ed88f9d45ddeef43d11d2aee7b267bd1e3546143?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3A674d9a4ab33eabc631aba510ed88f9d45ddeef43d11d2aee7b267bd1e3546143?X-Goog-Signature=redacted" }, "response": { "status": 200, @@ -4110,7 +4163,7 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "sentence": "Answered 1 of 2 parts. Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). Assumed: every creditor. No match for price of tea. Try a different wording or a related indicator.", "complete": false, "specs": [ "spec_78d04fefc3b3f1ef71acd622957e4995" diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json index 5a59471..d856c89 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json @@ -4,9 +4,9 @@ "description": "A question with one answered part and one part Search cannot read answers mixed, incomplete, with a not_understood gap on part 1. Fetching it raises IncompleteAnswerError before any build.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "recorded_at": "2026-10-20T16:03:54Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:57:25Z" }, "call": [ { @@ -44,20 +44,20 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "95437670d1314551aa1fbdce8c8122b6", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "d0fa88511b064cc6966082b296cd6ea8", "warnings": [], "timing_ms": { - "total": 140, + "total": 4688, "by_step": { "coverage": 0, - "extract": 1 + "extract": 928 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 5885, + "output_tokens": 606, + "cached_tokens": 860 }, "timed_out": false }, @@ -67,20 +67,20 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 58, + "total": 3547, "by_step": { - "recall": 0, + "recall": 312, "shape_arcs": 2, - "shape_probe_coverage": 15, - "shape_probe": 16, - "shape_groups": 5, - "shape_labels": 9, + "shape_probe_coverage": 2, + "shape_probe": 192, + "shape_groups": 2, + "shape_labels": 6, "shape_admission": 0, - "shape": 37, - "bind": 2, - "materialise": 9, - "answer": 2, - "options": 8 + "shape": 912, + "bind": 1643, + "materialise": 3, + "answer": 462, + "options": 215 } }, "restatement": { @@ -95,6 +95,14 @@ }, "operations": [], "departures": [], + "assumptions": [ + { + "kind": "open_role", + "binding_ref": "origin:", + "text": "every creditor", + "refs": [] + } + ], "status": "definite", "spec": { "spec_id": "spec_78d04fefc3b3f1ef71acd622957e4995", @@ -538,7 +546,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -1256,7 +1264,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3241,15 +3249,15 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 14, + "total": 502, "by_step": { - "recall": 0, + "recall": 307, "shape_arcs": 1, - "shape_probe": 3, - "shape_groups": 3, + "shape_probe": 190, + "shape_groups": 1, "shape_labels": 0, - "shape_admission": 2, - "shape": 14 + "shape_admission": 0, + "shape": 195 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", @@ -3264,6 +3272,7 @@ ], "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "variable_not_resolved", @@ -3273,12 +3282,27 @@ "ambiguous_entities": [], "source_terms": [], "ambiguous_sources": [], - "unbound_qualifiers": [] + "unbound_qualifiers": [], + "options": [] } } ], - "rendered_sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "rendered_sentence": "Answered 1 of 2 parts. Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). Assumed: every creditor. No match for price of tea. Try a different wording or a related indicator.", "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, { "kind": "slot", "text": "Kenya", @@ -3508,6 +3532,38 @@ "states": [], "part_index": 0 }, + { + "kind": "text", + "text": " ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Assumed: ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "every creditor", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, { "kind": "text", "text": " ", @@ -3551,7 +3607,7 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "sentence": "Answered 1 of 2 parts. Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). Assumed: every creditor. No match for price of tea. Try a different wording or a related indicator.", "complete": false, "specs": [ "spec_78d04fefc3b3f1ef71acd622957e4995" diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json index bfab004..bb13406 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json @@ -4,9 +4,9 @@ "description": "A question with three definite parts, the first two folded into one spec_id (binding_folded), builds each distinct spec_id once, in part order, each through build, files and download before the next. The dataset stacks two members, the first answering both folded parts, into one table with a part column first and each member's columns in member order.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "recorded_at": "2026-10-20T16:03:57Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:57:34Z" }, "call": [ { @@ -41,50 +41,50 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements for health and for education from Germany to Kenya, and GDP of Kenya", "normalized_query": "ODA disbursements for health and for education from Germany to Kenya, and GDP of Kenya", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "1c42f930c021432697eb26d2af4fb5c4", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "c354423648a442189d804c35586bd78a", "warnings": [], "timing_ms": { - "total": 5, + "total": 5956, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 919 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 15731, + "output_tokens": 1037, + "cached_tokens": 861 }, "timed_out": false }, "kind": "resolution", "parts": [ { - "variable_text": "health ODA disbursements", + "variable_text": "ODA disbursements for health", "warnings": [], "timing_ms": { - "total": 1771, + "total": 3227, "by_step": { - "recall": 2, - "shape_arcs": 1, - "shape_probe_coverage": 183, - "shape_probe": 183, - "shape_groups": 102, - "shape_labels": 20, + "recall": 535, + "shape_arcs": 0, + "shape_probe_coverage": 1, + "shape_probe": 197, + "shape_groups": 16, + "shape_labels": 4, "shape_admission": 0, - "shape": 599, - "bind": 39, - "materialise": 585, - "answer": 27, - "options": 519 + "shape": 1071, + "bind": 1345, + "materialise": 157, + "answer": 20, + "options": 99 } }, "restatement": { - "variable_text": "health ODA disbursements", + "variable_text": "ODA disbursements for health", "entities": [ { "text": "Germany", @@ -100,6 +100,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_25f482395c5d012ec278118f38dff29c", @@ -195,6 +196,14 @@ }, "measurement_denominator_unresolved": false, "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, { "axis": "how", "property": { @@ -235,14 +244,6 @@ }, "label": "netting basis" }, - { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, { "axis": "where", "label": "place" @@ -267,6 +268,20 @@ ] }, "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, { "key": { "axis": "how", @@ -466,20 +481,6 @@ }, "summable": false }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding": { - "kind": "unbound" - }, - "summable": true - }, { "key": { "axis": "where", @@ -587,6 +588,170 @@ } }, "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 104, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1606, + "served_rows": 21, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 83, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 136, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 136, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 111, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 1600, + "served_rows": 84, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 976, + "served_rows": 27, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE", + "label": "scholarship and student cost in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 38, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 819, + "served_rows": 19, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 315, + "served_rows": 19, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, { "key": { "axis": "how", @@ -806,198 +971,34 @@ ], "truncated": false, "source": "observed" - }, + } + ], + "entity_options": [], + "facet_options": [ { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, + "axis": "provenance", "options": [ { "value": { "ref": { - "ref": "CRSCooperationModalityB", - "label": "core contribution and pooled programme and fund" + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)" }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 104, - "served_rows_exact": true - }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ { "value": { "ref": { - "ref": "CRSCooperationModalityB03", - "label": "contribution to specific-purpose programme and fund managed by an international organisation" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityB", - "member_count": 1606, - "served_rows": 21, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityB01", - "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityB", - "member_count": 1331, - "served_rows": 83, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityC", - "label": "project-type intervention (group)" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 136, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityC01", - "label": "project-type intervention" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityC", - "member_count": 7005, - "served_rows": 136, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityD", - "label": "expert and other technical assistance" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 111, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityD02", - "label": "other technical assistance" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityD", - "member_count": 1600, - "served_rows": 84, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityD01", - "label": "donor country personnel" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityD", - "member_count": 976, - "served_rows": 27, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityE", - "label": "scholarship and student cost in donor country" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 38, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityE01", - "label": "scholarship and training in donor country" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityE", - "member_count": 819, - "served_rows": 19, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityE02", - "label": "imputed student cost" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityE", - "member_count": 315, - "served_rows": 19, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ - { - "axis": "provenance", - "options": [ - { - "value": { - "ref": { - "ref": "provenance/OECDCreditorReportingSystem", - "label": "OECD Creditor Reporting System (CRS)" - }, - "value_kind": "source" - } - } - ], - "truncated": false, - "source": "observed" - }, - { - "axis": "unit", - "options": [ - { - "value": { - "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" + "ref": "CurrencyUSD", + "label": "US Dollar" }, "value_kind": "enum_value" } @@ -1236,6 +1237,19 @@ } ], "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "how", @@ -1325,19 +1339,6 @@ ], "provenance": "measure_elected" }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "where", @@ -1373,26 +1374,26 @@ ], "query_qualifiers": [ { - "text": "health", + "text": "ODA", "named": [ { - "ref": "CRSPurposeCode120", - "label": "health" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" } ], - "slot": "crsPurpose", + "slot": "crsTypeOfFlow", "disposition": "bound", "selected": [] }, { - "text": "ODA", + "text": "health", "named": [ { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode120", + "label": "health" } ], - "slot": "crsTypeOfFlow", + "slot": "crsPurpose", "disposition": "bound", "selected": [] }, @@ -1409,7 +1410,7 @@ "selected": [] } ], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3728,33 +3729,33 @@ } }, { - "variable_text": "education ODA disbursements", + "variable_text": "ODA disbursements for education", "warnings": [ { "code": "binding_folded", "severity": "info", - "message": "'education ODA disbursements' resolved to the same shape as an earlier part; folded into that part's spec." + "message": "'ODA disbursements for education' resolved to the same shape as an earlier part; folded into that part's spec." } ], "timing_ms": { - "total": 1681, + "total": 3024, "by_step": { - "recall": 1, - "shape_arcs": 1, - "shape_probe_coverage": 16, - "shape_probe": 19, - "shape_groups": 119, - "shape_labels": 14, - "shape_admission": 1, - "shape": 237, - "bind": 24, - "materialise": 881, - "answer": 38, - "options": 500 + "recall": 456, + "shape_arcs": 0, + "shape_probe_coverage": 1, + "shape_probe": 183, + "shape_groups": 17, + "shape_labels": 4, + "shape_admission": 0, + "shape": 1070, + "bind": 1243, + "materialise": 82, + "answer": 19, + "options": 154 } }, "restatement": { - "variable_text": "education ODA disbursements", + "variable_text": "ODA disbursements for education", "entities": [ { "text": "Germany", @@ -3770,6 +3771,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_25f482395c5d012ec278118f38dff29c", @@ -3865,6 +3867,14 @@ }, "measurement_denominator_unresolved": false, "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, { "axis": "how", "property": { @@ -3905,14 +3915,6 @@ }, "label": "netting basis" }, - { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, { "axis": "where", "label": "place" @@ -3937,6 +3939,20 @@ ] }, "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, { "key": { "axis": "how", @@ -4136,20 +4152,6 @@ }, "summable": false }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding": { - "kind": "unbound" - }, - "summable": true - }, { "key": { "axis": "where", @@ -4261,189 +4263,160 @@ "key": { "axis": "how", "property": { - "ref": "crsPurpose", - "label": "CRS purpose" + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" }, - "label": "sector" + "label": "modality" }, "options": [ { "value": { "ref": { - "ref": "CRSPurposeCode121", - "label": "general health" + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" }, "value_kind": "enum_value" }, - "relation": "child", - "parent": "CRSPurposeCode120", - "member_count": 6, - "served_rows": 82, + "relation": "root", + "member_count": 0, + "served_rows": 104, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode122", - "label": "basic health" + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSPurposeCode120", - "member_count": 4, - "served_rows": 108, + "parent": "CRSCooperationModalityB", + "member_count": 1606, + "served_rows": 21, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode123", - "label": "noncommunicable disease" + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSPurposeCode120", - "member_count": 3, - "served_rows": 4, + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 83, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode100", - "label": "social infrastructure and services" + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" }, "value_kind": "enum_value" }, - "relation": "parent", - "member_count": 13, - "served_rows": 1214, + "relation": "root", + "member_count": 0, + "served_rows": 136, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode111", - "label": "unspecified-level education" + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSPurposeCode110", - "member_count": 6, - "served_rows": 78, + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 136, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode112", - "label": "basic education" + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" }, "value_kind": "enum_value" }, - "relation": "child", - "parent": "CRSPurposeCode110", - "member_count": 6, - "served_rows": 77, + "relation": "root", + "member_count": 0, + "served_rows": 111, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode113", - "label": "upper secondary education" + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSPurposeCode110", - "member_count": 5, - "served_rows": 69, + "parent": "CRSCooperationModalityD", + "member_count": 1600, + "served_rows": 84, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode114", - "label": "post-secondary education" + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSPurposeCode110", - "member_count": 4, - "served_rows": 94, + "parent": "CRSCooperationModalityD", + "member_count": 976, + "served_rows": 27, "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFinance", - "label": "CRS type of finance" }, - "label": "instrument" - }, - "options": [ { "value": { "ref": { - "ref": "CRSTypeOfFinance100", - "label": "grant" + "ref": "CRSCooperationModalityE", + "label": "scholarship and student cost in donor country" }, "value_kind": "enum_value" }, "relation": "root", "member_count": 0, - "served_rows": 501, + "served_rows": 38, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSTypeOfFinance110", - "label": "standard grant" + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSTypeOfFinance100", - "member_count": 12672, - "served_rows": 501, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance420", - "label": "debt instrument" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 11, + "parent": "CRSCooperationModalityE", + "member_count": 819, + "served_rows": 19, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSTypeOfFinance421", - "label": "standard loan" + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSTypeOfFinance420", - "member_count": 4620, - "served_rows": 11, + "parent": "CRSCooperationModalityE", + "member_count": 315, + "served_rows": 19, "served_rows_exact": true } ], @@ -4454,187 +4427,216 @@ "key": { "axis": "how", "property": { - "ref": "crsTypeOfFlow", - "label": "CRS type of flow" + "ref": "crsPurpose", + "label": "CRS purpose" }, - "label": "flow" + "label": "sector" }, "options": [ { "value": { "ref": { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode121", + "label": "general health" }, "value_kind": "enum_value" }, - "relation": "root", - "member_count": 14098, - "served_rows": 512, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 6, + "served_rows": 82, "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" }, - "label": "modality" - }, - "options": [ { "value": { "ref": { - "ref": "CRSCooperationModalityB", - "label": "core contribution and pooled programme and fund" + "ref": "CRSPurposeCode122", + "label": "basic health" }, "value_kind": "enum_value" }, - "relation": "root", - "member_count": 0, - "served_rows": 104, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 108, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityB03", - "label": "contribution to specific-purpose programme and fund managed by an international organisation" + "ref": "CRSPurposeCode123", + "label": "noncommunicable disease" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSCooperationModalityB", - "member_count": 1606, - "served_rows": 21, + "parent": "CRSPurposeCode120", + "member_count": 3, + "served_rows": 4, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityB01", - "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + "ref": "CRSPurposeCode100", + "label": "social infrastructure and services" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "member_count": 13, + "served_rows": 1214, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode111", + "label": "unspecified-level education" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSCooperationModalityB", - "member_count": 1331, - "served_rows": 83, + "parent": "CRSPurposeCode110", + "member_count": 6, + "served_rows": 78, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityC", - "label": "project-type intervention (group)" + "ref": "CRSPurposeCode112", + "label": "basic education" }, "value_kind": "enum_value" }, - "relation": "root", - "member_count": 0, - "served_rows": 136, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 6, + "served_rows": 77, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityC01", - "label": "project-type intervention" + "ref": "CRSPurposeCode113", + "label": "upper secondary education" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSCooperationModalityC", - "member_count": 7005, - "served_rows": 136, + "parent": "CRSPurposeCode110", + "member_count": 5, + "served_rows": 69, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityD", - "label": "expert and other technical assistance" + "ref": "CRSPurposeCode114", + "label": "post-secondary education" }, "value_kind": "enum_value" }, - "relation": "root", - "member_count": 0, - "served_rows": 111, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 4, + "served_rows": 94, "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" }, + "label": "instrument" + }, + "options": [ { "value": { "ref": { - "ref": "CRSCooperationModalityD02", - "label": "other technical assistance" + "ref": "CRSTypeOfFinance100", + "label": "grant" }, "value_kind": "enum_value" }, - "relation": "child", - "parent": "CRSCooperationModalityD", - "member_count": 1600, - "served_rows": 84, + "relation": "root", + "member_count": 0, + "served_rows": 501, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityD01", - "label": "donor country personnel" + "ref": "CRSTypeOfFinance110", + "label": "standard grant" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSCooperationModalityD", - "member_count": 976, - "served_rows": 27, + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 501, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityE", - "label": "scholarship and student cost in donor country" + "ref": "CRSTypeOfFinance420", + "label": "debt instrument" }, "value_kind": "enum_value" }, "relation": "root", "member_count": 0, - "served_rows": 38, + "served_rows": 11, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityE01", - "label": "scholarship and training in donor country" + "ref": "CRSTypeOfFinance421", + "label": "standard loan" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSCooperationModalityE", - "member_count": 819, - "served_rows": 19, + "parent": "CRSTypeOfFinance420", + "member_count": 4620, + "served_rows": 11, "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" }, + "label": "flow" + }, + "options": [ { "value": { "ref": { - "ref": "CRSCooperationModalityE02", - "label": "imputed student cost" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" }, "value_kind": "enum_value" }, - "relation": "child", - "parent": "CRSCooperationModalityE", - "member_count": 315, - "served_rows": 19, + "relation": "root", + "member_count": 14098, + "served_rows": 512, "served_rows_exact": true } ], @@ -4906,6 +4908,19 @@ } ], "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "how", @@ -4995,19 +5010,6 @@ ], "provenance": "measure_elected" }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "where", @@ -5043,26 +5045,26 @@ ], "query_qualifiers": [ { - "text": "health", + "text": "ODA", "named": [ { - "ref": "CRSPurposeCode120", - "label": "health" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" } ], - "slot": "crsPurpose", + "slot": "crsTypeOfFlow", "disposition": "bound", "selected": [] }, { - "text": "ODA", + "text": "health", "named": [ { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode120", + "label": "health" } ], - "slot": "crsTypeOfFlow", + "slot": "crsPurpose", "disposition": "bound", "selected": [] }, @@ -5079,7 +5081,7 @@ "selected": [] } ], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -7412,20 +7414,20 @@ } ], "timing_ms": { - "total": 2176, + "total": 3386, "by_step": { - "recall": 1, - "shape_arcs": 3, - "shape_probe_coverage": 11, - "shape_probe": 15, - "shape_groups": 116, - "shape_labels": 14, + "recall": 579, + "shape_arcs": 2, + "shape_probe_coverage": 1, + "shape_probe": 263, + "shape_groups": 19, + "shape_labels": 4, "shape_admission": 0, - "shape": 194, - "bind": 1952, - "materialise": 5, - "answer": 9, - "options": 15 + "shape": 1015, + "bind": 1274, + "materialise": 1, + "answer": 159, + "options": 358 } }, "restatement": { @@ -7458,6 +7460,7 @@ "text": "You named Kenya as a recipient. This measure has no recipients, so this shows the place itself." } ], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_f8dea3052d1ef6ba5667628815d1a663", @@ -8847,7 +8850,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -9380,7 +9383,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -9424,50 +9427,7 @@ } ], "measure_label_axes": [], - "measure_axis_values": [], - "related_group": { - "ref": "dc/g/EconomicActivity_ActivitySource-GrossDomesticProduction", - "label": "Economic Activity With Activity Source = Gross Domestic Production" - }, - "related_measures": [ - { - "stat_var": { - "ref": "GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "label": "Gross domestic product growth rate" - }, - "definition": { - "schema_version": 1, - "spec_id": "spec_4535d09baf2bdffef7c19c7796e96687", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "EconomicActivity", - "measured_property": "amount", - "stat_type": "growthRate" - }, - "slots": [ - { - "property": "activitySource", - "binding": { - "state": "value", - "ref": "GrossDomesticProduction" - } - } - ], - "entities": { - "observationAbout": [ - "country/DEU", - "country/KEN" - ] - }, - "requested_window": { - "kind": "all" - } - } - } - } - ] + "measure_axis_values": [] } } } @@ -10035,7 +9995,7 @@ } }, "content_version": "cv_d6ce435ea267b46680c94eae9423d420", - "prepared_at": "2026-10-20T15:55:47Z", + "prepared_at": "2026-10-21T08:57:44Z", "coverage": { "rows": 512, "dimensions": [ @@ -10064,9 +10024,9 @@ ], "window": { "kind": "all", - "origin": "default", + "start_year": 1997, "end_year": 2024, - "start_year": 1997 + "origin": "default" } }, "citation": { @@ -10152,47 +10112,25 @@ ] }, "trace": { - "facets": [ - { - "ref": "provenance/OECDCreditorReportingSystem", - "axis": "provenance", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - }, - { - "ref": "CurrencyUSD", - "axis": "unit", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - } - ], "applied_window": { "kind": "all", - "origin": "default", + "start_year": 1997, "end_year": 2024, - "start_year": 1997 + "origin": "default" }, - "graph_revision": "dfo-dev-dc-datacommons-service-00259-rpx", - "normalisations": [], + "graph_revision": null, "code_index_stamp": { - "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", "graph_endpoint": "graph_release" }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", "revision": "2026-10-15" } ], - "capability_version": "dset_1e6cd9546fac19e9", - "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA01_CRSPurposeCode11330_Nominal", @@ -14555,12 +14493,34 @@ "observation_count": 0 } ], - "family_member_count": 545, "family_member_digest": "0c7508fd1997d6cdc896f2eab0f092a4915cfca9e2400eb9577bb22b527fe882", + "family_member_count": 545, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDCreditorReportingSystem", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + } + ], + "normalisations": [], "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", - "served_from": "head", - "confirmed_at": "2026-10-20T15:55:47.839028+00:00" + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:57:44.735225+00:00" }, "warnings": [], "diagnostics": [ @@ -14580,7 +14540,7 @@ }, "bytes": 16150, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T15:55:47.734234+00:00", + "created_at": "2026-10-21T08:57:44.689444+00:00", "tier": "working", "url": "/api/datasets/spec_25f482395c5d012ec278118f38dff29c/cv_d6ce435ea267b46680c94eae9423d420/files/sha256:20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d" }, @@ -14591,14 +14551,14 @@ }, "bytes": 11612, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T15:55:47.734234+00:00", + "created_at": "2026-10-21T08:57:44.689444+00:00", "tier": "working", "url": "/api/datasets/spec_25f482395c5d012ec278118f38dff29c/cv_d6ce435ea267b46680c94eae9423d420/files/sha256:a5d2d7627c8fe1357519ca0ac021c791182ab08c76f44e8055b4bb50a6059179" } ], "series_count": 108, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -14833,7 +14793,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:44.689446Z" + } } } }, @@ -14845,15 +14809,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3A20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d?X-Goog-Signature=redacted" }, "response": { "status": 200, @@ -14999,7 +14962,7 @@ } }, "content_version": "cv_91f57bfc5bbc5f09983596996238787d", - "prepared_at": "2026-10-20T15:55:49Z", + "prepared_at": "2026-10-21T08:57:46Z", "coverage": { "rows": 132, "dimensions": [ @@ -15014,9 +14977,9 @@ ], "window": { "kind": "all", - "origin": "default", + "start_year": 1960, "end_year": 2025, - "start_year": 1960 + "origin": "default" } }, "citation": { @@ -15051,56 +15014,25 @@ ] }, "trace": { - "facets": [ - { - "ref": "dc/base/WorldDevelopmentIndicators", - "axis": "provenance", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "8535402560764839853", - "default_policy_version": "1" - }, - { - "ref": null, - "axis": "measurementMethod", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "absent_on_selected_facet", - "dispatch_facet_id": "8535402560764839853", - "default_policy_version": "1" - }, - { - "ref": "USDollar", - "axis": "unit", - "basis": "bound", - "default_policy": null, - "selection_reason": null, - "dispatch_facet_id": "8535402560764839853", - "default_policy_version": null - } - ], "applied_window": { "kind": "all", - "origin": "default", + "start_year": 1960, "end_year": 2025, - "start_year": 1960 + "origin": "default" }, - "graph_revision": "dfo-dev-dc-datacommons-service-00259-rpx", - "normalisations": [], + "graph_revision": null, "code_index_stamp": { - "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", "graph_endpoint": "graph_release" }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "dc/base/WorldDevelopmentIndicators", "revision": "2026-10-13" } ], - "capability_version": "dset_1e6cd9546fac19e9", - "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_EconomicActivity_GrossDomesticProduction_Nominal", @@ -15110,12 +15042,43 @@ "observation_count": 132 } ], - "family_member_count": 65, "family_member_digest": "73519eeb75639bdae33042fc844830cd46becc08e4f9122dfcd0886e9875f657", + "family_member_count": 65, + "facets": [ + { + "axis": "provenance", + "ref": "dc/base/WorldDevelopmentIndicators", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "8535402560764839853" + }, + { + "axis": "measurementMethod", + "ref": null, + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "8535402560764839853" + }, + { + "axis": "unit", + "ref": "USDollar", + "basis": "bound", + "default_policy": null, + "default_policy_version": null, + "selection_reason": null, + "dispatch_facet_id": "8535402560764839853" + } + ], + "normalisations": [], "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", - "served_from": "head", - "confirmed_at": "2026-10-20T15:55:50.035160+00:00" + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:57:46.634620+00:00" }, "warnings": [], "diagnostics": [ @@ -15135,7 +15098,7 @@ }, "bytes": 6545, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T15:55:49.978222+00:00", + "created_at": "2026-10-21T08:57:46.604801+00:00", "tier": "working", "url": "/api/datasets/spec_f8dea3052d1ef6ba5667628815d1a663/cv_91f57bfc5bbc5f09983596996238787d/files/sha256:9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839" }, @@ -15146,14 +15109,14 @@ }, "bytes": 5379, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T15:55:49.978222+00:00", + "created_at": "2026-10-21T08:57:46.604801+00:00", "tier": "working", "url": "/api/datasets/spec_f8dea3052d1ef6ba5667628815d1a663/cv_91f57bfc5bbc5f09983596996238787d/files/sha256:8eecb62c1741271464d6d66841353d96f7e36aa9c3915f7948ea7c78c7dbc9e7" } ], "series_count": 2, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -15307,7 +15270,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:46.604983Z" + } } } }, @@ -15319,15 +15286,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3A9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839?X-Goog-Signature=redacted" }, "response": { "status": 200, @@ -15389,7 +15355,7 @@ ], "part_rows": [ { - "part": "health ODA disbursements; education ODA disbursements", + "part": "ODA disbursements for health; ODA disbursements for education", "rows": 512 }, { @@ -15401,8 +15367,8 @@ "members": [ { "parts": [ - "health ODA disbursements", - "education ODA disbursements" + "ODA disbursements for health", + "ODA disbursements for education" ], "spec_id": "spec_25f482395c5d012ec278118f38dff29c", "content_version": "cv_d6ce435ea267b46680c94eae9423d420", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json index f283259..cc8a3e9 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json @@ -43,20 +43,20 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "95437670d1314551aa1fbdce8c8122b6", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "d0fa88511b064cc6966082b296cd6ea8", "warnings": [], "timing_ms": { - "total": 140, + "total": 4688, "by_step": { "coverage": 0, - "extract": 1 + "extract": 928 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 5885, + "output_tokens": 606, + "cached_tokens": 860 }, "timed_out": true }, @@ -66,20 +66,20 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 58, + "total": 3547, "by_step": { - "recall": 0, + "recall": 312, "shape_arcs": 2, - "shape_probe_coverage": 15, - "shape_probe": 16, - "shape_groups": 5, - "shape_labels": 9, + "shape_probe_coverage": 2, + "shape_probe": 192, + "shape_groups": 2, + "shape_labels": 6, "shape_admission": 0, - "shape": 37, - "bind": 2, - "materialise": 9, - "answer": 2, - "options": 8 + "shape": 912, + "bind": 1643, + "materialise": 3, + "answer": 462, + "options": 215 } }, "restatement": { @@ -94,6 +94,14 @@ }, "operations": [], "departures": [], + "assumptions": [ + { + "kind": "open_role", + "binding_ref": "origin:", + "text": "every creditor", + "refs": [] + } + ], "status": "definite", "spec": { "spec_id": "spec_78d04fefc3b3f1ef71acd622957e4995", @@ -537,7 +545,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -1255,7 +1263,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3240,15 +3248,15 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 14, + "total": 502, "by_step": { - "recall": 0, + "recall": 307, "shape_arcs": 1, - "shape_probe": 3, - "shape_groups": 3, + "shape_probe": 190, + "shape_groups": 1, "shape_labels": 0, - "shape_admission": 2, - "shape": 14 + "shape_admission": 0, + "shape": 195 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", @@ -3263,6 +3271,7 @@ ], "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "variable_not_resolved", @@ -3272,12 +3281,27 @@ "ambiguous_entities": [], "source_terms": [], "ambiguous_sources": [], - "unbound_qualifiers": [] + "unbound_qualifiers": [], + "options": [] } } ], - "rendered_sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "rendered_sentence": "Answered 1 of 2 parts. Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). Assumed: every creditor. No match for price of tea. Try a different wording or a related indicator.", "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, { "kind": "slot", "text": "Kenya", @@ -3507,6 +3531,38 @@ "states": [], "part_index": 0 }, + { + "kind": "text", + "text": " ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Assumed: ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "every creditor", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, { "kind": "text", "text": " ", @@ -3550,7 +3606,7 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "sentence": "Answered 1 of 2 parts. Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). Assumed: every creditor. No match for price of tea. Try a different wording or a related indicator.", "complete": false, "specs": [ "spec_78d04fefc3b3f1ef71acd622957e4995" diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json index c6414e4..ad7a507 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json @@ -37,23 +37,23 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements from Germany to Congo", "normalized_query": "ODA disbursements from Germany to Congo", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "cc29e19289f44bb6bb0a6e0f4c8524a7", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", "warnings": [], "timing_ms": { - "total": 1, + "total": 1788, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 1353 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 }, "timed_out": false }, @@ -63,9 +63,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 434, "by_step": { - "recall": 1 + "recall": 434 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -111,6 +111,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", @@ -139,27 +140,64 @@ "source_terms": [], "ambiguous_sources": [], "unbound_qualifiers": [], - "data_query": { - "kind": "parsed", - "parts": [ - { - "variable_text": "ODA disbursements", - "entities": [ + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Germany", - "role_text": "from", - "dcid": "country/DEU" - }, + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Congo", - "role_text": "to" + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] } - ], - "sources": [], - "operations": [] + ] } - ] - } + } + ] } } ], @@ -209,7 +247,7 @@ { "part": 0, "kind": "choice", - "options": 0 + "options": 2 } ] } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json index cfc738e..3110dcf 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json @@ -37,23 +37,23 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements from Germany to Congo", "normalized_query": "ODA disbursements from Germany to Congo", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "cc29e19289f44bb6bb0a6e0f4c8524a7", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", "warnings": [], "timing_ms": { - "total": 1, + "total": 1788, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 1353 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 }, "timed_out": false }, @@ -63,9 +63,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 434, "by_step": { - "recall": 1 + "recall": 434 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -111,6 +111,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", @@ -139,27 +140,64 @@ "source_terms": [], "ambiguous_sources": [], "unbound_qualifiers": [], - "data_query": { - "kind": "parsed", - "parts": [ - { - "variable_text": "ODA disbursements", - "entities": [ + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Germany", - "role_text": "from", - "dcid": "country/DEU" - }, + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Congo", - "role_text": "to" + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] } - ], - "sources": [], - "operations": [] + ] } - ] - } + } + ] } } ], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json index 7fd603f..857a8b9 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json @@ -43,20 +43,20 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "95437670d1314551aa1fbdce8c8122b6", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "d0fa88511b064cc6966082b296cd6ea8", "warnings": [], "timing_ms": { - "total": 140, + "total": 4688, "by_step": { "coverage": 0, - "extract": 1 + "extract": 928 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 5885, + "output_tokens": 606, + "cached_tokens": 860 }, "timed_out": false }, @@ -66,20 +66,20 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 58, + "total": 3547, "by_step": { - "recall": 0, + "recall": 312, "shape_arcs": 2, - "shape_probe_coverage": 15, - "shape_probe": 16, - "shape_groups": 5, - "shape_labels": 9, + "shape_probe_coverage": 2, + "shape_probe": 192, + "shape_groups": 2, + "shape_labels": 6, "shape_admission": 0, - "shape": 37, - "bind": 2, - "materialise": 9, - "answer": 2, - "options": 8 + "shape": 912, + "bind": 1643, + "materialise": 3, + "answer": 462, + "options": 215 } }, "restatement": { @@ -94,6 +94,14 @@ }, "operations": [], "departures": [], + "assumptions": [ + { + "kind": "open_role", + "binding_ref": "origin:", + "text": "every creditor", + "refs": [] + } + ], "status": "definite", "spec": { "spec_id": "spec_78d04fefc3b3f1ef71acd622957e4995", @@ -537,7 +545,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -1255,7 +1263,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3240,15 +3248,15 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 14, + "total": 502, "by_step": { - "recall": 0, + "recall": 307, "shape_arcs": 1, - "shape_probe": 3, - "shape_groups": 3, + "shape_probe": 190, + "shape_groups": 1, "shape_labels": 0, - "shape_admission": 2, - "shape": 14 + "shape_admission": 0, + "shape": 195 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", @@ -3263,6 +3271,7 @@ ], "operations": [], "departures": [], + "assumptions": [], "status": "deferred", "no_data": { "reason": "variable_not_resolved", @@ -3272,12 +3281,27 @@ "ambiguous_entities": [], "source_terms": [], "ambiguous_sources": [], - "unbound_qualifiers": [] + "unbound_qualifiers": [], + "options": [] } } ], - "rendered_sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "rendered_sentence": "Answered 1 of 2 parts. Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). Assumed: every creditor. No match for price of tea. Try a different wording or a related indicator.", "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, { "kind": "slot", "text": "Kenya", @@ -3507,6 +3531,38 @@ "states": [], "part_index": 0 }, + { + "kind": "text", + "text": " ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Assumed: ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "every creditor", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, { "kind": "text", "text": " ", @@ -3550,7 +3606,7 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "sentence": "Answered 1 of 2 parts. Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). Assumed: every creditor. No match for price of tea. Try a different wording or a related indicator.", "complete": false, "specs": [ "spec_78d04fefc3b3f1ef71acd622957e4995" diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json index e0e082f..66452cb 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json @@ -43,20 +43,20 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "95437670d1314551aa1fbdce8c8122b6", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "d0fa88511b064cc6966082b296cd6ea8", "warnings": [], "timing_ms": { - "total": 140, + "total": 4688, "by_step": { "coverage": 0, - "extract": 1 + "extract": 928 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 5885, + "output_tokens": 606, + "cached_tokens": 860 }, "timed_out": false }, @@ -66,20 +66,20 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 58, + "total": 3547, "by_step": { - "recall": 0, + "recall": 312, "shape_arcs": 2, - "shape_probe_coverage": 15, - "shape_probe": 16, - "shape_groups": 5, - "shape_labels": 9, + "shape_probe_coverage": 2, + "shape_probe": 192, + "shape_groups": 2, + "shape_labels": 6, "shape_admission": 0, - "shape": 37, - "bind": 2, - "materialise": 9, - "answer": 2, - "options": 8 + "shape": 912, + "bind": 1643, + "materialise": 3, + "answer": 462, + "options": 215 } }, "restatement": { @@ -94,6 +94,14 @@ }, "operations": [], "departures": [], + "assumptions": [ + { + "kind": "open_role", + "binding_ref": "origin:", + "text": "every creditor", + "refs": [] + } + ], "status": "definite", "spec": { "spec_id": "spec_78d04fefc3b3f1ef71acd622957e4995", @@ -537,7 +545,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -1255,7 +1263,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3240,15 +3248,15 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 14, + "total": 502, "by_step": { - "recall": 0, + "recall": 307, "shape_arcs": 1, - "shape_probe": 3, - "shape_groups": 3, + "shape_probe": 190, + "shape_groups": 1, "shape_labels": 0, - "shape_admission": 2, - "shape": 14 + "shape_admission": 0, + "shape": 195 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", @@ -3263,6 +3271,7 @@ ], "operations": [], "departures": [], + "assumptions": [], "status": "unsupported", "unsupported": { "code": "scope_too_broad", @@ -3271,8 +3280,22 @@ } } ], - "rendered_sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "rendered_sentence": "Answered 1 of 2 parts. Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). Assumed: every creditor. No match for price of tea. Try a different wording or a related indicator.", "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, { "kind": "slot", "text": "Kenya", @@ -3502,6 +3525,38 @@ "states": [], "part_index": 0 }, + { + "kind": "text", + "text": " ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Assumed: ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "every creditor", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, { "kind": "text", "text": " ", @@ -3545,7 +3600,7 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "sentence": "Answered 1 of 2 parts. Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). Assumed: every creditor. No match for price of tea. Try a different wording or a related indicator.", "complete": false, "specs": [ "spec_78d04fefc3b3f1ef71acd622957e4995" diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-assumed-reading.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-assumed-reading.json new file mode 100644 index 0000000..1f20d23 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-assumed-reading.json @@ -0,0 +1,3190 @@ +{ + "format_version": 1, + "name": "choose-candidate-assumed-reading", + "description": "Picking a candidate whose reading_assumptions entry holds an assumption posts that list unchanged as the identity entry's assumptions. The picked answer's assumptions and its sentence, closed by the assumption clause (\"Assumed: official development assistance.\"), are Search's response, which the client takes as it stands.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-candidates-choose-fetch", + "edit": "The picked reading's reading_assumptions entry holds one declared default, the pick echoes it, Search's answer states it, and the fetch goes." + }, + "call": [ + { + "op": "search", + "question": "GNI of Germany from 2015 to 2022" + }, + { + "op": "choose", + "option": 0 + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "GNI of Germany from 2015 to 2022" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "GNI of Germany from 2015 to 2022", + "normalized_query": "GNI of Germany from 2015 to 2022", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "8a56f4a56757466094a49079c6a116c4", + "warnings": [], + "timing_ms": { + "total": 4642, + "by_step": { + "coverage": 0, + "extract": 1227 + } + }, + "llm_usage": { + "input_tokens": 7300, + "output_tokens": 300, + "cached_tokens": 861 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GNI", + "warnings": [], + "timing_ms": { + "total": 3202, + "by_step": { + "recall": 421, + "shape_arcs": 4, + "shape_probe_coverage": 2, + "shape_probe": 211, + "shape_groups": 29, + "shape_labels": 15, + "shape_admission": 0, + "shape": 1184, + "bind": 1000, + "materialise": 429, + "answer": 168 + } + }, + "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "sentence_plan": [ + { + "kind": "text", + "text": "3 readings.", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "primary income", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross of fixed capital consumption", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "OECD DAC1", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity per capita", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "GNI", + "entities": [ + { + "text": "Germany" + } + ], + "time_text": "2015 to 2022", + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "candidates", + "candidates": { + "ordering": "intent_rank", + "max_candidates": 6, + "specs": [ + { + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "definition": { + "schema_version": 1, + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicunit_primaryincome_measuredvalue_nominal", + "label": "Gross national income", + "population_type": { + "ref": "EconomicUnit", + "label": "economic unit" + }, + "measured_property": { + "ref": "primaryIncome", + "label": "primary income" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "distinguishes": true + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + }, + { + "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "definition": { + "schema_version": 1, + "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "PurchasingPowerParity" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossNationalIncome" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity", + "label": "Gross National Income Based on Purchasing Power Parity", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "PurchasingPowerParity", + "label": "PurchasingPowerParity" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "833b9da89613fa6c1775652daac2388f38204c6c9f9929ca113deed9a0d08369", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ], + "upstream": { + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + } + } + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "fallback", + "ref": "InternationalDollar", + "label": "InternationalDollar" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "InternationalDollar", + "label": "InternationalDollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross national income based on purchasing power parity in international dollars, 2015 to 2022. World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross national income based on purchasing power parity", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "in international dollars", + "axis": "unit", + "segment": "heading", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + }, + { + "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", + "definition": { + "schema_version": 1, + "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "PurchasingPowerParity", + "measurement_denominator": { + "unresolved": true + } + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossNationalIncome" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity_per_unresolved", + "label": "Gross National Income Based on Purchasing Power Parity Per Capita", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "PurchasingPowerParity", + "label": "PurchasingPowerParity" + }, + "measurement_denominator": { + "ref": "PerCapita", + "label": "PerCapita" + }, + "measurement_denominator_unresolved": true, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "7b2d5b0fc09cfc0215c8d7c6c21a5195fa21e79f2a148a6bca9ce6c3af8bbb9f", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ], + "upstream": { + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + } + } + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "fallback", + "ref": "InternationalDollar", + "label": "InternationalDollar" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "InternationalDollar", + "label": "InternationalDollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross national income based on purchasing power parity per capita in international dollars, 2015 to 2022. World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross national income based on purchasing power parity per capita", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "in international dollars", + "axis": "unit", + "segment": "heading", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "truncated": false + }, + "reading_assumptions": { + "spec_c0f61f3ca3558aac184973441a67601e": [ + { + "kind": "declared_default", + "binding_ref": "how:dac2aAidType", + "text": "official development assistance", + "refs": [ + "DAC2aAidType206" + ] + } + ], + "spec_403a96317ee8b97f1d8569c71015e5ce": [], + "spec_d94656e5d53b7b6c6b0c683145a1cd98": [] + } + } + ], + "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "sentence_plan": [ + { + "kind": "text", + "text": "3 readings.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "primary income", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross of fixed capital consumption", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "OECD DAC1", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity per capita", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "candidates" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "dataset_resubmit", + "entries": [ + { + "entry_kind": "identity", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + }, + "assumptions": [ + { + "kind": "declared_default", + "binding_ref": "how:dac2aAidType", + "text": "official development assistance", + "refs": [ + "DAC2aAidType206" + ] + } + ], + "variable_text": "GNI" + } + ] + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "dataset_resubmit", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "2841fbd5b3f24a44b79d2e01ed6faf58", + "warnings": [], + "timing_ms": { + "total": 6, + "by_step": { + "coverage": 0 + } + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GNI", + "warnings": [], + "timing_ms": { + "total": 6, + "by_step": { + "validate": 1, + "walk": 3, + "reread_arcs": 0, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 0, + "bind": 0, + "where_places": 0, + "materialise": 1, + "answer": 0, + "options": 1 + } + }, + "operations": [], + "departures": [], + "assumptions": [ + { + "kind": "declared_default", + "binding_ref": "how:dac2aAidType", + "text": "official development assistance", + "refs": [ + "DAC2aAidType206" + ] + } + ], + "status": "definite", + "spec": { + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "definition": { + "schema_version": 1, + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicunit_primaryincome_measuredvalue_nominal", + "label": "Gross national income", + "population_type": { + "ref": "EconomicUnit", + "label": "economic unit" + }, + "measured_property": { + "ref": "primaryIncome", + "label": "primary income" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_347a470e04c97eec" + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [], + "related_measures": [] + } + } + } + ], + "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1. Assumed: official development assistance.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Assumed: ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "official development assistance", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "definite" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "candidates", + "sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 3 + } + ] + } + }, + { + "answer": { + "kind": "resolution", + "status": "definite", + "sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1. Assumed: official development assistance.", + "complete": true, + "specs": [ + "spec_c0f61f3ca3558aac184973441a67601e" + ], + "gaps": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-echoes-assumptions.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-echoes-assumptions.json new file mode 100644 index 0000000..476e117 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-echoes-assumptions.json @@ -0,0 +1,8990 @@ +{ + "format_version": 1, + "name": "choose-candidate-echoes-assumptions", + "description": "Choosing candidate 0 on part 0 beside a definite part that states assumptions posts each identity entry with its reading's assumptions echoed: the chosen candidate's reading_assumptions entry, [] here, and the definite part's own assumptions. The rebuilt definite part states the same assumptions; an entry with no assumptions would be read as a fresh request.", + "origin": { + "kind": "recorded", + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:59:25Z" + }, + "call": [ + { + "op": "search", + "question": "GNI of Germany and aid flows to Kenya" + }, + { + "op": "choose", + "part": 0, + "option": 0 + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "GNI of Germany and aid flows to Kenya" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "GNI of Germany and aid flows to Kenya", + "normalized_query": "GNI of Germany and aid flows to Kenya", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "a9c72d49f9a0435598d030e5ce335a36", + "warnings": [], + "timing_ms": { + "total": 3445, + "by_step": { + "coverage": 0, + "extract": 1025 + } + }, + "llm_usage": { + "input_tokens": 11874, + "output_tokens": 489, + "cached_tokens": 860 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GNI", + "warnings": [ + { + "code": "direction_discarded", + "severity": "warn", + "message": "Kenya was named as the recipient; this shape reports the place as its own subject, so the direction was dropped." + } + ], + "timing_ms": { + "total": 1504, + "by_step": { + "recall": 1, + "shape_arcs": 2, + "shape_probe_coverage": 5, + "shape_probe": 6, + "shape_groups": 24, + "shape_labels": 9, + "shape_admission": 0, + "shape": 698, + "bind": 802, + "materialise": 1, + "answer": 2 + } + }, + "rendered_sentence": "2 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 1960 to 2025 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 1990 to 2025. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", + "sentence_plan": [ + { + "kind": "text", + "text": "2 readings.", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Primary income", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross of fixed capital consumption", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany and Kenya", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "OECD DAC1", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "1960 to 2025", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Gross national income based on purchasing power parity", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany and Kenya", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "1990 to 2025", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", + "segment": "departure", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "GNI", + "entities": [ + { + "text": "Germany" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [ + { + "code": "direction_discarded", + "binding_ref": "where:", + "asked": "Kenya", + "text": "You named Kenya as a recipient. This measure has no recipients, so this shows the place itself." + } + ], + "assumptions": [], + "status": "candidates", + "candidates": { + "ordering": "intent_rank", + "max_candidates": 6, + "specs": [ + { + "spec_id": "spec_f0d0bb4841c0e55d6d4a353e45dcd52c", + "definition": { + "schema_version": 1, + "spec_id": "spec_f0d0bb4841c0e55d6d4a353e45dcd52c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicunit_primaryincome_measuredvalue_nominal", + "label": "Gross national income", + "population_type": { + "ref": "EconomicUnit", + "label": "economic unit" + }, + "measured_property": { + "ref": "primaryIncome", + "label": "primary income" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 66, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 1 + }, + { + "label": "observations", + "count": 66 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 66, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 1960, + "end_year": 2025 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1" + }, + "value_kind": "source" + } + }, + { + "value": { + "ref": { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 1960 to 2025. Current US dollars · OECD DAC1.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "distinguishes": true + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Germany and Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + }, + { + "spec_id": "spec_c024875e07eee23ed7cb8d18b4436df1", + "definition": { + "schema_version": 1, + "spec_id": "spec_c024875e07eee23ed7cb8d18b4436df1", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "PurchasingPowerParity" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossNationalIncome" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity", + "label": "Gross National Income Based on Purchasing Power Parity", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "PurchasingPowerParity", + "label": "PurchasingPowerParity" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "833b9da89613fa6c1775652daac2388f38204c6c9f9929ca113deed9a0d08369", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ], + "upstream": { + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + } + } + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1990", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 72, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 2 + }, + { + "label": "observations", + "count": 36 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 72, + "rows_exact": true, + "series": 2, + "window": { + "start_year": 1990, + "end_year": 2025 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "fallback", + "ref": "InternationalDollar", + "label": "InternationalDollar" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "InternationalDollar", + "label": "InternationalDollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Gross national income based on purchasing power parity in international dollars in Germany and Kenya, 1990 to 2025. World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Gross national income based on purchasing power parity", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "in international dollars", + "axis": "unit", + "segment": "heading", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Germany and Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1990 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "truncated": false + }, + "reading_assumptions": { + "spec_f0d0bb4841c0e55d6d4a353e45dcd52c": [], + "spec_c024875e07eee23ed7cb8d18b4436df1": [] + } + }, + { + "variable_text": "aid flows", + "warnings": [ + { + "code": "retrieval_score_weak", + "severity": "info", + "message": "the chosen reading's match to the query is weak; treat it with less confidence than a strong match." + }, + { + "code": "slot_defaulted", + "severity": "warn", + "message": "No aid type was named, so the answer covers official development assistance." + } + ], + "timing_ms": { + "total": 2329, + "by_step": { + "recall": 476, + "shape_arcs": 1, + "shape_probe_coverage": 4, + "shape_probe": 282, + "shape_groups": 22, + "shape_labels": 0, + "shape_admission": 1, + "shape": 1001, + "bind": 838, + "materialise": 6, + "answer": 5, + "options": 3 + } + }, + "restatement": { + "variable_text": "aid flows", + "entities": [ + { + "text": "Germany" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [ + { + "code": "closest_match", + "asked": "aid flows", + "shown": "gross disbursements", + "text": "You asked for aid flows. This shows gross disbursements, the closest measure the data holds." + }, + { + "code": "direction_inferred", + "binding_ref": "where:", + "asked": "Germany", + "text": "You named Germany without a direction. Only the data with Germany as the provider holds values, so this reads it as the provider." + } + ], + "assumptions": [ + { + "kind": "declared_default", + "binding_ref": "how:dac2aAidType", + "text": "official development assistance", + "refs": [ + "DAC2aAidType206" + ] + } + ], + "status": "definite", + "spec": { + "spec_id": "spec_473682ae7e62be173cac86a13815f0fa", + "definition": { + "schema_version": 1, + "spec_id": "spec_473682ae7e62be173cac86a13815f0fa", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal_family_f096b1ba", + "label": "gross disbursements (official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "DAC2aAidType206", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "dacTypeOfFinance", + "financialObligationType" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 65, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 65 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2024, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + } + ] + }, + "download": { + "rows": 65, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 1960, + "end_year": 2024 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "DAC2aAidType218", + "label": "ODA loans and other long-term capital" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 2, + "served_rows": 61, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType201", + "label": "ODA grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 1, + "served_rows": 65, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType207", + "label": "free-standing technical co-operation" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 59, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType213", + "label": "developmental food aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 44, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType216", + "label": "humanitarian aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 29, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross disbursements to Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2a", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "DAC2aAidType206", + "label": "official development assistance" + } + ], + "provenance": "declared_default" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "measure_elected" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "measure_elected" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "high", + "available_at_place": true, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_433a5ca3b9aa482f8f332201570ef664", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 65, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1985, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1992, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1973, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1994, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1987, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1989, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1987, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1961, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 1985, + "end_year": 1990 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "KES", + "origin": "EUR" + } + } + } + } + } + ], + "rendered_sentence": "Answered 1 of 2 parts. GNI has 2 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 1960 to 2025 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 1990 to 2025. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself. Germany's gross disbursements to Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a. You asked for aid flows. This shows gross disbursements, the closest measure the data holds. You named Germany without a direction. Only the data with Germany as the provider holds values, so this reads it as the provider. Assumed: official development assistance.", + "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "GNI", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " has 2 readings.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Primary income", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross of fixed capital consumption", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany and Kenya", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "OECD DAC1", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "1960 to 2025", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Gross national income based on purchasing power parity", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany and Kenya", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "1990 to 2025", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "1960 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "You asked for aid flows. This shows gross disbursements, the closest measure the data holds.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "You named Germany without a direction. Only the data with Germany as the provider holds values, so this reads it as the provider.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "Assumed: ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "official development assistance", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 1 + } + ], + "status": "mixed" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "dataset_resubmit", + "entries": [ + { + "entry_kind": "identity", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + } + }, + "assumptions": [], + "variable_text": "GNI" + }, + { + "entry_kind": "identity", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + }, + "assumptions": [ + { + "kind": "declared_default", + "binding_ref": "how:dac2aAidType", + "text": "official development assistance", + "refs": [ + "DAC2aAidType206" + ] + } + ], + "variable_text": "aid flows" + } + ] + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "dataset_resubmit", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "e6a2e3be3760490a92f536f24e5b3be0", + "warnings": [], + "timing_ms": { + "total": 1743, + "by_step": { + "coverage": 0 + } + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GNI", + "warnings": [], + "timing_ms": { + "total": 2, + "by_step": { + "validate": 0, + "walk": 0, + "reread_arcs": 0, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 1, + "bind": 0, + "where_places": 0, + "materialise": 0, + "answer": 1, + "options": 0 + } + }, + "operations": [], + "departures": [ + { + "code": "entity_unavailable", + "binding_ref": "where:", + "text": "You asked for Kenya. The data holds no values for it." + } + ], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_f0d0bb4841c0e55d6d4a353e45dcd52c", + "definition": { + "schema_version": 1, + "spec_id": "spec_f0d0bb4841c0e55d6d4a353e45dcd52c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicunit_primaryincome_measuredvalue_nominal", + "label": "Gross national income", + "population_type": { + "ref": "EconomicUnit", + "label": "economic unit" + }, + "measured_property": { + "ref": "primaryIncome", + "label": "primary income" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 66, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 1 + }, + { + "label": "observations", + "count": 66 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 66, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 1960, + "end_year": 2025 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1" + }, + "value_kind": "source" + } + }, + { + "value": { + "ref": { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 1960 to 2025. Current US dollars · OECD DAC1.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Germany and Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec" + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [], + "related_measures": [] + } + } + }, + { + "variable_text": "aid flows", + "warnings": [], + "timing_ms": { + "total": 1718, + "by_step": { + "validate": 0, + "walk": 6, + "reread_arcs": 0, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 1700, + "bind": 0, + "where_places": 1, + "materialise": 5, + "answer": 5, + "options": 1 + } + }, + "operations": [], + "departures": [], + "assumptions": [ + { + "kind": "declared_default", + "binding_ref": "how:dac2aAidType", + "text": "official development assistance", + "refs": [ + "DAC2aAidType206" + ] + } + ], + "status": "definite", + "spec": { + "spec_id": "spec_473682ae7e62be173cac86a13815f0fa", + "definition": { + "schema_version": 1, + "spec_id": "spec_473682ae7e62be173cac86a13815f0fa", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal_family_f096b1ba", + "label": "gross disbursements (official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "DAC2aAidType206", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "dacTypeOfFinance" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 65, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 65 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2024, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + } + ] + }, + "download": { + "rows": 65, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 1960, + "end_year": 2024 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "DAC2aAidType218", + "label": "ODA loans and other long-term capital" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 2, + "served_rows": 61, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType201", + "label": "ODA grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 1, + "served_rows": 65, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType207", + "label": "free-standing technical co-operation" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 59, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType213", + "label": "developmental food aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 44, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType216", + "label": "humanitarian aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 29, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross disbursements to Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2a", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "DAC2aAidType206", + "label": "official development assistance" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec" + }, + "confidence": "high", + "available_at_place": true, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_433a5ca3b9aa482f8f332201570ef664", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 65, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1985, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1992, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1973, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1994, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1987, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1989, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1987, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1961, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 1985, + "end_year": 1990 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "KES", + "origin": "EUR" + } + } + } + } + } + ], + "rendered_sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 1960 to 2025. Current US dollars · OECD DAC1. You asked for Kenya. The data holds no values for it. Germany's gross disbursements to Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a. Assumed: official development assistance.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Germany and Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "You asked for Kenya. The data holds no values for it.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "1960 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "Assumed: ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "official development assistance", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 1 + } + ], + "status": "definite" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "mixed", + "sentence": "Answered 1 of 2 parts. GNI has 2 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 1960 to 2025 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 1990 to 2025. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself. Germany's gross disbursements to Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a. You asked for aid flows. This shows gross disbursements, the closest measure the data holds. You named Germany without a direction. Only the data with Germany as the provider holds values, so this reads it as the provider. Assumed: official development assistance.", + "complete": false, + "specs": [ + "spec_473682ae7e62be173cac86a13815f0fa" + ], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 2 + } + ] + } + }, + { + "answer": { + "kind": "resolution", + "status": "definite", + "sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 1960 to 2025. Current US dollars · OECD DAC1. You asked for Kenya. The data holds no values for it. Germany's gross disbursements to Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a. Assumed: official development assistance.", + "complete": true, + "specs": [ + "spec_f0d0bb4841c0e55d6d4a353e45dcd52c", + "spec_473682ae7e62be173cac86a13815f0fa" + ], + "gaps": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json index bdb34fa..23c879d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json @@ -4,9 +4,9 @@ "description": "Choosing candidate 0 on the candidates part of a two-part answer posts dataset_resubmit with one entry per part in part order: the chosen candidate's identity, and the definite part's identity with its entity_groups. Both parts answer definite, and the fetch stacks two members with each member's parts as its part column value.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "7175fe98eec005479f1397936dc011ad120092d5", - "recorded_at": "2026-10-20T16:52:45Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:59:13Z" }, "call": [ { @@ -49,14 +49,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "7175fe98eec005479f1397936dc011ad120092d5", - "trace_id": "7f6a04c16900442189166cabc9808dda", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "f1b9ad36ed4747939262b9ac26591ecf", "warnings": [], "timing_ms": { - "total": 6868, + "total": 4221, "by_step": { "coverage": 0, - "extract": 1449 + "extract": 1149 } }, "llm_usage": { @@ -83,19 +83,19 @@ } ], "timing_ms": { - "total": 4195, + "total": 2297, "by_step": { - "recall": 345, - "shape_arcs": 5, - "shape_probe_coverage": 6, - "shape_probe": 105, - "shape_groups": 66, - "shape_labels": 16, - "shape_admission": 173, - "shape": 2104, - "bind": 1323, - "materialise": 194, - "answer": 229 + "recall": 1, + "shape_arcs": 2, + "shape_probe_coverage": 3, + "shape_probe": 4, + "shape_groups": 19, + "shape_labels": 6, + "shape_admission": 297, + "shape": 1171, + "bind": 890, + "materialise": 220, + "answer": 15 } }, "rendered_sentence": "3 readings. Primary income for gross of fixed capital consumption in 49 places. World Bank International Debt Statistics (IDS) · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in 49 places. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in 49 places. World Development Indicators · 2015 to 2022. You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself.", @@ -413,6 +413,7 @@ "text": "You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself." } ], + "assumptions": [], "status": "candidates", "candidates": { "ordering": "intent_rank", @@ -1975,7 +1976,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -3560,7 +3561,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -5153,7 +5154,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -5193,6 +5194,11 @@ } ], "truncated": false + }, + "reading_assumptions": { + "spec_bc87ff8e0f29960c38c96a4f4d2b0e20": [], + "spec_07c78f9c1c511ed05a0f700b7f6c121e": [], + "spec_62eeede92636290b4c10e207bd8bffbb": [] } }, { @@ -5205,20 +5211,20 @@ } ], "timing_ms": { - "total": 4537, + "total": 2607, "by_step": { - "recall": 532, + "recall": 0, "shape_arcs": 1, - "shape_probe_coverage": 95, - "shape_probe": 218, - "shape_groups": 70, - "shape_labels": 1, - "shape_admission": 3, - "shape": 1461, - "bind": 2124, - "materialise": 35, - "answer": 367, - "options": 18 + "shape_probe_coverage": 5, + "shape_probe": 6, + "shape_groups": 17, + "shape_labels": 0, + "shape_admission": 347, + "shape": 1442, + "bind": 1148, + "materialise": 9, + "answer": 6, + "options": 2 } }, "restatement": { @@ -5246,6 +5252,7 @@ "text": "You asked for sub-Saharan Africa. This shows the countries in it, each on its own." } ], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_941030940d23f46826acaa0c6fed8bbc", @@ -6279,7 +6286,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -7170,7 +7177,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -9340,8 +9347,22 @@ } } ], - "rendered_sentence": "GNI has 3 readings. Primary income for gross of fixed capital consumption in 49 places. World Bank International Debt Statistics (IDS) · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in 49 places. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in 49 places. World Development Indicators · 2015 to 2022. You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself. Germany's gross disbursements to the 48 countries in Sub-Saharan Africa for official development assistance, 2015 to 2022. Current US dollars · OECD DAC2a. You asked for sub-Saharan Africa. This shows the countries in it, each on its own.", + "rendered_sentence": "Answered 1 of 2 parts. GNI has 3 readings. Primary income for gross of fixed capital consumption in 49 places. World Bank International Debt Statistics (IDS) · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in 49 places. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in 49 places. World Development Indicators · 2015 to 2022. You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself. Germany's gross disbursements to the 48 countries in Sub-Saharan Africa for official development assistance, 2015 to 2022. Current US dollars · OECD DAC2a. You asked for sub-Saharan Africa. This shows the countries in it, each on its own.", "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, { "kind": "slot", "text": "GNI", @@ -10039,6 +10060,7 @@ "end_year": 2022 } }, + "assumptions": [], "variable_text": "GNI" }, { @@ -10149,6 +10171,7 @@ "entity_type": "UNGeoRegion" } }, + "assumptions": [], "variable_text": "ODA disbursements" } ] @@ -10167,8 +10190,8 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "7175fe98eec005479f1397936dc011ad120092d5", - "trace_id": "31b91cf34a354255812599acec1c4e74", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "404ec2ac166b4737a42231c5569b432c", "warnings": [], "timing_ms": { "total": 1684, @@ -10184,19 +10207,19 @@ "variable_text": "GNI", "warnings": [], "timing_ms": { - "total": 97, + "total": 7, "by_step": { "validate": 0, - "walk": 78, + "walk": 0, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, "shape": 1, "bind": 0, "where_places": 0, - "materialise": 10, - "answer": 6, - "options": 2 + "materialise": 3, + "answer": 2, + "options": 1 } }, "operations": [], @@ -10207,6 +10230,7 @@ "text": "You asked for Germany, Eritrea, Namibia, South Sudan, and Seychelles. The data holds no values for them." } ], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", @@ -11762,7 +11786,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761" + "capability_version": "cap_347a470e04c97eec" }, "confidence": "high", "available_at_place": true, @@ -11776,19 +11800,19 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1514, + "total": 1491, "by_step": { "validate": 0, - "walk": 13, + "walk": 4, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 1451, + "shape": 1467, "bind": 0, - "where_places": 0, - "materialise": 31, - "answer": 16, - "options": 3 + "where_places": 1, + "materialise": 11, + "answer": 7, + "options": 1 } }, "operations": [], @@ -11799,6 +11823,7 @@ "text": "This shows the 48 countries in Sub-Saharan Africa, each on its own." } ], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_941030940d23f46826acaa0c6fed8bbc", @@ -12831,7 +12856,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -13709,7 +13734,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761" + "capability_version": "cap_347a470e04c97eec" }, "confidence": "high", "available_at_place": true, @@ -16477,7 +16502,7 @@ } }, "content_version": "cv_18a63cb9e24a4ce6dfcd1c60f0c5a470", - "prepared_at": "2026-10-20T16:52:56Z", + "prepared_at": "2026-10-21T08:59:20Z", "coverage": { "rows": 348, "dimensions": [ @@ -16576,13 +16601,13 @@ "end_year": 2022, "origin": "query" }, - "graph_revision": "dfo-dev-dc-datacommons-service-00259-rpx", + "graph_revision": null, "code_index_stamp": { "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", - "exported_at": "2026-10-20T13:18:18Z", + "exported_at": "2026-10-20T19:50:14Z", "graph_endpoint": "graph_release" }, - "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/WorldBankInternationalDebtStatistics", @@ -16650,10 +16675,10 @@ } ], "frame_grammar_version": "1.1.0", - "materialiser_build": "7175fe98eec005479f1397936dc011ad120092d5", - "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-20T16:52:56.474699+00:00" + "confirmed_at": "2026-10-21T08:59:20.553015+00:00" }, "warnings": [ { @@ -16679,7 +16704,7 @@ }, "bytes": 9453, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T16:52:56.418340+00:00", + "created_at": "2026-10-21T08:59:20.525876+00:00", "tier": "working", "url": "/api/datasets/spec_bc87ff8e0f29960c38c96a4f4d2b0e20/cv_18a63cb9e24a4ce6dfcd1c60f0c5a470/files/sha256:05184087a3031ed02bb45806f4a6c134b580ace5cada64878fca2aaa75acdb91" }, @@ -16690,14 +16715,14 @@ }, "bytes": 8146, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T16:52:56.418340+00:00", + "created_at": "2026-10-21T08:59:20.525876+00:00", "tier": "working", "url": "/api/datasets/spec_bc87ff8e0f29960c38c96a4f4d2b0e20/cv_18a63cb9e24a4ce6dfcd1c60f0c5a470/files/sha256:9f6cef75c54026bc957665229b19adb252d00d61f542483166394fa4aa273370" } ], "series_count": 44, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -16851,7 +16876,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:59:20.525956Z" + } } } }, @@ -16863,15 +16892,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A05184087a3031ed02bb45806f4a6c134b580ace5cada64878fca2aaa75acdb91?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A05184087a3031ed02bb45806f4a6c134b580ace5cada64878fca2aaa75acdb91?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A05184087a3031ed02bb45806f4a6c134b580ace5cada64878fca2aaa75acdb91?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3A05184087a3031ed02bb45806f4a6c134b580ace5cada64878fca2aaa75acdb91?X-Goog-Signature=redacted" }, "response": { "status": 200, @@ -17111,7 +17139,7 @@ } }, "content_version": "cv_9362a741d742d00a0f4f5d671e0b400c", - "prepared_at": "2026-10-20T16:52:58Z", + "prepared_at": "2026-10-21T08:59:21Z", "coverage": { "rows": 372, "dimensions": [ @@ -17234,13 +17262,13 @@ "end_year": 2022, "origin": "query" }, - "graph_revision": "dfo-dev-dc-datacommons-service-00259-rpx", + "graph_revision": null, "code_index_stamp": { "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", - "exported_at": "2026-10-20T13:18:18Z", + "exported_at": "2026-10-20T19:50:14Z", "graph_endpoint": "graph_release" }, - "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDDAC2A", @@ -17290,10 +17318,10 @@ ], "normalisations": [], "frame_grammar_version": "1.1.0", - "materialiser_build": "7175fe98eec005479f1397936dc011ad120092d5", - "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-20T16:52:58.346624+00:00" + "confirmed_at": "2026-10-21T08:59:21.291262+00:00" }, "warnings": [], "diagnostics": [ @@ -17313,7 +17341,7 @@ }, "bytes": 10503, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T16:52:58.292456+00:00", + "created_at": "2026-10-21T08:59:21.265462+00:00", "tier": "working", "url": "/api/datasets/spec_941030940d23f46826acaa0c6fed8bbc/cv_9362a741d742d00a0f4f5d671e0b400c/files/sha256:8fd31163adf485e022515e99d523bd1b93a1274726800598df8583981bc0984d" }, @@ -17324,14 +17352,14 @@ }, "bytes": 8083, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T16:52:58.292456+00:00", + "created_at": "2026-10-21T08:59:21.265462+00:00", "tier": "working", "url": "/api/datasets/spec_941030940d23f46826acaa0c6fed8bbc/cv_9362a741d742d00a0f4f5d671e0b400c/files/sha256:27b4eefb8edbb7ed613cf134d8df4fba5dfeab885ed8c2f210c26e35032df8bc" } ], "series_count": 48, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -17572,7 +17600,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:59:21.265858Z" + } } } }, @@ -17584,15 +17616,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A8fd31163adf485e022515e99d523bd1b93a1274726800598df8583981bc0984d?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A8fd31163adf485e022515e99d523bd1b93a1274726800598df8583981bc0984d?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A8fd31163adf485e022515e99d523bd1b93a1274726800598df8583981bc0984d?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3A8fd31163adf485e022515e99d523bd1b93a1274726800598df8583981bc0984d?X-Goog-Signature=redacted" }, "response": { "status": 200, @@ -17608,7 +17639,7 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "GNI has 3 readings. Primary income for gross of fixed capital consumption in 49 places. World Bank International Debt Statistics (IDS) · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in 49 places. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in 49 places. World Development Indicators · 2015 to 2022. You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself. Germany's gross disbursements to the 48 countries in Sub-Saharan Africa for official development assistance, 2015 to 2022. Current US dollars · OECD DAC2a. You asked for sub-Saharan Africa. This shows the countries in it, each on its own.", + "sentence": "Answered 1 of 2 parts. GNI has 3 readings. Primary income for gross of fixed capital consumption in 49 places. World Bank International Debt Statistics (IDS) · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in 49 places. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in 49 places. World Development Indicators · 2015 to 2022. You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself. Germany's gross disbursements to the 48 countries in Sub-Saharan Africa for official development assistance, 2015 to 2022. Current US dollars · OECD DAC2a. You asked for sub-Saharan Africa. This shows the countries in it, each on its own.", "complete": false, "specs": [ "spec_941030940d23f46826acaa0c6fed8bbc" diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-part-by-mention.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-part-by-mention.json index 50b871b..d24e655 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-part-by-mention.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-part-by-mention.json @@ -3,9 +3,10 @@ "name": "choose-part-by-mention", "description": "Naming the part by \"Congo\", a word its options mention, and the option by label posts that option's data_query, as naming the part by index does.", "origin": { - "kind": "synthetic", - "derived_from": "search-place-ambiguous", - "edit": "The refusal's data_query becomes options, and the choice is recorded live." + "kind": "recorded", + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:59:01Z" }, "call": [ { @@ -42,23 +43,23 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements from Germany to Congo", "normalized_query": "ODA disbursements from Germany to Congo", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "cc29e19289f44bb6bb0a6e0f4c8524a7", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "2ea977c9567e4f2e9c14324b2748a52d", "warnings": [], "timing_ms": { - "total": 1, + "total": 1645, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 1643 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 }, "timed_out": false }, @@ -116,6 +117,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", @@ -280,19 +282,19 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "7175fe98eec005479f1397936dc011ad120092d5", - "trace_id": "afd8940c0d5744b1ab5b12df2287d858", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "f5c1d08be0fc4630b1a1653334f28190", "warnings": [], "timing_ms": { - "total": 4246, + "total": 2024, "by_step": { - "coverage": 0 + "coverage": 1 } }, "llm_usage": { - "input_tokens": 3690, - "output_tokens": 171, - "cached_tokens": 0 + "input_tokens": 4231, + "output_tokens": 200, + "cached_tokens": 1516 }, "timed_out": false }, @@ -313,20 +315,20 @@ } ], "timing_ms": { - "total": 3780, + "total": 1906, "by_step": { "recall": 1, - "shape_arcs": 1, - "shape_probe_coverage": 11, - "shape_probe": 172, - "shape_groups": 56, - "shape_labels": 1, - "shape_admission": 1, - "shape": 498, - "bind": 3246, - "materialise": 16, - "answer": 11, - "options": 8 + "shape_arcs": 0, + "shape_probe_coverage": 3, + "shape_probe": 3, + "shape_groups": 16, + "shape_labels": 0, + "shape_admission": 0, + "shape": 845, + "bind": 1051, + "materialise": 4, + "answer": 4, + "options": 1 } }, "restatement": { @@ -348,6 +350,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_53b1ed52ebddd28ce274d419b53037c3", @@ -697,7 +700,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -1161,7 +1164,7 @@ "selected": [] } ], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-place-beside-definite.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-place-beside-definite.json index 43c041d..461e6af 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-place-beside-definite.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-place-beside-definite.json @@ -5,7 +5,7 @@ "origin": { "kind": "synthetic", "derived_from": "search-two-parts-place-ambiguous", - "edit": "Part 0 becomes the definite part, entity groups included, of a live search for \"GDP of the least developed countries\"; part 1's data_query becomes options; the choice is recorded live." + "edit": "Part 0 becomes the definite part, entity groups included, of a live search for \"GDP of the least developed countries\", and the choice is recorded live." }, "call": [ { @@ -42,23 +42,23 @@ "entry_path": "raw_text", "raw_query": "Kenya's GDP, and ODA disbursements from Germany to Congo", "normalized_query": "Kenya's GDP, and ODA disbursements from Germany to Congo", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "1fdae229dbd2489c8551682aa2bb6880", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "670f1650b70c4616805aa3dd54c4dae8", "warnings": [], "timing_ms": { - "total": 2, + "total": 1333, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 1329 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 2256, + "output_tokens": 207, + "cached_tokens": 861 }, "timed_out": false }, @@ -68,27 +68,26 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 3568, + "total": 2622, "by_step": { - "recall": 479, - "shape_arcs": 4, + "recall": 1, + "shape_arcs": 2, "shape_probe": 0, - "shape_groups": 97, - "shape_labels": 14, - "shape_admission": 1, - "shape": 1189, - "bind": 1465, - "materialise": 70, - "answer": 241, - "options": 124 + "shape_groups": 25, + "shape_labels": 6, + "shape_admission": 0, + "shape": 839, + "bind": 1261, + "materialise": 253, + "answer": 7, + "options": 261 } }, "restatement": { "variable_text": "GDP", "entities": [ { - "text": "Least Developed Countries", - "members": true + "text": "Least Developed Countries" } ], "sources": [], @@ -103,6 +102,7 @@ "text": "You asked for least developed countries. This shows its members, each on its own." } ], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_e11cdfec28d9fac6551cfaa892be9558", @@ -2389,7 +2389,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3822,7 +3822,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3929,9 +3929,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 0, + "total": 2, "by_step": { - "recall": 0 + "recall": 2 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -3981,6 +3981,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", @@ -4215,6 +4216,7 @@ "group_id": "groups/UN.LDC" } }, + "assumptions": [], "variable_text": "GDP" }, { @@ -4258,19 +4260,19 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "7175fe98eec005479f1397936dc011ad120092d5", - "trace_id": "a5fa21b9a9af4c30ade3d59d4dcbef4b", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "6181bee2a8f84811bec4231e3fae4535", "warnings": [], "timing_ms": { - "total": 2385, + "total": 3738, "by_step": { "coverage": 0 } }, "llm_usage": { - "input_tokens": 3703, - "output_tokens": 173, - "cached_tokens": 0 + "input_tokens": 4244, + "output_tokens": 202, + "cached_tokens": 1518 }, "timed_out": false }, @@ -4280,19 +4282,19 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 1299, + "total": 3733, "by_step": { - "validate": 1, - "walk": 179, + "validate": 0, + "walk": 0, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 873, + "shape": 593, "bind": 0, - "where_places": 1, - "materialise": 118, - "answer": 3, - "options": 124 + "where_places": 0, + "materialise": 203, + "answer": 1, + "options": 2936 } }, "operations": [], @@ -4303,6 +4305,7 @@ "text": "This shows the 44 Least Developed Countries, each on its own." } ], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_e11cdfec28d9fac6551cfaa892be9558", @@ -6296,7 +6299,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_3f35867df5a65761" + "capability_version": "cap_347a470e04c97eec" }, "confidence": "high", "available_at_place": true, @@ -6405,20 +6408,20 @@ } ], "timing_ms": { - "total": 1816, + "total": 2095, "by_step": { - "recall": 0, + "recall": 1, "shape_arcs": 1, - "shape_probe_coverage": 14, - "shape_probe": 135, - "shape_groups": 66, - "shape_labels": 1, + "shape_probe_coverage": 3, + "shape_probe": 182, + "shape_groups": 23, + "shape_labels": 0, "shape_admission": 0, - "shape": 594, - "bind": 1190, - "materialise": 15, - "answer": 9, - "options": 8 + "shape": 1093, + "bind": 985, + "materialise": 7, + "answer": 6, + "options": 3 } }, "restatement": { @@ -6445,6 +6448,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_4b8c1ba9efe879b10dc3fde2c24dc483", @@ -6810,7 +6814,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -7283,7 +7287,7 @@ "selected": [] } ], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-place-one-part.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-place-one-part.json index 63e0092..0010946 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-place-one-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-place-one-part.json @@ -1,11 +1,12 @@ { "format_version": 1, "name": "choose-place-one-part", - "description": "A place refusal offers one option per candidate, so its choice gap has two options. Choosing \"Congo [DRC]\" by label in a one-part answer posts that option's data_query unchanged as the input of a new search, which answers definite.", + "description": "Choosing \"Congo [DRC]\" by label in a one-part answer posts that option's data_query unchanged as the input of a new search, which answers definite.", "origin": { - "kind": "synthetic", - "derived_from": "search-place-ambiguous", - "edit": "Each refusal's data_query becomes the no_data options Search serves, and the chosen option's answer is recorded live." + "kind": "recorded", + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:58:57Z" }, "call": [ { @@ -41,23 +42,23 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements from Germany to Congo", "normalized_query": "ODA disbursements from Germany to Congo", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "cc29e19289f44bb6bb0a6e0f4c8524a7", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "9c755dc7ffaf4568afe68d812e56d8fa", "warnings": [], "timing_ms": { - "total": 1, + "total": 1084, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 1082 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 }, "timed_out": false }, @@ -67,9 +68,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 0, "by_step": { - "recall": 1 + "recall": 0 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -115,6 +116,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", @@ -279,19 +281,18 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "5999fc9843df4455932843b0a2ac8175", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "2c9b56f048d44958a65955fad3114ade", "warnings": [], "timing_ms": { - "total": 3, + "total": 2145, "by_step": { - "coverage": 0, - "response_cache_layer2": 1 + "coverage": 0 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, + "input_tokens": 4231, + "output_tokens": 200, "cached_tokens": 0 }, "timed_out": false @@ -313,20 +314,20 @@ } ], "timing_ms": { - "total": 1703, + "total": 2028, "by_step": { "recall": 0, - "shape_arcs": 2, - "shape_probe_coverage": 8, - "shape_probe": 136, - "shape_groups": 41, + "shape_arcs": 0, + "shape_probe_coverage": 3, + "shape_probe": 309, + "shape_groups": 20, "shape_labels": 1, "shape_admission": 0, - "shape": 380, - "bind": 1297, - "materialise": 13, - "answer": 7, - "options": 6 + "shape": 1051, + "bind": 967, + "materialise": 4, + "answer": 4, + "options": 2 } }, "restatement": { @@ -348,6 +349,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_53b1ed52ebddd28ce274d419b53037c3", @@ -697,7 +699,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -1161,7 +1163,7 @@ "selected": [] } ], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-place-two-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-place-two-parts.json index b3398e8..047db53 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-place-two-parts.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-place-two-parts.json @@ -1,11 +1,12 @@ { "format_version": 1, "name": "choose-place-two-parts", - "description": "Choosing \"Congo [DRC]\" on part 1 of a two-part answer posts dataset_resubmit with one entry per part in part order: the chosen option's data_query part as a parsed entry, and part 0, still a refusal, as a parsed entry of its restatement. Part 1 answers definite and part 0 refuses again with its two options.", + "description": "Choosing \"Congo [DRC]\" on part 1 of a two-part answer posts dataset_resubmit with one entry per part in part order: the chosen option's data_query part as a parsed entry, and part 0, still a refusal, as a parsed entry of its restatement. Part 1 answers definite.", "origin": { - "kind": "synthetic", - "derived_from": "search-two-parts-place-ambiguous", - "edit": "Each refusal's data_query becomes the no_data options Search serves, and the chosen option's answer is recorded live." + "kind": "recorded", + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:59:04Z" }, "call": [ { @@ -42,23 +43,23 @@ "entry_path": "raw_text", "raw_query": "Kenya's GDP, and ODA disbursements from Germany to Congo", "normalized_query": "Kenya's GDP, and ODA disbursements from Germany to Congo", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "1fdae229dbd2489c8551682aa2bb6880", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "1766e66cd8cf4a89be01be85c97b7faa", "warnings": [], "timing_ms": { - "total": 2, + "total": 1165, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 1160 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 2256, + "output_tokens": 207, + "cached_tokens": 861 }, "timed_out": false }, @@ -120,6 +121,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", @@ -222,9 +224,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 0, + "total": 1, "by_step": { - "recall": 0 + "recall": 1 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -274,6 +276,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", @@ -475,18 +478,18 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "d81985d7be53420d9ad6129d1c803479", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "1fff9c87a16c4188ab68dc6df0cd69b3", "warnings": [], "timing_ms": { - "total": 848, + "total": 2296, "by_step": { "coverage": 0 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, + "input_tokens": 4244, + "output_tokens": 202, "cached_tokens": 0 }, "timed_out": false @@ -503,9 +506,9 @@ } ], "timing_ms": { - "total": 1, + "total": 0, "by_step": { - "recall": 1 + "recall": 0 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -555,6 +558,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", @@ -668,20 +672,20 @@ } ], "timing_ms": { - "total": 374, + "total": 2151, "by_step": { - "recall": 1, - "shape_arcs": 4, - "shape_probe_coverage": 7, - "shape_probe": 7, - "shape_groups": 42, - "shape_labels": 1, + "recall": 0, + "shape_arcs": 0, + "shape_probe_coverage": 2, + "shape_probe": 366, + "shape_groups": 16, + "shape_labels": 0, "shape_admission": 1, - "shape": 335, - "bind": 9, - "materialise": 15, - "answer": 9, - "options": 5 + "shape": 1139, + "bind": 1000, + "materialise": 6, + "answer": 4, + "options": 2 } }, "restatement": { @@ -708,6 +712,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_4b8c1ba9efe879b10dc3fde2c24dc483", @@ -1073,7 +1078,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -1546,7 +1551,7 @@ "selected": [] } ], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3671,8 +3676,22 @@ } } ], - "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific. Germany's gross disbursements to Democratic Republic of the Congo and Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", + "rendered_sentence": "Answered 1 of 2 parts. \"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific. Germany's gross disbursements to Democratic Republic of the Congo and Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, { "kind": "text", "text": "\"", @@ -3936,7 +3955,7 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific. Germany's gross disbursements to Democratic Republic of the Congo and Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", + "sentence": "Answered 1 of 2 parts. \"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific. Germany's gross disbursements to Democratic Republic of the Congo and Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", "complete": false, "specs": [ "spec_4b8c1ba9efe879b10dc3fde2c24dc483" diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json index 4f6fcaf..7409751 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json @@ -45,20 +45,20 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "95437670d1314551aa1fbdce8c8122b6", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "d0fa88511b064cc6966082b296cd6ea8", "warnings": [], "timing_ms": { - "total": 140, + "total": 4688, "by_step": { "coverage": 0, - "extract": 1 + "extract": 928 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 5885, + "output_tokens": 606, + "cached_tokens": 860 }, "timed_out": false }, @@ -68,20 +68,20 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 58, + "total": 3547, "by_step": { - "recall": 0, + "recall": 312, "shape_arcs": 2, - "shape_probe_coverage": 15, - "shape_probe": 16, - "shape_groups": 5, - "shape_labels": 9, + "shape_probe_coverage": 2, + "shape_probe": 192, + "shape_groups": 2, + "shape_labels": 6, "shape_admission": 0, - "shape": 37, - "bind": 2, - "materialise": 9, - "answer": 2, - "options": 8 + "shape": 912, + "bind": 1643, + "materialise": 3, + "answer": 462, + "options": 215 } }, "restatement": { @@ -96,6 +96,14 @@ }, "operations": [], "departures": [], + "assumptions": [ + { + "kind": "open_role", + "binding_ref": "origin:", + "text": "every creditor", + "refs": [] + } + ], "status": "definite", "spec": { "spec_id": "spec_78d04fefc3b3f1ef71acd622957e4995", @@ -539,7 +547,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -1257,7 +1265,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3242,15 +3250,15 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 14, + "total": 502, "by_step": { - "recall": 0, + "recall": 307, "shape_arcs": 1, - "shape_probe": 3, - "shape_groups": 3, + "shape_probe": 190, + "shape_groups": 1, "shape_labels": 0, - "shape_admission": 2, - "shape": 14 + "shape_admission": 0, + "shape": 195 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", @@ -3265,6 +3273,7 @@ ], "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "variable_not_resolved", @@ -3274,12 +3283,27 @@ "ambiguous_entities": [], "source_terms": [], "ambiguous_sources": [], - "unbound_qualifiers": [] + "unbound_qualifiers": [], + "options": [] } } ], - "rendered_sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "rendered_sentence": "Answered 1 of 2 parts. Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). Assumed: every creditor. No match for price of tea. Try a different wording or a related indicator.", "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, { "kind": "slot", "text": "Kenya", @@ -3509,6 +3533,38 @@ "states": [], "part_index": 0 }, + { + "kind": "text", + "text": " ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Assumed: ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "every creditor", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, { "kind": "text", "text": " ", @@ -3552,7 +3608,7 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "sentence": "Answered 1 of 2 parts. Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). Assumed: every creditor. No match for price of tea. Try a different wording or a related indicator.", "complete": false, "specs": [ "spec_78d04fefc3b3f1ef71acd622957e4995" diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json index c2d409f..02fec5e 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json @@ -5,7 +5,7 @@ "origin": { "kind": "synthetic", "derived_from": "search-two-parts-place-ambiguous", - "edit": "Each refusal's data_query becomes options, and a choice on part \"Congo\" follows." + "edit": "A choice of \"Congo [DRC]\" on part \"Congo\" follows the search." }, "call": [ { @@ -42,23 +42,23 @@ "entry_path": "raw_text", "raw_query": "Kenya's GDP, and ODA disbursements from Germany to Congo", "normalized_query": "Kenya's GDP, and ODA disbursements from Germany to Congo", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "1fdae229dbd2489c8551682aa2bb6880", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "670f1650b70c4616805aa3dd54c4dae8", "warnings": [], "timing_ms": { - "total": 2, + "total": 1333, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 1329 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 2256, + "output_tokens": 207, + "cached_tokens": 861 }, "timed_out": false }, @@ -120,6 +120,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", @@ -222,9 +223,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 0, + "total": 2, "by_step": { - "recall": 0 + "recall": 2 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -274,6 +275,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json index 1a69611..2c869e7 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json @@ -41,22 +41,22 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements from Germany to Nigeria for basic health care", "normalized_query": "ODA disbursements from Germany to Nigeria for basic health care", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "c37510c195ea4f928cd9dc72e7adf6b9", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", "warnings": [], "timing_ms": { - "total": 4, + "total": 4556, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 889 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, + "input_tokens": 6116, + "output_tokens": 408, "cached_tokens": 0 }, "timed_out": false @@ -64,27 +64,27 @@ "kind": "resolution", "parts": [ { - "variable_text": "ODA disbursements for basic health care", + "variable_text": "basic health care ODA disbursements", "warnings": [], "timing_ms": { - "total": 4815, + "total": 3505, "by_step": { - "recall": 549, + "recall": 628, "shape_arcs": 1, - "shape_probe_coverage": 80, - "shape_probe": 238, - "shape_groups": 142, - "shape_labels": 0, + "shape_probe_coverage": 5, + "shape_probe": 477, + "shape_groups": 22, + "shape_labels": 1, "shape_admission": 1, - "shape": 1269, - "bind": 2396, - "materialise": 226, - "answer": 227, - "options": 148 + "shape": 1283, + "bind": 1188, + "materialise": 11, + "answer": 381, + "options": 14 } }, "restatement": { - "variable_text": "ODA disbursements for basic health care", + "variable_text": "basic health care ODA disbursements", "entities": [ { "text": "Germany", @@ -100,6 +100,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", @@ -192,14 +193,6 @@ }, "measurement_denominator_unresolved": false, "slot_keys": [ - { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, { "axis": "how", "property": { @@ -240,6 +233,14 @@ }, "label": "netting basis" }, + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, { "axis": "where", "label": "place" @@ -264,20 +265,6 @@ ] }, "slots": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding": { - "kind": "unbound" - }, - "summable": true - }, { "key": { "axis": "how", @@ -376,6 +363,20 @@ }, "summable": false }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, { "key": { "axis": "where", @@ -512,7 +513,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -537,6 +538,102 @@ } }, "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 88, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 30, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, { "key": { "axis": "how", @@ -645,102 +742,6 @@ ], "truncated": false, "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsPurpose", - "label": "CRS purpose" - }, - "label": "sector" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSPurposeCode122", - "label": "basic health" - }, - "value_kind": "enum_value" - }, - "relation": "parent", - "parent": "CRSPurposeCode120", - "member_count": 4, - "served_rows": 88, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFinance", - "label": "CRS type of finance" - }, - "label": "instrument" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance100", - "label": "grant" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 30, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance110", - "label": "standard grant" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSTypeOfFinance100", - "member_count": 12672, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFlow", - "label": "CRS type of flow" - }, - "label": "flow" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 14098, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" } ], "entity_options": [], @@ -1008,19 +1009,6 @@ } ], "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "how", @@ -1106,6 +1094,19 @@ ], "provenance": "measure_elected" }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "where", @@ -1141,31 +1142,31 @@ ], "query_qualifiers": [ { - "text": "ODA", + "text": "basic health care", "named": [ { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode12220", + "label": "basic health care" } ], - "slot": "crsTypeOfFlow", + "slot": "crsPurpose", "disposition": "bound", "selected": [] }, { - "text": "basic health care", + "text": "ODA", "named": [ { - "ref": "CRSPurposeCode12220", - "label": "basic health care" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" } ], - "slot": "crsPurpose", + "slot": "crsTypeOfFlow", "disposition": "bound", "selected": [] } ], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json index 1767aff..481c899 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json @@ -5,7 +5,7 @@ "origin": { "kind": "synthetic", "derived_from": "search-place-ambiguous", - "edit": "A choice of option 0 follows the search." + "edit": "The no_data part's options go, and a choice of option 0 follows the search." }, "call": [ { @@ -41,23 +41,23 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements from Germany to Congo", "normalized_query": "ODA disbursements from Germany to Congo", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "cc29e19289f44bb6bb0a6e0f4c8524a7", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", "warnings": [], "timing_ms": { - "total": 1, + "total": 1788, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 1353 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 }, "timed_out": false }, @@ -67,9 +67,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 434, "by_step": { - "recall": 1 + "recall": 434 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -115,6 +115,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", @@ -142,28 +143,7 @@ ], "source_terms": [], "ambiguous_sources": [], - "unbound_qualifiers": [], - "data_query": { - "kind": "parsed", - "parts": [ - { - "variable_text": "ODA disbursements", - "entities": [ - { - "text": "Germany", - "role_text": "from", - "dcid": "country/DEU" - }, - { - "text": "Congo", - "role_text": "to" - } - ], - "sources": [], - "operations": [] - } - ] - } + "unbound_qualifiers": [] } } ], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json index 2c387eb..0e8785d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json @@ -41,23 +41,23 @@ "entry_path": "raw_text", "raw_query": "GNI of Germany from 2015 to 2022", "normalized_query": "GNI of Germany from 2015 to 2022", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "b018f4db7a8e41cbac1f24b9e43abab8", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "8a56f4a56757466094a49079c6a116c4", "warnings": [], "timing_ms": { - "total": 2, + "total": 4642, "by_step": { "coverage": 0, - "response_cache_layer1": 0 + "extract": 1227 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 7300, + "output_tokens": 300, + "cached_tokens": 861 }, "timed_out": false }, @@ -67,19 +67,19 @@ "variable_text": "GNI", "warnings": [], "timing_ms": { - "total": 4620, + "total": 3202, "by_step": { - "recall": 478, - "shape_arcs": 3, - "shape_probe_coverage": 13, - "shape_probe": 108, - "shape_groups": 200, - "shape_labels": 12, - "shape_admission": 10, - "shape": 1457, - "bind": 2338, - "materialise": 186, - "answer": 161 + "recall": 421, + "shape_arcs": 4, + "shape_probe_coverage": 2, + "shape_probe": 211, + "shape_groups": 29, + "shape_labels": 15, + "shape_admission": 0, + "shape": 1184, + "bind": 1000, + "materialise": 429, + "answer": 168 } }, "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", @@ -392,6 +392,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "candidates", "candidates": { "ordering": "intent_rank", @@ -895,7 +896,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -1429,7 +1430,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -1971,7 +1972,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -2011,6 +2012,11 @@ } ], "truncated": false + }, + "reading_assumptions": { + "spec_c0f61f3ca3558aac184973441a67601e": [], + "spec_403a96317ee8b97f1d8569c71015e5ce": [], + "spec_d94656e5d53b7b6c6b0c683145a1cd98": [] } } ], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json index 05513c8..5c2f432 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json @@ -41,23 +41,23 @@ "entry_path": "raw_text", "raw_query": "Kenya's GDP, and ODA disbursements from Germany to Congo", "normalized_query": "Kenya's GDP, and ODA disbursements from Germany to Congo", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "1fdae229dbd2489c8551682aa2bb6880", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "670f1650b70c4616805aa3dd54c4dae8", "warnings": [], "timing_ms": { - "total": 2, + "total": 1333, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 1329 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 2256, + "output_tokens": 207, + "cached_tokens": 861 }, "timed_out": false }, @@ -119,6 +119,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", @@ -147,41 +148,83 @@ "source_terms": [], "ambiguous_sources": [], "unbound_qualifiers": [], - "data_query": { - "kind": "parsed", - "parts": [ - { - "variable_text": "GDP", - "entities": [ - { - "text": "Kenya", - "role_text": "to", - "dcid": "country/KEN" - }, + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Germany", - "role_text": "from", - "dcid": "country/DEU" - }, + "variable_text": "GDP", + "entities": [ + { + "text": "Kenya", + "role_text": "to", + "dcid": "country/KEN" + }, + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Congo", - "role_text": "to" + "variable_text": "GDP", + "entities": [ + { + "text": "Kenya", + "role_text": "to", + "dcid": "country/KEN" + }, + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] } - ], - "sources": [], - "operations": [] + ] } - ] - } + } + ] } }, { "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 0, + "total": 2, "by_step": { - "recall": 0 + "recall": 2 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -231,6 +274,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", @@ -259,32 +303,74 @@ "source_terms": [], "ambiguous_sources": [], "unbound_qualifiers": [], - "data_query": { - "kind": "parsed", - "parts": [ - { - "variable_text": "ODA disbursements", - "entities": [ - { - "text": "Kenya", - "role_text": "to", - "dcid": "country/KEN" - }, + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Germany", - "role_text": "from", - "dcid": "country/DEU" - }, + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Kenya", + "role_text": "to", + "dcid": "country/KEN" + }, + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Congo", - "role_text": "to" + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Kenya", + "role_text": "to", + "dcid": "country/KEN" + }, + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] } - ], - "sources": [], - "operations": [] + ] } - ] - } + } + ] } } ], @@ -331,12 +417,12 @@ { "part": 0, "kind": "choice", - "options": 0 + "options": 2 }, { "part": 1, "kind": "choice", - "options": 0 + "options": 2 } ] } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json index e10d804..46e373f 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json @@ -5,7 +5,7 @@ "origin": { "kind": "synthetic", "derived_from": "search-place-ambiguous", - "edit": "The refusal's data_query becomes options, and a choice of \"Congo [Nowhere]\" follows." + "edit": "A choice of \"Congo [Nowhere]\" follows the search." }, "call": [ { @@ -41,23 +41,23 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements from Germany to Congo", "normalized_query": "ODA disbursements from Germany to Congo", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "cc29e19289f44bb6bb0a6e0f4c8524a7", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", "warnings": [], "timing_ms": { - "total": 1, + "total": 1788, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 1353 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 }, "timed_out": false }, @@ -67,9 +67,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 434, "by_step": { - "recall": 1 + "recall": 434 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -115,6 +115,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json index 49d9a40..e49f3bb 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json @@ -45,20 +45,20 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "95437670d1314551aa1fbdce8c8122b6", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "d0fa88511b064cc6966082b296cd6ea8", "warnings": [], "timing_ms": { - "total": 140, + "total": 4688, "by_step": { "coverage": 0, - "extract": 1 + "extract": 928 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 5885, + "output_tokens": 606, + "cached_tokens": 860 }, "timed_out": false }, @@ -68,20 +68,20 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 58, + "total": 3547, "by_step": { - "recall": 0, + "recall": 312, "shape_arcs": 2, - "shape_probe_coverage": 15, - "shape_probe": 16, - "shape_groups": 5, - "shape_labels": 9, + "shape_probe_coverage": 2, + "shape_probe": 192, + "shape_groups": 2, + "shape_labels": 6, "shape_admission": 0, - "shape": 37, - "bind": 2, - "materialise": 9, - "answer": 2, - "options": 8 + "shape": 912, + "bind": 1643, + "materialise": 3, + "answer": 462, + "options": 215 } }, "restatement": { @@ -96,6 +96,14 @@ }, "operations": [], "departures": [], + "assumptions": [ + { + "kind": "open_role", + "binding_ref": "origin:", + "text": "every creditor", + "refs": [] + } + ], "status": "definite", "spec": { "spec_id": "spec_78d04fefc3b3f1ef71acd622957e4995", @@ -539,7 +547,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -1257,7 +1265,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3242,15 +3250,15 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 14, + "total": 502, "by_step": { - "recall": 0, + "recall": 307, "shape_arcs": 1, - "shape_probe": 3, - "shape_groups": 3, + "shape_probe": 190, + "shape_groups": 1, "shape_labels": 0, - "shape_admission": 2, - "shape": 14 + "shape_admission": 0, + "shape": 195 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", @@ -3265,6 +3273,7 @@ ], "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "variable_not_resolved", @@ -3274,12 +3283,27 @@ "ambiguous_entities": [], "source_terms": [], "ambiguous_sources": [], - "unbound_qualifiers": [] + "unbound_qualifiers": [], + "options": [] } } ], - "rendered_sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "rendered_sentence": "Answered 1 of 2 parts. Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). Assumed: every creditor. No match for price of tea. Try a different wording or a related indicator.", "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, { "kind": "slot", "text": "Kenya", @@ -3509,6 +3533,38 @@ "states": [], "part_index": 0 }, + { + "kind": "text", + "text": " ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Assumed: ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "every creditor", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, { "kind": "text", "text": " ", @@ -3552,7 +3608,7 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). No match for price of tea. Try a different wording or a related indicator.", + "sentence": "Answered 1 of 2 parts. Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). Assumed: every creditor. No match for price of tea. Try a different wording or a related indicator.", "complete": false, "specs": [ "spec_78d04fefc3b3f1ef71acd622957e4995" diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json index 989bd2f..7923382 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json @@ -41,50 +41,50 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements for health and for education from Germany to Kenya, and GDP of Kenya", "normalized_query": "ODA disbursements for health and for education from Germany to Kenya, and GDP of Kenya", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "1c42f930c021432697eb26d2af4fb5c4", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "c354423648a442189d804c35586bd78a", "warnings": [], "timing_ms": { - "total": 5, + "total": 5956, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 919 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 15731, + "output_tokens": 1037, + "cached_tokens": 861 }, "timed_out": false }, "kind": "resolution", "parts": [ { - "variable_text": "health ODA disbursements", + "variable_text": "ODA disbursements for health", "warnings": [], "timing_ms": { - "total": 1771, + "total": 3227, "by_step": { - "recall": 2, - "shape_arcs": 1, - "shape_probe_coverage": 183, - "shape_probe": 183, - "shape_groups": 102, - "shape_labels": 20, + "recall": 535, + "shape_arcs": 0, + "shape_probe_coverage": 1, + "shape_probe": 197, + "shape_groups": 16, + "shape_labels": 4, "shape_admission": 0, - "shape": 599, - "bind": 39, - "materialise": 585, - "answer": 27, - "options": 519 + "shape": 1071, + "bind": 1345, + "materialise": 157, + "answer": 20, + "options": 99 } }, "restatement": { - "variable_text": "health ODA disbursements", + "variable_text": "ODA disbursements for health", "entities": [ { "text": "Germany", @@ -100,6 +100,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_25f482395c5d012ec278118f38dff29c", @@ -195,6 +196,14 @@ }, "measurement_denominator_unresolved": false, "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, { "axis": "how", "property": { @@ -235,14 +244,6 @@ }, "label": "netting basis" }, - { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, { "axis": "where", "label": "place" @@ -267,6 +268,20 @@ ] }, "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, { "key": { "axis": "how", @@ -466,20 +481,6 @@ }, "summable": false }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding": { - "kind": "unbound" - }, - "summable": true - }, { "key": { "axis": "where", @@ -591,189 +592,160 @@ "key": { "axis": "how", "property": { - "ref": "crsPurpose", - "label": "CRS purpose" + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" }, - "label": "sector" + "label": "modality" }, "options": [ { "value": { "ref": { - "ref": "CRSPurposeCode121", - "label": "general health" + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" }, "value_kind": "enum_value" }, - "relation": "child", - "parent": "CRSPurposeCode120", - "member_count": 6, - "served_rows": 82, + "relation": "root", + "member_count": 0, + "served_rows": 104, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode122", - "label": "basic health" + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSPurposeCode120", - "member_count": 4, - "served_rows": 108, + "parent": "CRSCooperationModalityB", + "member_count": 1606, + "served_rows": 21, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode123", - "label": "noncommunicable disease" + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSPurposeCode120", - "member_count": 3, - "served_rows": 4, + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 83, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode100", - "label": "social infrastructure and services" + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" }, "value_kind": "enum_value" }, - "relation": "parent", - "member_count": 13, - "served_rows": 1214, + "relation": "root", + "member_count": 0, + "served_rows": 136, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode111", - "label": "unspecified-level education" + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSPurposeCode110", - "member_count": 6, - "served_rows": 78, + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 136, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode112", - "label": "basic education" + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" }, "value_kind": "enum_value" }, - "relation": "child", - "parent": "CRSPurposeCode110", - "member_count": 6, - "served_rows": 77, + "relation": "root", + "member_count": 0, + "served_rows": 111, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode113", - "label": "upper secondary education" + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSPurposeCode110", - "member_count": 5, - "served_rows": 69, + "parent": "CRSCooperationModalityD", + "member_count": 1600, + "served_rows": 84, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode114", - "label": "post-secondary education" + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSPurposeCode110", - "member_count": 4, - "served_rows": 94, + "parent": "CRSCooperationModalityD", + "member_count": 976, + "served_rows": 27, "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFinance", - "label": "CRS type of finance" }, - "label": "instrument" - }, - "options": [ { "value": { "ref": { - "ref": "CRSTypeOfFinance100", - "label": "grant" + "ref": "CRSCooperationModalityE", + "label": "scholarship and student cost in donor country" }, "value_kind": "enum_value" }, "relation": "root", "member_count": 0, - "served_rows": 501, + "served_rows": 38, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSTypeOfFinance110", - "label": "standard grant" + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSTypeOfFinance100", - "member_count": 12672, - "served_rows": 501, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance420", - "label": "debt instrument" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 11, + "parent": "CRSCooperationModalityE", + "member_count": 819, + "served_rows": 19, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSTypeOfFinance421", - "label": "standard loan" + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSTypeOfFinance420", - "member_count": 4620, - "served_rows": 11, + "parent": "CRSCooperationModalityE", + "member_count": 315, + "served_rows": 19, "served_rows_exact": true } ], @@ -784,187 +756,216 @@ "key": { "axis": "how", "property": { - "ref": "crsTypeOfFlow", - "label": "CRS type of flow" + "ref": "crsPurpose", + "label": "CRS purpose" }, - "label": "flow" + "label": "sector" }, "options": [ { "value": { "ref": { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode121", + "label": "general health" }, "value_kind": "enum_value" }, - "relation": "root", - "member_count": 14098, - "served_rows": 512, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 6, + "served_rows": 82, "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" }, - "label": "modality" - }, - "options": [ { "value": { "ref": { - "ref": "CRSCooperationModalityB", - "label": "core contribution and pooled programme and fund" + "ref": "CRSPurposeCode122", + "label": "basic health" }, "value_kind": "enum_value" }, - "relation": "root", - "member_count": 0, - "served_rows": 104, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 108, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityB03", - "label": "contribution to specific-purpose programme and fund managed by an international organisation" + "ref": "CRSPurposeCode123", + "label": "noncommunicable disease" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSCooperationModalityB", - "member_count": 1606, - "served_rows": 21, + "parent": "CRSPurposeCode120", + "member_count": 3, + "served_rows": 4, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityB01", - "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + "ref": "CRSPurposeCode100", + "label": "social infrastructure and services" }, "value_kind": "enum_value" }, - "relation": "child", - "parent": "CRSCooperationModalityB", - "member_count": 1331, - "served_rows": 83, + "relation": "parent", + "member_count": 13, + "served_rows": 1214, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityC", - "label": "project-type intervention (group)" + "ref": "CRSPurposeCode111", + "label": "unspecified-level education" }, "value_kind": "enum_value" }, - "relation": "root", - "member_count": 0, - "served_rows": 136, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 6, + "served_rows": 78, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityC01", - "label": "project-type intervention" + "ref": "CRSPurposeCode112", + "label": "basic education" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSCooperationModalityC", - "member_count": 7005, - "served_rows": 136, + "parent": "CRSPurposeCode110", + "member_count": 6, + "served_rows": 77, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityD", - "label": "expert and other technical assistance" + "ref": "CRSPurposeCode113", + "label": "upper secondary education" }, "value_kind": "enum_value" }, - "relation": "root", - "member_count": 0, - "served_rows": 111, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 5, + "served_rows": 69, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityD02", - "label": "other technical assistance" + "ref": "CRSPurposeCode114", + "label": "post-secondary education" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSCooperationModalityD", - "member_count": 1600, - "served_rows": 84, + "parent": "CRSPurposeCode110", + "member_count": 4, + "served_rows": 94, "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" }, + "label": "instrument" + }, + "options": [ { "value": { "ref": { - "ref": "CRSCooperationModalityD01", - "label": "donor country personnel" + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 501, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSCooperationModalityD", - "member_count": 976, - "served_rows": 27, + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 501, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityE", - "label": "scholarship and student cost in donor country" + "ref": "CRSTypeOfFinance420", + "label": "debt instrument" }, "value_kind": "enum_value" }, "relation": "root", "member_count": 0, - "served_rows": 38, + "served_rows": 11, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityE01", - "label": "scholarship and training in donor country" + "ref": "CRSTypeOfFinance421", + "label": "standard loan" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSCooperationModalityE", - "member_count": 819, - "served_rows": 19, + "parent": "CRSTypeOfFinance420", + "member_count": 4620, + "served_rows": 11, "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" }, + "label": "flow" + }, + "options": [ { "value": { "ref": { - "ref": "CRSCooperationModalityE02", - "label": "imputed student cost" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" }, "value_kind": "enum_value" }, - "relation": "child", - "parent": "CRSCooperationModalityE", - "member_count": 315, - "served_rows": 19, + "relation": "root", + "member_count": 14098, + "served_rows": 512, "served_rows_exact": true } ], @@ -1236,6 +1237,19 @@ } ], "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "how", @@ -1325,19 +1339,6 @@ ], "provenance": "measure_elected" }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "where", @@ -1373,26 +1374,26 @@ ], "query_qualifiers": [ { - "text": "health", + "text": "ODA", "named": [ { - "ref": "CRSPurposeCode120", - "label": "health" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" } ], - "slot": "crsPurpose", + "slot": "crsTypeOfFlow", "disposition": "bound", "selected": [] }, { - "text": "ODA", + "text": "health", "named": [ { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode120", + "label": "health" } ], - "slot": "crsTypeOfFlow", + "slot": "crsPurpose", "disposition": "bound", "selected": [] }, @@ -1409,7 +1410,7 @@ "selected": [] } ], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3728,33 +3729,33 @@ } }, { - "variable_text": "education ODA disbursements", + "variable_text": "ODA disbursements for education", "warnings": [ { "code": "binding_folded", "severity": "info", - "message": "'education ODA disbursements' resolved to the same shape as an earlier part; folded into that part's spec." + "message": "'ODA disbursements for education' resolved to the same shape as an earlier part; folded into that part's spec." } ], "timing_ms": { - "total": 1681, + "total": 3024, "by_step": { - "recall": 1, - "shape_arcs": 1, - "shape_probe_coverage": 16, - "shape_probe": 19, - "shape_groups": 119, - "shape_labels": 14, - "shape_admission": 1, - "shape": 237, - "bind": 24, - "materialise": 881, - "answer": 38, - "options": 500 + "recall": 456, + "shape_arcs": 0, + "shape_probe_coverage": 1, + "shape_probe": 183, + "shape_groups": 17, + "shape_labels": 4, + "shape_admission": 0, + "shape": 1070, + "bind": 1243, + "materialise": 82, + "answer": 19, + "options": 154 } }, "restatement": { - "variable_text": "education ODA disbursements", + "variable_text": "ODA disbursements for education", "entities": [ { "text": "Germany", @@ -3770,6 +3771,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_25f482395c5d012ec278118f38dff29c", @@ -3865,6 +3867,14 @@ }, "measurement_denominator_unresolved": false, "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, { "axis": "how", "property": { @@ -3905,14 +3915,6 @@ }, "label": "netting basis" }, - { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, { "axis": "where", "label": "place" @@ -3937,6 +3939,20 @@ ] }, "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, { "key": { "axis": "how", @@ -4136,20 +4152,6 @@ }, "summable": false }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding": { - "kind": "unbound" - }, - "summable": true - }, { "key": { "axis": "where", @@ -4240,23 +4242,187 @@ "label": "US Dollar", "currency": "USD" }, - "provenance": { - "basis": "fallback", - "ref": "provenance/OECDCreditorReportingSystem", - "label": "OECD Creditor Reporting System (CRS)", - "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" - }, - "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" - }, - "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", - "account": "provider" - } - }, - "slot_options": [ + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", + "account": "provider" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 104, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1606, + "served_rows": 21, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 83, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 136, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 136, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 111, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 1600, + "served_rows": 84, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 976, + "served_rows": 27, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE", + "label": "scholarship and student cost in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 38, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 819, + "served_rows": 19, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 315, + "served_rows": 19, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, { "key": { "axis": "how", @@ -4476,170 +4642,6 @@ ], "truncated": false, "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSCooperationModalityB", - "label": "core contribution and pooled programme and fund" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 104, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityB03", - "label": "contribution to specific-purpose programme and fund managed by an international organisation" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityB", - "member_count": 1606, - "served_rows": 21, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityB01", - "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityB", - "member_count": 1331, - "served_rows": 83, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityC", - "label": "project-type intervention (group)" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 136, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityC01", - "label": "project-type intervention" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityC", - "member_count": 7005, - "served_rows": 136, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityD", - "label": "expert and other technical assistance" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 111, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityD02", - "label": "other technical assistance" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityD", - "member_count": 1600, - "served_rows": 84, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityD01", - "label": "donor country personnel" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityD", - "member_count": 976, - "served_rows": 27, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityE", - "label": "scholarship and student cost in donor country" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 38, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityE01", - "label": "scholarship and training in donor country" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityE", - "member_count": 819, - "served_rows": 19, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityE02", - "label": "imputed student cost" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityE", - "member_count": 315, - "served_rows": 19, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" } ], "entity_options": [], @@ -4906,6 +4908,19 @@ } ], "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "how", @@ -4995,19 +5010,6 @@ ], "provenance": "measure_elected" }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "where", @@ -5043,26 +5045,26 @@ ], "query_qualifiers": [ { - "text": "health", + "text": "ODA", "named": [ { - "ref": "CRSPurposeCode120", - "label": "health" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" } ], - "slot": "crsPurpose", + "slot": "crsTypeOfFlow", "disposition": "bound", "selected": [] }, { - "text": "ODA", + "text": "health", "named": [ { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode120", + "label": "health" } ], - "slot": "crsTypeOfFlow", + "slot": "crsPurpose", "disposition": "bound", "selected": [] }, @@ -5079,7 +5081,7 @@ "selected": [] } ], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -7412,20 +7414,20 @@ } ], "timing_ms": { - "total": 2176, + "total": 3386, "by_step": { - "recall": 1, - "shape_arcs": 3, - "shape_probe_coverage": 11, - "shape_probe": 15, - "shape_groups": 116, - "shape_labels": 14, + "recall": 579, + "shape_arcs": 2, + "shape_probe_coverage": 1, + "shape_probe": 263, + "shape_groups": 19, + "shape_labels": 4, "shape_admission": 0, - "shape": 194, - "bind": 1952, - "materialise": 5, - "answer": 9, - "options": 15 + "shape": 1015, + "bind": 1274, + "materialise": 1, + "answer": 159, + "options": 358 } }, "restatement": { @@ -7458,6 +7460,7 @@ "text": "You named Kenya as a recipient. This measure has no recipients, so this shows the place itself." } ], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_f8dea3052d1ef6ba5667628815d1a663", @@ -8847,7 +8850,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -9380,7 +9383,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -9424,50 +9427,7 @@ } ], "measure_label_axes": [], - "measure_axis_values": [], - "related_group": { - "ref": "dc/g/EconomicActivity_ActivitySource-GrossDomesticProduction", - "label": "Economic Activity With Activity Source = Gross Domestic Production" - }, - "related_measures": [ - { - "stat_var": { - "ref": "GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "label": "Gross domestic product growth rate" - }, - "definition": { - "schema_version": 1, - "spec_id": "spec_4535d09baf2bdffef7c19c7796e96687", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "EconomicActivity", - "measured_property": "amount", - "stat_type": "growthRate" - }, - "slots": [ - { - "property": "activitySource", - "binding": { - "state": "value", - "ref": "GrossDomesticProduction" - } - } - ], - "entities": { - "observationAbout": [ - "country/DEU", - "country/KEN" - ] - }, - "requested_window": { - "kind": "all" - } - } - } - } - ] + "measure_axis_values": [] } } } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json index 2cbba43..07eb593 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json @@ -1,7 +1,7 @@ { "format_version": 1, "name": "fetch-null-member", - "description": "A required member that admits null may be left out or served as null; a client reads both as null, and neither changes the outcome. The recording and this record carry the two forms of the status column's distinct.", + "description": "A member that admits null may be left out or served as null; a client reads both as null, and neither changes the outcome. The recording and this record carry the two forms of the status column's distinct.", "origin": { "kind": "synthetic", "derived_from": "answer-definite-fetch", @@ -40,22 +40,22 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements from Germany to Nigeria for basic health care", "normalized_query": "ODA disbursements from Germany to Nigeria for basic health care", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "c37510c195ea4f928cd9dc72e7adf6b9", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", "warnings": [], "timing_ms": { - "total": 4, + "total": 4556, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 889 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, + "input_tokens": 6116, + "output_tokens": 408, "cached_tokens": 0 }, "timed_out": false @@ -63,27 +63,27 @@ "kind": "resolution", "parts": [ { - "variable_text": "ODA disbursements for basic health care", + "variable_text": "basic health care ODA disbursements", "warnings": [], "timing_ms": { - "total": 4815, + "total": 3505, "by_step": { - "recall": 549, + "recall": 628, "shape_arcs": 1, - "shape_probe_coverage": 80, - "shape_probe": 238, - "shape_groups": 142, - "shape_labels": 0, + "shape_probe_coverage": 5, + "shape_probe": 477, + "shape_groups": 22, + "shape_labels": 1, "shape_admission": 1, - "shape": 1269, - "bind": 2396, - "materialise": 226, - "answer": 227, - "options": 148 + "shape": 1283, + "bind": 1188, + "materialise": 11, + "answer": 381, + "options": 14 } }, "restatement": { - "variable_text": "ODA disbursements for basic health care", + "variable_text": "basic health care ODA disbursements", "entities": [ { "text": "Germany", @@ -99,6 +99,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", @@ -191,14 +192,6 @@ }, "measurement_denominator_unresolved": false, "slot_keys": [ - { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, { "axis": "how", "property": { @@ -239,6 +232,14 @@ }, "label": "netting basis" }, + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, { "axis": "where", "label": "place" @@ -263,20 +264,6 @@ ] }, "slots": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding": { - "kind": "unbound" - }, - "summable": true - }, { "key": { "axis": "how", @@ -375,6 +362,20 @@ }, "summable": false }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, { "key": { "axis": "where", @@ -511,7 +512,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -536,6 +537,102 @@ } }, "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 88, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 30, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, { "key": { "axis": "how", @@ -644,102 +741,6 @@ ], "truncated": false, "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsPurpose", - "label": "CRS purpose" - }, - "label": "sector" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSPurposeCode122", - "label": "basic health" - }, - "value_kind": "enum_value" - }, - "relation": "parent", - "parent": "CRSPurposeCode120", - "member_count": 4, - "served_rows": 88, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFinance", - "label": "CRS type of finance" - }, - "label": "instrument" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance100", - "label": "grant" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 30, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance110", - "label": "standard grant" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSTypeOfFinance100", - "member_count": 12672, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFlow", - "label": "CRS type of flow" - }, - "label": "flow" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 14098, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" } ], "entity_options": [], @@ -1007,19 +1008,6 @@ } ], "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "how", @@ -1105,6 +1093,19 @@ ], "provenance": "measure_elected" }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "where", @@ -1140,31 +1141,31 @@ ], "query_qualifiers": [ { - "text": "ODA", + "text": "basic health care", "named": [ { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode12220", + "label": "basic health care" } ], - "slot": "crsTypeOfFlow", + "slot": "crsPurpose", "disposition": "bound", "selected": [] }, { - "text": "basic health care", + "text": "ODA", "named": [ { - "ref": "CRSPurposeCode12220", - "label": "basic health care" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" } ], - "slot": "crsPurpose", + "slot": "crsTypeOfFlow", "disposition": "bound", "selected": [] } ], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3833,7 +3834,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-11T20:09:36Z", + "prepared_at": "2026-10-21T08:57:19Z", "coverage": { "rows": 30, "dimensions": [ @@ -3862,13 +3863,13 @@ ], "window": { "kind": "all", - "origin": "default", + "start_year": 1995, "end_year": 2024, - "start_year": 1995 + "origin": "default" } }, "citation": { - "text": "OECD Creditor Reporting System (CRS)", + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", "sources": [ { "ref": "provenance/OECDCreditorReportingSystem", @@ -3889,9 +3890,9 @@ "publisher": "Organisation for Economic Co-operation and Development (OECD)", "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", - "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-08)", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", "update_cadence": "Quarterly", - "last_update": "2026-10-08", + "last_update": "2026-10-15", "years_covered": "1973-2024", "granularity": "Annual, by provider and recipient", "currencies": [ @@ -3902,6 +3903,10 @@ "transformation": "Download the source data", "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, { "transformation": "Exclude donor core contributions to multilaterals", "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." @@ -3921,22 +3926,22 @@ ], "version_history": [ { - "date": "2026-09-22", - "title": "Exclude donor core contributions", + "date": "2026-10-15", + "title": "Partial preliminary year excluded", "changes": [ { "kind": "changed", - "note": "Donor core contributions to multilateral organisations (`bi_multi = 2`) are excluded from bilateral flows, since they would otherwise double count." + "note": "The partial preliminary year published ahead of the next full release is excluded." } ] }, { - "date": "2026-08-20", + "date": "2026-10-14", "title": "First release", "changes": [ { "kind": "added", - "note": "Dataset added to the graph." + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." } ] } @@ -3946,47 +3951,25 @@ ] }, "trace": { - "facets": [ - { - "ref": "provenance/OECDCreditorReportingSystem", - "axis": "provenance", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - }, - { - "ref": "CurrencyUSD", - "axis": "unit", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - } - ], "applied_window": { "kind": "all", - "origin": "default", + "start_year": 1995, "end_year": 2024, - "start_year": 1995 + "origin": "default" }, - "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", - "normalisations": [], + "graph_revision": null, "code_index_stamp": { - "exported_at": "2026-10-10T10:52:17Z", - "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", - "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", + "graph_endpoint": "graph_release" }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", - "revision": "2026-10-08" + "revision": "2026-10-15" } ], - "capability_version": "dset_ac879dbf49857907", - "materialiser_build": "1f6ed6307bea979d38cc35c4e38e0da896c431ad", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -4157,20 +4140,36 @@ "observation_count": 0 } ], - "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "family_member_count": 21, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDCreditorReportingSystem", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + } + ], + "normalisations": [], "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261011T194155Z-80081f08", - "served_from": "head", - "confirmed_at": "2026-10-20T15:55:32.214385+00:00" + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:57:19.628756+00:00" }, - "warnings": [ - { - "code": "processing_level_undeclared", - "severity": "info", - "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." - } - ], + "warnings": [], "diagnostics": [ { "code": "processing_level_undeclared", @@ -4188,7 +4187,7 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-19T10:58:01.080848+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, @@ -4199,14 +4198,14 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-08T08:43:31.704442+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } ], "series_count": 5, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -4442,7 +4441,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:19.589587Z" + } } } }, @@ -4454,15 +4457,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" }, "response": { "status": 200, @@ -4521,7 +4523,7 @@ "members": [ { "parts": [ - "ODA disbursements for basic health care" + "basic health care ODA disbursements" ], "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json index 34fc03d..fbd95ea 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json @@ -41,23 +41,23 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements from Germany to Congo", "normalized_query": "ODA disbursements from Germany to Congo", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "cc29e19289f44bb6bb0a6e0f4c8524a7", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", "warnings": [], "timing_ms": { - "total": 1, + "total": 1788, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 1353 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 }, "timed_out": false }, @@ -67,9 +67,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 434, "by_step": { - "recall": 1 + "recall": 434 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -115,6 +115,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", @@ -143,27 +144,64 @@ "source_terms": [], "ambiguous_sources": [], "unbound_qualifiers": [], - "data_query": { - "kind": "parsed", - "parts": [ - { - "variable_text": "ODA disbursements", - "entities": [ + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Germany", - "role_text": "from", - "dcid": "country/DEU" - }, + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Congo", - "role_text": "to" + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] } - ], - "sources": [], - "operations": [] + ] } - ] - } + } + ] } } ], @@ -213,7 +251,7 @@ { "part": 0, "kind": "choice", - "options": 0 + "options": 2 } ] } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-file-selector.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-file-selector.json new file mode 100644 index 0000000..b6a9f88 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-file-selector.json @@ -0,0 +1,903 @@ +{ + "format_version": 1, + "name": "fetch-ref-expired-file-selector", + "description": "When the files route refuses artifact_expired, the client asks the file selector for the stored version in the ref's rendering and downloads the file it redirects to, which hashes to the stored digest.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-ref", + "edit": "The files route refuses 410 artifact_expired, and the file selector redirects to the parent's signed download." + }, + "call": [ + { + "op": "fetch", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [ + "basic health care ODA disbursements" + ], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + } + }, + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "artifact": { + "digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "rendering": { + "format": "parquet", + "bundle": false + } + } + } + ] + } + } + ], + "exchanges": [ + { + "request": { + "method": "GET", + "path": "/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + }, + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "prepared_at": "2026-10-21T08:57:19Z", + "coverage": { + "rows": 30, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 27 + } + ], + "window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1995 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1995 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 7 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 15 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9785, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:19.589654+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + }, + { + "artifact_digest": "sha256:ac65501b1aef56a9caaadf063eb0390e8d816198384081e2c1645b04816693b8", + "rendering": { + "format": "frame" + }, + "bytes": 4764, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:19.589654+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:ac65501b1aef56a9caaadf063eb0390e8d816198384081e2c1645b04816693b8" + }, + { + "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", + "rendering": { + "statistics": "series" + }, + "bytes": 5981, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:19.589654+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" + } + ], + "series_count": 5, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 5 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 27 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "stat_var", + "columns": "time_period", + "state": "available", + "width": 28, + "cells": 140 + }, + { + "index": "time_period", + "columns": "stat_var", + "state": "available", + "width": 6, + "cells": 162 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:19.589587Z" + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + }, + "response": { + "status": 410, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/artifact_expired", + "title": "Gone", + "status": 410, + "detail": "Every listable artifact of this version aged out of the working tier unpinned.", + "code": "artifact_expired", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": false + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/file?format=parquet&bundle=false" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "fetch-ref.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 30, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "crsCooperationModality", + "crsCooperationModality_label", + "crsPurpose", + "crsPurpose_label", + "crsTypeOfFinance", + "crsTypeOfFinance_label", + "crsTypeOfFlow", + "crsTypeOfFlow_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [ + "basic health care ODA disbursements" + ], + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." + } + ], + "missing": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json index e925717..c53b99d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json @@ -15,7 +15,7 @@ "members": [ { "parts": [ - "ODA disbursements for basic health care" + "basic health care ODA disbursements" ], "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", "spec": { @@ -282,7 +282,7 @@ } }, "content_version": "cv_11111111111111111111111111111111", - "prepared_at": "2026-10-11T20:09:36Z", + "prepared_at": "2026-10-21T08:57:19Z", "coverage": { "rows": 30, "dimensions": [ @@ -311,13 +311,13 @@ ], "window": { "kind": "all", - "origin": "default", + "start_year": 1995, "end_year": 2024, - "start_year": 1995 + "origin": "default" } }, "citation": { - "text": "OECD Creditor Reporting System (CRS)", + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", "sources": [ { "ref": "provenance/OECDCreditorReportingSystem", @@ -338,9 +338,9 @@ "publisher": "Organisation for Economic Co-operation and Development (OECD)", "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", - "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-08)", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", "update_cadence": "Quarterly", - "last_update": "2026-10-08", + "last_update": "2026-10-15", "years_covered": "1973-2024", "granularity": "Annual, by provider and recipient", "currencies": [ @@ -351,6 +351,10 @@ "transformation": "Download the source data", "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, { "transformation": "Exclude donor core contributions to multilaterals", "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." @@ -370,22 +374,22 @@ ], "version_history": [ { - "date": "2026-09-22", - "title": "Exclude donor core contributions", + "date": "2026-10-15", + "title": "Partial preliminary year excluded", "changes": [ { "kind": "changed", - "note": "Donor core contributions to multilateral organisations (`bi_multi = 2`) are excluded from bilateral flows, since they would otherwise double count." + "note": "The partial preliminary year published ahead of the next full release is excluded." } ] }, { - "date": "2026-08-20", + "date": "2026-10-14", "title": "First release", "changes": [ { "kind": "added", - "note": "Dataset added to the graph." + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." } ] } @@ -395,47 +399,25 @@ ] }, "trace": { - "facets": [ - { - "ref": "provenance/OECDCreditorReportingSystem", - "axis": "provenance", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - }, - { - "ref": "CurrencyUSD", - "axis": "unit", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - } - ], "applied_window": { "kind": "all", - "origin": "default", + "start_year": 1995, "end_year": 2024, - "start_year": 1995 + "origin": "default" }, - "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", - "normalisations": [], + "graph_revision": null, "code_index_stamp": { - "exported_at": "2026-10-10T10:52:17Z", - "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", - "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", + "graph_endpoint": "graph_release" }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", - "revision": "2026-10-08" + "revision": "2026-10-15" } ], - "capability_version": "dset_ac879dbf49857907", - "materialiser_build": "1f6ed6307bea979d38cc35c4e38e0da896c431ad", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -606,20 +588,36 @@ "observation_count": 0 } ], - "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "family_member_count": 21, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDCreditorReportingSystem", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + } + ], + "normalisations": [], "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261011T194155Z-80081f08", - "served_from": "head", - "confirmed_at": "2026-10-20T15:55:32.214385+00:00" + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:57:19.628756+00:00" }, - "warnings": [ - { - "code": "processing_level_undeclared", - "severity": "info", - "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." - } - ], + "warnings": [], "diagnostics": [ { "code": "processing_level_undeclared", @@ -637,7 +635,7 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-19T10:58:01.080848+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, @@ -648,14 +646,14 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-08T08:43:31.704442+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } ], "series_count": 5, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -890,7 +888,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:19.589587Z" + } } } } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json index 0ea58f0..fc66dd8 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json @@ -1,7 +1,7 @@ { "format_version": 1, "name": "fetch-ref-expired-not-reproducible", - "description": "When the stored version has expired and the build is refused, the client reads the versions route for the newest version. Dev refuses the keyless recorder 403 publish_not_permitted there, so the client raises VersionUnavailableError with the snapshot's artifact_expired code and no newest version.", + "description": "When the stored version has expired and the build is refused, the client asks the versions route for the newest version alone with limit=1, since the route lists versions newest first, and raises VersionUnavailableError with the snapshot's artifact_expired code and that version as the newest.", "origin": { "kind": "synthetic", "derived_from": "fetch-ref", @@ -15,7 +15,7 @@ "members": [ { "parts": [ - "ODA disbursements for basic health care" + "basic health care ODA disbursements" ], "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", "spec": { @@ -227,22 +227,26 @@ { "request": { "method": "GET", - "path": "/datasets/spec_774d6c001a6250aa67ca676ab067895e/versions" + "path": "/datasets/spec_774d6c001a6250aa67ca676ab067895e/versions?limit=1" }, "response": { - "status": 403, + "status": 200, "headers": { - "content-type": "application/problem+json" + "content-type": "application/json" }, "json": { - "type": "/codes/publish_not_permitted", - "title": "Publish Not Permitted", - "status": 403, - "detail": "no principal header was presented; the publish permission is not granted to this caller", - "code": "publish_not_permitted", - "trace_id": "85846c77110a4f20924573e2f3654b1e", - "capability_version": "dset_1e6cd9546fac19e9", - "retryable": false + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "versions": [ + { + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "base_content_version": null, + "rendering": "plain", + "groupby": null + } + ], + "next_cursor": null, + "complete": true } } } @@ -252,7 +256,7 @@ "error": { "class": "VersionUnavailableError", "code": "artifact_expired", - "newest_version": null + "newest_version": "cv_b92d94774702c7f05f2075d0b03dd756" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-same-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-same-version.json index 73ca431..86a76d5 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-same-version.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-same-version.json @@ -15,7 +15,7 @@ "members": [ { "parts": [ - "ODA disbursements for basic health care" + "basic health care ODA disbursements" ], "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", "spec": { @@ -282,7 +282,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-11T20:09:36Z", + "prepared_at": "2026-10-21T08:57:19Z", "coverage": { "rows": 30, "dimensions": [ @@ -311,13 +311,13 @@ ], "window": { "kind": "all", - "origin": "default", + "start_year": 1995, "end_year": 2024, - "start_year": 1995 + "origin": "default" } }, "citation": { - "text": "OECD Creditor Reporting System (CRS)", + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", "sources": [ { "ref": "provenance/OECDCreditorReportingSystem", @@ -338,9 +338,9 @@ "publisher": "Organisation for Economic Co-operation and Development (OECD)", "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", - "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-08)", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", "update_cadence": "Quarterly", - "last_update": "2026-10-08", + "last_update": "2026-10-15", "years_covered": "1973-2024", "granularity": "Annual, by provider and recipient", "currencies": [ @@ -351,6 +351,10 @@ "transformation": "Download the source data", "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, { "transformation": "Exclude donor core contributions to multilaterals", "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." @@ -370,22 +374,22 @@ ], "version_history": [ { - "date": "2026-09-22", - "title": "Exclude donor core contributions", + "date": "2026-10-15", + "title": "Partial preliminary year excluded", "changes": [ { "kind": "changed", - "note": "Donor core contributions to multilateral organisations (`bi_multi = 2`) are excluded from bilateral flows, since they would otherwise double count." + "note": "The partial preliminary year published ahead of the next full release is excluded." } ] }, { - "date": "2026-08-20", + "date": "2026-10-14", "title": "First release", "changes": [ { "kind": "added", - "note": "Dataset added to the graph." + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." } ] } @@ -395,47 +399,25 @@ ] }, "trace": { - "facets": [ - { - "ref": "provenance/OECDCreditorReportingSystem", - "axis": "provenance", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - }, - { - "ref": "CurrencyUSD", - "axis": "unit", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - } - ], "applied_window": { "kind": "all", - "origin": "default", + "start_year": 1995, "end_year": 2024, - "start_year": 1995 + "origin": "default" }, - "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", - "normalisations": [], + "graph_revision": null, "code_index_stamp": { - "exported_at": "2026-10-10T10:52:17Z", - "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", - "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", + "graph_endpoint": "graph_release" }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", - "revision": "2026-10-08" + "revision": "2026-10-15" } ], - "capability_version": "dset_ac879dbf49857907", - "materialiser_build": "1f6ed6307bea979d38cc35c4e38e0da896c431ad", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -606,20 +588,36 @@ "observation_count": 0 } ], - "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "family_member_count": 21, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDCreditorReportingSystem", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + } + ], + "normalisations": [], "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261011T194155Z-80081f08", - "served_from": "head", - "confirmed_at": "2026-10-20T15:55:32.214385+00:00" + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:57:19.628756+00:00" }, - "warnings": [ - { - "code": "processing_level_undeclared", - "severity": "info", - "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." - } - ], + "warnings": [], "diagnostics": [ { "code": "processing_level_undeclared", @@ -637,7 +635,7 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-19T10:58:01.080848+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, @@ -648,14 +646,14 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-08T08:43:31.704442+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } ], "series_count": 5, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -890,7 +888,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:19.589587Z" + } } } }, @@ -902,15 +904,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" }, "response": { "status": 200, @@ -957,7 +958,7 @@ "members": [ { "parts": [ - "ODA disbursements for basic health care" + "basic health care ODA disbursements" ], "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused.json index 52ac325..ee41c60 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused.json @@ -15,7 +15,7 @@ "members": [ { "parts": [ - "ODA disbursements for basic health care" + "basic health care ODA disbursements" ], "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", "spec": { @@ -182,7 +182,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-11T20:09:36Z", + "prepared_at": "2026-10-21T08:57:19Z", "coverage": { "rows": 30, "dimensions": [ @@ -217,7 +217,7 @@ } }, "citation": { - "text": "OECD Creditor Reporting System (CRS)", + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", "sources": [ { "ref": "provenance/OECDCreditorReportingSystem", @@ -238,9 +238,9 @@ "publisher": "Organisation for Economic Co-operation and Development (OECD)", "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", - "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-08)", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", "update_cadence": "Quarterly", - "last_update": "2026-10-08", + "last_update": "2026-10-15", "years_covered": "1973-2024", "granularity": "Annual, by provider and recipient", "currencies": [ @@ -251,6 +251,10 @@ "transformation": "Download the source data", "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, { "transformation": "Exclude donor core contributions to multilaterals", "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." @@ -270,22 +274,22 @@ ], "version_history": [ { - "date": "2026-09-22", - "title": "Exclude donor core contributions", + "date": "2026-10-15", + "title": "Partial preliminary year excluded", "changes": [ { "kind": "changed", - "note": "Donor core contributions to multilateral organisations (`bi_multi = 2`) are excluded from bilateral flows, since they would otherwise double count." + "note": "The partial preliminary year published ahead of the next full release is excluded." } ] }, { - "date": "2026-08-20", + "date": "2026-10-14", "title": "First release", "changes": [ { "kind": "added", - "note": "Dataset added to the graph." + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." } ] } @@ -321,21 +325,21 @@ "end_year": 2024, "start_year": 1995 }, - "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", + "graph_revision": null, "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-10T10:52:17Z", - "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", - "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" }, "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", - "revision": "2026-10-08" + "revision": "2026-10-15" } ], - "capability_version": "dset_ac879dbf49857907", - "materialiser_build": "1f6ed6307bea979d38cc35c4e38e0da896c431ad", + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -509,15 +513,9 @@ "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261011T194155Z-80081f08" + "origin_catalogue_build_id": "20261021T070020Z-7262111e" }, - "warnings": [ - { - "code": "processing_level_undeclared", - "severity": "info", - "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." - } - ], + "warnings": [], "diagnostics": [ { "code": "processing_level_undeclared", @@ -526,19 +524,6 @@ } ], "artifacts": [ - { - "artifact_digest": "sha256:028287e7243fdcb2c2926c98c15518dd57c9a8f52c111abaf0b9f183ecb6f595", - "rendering": { - "bundle": true, - "format": "parquet", - "rendition": "v3-26b274fff9db" - }, - "bytes": 39475, - "media_type": "application/zip", - "created_at": "2026-10-12T18:52:11.949332+00:00", - "tier": "working", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:028287e7243fdcb2c2926c98c15518dd57c9a8f52c111abaf0b9f183ecb6f595" - }, { "artifact_digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", "rendering": { @@ -548,88 +533,10 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-19T10:58:01.080848+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, - { - "artifact_digest": "sha256:9b3560e6b247a8365ccf74af916285e383f9ce0f521ab256fdce30a14a6efe86", - "rendering": { - "bundle": false, - "format": "csv", - "layout": 3 - }, - "bytes": 15045, - "media_type": "text/csv", - "created_at": "2026-10-19T10:57:48.537709+00:00", - "tier": "working", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:9b3560e6b247a8365ccf74af916285e383f9ce0f521ab256fdce30a14a6efe86" - }, - { - "artifact_digest": "sha256:ff9128db5d413742585685cfe34b6a7eab1be17b2fbbe72d162ed03611b6e56c", - "rendering": { - "bundle": true, - "format": "csv", - "rendition": "v3-26b274fff9db" - }, - "bytes": 44876, - "media_type": "application/zip", - "created_at": "2026-10-19T07:03:54.443890+00:00", - "tier": "working", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:ff9128db5d413742585685cfe34b6a7eab1be17b2fbbe72d162ed03611b6e56c" - }, - { - "artifact_digest": "sha256:2ff184d2ad022189c2b071f35cfd3a1119cd987cd883c5e84b2e61c9a68dc9cf", - "rendering": { - "bundle": false, - "format": "csv", - "layout": 2 - }, - "bytes": 14626, - "media_type": "text/csv", - "created_at": "2026-10-11T09:30:05.520251+00:00", - "tier": "working", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:2ff184d2ad022189c2b071f35cfd3a1119cd987cd883c5e84b2e61c9a68dc9cf" - }, - { - "artifact_digest": "sha256:6e6947dc05a82cf486d99563f5d33f72ac00ca787e70f71ce673de77e43c8550", - "rendering": { - "bundle": false, - "format": "parquet", - "layout": 2 - }, - "bytes": 9106, - "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-11T20:09:39.444643+00:00", - "tier": "working", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:6e6947dc05a82cf486d99563f5d33f72ac00ca787e70f71ce673de77e43c8550" - }, - { - "artifact_digest": "sha256:81085991152fd08de3ea248e42ecddaf04668fc0d730b0ddfe079bf53a76e7be", - "rendering": { - "bundle": false, - "format": "xlsx", - "layout": 2 - }, - "bytes": 8195, - "media_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", - "created_at": "2026-10-11T20:09:38.525130+00:00", - "tier": "working", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:81085991152fd08de3ea248e42ecddaf04668fc0d730b0ddfe079bf53a76e7be" - }, - { - "artifact_digest": "sha256:9759397ab0ee82ea2b2fd4a0daae7cadcd4a838ac23ce3e87c0b46ad501e6fc4", - "rendering": { - "bundle": true, - "format": "csv", - "rendition": "v2-fa20478fa7f3" - }, - "bytes": 42512, - "media_type": "application/zip", - "created_at": "2026-10-11T20:09:36.814329+00:00", - "tier": "pinned", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:9759397ab0ee82ea2b2fd4a0daae7cadcd4a838ac23ce3e87c0b46ad501e6fc4" - }, { "artifact_digest": "sha256:ac65501b1aef56a9caaadf063eb0390e8d816198384081e2c1645b04816693b8", "rendering": { @@ -637,8 +544,8 @@ }, "bytes": 4764, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-11T20:09:36.814329+00:00", - "tier": "pinned", + "created_at": "2026-10-21T08:57:19.589654+00:00", + "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:ac65501b1aef56a9caaadf063eb0390e8d816198384081e2c1645b04816693b8" }, { @@ -648,14 +555,14 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-08T08:43:31.704442+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } ], "series_count": 5, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -890,7 +797,11 @@ ] } }, - "series_coverage_stamp": "75f0dd0656b52cc6014f68e85c4ee297" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:19.589587Z" + } } } }, @@ -902,15 +813,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" }, "response": { "status": 403, @@ -927,15 +837,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" }, "response": { "status": 200, @@ -982,7 +891,7 @@ "members": [ { "parts": [ - "ODA disbursements for basic health care" + "basic health care ODA disbursements" ], "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-unknown-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-unknown-version.json index 8665002..3e65680 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-unknown-version.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-unknown-version.json @@ -4,9 +4,9 @@ "description": "Fetching a ref whose content_version the server never built ends at the snapshot route's 404 snapshot_not_found, which raises NotFoundError with no build: an unknown version is not an expired one.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "recorded_at": "2026-10-20T16:04:08Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:58:01Z" }, "call": [ { @@ -16,7 +16,7 @@ "members": [ { "parts": [ - "ODA disbursements for basic health care" + "basic health care ODA disbursements" ], "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", "spec": { @@ -119,8 +119,8 @@ "status": 404, "detail": "'spec_774d6c001a6250aa67ca676ab067895e' has no version at content_version 'cv_00000000000000000000000000000000'", "code": "snapshot_not_found", - "trace_id": "6a3468f97c5d4fab84110d3dfedbf9ac", - "capability_version": "dset_1e6cd9546fac19e9", + "trace_id": "a2f44c8df4c642a58f0a2a0723f7e104", + "capability_version": "dset_88fecfec3c5b89d1", "retryable": false } } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref.json index f15ffa4..5afcb7b 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref.json @@ -4,9 +4,9 @@ "description": "Fetching a ref with the cache off reads the stored version through the snapshot route, then the files route at the artifact url whose digest the ref stores, and returns the ref's member with its stored parts and sentence and no build or Search call.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "recorded_at": "2026-10-20T16:04:06Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:58:01Z" }, "call": [ { @@ -16,7 +16,7 @@ "members": [ { "parts": [ - "ODA disbursements for basic health care" + "basic health care ODA disbursements" ], "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", "spec": { @@ -183,7 +183,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-11T20:09:36Z", + "prepared_at": "2026-10-21T08:57:19Z", "coverage": { "rows": 30, "dimensions": [ @@ -218,7 +218,7 @@ } }, "citation": { - "text": "OECD Creditor Reporting System (CRS)", + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", "sources": [ { "ref": "provenance/OECDCreditorReportingSystem", @@ -239,9 +239,9 @@ "publisher": "Organisation for Economic Co-operation and Development (OECD)", "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", - "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-08)", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", "update_cadence": "Quarterly", - "last_update": "2026-10-08", + "last_update": "2026-10-15", "years_covered": "1973-2024", "granularity": "Annual, by provider and recipient", "currencies": [ @@ -252,6 +252,10 @@ "transformation": "Download the source data", "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, { "transformation": "Exclude donor core contributions to multilaterals", "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." @@ -271,22 +275,22 @@ ], "version_history": [ { - "date": "2026-09-22", - "title": "Exclude donor core contributions", + "date": "2026-10-15", + "title": "Partial preliminary year excluded", "changes": [ { "kind": "changed", - "note": "Donor core contributions to multilateral organisations (`bi_multi = 2`) are excluded from bilateral flows, since they would otherwise double count." + "note": "The partial preliminary year published ahead of the next full release is excluded." } ] }, { - "date": "2026-08-20", + "date": "2026-10-14", "title": "First release", "changes": [ { "kind": "added", - "note": "Dataset added to the graph." + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." } ] } @@ -322,21 +326,21 @@ "end_year": 2024, "start_year": 1995 }, - "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", + "graph_revision": null, "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-10T10:52:17Z", - "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", - "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" }, "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", - "revision": "2026-10-08" + "revision": "2026-10-15" } ], - "capability_version": "dset_ac879dbf49857907", - "materialiser_build": "1f6ed6307bea979d38cc35c4e38e0da896c431ad", + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -510,15 +514,9 @@ "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261011T194155Z-80081f08" + "origin_catalogue_build_id": "20261021T070020Z-7262111e" }, - "warnings": [ - { - "code": "processing_level_undeclared", - "severity": "info", - "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." - } - ], + "warnings": [], "diagnostics": [ { "code": "processing_level_undeclared", @@ -527,19 +525,6 @@ } ], "artifacts": [ - { - "artifact_digest": "sha256:028287e7243fdcb2c2926c98c15518dd57c9a8f52c111abaf0b9f183ecb6f595", - "rendering": { - "bundle": true, - "format": "parquet", - "rendition": "v3-26b274fff9db" - }, - "bytes": 39475, - "media_type": "application/zip", - "created_at": "2026-10-12T18:52:11.949332+00:00", - "tier": "working", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:028287e7243fdcb2c2926c98c15518dd57c9a8f52c111abaf0b9f183ecb6f595" - }, { "artifact_digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", "rendering": { @@ -549,88 +534,10 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-19T10:58:01.080848+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, - { - "artifact_digest": "sha256:9b3560e6b247a8365ccf74af916285e383f9ce0f521ab256fdce30a14a6efe86", - "rendering": { - "bundle": false, - "format": "csv", - "layout": 3 - }, - "bytes": 15045, - "media_type": "text/csv", - "created_at": "2026-10-19T10:57:48.537709+00:00", - "tier": "working", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:9b3560e6b247a8365ccf74af916285e383f9ce0f521ab256fdce30a14a6efe86" - }, - { - "artifact_digest": "sha256:ff9128db5d413742585685cfe34b6a7eab1be17b2fbbe72d162ed03611b6e56c", - "rendering": { - "bundle": true, - "format": "csv", - "rendition": "v3-26b274fff9db" - }, - "bytes": 44876, - "media_type": "application/zip", - "created_at": "2026-10-19T07:03:54.443890+00:00", - "tier": "working", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:ff9128db5d413742585685cfe34b6a7eab1be17b2fbbe72d162ed03611b6e56c" - }, - { - "artifact_digest": "sha256:2ff184d2ad022189c2b071f35cfd3a1119cd987cd883c5e84b2e61c9a68dc9cf", - "rendering": { - "bundle": false, - "format": "csv", - "layout": 2 - }, - "bytes": 14626, - "media_type": "text/csv", - "created_at": "2026-10-11T09:30:05.520251+00:00", - "tier": "working", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:2ff184d2ad022189c2b071f35cfd3a1119cd987cd883c5e84b2e61c9a68dc9cf" - }, - { - "artifact_digest": "sha256:6e6947dc05a82cf486d99563f5d33f72ac00ca787e70f71ce673de77e43c8550", - "rendering": { - "bundle": false, - "format": "parquet", - "layout": 2 - }, - "bytes": 9106, - "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-11T20:09:39.444643+00:00", - "tier": "working", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:6e6947dc05a82cf486d99563f5d33f72ac00ca787e70f71ce673de77e43c8550" - }, - { - "artifact_digest": "sha256:81085991152fd08de3ea248e42ecddaf04668fc0d730b0ddfe079bf53a76e7be", - "rendering": { - "bundle": false, - "format": "xlsx", - "layout": 2 - }, - "bytes": 8195, - "media_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", - "created_at": "2026-10-11T20:09:38.525130+00:00", - "tier": "working", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:81085991152fd08de3ea248e42ecddaf04668fc0d730b0ddfe079bf53a76e7be" - }, - { - "artifact_digest": "sha256:9759397ab0ee82ea2b2fd4a0daae7cadcd4a838ac23ce3e87c0b46ad501e6fc4", - "rendering": { - "bundle": true, - "format": "csv", - "rendition": "v2-fa20478fa7f3" - }, - "bytes": 42512, - "media_type": "application/zip", - "created_at": "2026-10-11T20:09:36.814329+00:00", - "tier": "pinned", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:9759397ab0ee82ea2b2fd4a0daae7cadcd4a838ac23ce3e87c0b46ad501e6fc4" - }, { "artifact_digest": "sha256:ac65501b1aef56a9caaadf063eb0390e8d816198384081e2c1645b04816693b8", "rendering": { @@ -638,8 +545,8 @@ }, "bytes": 4764, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-11T20:09:36.814329+00:00", - "tier": "pinned", + "created_at": "2026-10-21T08:57:19.589654+00:00", + "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:ac65501b1aef56a9caaadf063eb0390e8d816198384081e2c1645b04816693b8" }, { @@ -649,14 +556,14 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-08T08:43:31.704442+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } ], "series_count": 5, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -891,7 +798,11 @@ ] } }, - "series_coverage_stamp": "75f0dd0656b52cc6014f68e85c4ee297" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:19.589587Z" + } } } }, @@ -903,15 +814,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" }, "response": { "status": 200, @@ -958,7 +868,7 @@ "members": [ { "parts": [ - "ODA disbursements for basic health care" + "basic health care ODA disbursements" ], "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json index 083d7e4..26487f6 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json @@ -40,22 +40,22 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements from Germany to Nigeria for basic health care", "normalized_query": "ODA disbursements from Germany to Nigeria for basic health care", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "c37510c195ea4f928cd9dc72e7adf6b9", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", "warnings": [], "timing_ms": { - "total": 4, + "total": 4556, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 889 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, + "input_tokens": 6116, + "output_tokens": 408, "cached_tokens": 0 }, "timed_out": false @@ -63,27 +63,27 @@ "kind": "resolution", "parts": [ { - "variable_text": "ODA disbursements for basic health care", + "variable_text": "basic health care ODA disbursements", "warnings": [], "timing_ms": { - "total": 4815, + "total": 3505, "by_step": { - "recall": 549, + "recall": 628, "shape_arcs": 1, - "shape_probe_coverage": 80, - "shape_probe": 238, - "shape_groups": 142, - "shape_labels": 0, + "shape_probe_coverage": 5, + "shape_probe": 477, + "shape_groups": 22, + "shape_labels": 1, "shape_admission": 1, - "shape": 1269, - "bind": 2396, - "materialise": 226, - "answer": 227, - "options": 148 + "shape": 1283, + "bind": 1188, + "materialise": 11, + "answer": 381, + "options": 14 } }, "restatement": { - "variable_text": "ODA disbursements for basic health care", + "variable_text": "basic health care ODA disbursements", "entities": [ { "text": "Germany", @@ -99,6 +99,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", @@ -191,14 +192,6 @@ }, "measurement_denominator_unresolved": false, "slot_keys": [ - { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, { "axis": "how", "property": { @@ -239,6 +232,14 @@ }, "label": "netting basis" }, + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, { "axis": "where", "label": "place" @@ -263,20 +264,6 @@ ] }, "slots": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding": { - "kind": "unbound" - }, - "summable": true - }, { "key": { "axis": "how", @@ -375,6 +362,20 @@ }, "summable": false }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, { "key": { "axis": "where", @@ -511,7 +512,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -536,6 +537,102 @@ } }, "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 88, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 30, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, { "key": { "axis": "how", @@ -644,102 +741,6 @@ ], "truncated": false, "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsPurpose", - "label": "CRS purpose" - }, - "label": "sector" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSPurposeCode122", - "label": "basic health" - }, - "value_kind": "enum_value" - }, - "relation": "parent", - "parent": "CRSPurposeCode120", - "member_count": 4, - "served_rows": 88, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFinance", - "label": "CRS type of finance" - }, - "label": "instrument" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance100", - "label": "grant" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 30, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance110", - "label": "standard grant" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSTypeOfFinance100", - "member_count": 12672, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFlow", - "label": "CRS type of flow" - }, - "label": "flow" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 14098, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" } ], "entity_options": [], @@ -1007,19 +1008,6 @@ } ], "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "how", @@ -1105,6 +1093,19 @@ ], "provenance": "measure_elected" }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "where", @@ -1140,31 +1141,31 @@ ], "query_qualifiers": [ { - "text": "ODA", + "text": "basic health care", "named": [ { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode12220", + "label": "basic health care" } ], - "slot": "crsTypeOfFlow", + "slot": "crsPurpose", "disposition": "bound", "selected": [] }, { - "text": "basic health care", + "text": "ODA", "named": [ { - "ref": "CRSPurposeCode12220", - "label": "basic health care" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" } ], - "slot": "crsPurpose", + "slot": "crsTypeOfFlow", "disposition": "bound", "selected": [] } ], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3832,7 +3833,7 @@ } } }, - "prepared_at": "2026-10-11T20:09:36Z", + "prepared_at": "2026-10-21T08:57:19Z", "coverage": { "rows": 30, "dimensions": [ @@ -3861,13 +3862,13 @@ ], "window": { "kind": "all", - "origin": "default", + "start_year": 1995, "end_year": 2024, - "start_year": 1995 + "origin": "default" } }, "citation": { - "text": "OECD Creditor Reporting System (CRS)", + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", "sources": [ { "ref": "provenance/OECDCreditorReportingSystem", @@ -3888,9 +3889,9 @@ "publisher": "Organisation for Economic Co-operation and Development (OECD)", "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", - "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-08)", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", "update_cadence": "Quarterly", - "last_update": "2026-10-08", + "last_update": "2026-10-15", "years_covered": "1973-2024", "granularity": "Annual, by provider and recipient", "currencies": [ @@ -3901,6 +3902,10 @@ "transformation": "Download the source data", "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, { "transformation": "Exclude donor core contributions to multilaterals", "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." @@ -3920,22 +3925,22 @@ ], "version_history": [ { - "date": "2026-09-22", - "title": "Exclude donor core contributions", + "date": "2026-10-15", + "title": "Partial preliminary year excluded", "changes": [ { "kind": "changed", - "note": "Donor core contributions to multilateral organisations (`bi_multi = 2`) are excluded from bilateral flows, since they would otherwise double count." + "note": "The partial preliminary year published ahead of the next full release is excluded." } ] }, { - "date": "2026-08-20", + "date": "2026-10-14", "title": "First release", "changes": [ { "kind": "added", - "note": "Dataset added to the graph." + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." } ] } @@ -3945,47 +3950,25 @@ ] }, "trace": { - "facets": [ - { - "ref": "provenance/OECDCreditorReportingSystem", - "axis": "provenance", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - }, - { - "ref": "CurrencyUSD", - "axis": "unit", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - } - ], "applied_window": { "kind": "all", - "origin": "default", + "start_year": 1995, "end_year": 2024, - "start_year": 1995 + "origin": "default" }, - "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", - "normalisations": [], + "graph_revision": null, "code_index_stamp": { - "exported_at": "2026-10-10T10:52:17Z", - "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", - "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", + "graph_endpoint": "graph_release" }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", - "revision": "2026-10-08" + "revision": "2026-10-15" } ], - "capability_version": "dset_ac879dbf49857907", - "materialiser_build": "1f6ed6307bea979d38cc35c4e38e0da896c431ad", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -4156,20 +4139,36 @@ "observation_count": 0 } ], - "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "family_member_count": 21, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDCreditorReportingSystem", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + } + ], + "normalisations": [], "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261011T194155Z-80081f08", - "served_from": "head", - "confirmed_at": "2026-10-20T15:55:32.214385+00:00" + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:57:19.628756+00:00" }, - "warnings": [ - { - "code": "processing_level_undeclared", - "severity": "info", - "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." - } - ], + "warnings": [], "diagnostics": [ { "code": "processing_level_undeclared", @@ -4187,7 +4186,7 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-19T10:58:01.080848+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, @@ -4198,14 +4197,14 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-08T08:43:31.704442+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } ], "series_count": 5, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -4440,7 +4439,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:19.589587Z" + }, "contentVersion": "cv_b92d94774702c7f05f2075d0b03dd756" } } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json index 7938837..2aee0f0 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json @@ -40,22 +40,22 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements from Germany to Nigeria for basic health care", "normalized_query": "ODA disbursements from Germany to Nigeria for basic health care", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "c37510c195ea4f928cd9dc72e7adf6b9", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", "warnings": [], "timing_ms": { - "total": 4, + "total": 4556, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 889 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, + "input_tokens": 6116, + "output_tokens": 408, "cached_tokens": 0 }, "timed_out": false @@ -63,27 +63,27 @@ "kind": "resolution", "parts": [ { - "variable_text": "ODA disbursements for basic health care", + "variable_text": "basic health care ODA disbursements", "warnings": [], "timing_ms": { - "total": 4815, + "total": 3505, "by_step": { - "recall": 549, + "recall": 628, "shape_arcs": 1, - "shape_probe_coverage": 80, - "shape_probe": 238, - "shape_groups": 142, - "shape_labels": 0, + "shape_probe_coverage": 5, + "shape_probe": 477, + "shape_groups": 22, + "shape_labels": 1, "shape_admission": 1, - "shape": 1269, - "bind": 2396, - "materialise": 226, - "answer": 227, - "options": 148 + "shape": 1283, + "bind": 1188, + "materialise": 11, + "answer": 381, + "options": 14 } }, "restatement": { - "variable_text": "ODA disbursements for basic health care", + "variable_text": "basic health care ODA disbursements", "entities": [ { "text": "Germany", @@ -99,6 +99,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", @@ -191,14 +192,6 @@ }, "measurement_denominator_unresolved": false, "slot_keys": [ - { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, { "axis": "how", "property": { @@ -239,6 +232,14 @@ }, "label": "netting basis" }, + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, { "axis": "where", "label": "place" @@ -263,20 +264,6 @@ ] }, "slots": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding": { - "kind": "unbound" - }, - "summable": true - }, { "key": { "axis": "how", @@ -375,6 +362,20 @@ }, "summable": false }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, { "key": { "axis": "where", @@ -511,7 +512,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -536,6 +537,102 @@ } }, "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 88, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 30, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, { "key": { "axis": "how", @@ -644,102 +741,6 @@ ], "truncated": false, "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsPurpose", - "label": "CRS purpose" - }, - "label": "sector" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSPurposeCode122", - "label": "basic health" - }, - "value_kind": "enum_value" - }, - "relation": "parent", - "parent": "CRSPurposeCode120", - "member_count": 4, - "served_rows": 88, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFinance", - "label": "CRS type of finance" - }, - "label": "instrument" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance100", - "label": "grant" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 30, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance110", - "label": "standard grant" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSTypeOfFinance100", - "member_count": 12672, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFlow", - "label": "CRS type of flow" - }, - "label": "flow" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 14098, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" } ], "entity_options": [], @@ -1007,19 +1008,6 @@ } ], "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "how", @@ -1105,6 +1093,19 @@ ], "provenance": "measure_elected" }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "where", @@ -1140,31 +1141,31 @@ ], "query_qualifiers": [ { - "text": "ODA", + "text": "basic health care", "named": [ { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode12220", + "label": "basic health care" } ], - "slot": "crsTypeOfFlow", + "slot": "crsPurpose", "disposition": "bound", "selected": [] }, { - "text": "basic health care", + "text": "ODA", "named": [ { - "ref": "CRSPurposeCode12220", - "label": "basic health care" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" } ], - "slot": "crsPurpose", + "slot": "crsTypeOfFlow", "disposition": "bound", "selected": [] } ], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3933,7 +3934,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-11T20:09:36Z", + "prepared_at": "2026-10-21T08:57:19Z", "coverage": { "rows": 30, "dimensions": [ @@ -3962,13 +3963,13 @@ ], "window": { "kind": "all", - "origin": "default", + "start_year": 1995, "end_year": 2024, - "start_year": 1995 + "origin": "default" } }, "citation": { - "text": "OECD Creditor Reporting System (CRS)", + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", "sources": [ { "ref": "provenance/OECDCreditorReportingSystem", @@ -3989,9 +3990,9 @@ "publisher": "Organisation for Economic Co-operation and Development (OECD)", "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", - "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-08)", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", "update_cadence": "Quarterly", - "last_update": "2026-10-08", + "last_update": "2026-10-15", "years_covered": "1973-2024", "granularity": "Annual, by provider and recipient", "currencies": [ @@ -4002,6 +4003,10 @@ "transformation": "Download the source data", "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, { "transformation": "Exclude donor core contributions to multilaterals", "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." @@ -4021,22 +4026,22 @@ ], "version_history": [ { - "date": "2026-09-22", - "title": "Exclude donor core contributions", + "date": "2026-10-15", + "title": "Partial preliminary year excluded", "changes": [ { "kind": "changed", - "note": "Donor core contributions to multilateral organisations (`bi_multi = 2`) are excluded from bilateral flows, since they would otherwise double count." + "note": "The partial preliminary year published ahead of the next full release is excluded." } ] }, { - "date": "2026-08-20", + "date": "2026-10-14", "title": "First release", "changes": [ { "kind": "added", - "note": "Dataset added to the graph." + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." } ] } @@ -4046,47 +4051,25 @@ ] }, "trace": { - "facets": [ - { - "ref": "provenance/OECDCreditorReportingSystem", - "axis": "provenance", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - }, - { - "ref": "CurrencyUSD", - "axis": "unit", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - } - ], "applied_window": { "kind": "all", - "origin": "default", + "start_year": 1995, "end_year": 2024, - "start_year": 1995 + "origin": "default" }, - "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", - "normalisations": [], + "graph_revision": null, "code_index_stamp": { - "exported_at": "2026-10-10T10:52:17Z", - "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", - "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", + "graph_endpoint": "graph_release" }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", - "revision": "2026-10-08" + "revision": "2026-10-15" } ], - "capability_version": "dset_ac879dbf49857907", - "materialiser_build": "1f6ed6307bea979d38cc35c4e38e0da896c431ad", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -4257,20 +4240,36 @@ "observation_count": 0 } ], - "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "family_member_count": 21, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDCreditorReportingSystem", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + } + ], + "normalisations": [], "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261011T194155Z-80081f08", - "served_from": "head", - "confirmed_at": "2026-10-20T15:55:32.214385+00:00" + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:57:19.628756+00:00" }, - "warnings": [ - { - "code": "processing_level_undeclared", - "severity": "info", - "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." - } - ], + "warnings": [], "diagnostics": [ { "code": "processing_level_undeclared", @@ -4288,7 +4287,7 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-19T10:58:01.080848+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, @@ -4299,14 +4298,14 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-08T08:43:31.704442+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } ], "series_count": 5, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -4541,7 +4540,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:19.589587Z" + } } } }, @@ -4553,15 +4556,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" }, "response": { "status": 200, @@ -4620,7 +4622,7 @@ "members": [ { "parts": [ - "ODA disbursements for basic health care" + "basic health care ODA disbursements" ], "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-async-build.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-async-build.json new file mode 100644 index 0000000..459d801 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-async-build.json @@ -0,0 +1,1208 @@ +{ + "format_version": 1, + "name": "fetch-spec-async-build", + "description": "Fetching a spec whose build answers 202 polls the operation: it waits the 202's retry_after_ms, then each poll's, backing off from 1 to 8 seconds when a poll gives none, and downloads the done manifest's file.", + "origin": { + "kind": "synthetic", + "derived_from": "mint-async-build", + "edit": "The mint and result steps become one fetch of the spec, which makes the same exchanges." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + }, + "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 202, + "headers": { + "content-type": "application/json", + "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "pending", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500 + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1516, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1900, + "progress": { + "rows_written": 14493, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "3" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 2377, + "progress": { + "rows_written": 41372, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "3" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 2975, + "progress": { + "rows_written": 75380, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "4" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 3755, + "progress": { + "rows_written": 108798, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "done" + }, + "manifest": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "ref": "DAC2aAidType206", + "state": "value" + }, + "property": "dac2aAidType" + }, + { + "binding": { + "state": "unbound" + }, + "property": "dacTypeOfFinance" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "facets": { + "provenance": { + "ref": "provenance/OECDDAC2A", + "state": "value" + } + }, + "entities": {}, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2024, + "start_year": 2018 + } + } + }, + "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", + "prepared_at": "2026-10-21T08:58:24Z", + "coverage": { + "rows": 108798, + "dimensions": [ + { + "label": "financingProvider", + "count": 172, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 238, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 7 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 2018 + } + }, + "citation": { + "text": "OECD DAC2A (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=dac2a&pg=0&snb=1&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_DAC2%40DF_DAC2A&df[ag]=OECD.DCD.FSD&df[vs]=1.6&dq=.DPGC.206.USD.Q&lom=LASTNPERIODS&lo=5&to[TIME_PERIOD]=false&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "DAC2A is the OECD Development Assistance Committee's table of ODA disbursements by donor and recipient country or region. It covers bilateral donors and multilateral agencies reporting their own outflows, and includes the OECD's estimate of each donor's core multilateral contributions attributed to recipients.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip", + "attribution": "OECD (2026), OECD DAC2A, OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip (accessed on 2026-10-12)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1960-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The OECD publishes DAC2A in April, June, September and December. The complete table is downloaded from the OECD each time it is republished, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets. The totals DAC2A reports for groups of providers, such as all DAC countries, and for groups of recipients, such as regions and income groups, are included as providers and recipients of their own. Where two provider codes name the same organisation and report the same figures, the figures are counted once. Where two recipient codes name the same organisation, such as IDA and IDA's Multilateral Debt Relief Initiative, their flows are added." + }, + { + "transformation": "Select figures", + "description": "Only figures in current US dollars are included, not constant US dollars. Only flows to recipients on Part I of the DAC List are included: the developing countries, and the multilateral organisations DAC2A reports as recipients, such as development banks and UN agencies. Flows to Part II recipients, the countries in transition, are excluded." + }, + { + "transformation": "Convert to whole units", + "description": "DAC2A reports amounts in millions, which are converted to whole units. ODA per person and ODA as a share of GNI are kept as reported." + }, + { + "transformation": "Select dimensions", + "description": "Each figure is reported by year, provider, recipient and type of aid, such as grants, repayments, interest received, or debt forgiven or rescheduled. DAC2A is a table of disbursements, so every figure, repayments and interest included, is recorded as a disbursement. Figures are marked as gross or net, except where DAC2A does not say which, and as grants or non-grants where the type of aid is wholly one or the other. Imputed multilateral ODA, the OECD's estimate of each provider's share of multilateral organisations' ODA, is marked as modelled. ODA as a share of GNI records the recipient's GNI as its denominator, and ODA per person records the recipient's population." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "ODA disbursements by donor and recipient country or region, including the OECD's imputed multilateral contributions, and ODA per person and as a share of recipient GNI." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDDAC2A", + "axis": "provenance", + "basis": "bound", + "default_policy": null, + "selection_reason": null, + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": null + }, + { + "ref": null, + "axis": "measurementMethod", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 2018 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDDAC2A", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 108798 + } + ], + "family_member_count": 1, + "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:58:25.535416+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 913395, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:58:25.500374+00:00", + "tier": "working", + "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + }, + { + "artifact_digest": "sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93", + "rendering": { + "statistics": "series" + }, + "bytes": 967921, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:58:25.500374+00:00", + "tier": "working", + "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" + } + ], + "series_count": 21017, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 172 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 238 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 7 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 172, + "covered": 50 + }, + "missing": [ + { + "ref": "AdaptationFund", + "label": "Adaptation Fund" + }, + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentBankGroup", + "label": "African Development Bank Group" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AndrewCarnegieFoundation", + "label": "Andrew Carnegie Foundation" + }, + { + "ref": "ArabFundForEconomicAndSocialDevelopment", + "label": "Arab Fund for Economic and Social Development" + }, + { + "ref": "Arcadia", + "label": "Arcadia" + }, + { + "ref": "ArcusFoundation", + "label": "Arcus Foundation" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianInfrastructureInvestmentBank", + "label": "Asian Infrastructure Investment Bank" + } + ], + "truncated": true + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 172, + "covered": 50 + }, + "missing": [ + { + "ref": "AdaptationFund", + "label": "Adaptation Fund" + }, + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentBankGroup", + "label": "African Development Bank Group" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AndrewCarnegieFoundation", + "label": "Andrew Carnegie Foundation" + }, + { + "ref": "ArabFundForEconomicAndSocialDevelopment", + "label": "Arab Fund for Economic and Social Development" + }, + { + "ref": "Arcadia", + "label": "Arcadia" + }, + { + "ref": "ArcusFoundation", + "label": "Arcus Foundation" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianInfrastructureInvestmentBank", + "label": "Asian Infrastructure Investment Bank" + } + ], + "truncated": true + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 238, + "covered": 143 + }, + "missing": [ + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianDevelopmentBankSpecialFunds", + "label": "Asian Development Bank Special Funds" + }, + { + "ref": "CaribbeanDevelopmentBank", + "label": "Caribbean Development Bank" + }, + { + "ref": "CentralAmericanBankForEconomicIntegration", + "label": "Central American Bank for Economic Integration" + }, + { + "ref": "DACACPCountries", + "label": "ACP countries (DAC)" + }, + { + "ref": "DACAfrica", + "label": "Africa (DAC)" + }, + { + "ref": "DACAfricaUnallocated", + "label": "Africa, unallocated by country (DAC)" + }, + { + "ref": "DACAllMultilateralRecipients", + "label": "all multilateral recipients (DAC)" + } + ], + "truncated": true + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 238, + "covered": 141 + }, + "missing": [ + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianDevelopmentBankSpecialFunds", + "label": "Asian Development Bank Special Funds" + }, + { + "ref": "CaribbeanDevelopmentBank", + "label": "Caribbean Development Bank" + }, + { + "ref": "CentralAmericanBankForEconomicIntegration", + "label": "Central American Bank for Economic Integration" + }, + { + "ref": "DACACPCountries", + "label": "ACP countries (DAC)" + }, + { + "ref": "DACAfrica", + "label": "Africa (DAC)" + }, + { + "ref": "DACAfricaUnallocated", + "label": "Africa, unallocated by country (DAC)" + }, + { + "ref": "DACAllMultilateralRecipients", + "label": "all multilateral recipients (DAC)" + } + ], + "truncated": true + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "financingProvider", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 7 + } + ] + }, + { + "index": "financingProvider", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 238 + } + ] + }, + { + "index": "financingRecipient", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 7 + } + ] + }, + { + "index": "financingRecipient", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 172 + } + ] + }, + { + "index": "time_period", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 238 + } + ] + }, + { + "index": "time_period", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 172 + } + ] + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:58:25.500506Z" + } + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "mint-async-build.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 108798, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "dac2aAidType", + "dac2aAidType_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", + "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + } + ], + "missing": [], + "long_builds": [ + { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll_waits": [ + 1.5, + 1.5, + 1.5, + 1.5, + 1.516, + 1.9, + 2.377, + 2.975, + 3.755 + ], + "resubmissions": 0 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-capability-unavailable.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-capability-unavailable.json new file mode 100644 index 0000000..0bb8cf1 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-capability-unavailable.json @@ -0,0 +1,198 @@ +{ + "format_version": 1, + "name": "fetch-spec-capability-unavailable", + "description": "A well-formed build that asks for a rendering this deployment does not enable refuses 501 capability_unavailable, which raises InvalidRequestError, since the caller asks for another rendering, and makes no further request.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-frame-layout", + "edit": "A 501 capability_unavailable answers the build." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." + }, + "layout": "frame" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false, + "layout": "frame" + } + } + }, + "response": { + "status": 501, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/capability_unavailable", + "title": "Not Implemented", + "status": 501, + "detail": "This deployment does not enable the frame layout.", + "code": "capability_unavailable", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": false + } + } + } + ], + "expect": [ + { + "error": { + "class": "InvalidRequestError", + "code": "capability_unavailable" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json index e231dce..4815ccb 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json @@ -248,7 +248,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-20T13:59:17Z", + "prepared_at": "2026-10-21T08:57:50Z", "coverage": { "rows": 4, "dimensions": [ @@ -394,7 +394,7 @@ "graph_revision": null, "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T13:18:18Z", + "exported_at": "2026-10-20T19:50:14Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "graph_endpoint": "graph_release" }, @@ -404,8 +404,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_1e6cd9546fac19e9", - "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -579,9 +579,9 @@ "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "head", - "confirmed_at": "2026-10-20T15:55:51.543555+00:00" + "confirmed_at": "2026-10-21T08:57:50.475926+00:00" }, "warnings": [ { @@ -607,7 +607,7 @@ }, "bytes": 9541, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T13:59:18.050980+00:00", + "created_at": "2026-10-21T08:57:50.451120+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" }, @@ -618,14 +618,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T13:59:18.050980+00:00", + "created_at": "2026-10-21T08:57:50.451120+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -845,7 +845,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:50.451687Z" + } } } }, @@ -857,15 +861,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" }, "response": { "status": 200, @@ -883,15 +886,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" }, "response": { "status": 200, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json index 94753ef..5437487 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json @@ -4,9 +4,9 @@ "description": "Fetching a two-role spec with entities binding origin to null posts input.scope.entities with origin dropped and destination kept, and the build answers a new spec_id bound to destination alone.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "687d48bf1bbeffce437765ae950a2ba755137b98", - "recorded_at": "2026-10-21T06:52:59Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:57:51Z" }, "call": [ { @@ -189,12 +189,21 @@ "schema_version": 1, "spec_id": "spec_4c228c73be6c18efd0939eabb3b3c456", "identity": { + "entities": { + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + }, "shape": { "kind": "statvar_schema", - "stat_type": "measuredValue", - "population_type": "FinancialFlow", "measured_property": "amount", - "measurement_qualifier": "Nominal" + "measurement_qualifier": "Nominal", + "population_type": "FinancialFlow", + "stat_type": "measuredValue" }, "slots": [ { @@ -237,20 +246,11 @@ }, "property": "nettingBasis" } - ], - "entities": { - "destination": [ - "country/NGA" - ] - }, - "identity_version": "spec1", - "requested_window": { - "kind": "all" - } + ] } }, "content_version": "cv_1868d697e8e7d56da6a83740a940c2e5", - "prepared_at": "2026-10-21T06:50:59Z", + "prepared_at": "2026-10-21T08:57:52Z", "coverage": { "rows": 309, "dimensions": [ @@ -279,9 +279,9 @@ ], "window": { "kind": "all", - "origin": "default", + "start_year": 1995, "end_year": 2024, - "start_year": 1995 + "origin": "default" } }, "citation": { @@ -367,47 +367,25 @@ ] }, "trace": { - "facets": [ - { - "ref": "provenance/OECDCreditorReportingSystem", - "axis": "provenance", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - }, - { - "ref": "CurrencyUSD", - "axis": "unit", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - } - ], "applied_window": { "kind": "all", - "origin": "default", + "start_year": 1995, "end_year": 2024, - "start_year": 1995 + "origin": "default" }, - "graph_revision": "dfo-dev-dc-datacommons-service-00260-6xk", - "normalisations": [], + "graph_revision": null, "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", "graph_endpoint": "graph_release" }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", "revision": "2026-10-15" } ], - "capability_version": "dset_1e6cd9546fac19e9", - "materialiser_build": "687d48bf1bbeffce437765ae950a2ba755137b98", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -578,12 +556,34 @@ "observation_count": 0 } ], - "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "family_member_count": 21, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDCreditorReportingSystem", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + } + ], + "normalisations": [], "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261020T170016Z-691bf0da", - "served_from": "head", - "confirmed_at": "2026-10-21T06:50:59.928161+00:00" + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:57:52.666745+00:00" }, "warnings": [], "diagnostics": [ @@ -603,7 +603,7 @@ }, "bytes": 13341, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T06:50:59.873948+00:00", + "created_at": "2026-10-21T08:57:52.631622+00:00", "tier": "working", "url": "/api/datasets/spec_4c228c73be6c18efd0939eabb3b3c456/cv_1868d697e8e7d56da6a83740a940c2e5/files/sha256:da9aa46394801d54e23b886528b98b609d8fda2ed46a2eb9e365575ee73ddf3a" }, @@ -614,14 +614,14 @@ }, "bytes": 9074, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T06:50:59.873948+00:00", + "created_at": "2026-10-21T08:57:52.631622+00:00", "tier": "working", "url": "/api/datasets/spec_4c228c73be6c18efd0939eabb3b3c456/cv_1868d697e8e7d56da6a83740a940c2e5/files/sha256:ffd0e9eaabfc35d3113188c82648ce0bf809307a01a024b52b0baa133ef63d18" } ], "series_count": 58, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -974,7 +974,11 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:52.631891Z" + } } } }, @@ -991,12 +995,21 @@ "entry_kind": "identity", "variable_text": "dataset", "identity": { + "entities": { + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + }, "shape": { "kind": "statvar_schema", - "stat_type": "measuredValue", - "population_type": "FinancialFlow", "measured_property": "amount", - "measurement_qualifier": "Nominal" + "measurement_qualifier": "Nominal", + "population_type": "FinancialFlow", + "stat_type": "measuredValue" }, "slots": [ { @@ -1039,16 +1052,7 @@ }, "property": "nettingBasis" } - ], - "entities": { - "destination": [ - "country/NGA" - ] - }, - "identity_version": "spec1", - "requested_window": { - "kind": "all" - } + ] } } ] @@ -1067,11 +1071,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "687d48bf1bbeffce437765ae950a2ba755137b98", - "trace_id": "7d611a2ae07b416194eac78b2d77f22b", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "abe8d0c9bf6e4834b93b843fb67a3fb7", "warnings": [], "timing_ms": { - "total": 505, + "total": 127, "by_step": { "coverage": 0 } @@ -1090,23 +1094,31 @@ } ], "timing_ms": { - "total": 339, + "total": 91, "by_step": { - "validate": 4, - "walk": 222, + "validate": 2, + "walk": 64, "reread_arcs": 1, "detect_edits": 0, "resolve_survivors": 0, - "shape": 4, - "bind": 1, - "where_places": 1, - "materialise": 57, - "answer": 21, - "options": 28 + "shape": 1, + "bind": 0, + "where_places": 0, + "materialise": 11, + "answer": 10, + "options": 2 } }, "operations": [], "departures": [], + "assumptions": [ + { + "kind": "open_role", + "binding_ref": "origin:", + "text": "every provider", + "refs": [] + } + ], "status": "definite", "spec": { "spec_id": "spec_4c228c73be6c18efd0939eabb3b3c456", @@ -2237,7 +2249,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_3f35867df5a65761" + "capability_version": "cap_347a470e04c97eec" }, "confidence": "high", "available_at_place": true, @@ -4618,7 +4630,7 @@ } } ], - "rendered_sentence": "Gross ODA disbursements to Nigeria from 25 providers for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "rendered_sentence": "Gross ODA disbursements to Nigeria from 25 providers for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS). Assumed: every provider.", "sentence_plan": [ { "kind": "slot", @@ -4821,6 +4833,38 @@ "segment": "byline", "entity_refs": [], "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Assumed: ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "every provider", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 } ], "status": "definite" @@ -4835,15 +4879,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ada9aa46394801d54e23b886528b98b609d8fda2ed46a2eb9e365575ee73ddf3a?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ada9aa46394801d54e23b886528b98b609d8fda2ed46a2eb9e365575ee73ddf3a?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ada9aa46394801d54e23b886528b98b609d8fda2ed46a2eb9e365575ee73ddf3a?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3Ada9aa46394801d54e23b886528b98b609d8fda2ed46a2eb9e365575ee73ddf3a?X-Goog-Signature=redacted" }, "response": { "status": 200, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json index 133d325..5725b10 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json @@ -4,9 +4,9 @@ "description": "Fetching a two-role spec with entities naming only origin posts input.scope.entities with origin replaced and destination kept from the spec's definition, because the server's scope.entities replaces the spec's whole entity binding. The build answers a new spec_id bound to both roles.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "687d48bf1bbeffce437765ae950a2ba755137b98", - "recorded_at": "2026-10-21T06:52:57Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:57:50Z" }, "call": [ { @@ -194,12 +194,24 @@ "schema_version": 1, "spec_id": "spec_1ee5f6648c9e46ddcc806fa0034bb6a8", "identity": { + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/FRA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + }, "shape": { "kind": "statvar_schema", - "stat_type": "measuredValue", - "population_type": "FinancialFlow", "measured_property": "amount", - "measurement_qualifier": "Nominal" + "measurement_qualifier": "Nominal", + "population_type": "FinancialFlow", + "stat_type": "measuredValue" }, "slots": [ { @@ -242,23 +254,11 @@ }, "property": "nettingBasis" } - ], - "entities": { - "origin": [ - "country/FRA" - ], - "destination": [ - "country/NGA" - ] - }, - "identity_version": "spec1", - "requested_window": { - "kind": "all" - } + ] } }, "content_version": "cv_7947f7ed828c0b23b8df4c601d463c09", - "prepared_at": "2026-10-21T06:50:58Z", + "prepared_at": "2026-10-21T08:57:51Z", "coverage": { "rows": 2, "dimensions": [ @@ -287,9 +287,9 @@ ], "window": { "kind": "all", - "origin": "default", + "start_year": 2019, "end_year": 2021, - "start_year": 2019 + "origin": "default" } }, "citation": { @@ -375,47 +375,25 @@ ] }, "trace": { - "facets": [ - { - "ref": "provenance/OECDCreditorReportingSystem", - "axis": "provenance", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - }, - { - "ref": "CurrencyUSD", - "axis": "unit", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - } - ], "applied_window": { "kind": "all", - "origin": "default", + "start_year": 2019, "end_year": 2021, - "start_year": 2019 + "origin": "default" }, - "graph_revision": "dfo-dev-dc-datacommons-service-00260-6xk", - "normalisations": [], + "graph_revision": null, "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", "graph_endpoint": "graph_release" }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", "revision": "2026-10-15" } ], - "capability_version": "dset_1e6cd9546fac19e9", - "materialiser_build": "687d48bf1bbeffce437765ae950a2ba755137b98", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -586,12 +564,34 @@ "observation_count": 0 } ], - "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "family_member_count": 21, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDCreditorReportingSystem", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + } + ], + "normalisations": [], "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261020T170016Z-691bf0da", - "served_from": "head", - "confirmed_at": "2026-10-21T06:50:59.135638+00:00" + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:57:51.201451+00:00" }, "warnings": [], "diagnostics": [ @@ -611,7 +611,7 @@ }, "bytes": 9059, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T06:50:59.083645+00:00", + "created_at": "2026-10-21T08:57:51.176503+00:00", "tier": "working", "url": "/api/datasets/spec_1ee5f6648c9e46ddcc806fa0034bb6a8/cv_7947f7ed828c0b23b8df4c601d463c09/files/sha256:3f42e71fd7f6c7dde3c7294e7eb1eb6525ab0748650d41948ba054114025b297" }, @@ -622,14 +622,14 @@ }, "bytes": 5628, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T06:50:59.083645+00:00", + "created_at": "2026-10-21T08:57:51.176503+00:00", "tier": "working", "url": "/api/datasets/spec_1ee5f6648c9e46ddcc806fa0034bb6a8/cv_7947f7ed828c0b23b8df4c601d463c09/files/sha256:36616ef68df33904cc9dfa37fb145d8fd1563b1b3701710dcd8d9e04ed50d79a" } ], "series_count": 2, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -864,7 +864,11 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:51.176927Z" + } } } }, @@ -881,12 +885,24 @@ "entry_kind": "identity", "variable_text": "dataset", "identity": { + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/FRA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + }, "shape": { "kind": "statvar_schema", - "stat_type": "measuredValue", - "population_type": "FinancialFlow", "measured_property": "amount", - "measurement_qualifier": "Nominal" + "measurement_qualifier": "Nominal", + "population_type": "FinancialFlow", + "stat_type": "measuredValue" }, "slots": [ { @@ -929,19 +945,7 @@ }, "property": "nettingBasis" } - ], - "entities": { - "origin": [ - "country/FRA" - ], - "destination": [ - "country/NGA" - ] - }, - "identity_version": "spec1", - "requested_window": { - "kind": "all" - } + ] } } ] @@ -960,11 +964,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "687d48bf1bbeffce437765ae950a2ba755137b98", - "trace_id": "a4fd321a6db64e49b724fb75dac0193b", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "489a2234e7584dfdac5aad7c27819e90", "warnings": [], "timing_ms": { - "total": 398, + "total": 608, "by_step": { "coverage": 0 } @@ -977,23 +981,24 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 293, + "total": 587, "by_step": { - "validate": 5, - "walk": 242, - "reread_arcs": 1, + "validate": 2, + "walk": 65, + "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 3, - "bind": 1, - "where_places": 0, - "materialise": 16, - "answer": 21, - "options": 4 + "shape": 2, + "bind": 0, + "where_places": 329, + "materialise": 5, + "answer": 183, + "options": 1 } }, "operations": [], "departures": [], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_1ee5f6648c9e46ddcc806fa0034bb6a8", @@ -2000,7 +2005,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_3f35867df5a65761" + "capability_version": "cap_347a470e04c97eec" }, "confidence": "high", "available_at_place": true, @@ -4605,15 +4610,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A3f42e71fd7f6c7dde3c7294e7eb1eb6525ab0748650d41948ba054114025b297?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A3f42e71fd7f6c7dde3c7294e7eb1eb6525ab0748650d41948ba054114025b297?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A3f42e71fd7f6c7dde3c7294e7eb1eb6525ab0748650d41948ba054114025b297?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3A3f42e71fd7f6c7dde3c7294e7eb1eb6525ab0748650d41948ba054114025b297?X-Goog-Signature=redacted" }, "response": { "status": 200, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.json index d988575..8c1ac2d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.json @@ -4,9 +4,9 @@ "description": "Fetching a spec with layout=\"frame\" posts the frame rendering as the build's options and downloads the manifest's frame artifact, matched on format, bundle and its frame layout, with no Search call.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "687d48bf1bbeffce437765ae950a2ba755137b98", - "recorded_at": "2026-10-20T21:01:07Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:58:51Z" }, "call": [ { @@ -245,7 +245,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-11T20:09:36Z", + "prepared_at": "2026-10-21T08:57:19Z", "coverage": { "rows": 30, "dimensions": [ @@ -280,7 +280,7 @@ } }, "citation": { - "text": "OECD Creditor Reporting System (CRS)", + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", "sources": [ { "ref": "provenance/OECDCreditorReportingSystem", @@ -301,9 +301,9 @@ "publisher": "Organisation for Economic Co-operation and Development (OECD)", "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", - "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-08)", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", "update_cadence": "Quarterly", - "last_update": "2026-10-08", + "last_update": "2026-10-15", "years_covered": "1973-2024", "granularity": "Annual, by provider and recipient", "currencies": [ @@ -314,6 +314,10 @@ "transformation": "Download the source data", "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, { "transformation": "Exclude donor core contributions to multilaterals", "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." @@ -333,22 +337,22 @@ ], "version_history": [ { - "date": "2026-09-22", - "title": "Exclude donor core contributions", + "date": "2026-10-15", + "title": "Partial preliminary year excluded", "changes": [ { "kind": "changed", - "note": "Donor core contributions to multilateral organisations (`bi_multi = 2`) are excluded from bilateral flows, since they would otherwise double count." + "note": "The partial preliminary year published ahead of the next full release is excluded." } ] }, { - "date": "2026-08-20", + "date": "2026-10-14", "title": "First release", "changes": [ { "kind": "added", - "note": "Dataset added to the graph." + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." } ] } @@ -384,21 +388,21 @@ "end_year": 2024, "start_year": 1995 }, - "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", + "graph_revision": null, "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-10T10:52:17Z", - "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", - "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" }, "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", - "revision": "2026-10-08" + "revision": "2026-10-15" } ], - "capability_version": "dset_ac879dbf49857907", - "materialiser_build": "1f6ed6307bea979d38cc35c4e38e0da896c431ad", + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -572,17 +576,11 @@ "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261011T194155Z-80081f08", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "head", - "confirmed_at": "2026-10-20T21:01:12.474481+00:00" + "confirmed_at": "2026-10-21T08:57:19.628756+00:00" }, - "warnings": [ - { - "code": "processing_level_undeclared", - "severity": "info", - "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." - } - ], + "warnings": [], "diagnostics": [ { "code": "processing_level_undeclared", @@ -600,7 +598,7 @@ }, "bytes": 5627, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T20:44:10.228016+00:00", + "created_at": "2026-10-21T08:58:51.912379+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:f4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104" }, @@ -611,14 +609,14 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-08T08:43:31.704442+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } ], "series_count": 5, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -853,7 +851,11 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:19.589587Z" + } } } }, @@ -865,15 +867,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Af4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Af4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Af4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3Af4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104?X-Goog-Signature=redacted" }, "response": { "status": 200, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.json index 209ed01..7ab13ce 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.json @@ -4,9 +4,9 @@ "description": "Fetching a spec whose destination is the least developed countries group with window=(2020, 2023) answers a new spec_id. The identity entry that asks Search for its sentence carries the spec's entity_groups whole, since a window leaves every role's binding as it was, and the sentence names the group.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "36b9f48d83282bcd5d99cb8f67b83e57a00216fd", - "recorded_at": "2026-10-21T07:08:47Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:57:52Z" }, "call": [ { @@ -352,7 +352,7 @@ } }, "content_version": "cv_daec84e443d4e1b37291242d90fc8fa8", - "prepared_at": "2026-10-21T07:08:48Z", + "prepared_at": "2026-10-21T08:57:57Z", "coverage": { "rows": 170, "dimensions": [ @@ -475,7 +475,7 @@ "end_year": 2023, "origin": "query" }, - "graph_revision": "dfo-dev-dc-datacommons-service-00260-6xk", + "graph_revision": null, "code_index_stamp": { "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "exported_at": "2026-10-20T19:50:14Z", @@ -531,10 +531,10 @@ ], "normalisations": [], "frame_grammar_version": "1.1.0", - "materialiser_build": "36b9f48d83282bcd5d99cb8f67b83e57a00216fd", - "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T07:08:48.876767+00:00" + "confirmed_at": "2026-10-21T08:57:57.507793+00:00" }, "warnings": [ { @@ -560,7 +560,7 @@ }, "bytes": 8716, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T07:08:48.809260+00:00", + "created_at": "2026-10-21T08:57:57.481612+00:00", "tier": "working", "url": "/api/datasets/spec_f04936b8378cde70bc6289ac1e45ee9b/cv_daec84e443d4e1b37291242d90fc8fa8/files/sha256:5674a67518081e6d1d436a9ba9ebd4cfe59bb8aec561571b3264522dda1d72b0" }, @@ -571,14 +571,14 @@ }, "bytes": 7768, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T07:08:48.809260+00:00", + "created_at": "2026-10-21T08:57:57.481612+00:00", "tier": "working", "url": "/api/datasets/spec_f04936b8378cde70bc6289ac1e45ee9b/cv_daec84e443d4e1b37291242d90fc8fa8/files/sha256:78ad78b09dcc0d40e50f5804d66f3399fa6b851ae4b4ac48b27ce5a6f2124ef0" } ], "series_count": 43, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -819,7 +819,11 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:57.481991Z" + } } } }, @@ -953,11 +957,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "36b9f48d83282bcd5d99cb8f67b83e57a00216fd", - "trace_id": "573e457b43fd4b7f8275c71ef3fb1ce7", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "2f2da913d19e45f88486a58418e0d588", "warnings": [], "timing_ms": { - "total": 1722, + "total": 1862, "by_step": { "coverage": 0 } @@ -970,19 +974,19 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 1644, + "total": 1841, "by_step": { - "validate": 1, - "walk": 14, + "validate": 0, + "walk": 5, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 1577, + "shape": 1818, "bind": 0, - "where_places": 1, - "materialise": 31, - "answer": 17, - "options": 3 + "where_places": 0, + "materialise": 11, + "answer": 6, + "options": 1 } }, "operations": [], @@ -998,6 +1002,7 @@ "text": "This shows the 44 Least Developed Countries, each on its own." } ], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_f04936b8378cde70bc6289ac1e45ee9b", @@ -2815,7 +2820,7 @@ "start_year": 2020, "end_year": 2023 }, - "capability_version": "cap_3f35867df5a65761" + "capability_version": "cap_347a470e04c97eec" }, "confidence": "high", "available_at_place": true, @@ -5253,15 +5258,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A5674a67518081e6d1d436a9ba9ebd4cfe59bb8aec561571b3264522dda1d72b0?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A5674a67518081e6d1d436a9ba9ebd4cfe59bb8aec561571b3264522dda1d72b0?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A5674a67518081e6d1d436a9ba9ebd4cfe59bb8aec561571b3264522dda1d72b0?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3A5674a67518081e6d1d436a9ba9ebd4cfe59bb8aec561571b3264522dda1d72b0?X-Goog-Signature=redacted" }, "response": { "status": 200, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json index 89d6fd5..d804cb2 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json @@ -4,9 +4,9 @@ "description": "Fetching a spec of Germany's flows to the least developed countries group with entities naming only origin rebinds origin to France. The identity entry that asks Search for the built sentence carries the destination's group, whose binding the build kept, and the sentence names the group.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "36b9f48d83282bcd5d99cb8f67b83e57a00216fd", - "recorded_at": "2026-10-21T07:08:52Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:57:59Z" }, "call": [ { @@ -397,7 +397,7 @@ } }, "content_version": "cv_66a0a4a0331d59b519aa1629dade3d99", - "prepared_at": "2026-10-21T07:08:52Z", + "prepared_at": "2026-10-21T08:58:00Z", "coverage": { "rows": 2114, "dimensions": [ @@ -520,7 +520,7 @@ "end_year": 2024, "origin": "default" }, - "graph_revision": "dfo-dev-dc-datacommons-service-00260-6xk", + "graph_revision": null, "code_index_stamp": { "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "exported_at": "2026-10-20T19:50:14Z", @@ -576,10 +576,10 @@ ], "normalisations": [], "frame_grammar_version": "1.1.0", - "materialiser_build": "36b9f48d83282bcd5d99cb8f67b83e57a00216fd", - "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T07:08:52.918932+00:00" + "confirmed_at": "2026-10-21T08:58:00.100626+00:00" }, "warnings": [], "diagnostics": [ @@ -599,7 +599,7 @@ }, "bytes": 21027, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T07:08:52.857494+00:00", + "created_at": "2026-10-21T08:58:00.074970+00:00", "tier": "working", "url": "/api/datasets/spec_c2f21170dfa9f31705e47ed60c8fa305/cv_66a0a4a0331d59b519aa1629dade3d99/files/sha256:1ea84fd402e660f640baf08b43a6ef4ed031c01b7dc8a781237c1c3006a3f934" }, @@ -610,14 +610,14 @@ }, "bytes": 8093, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T07:08:52.857494+00:00", + "created_at": "2026-10-21T08:58:00.074970+00:00", "tier": "working", "url": "/api/datasets/spec_c2f21170dfa9f31705e47ed60c8fa305/cv_66a0a4a0331d59b519aa1629dade3d99/files/sha256:b1f80f2d3df16b6cda3831730ee4749b13e1eb3fff82cdf2f479e71f087bfe2b" } ], "series_count": 44, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -858,7 +858,11 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:58:00.075319Z" + } } } }, @@ -990,11 +994,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "36b9f48d83282bcd5d99cb8f67b83e57a00216fd", - "trace_id": "51c7ccf406404774860a36e433d3d603", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "d797c89c55b74aeda65514aff049c68b", "warnings": [], "timing_ms": { - "total": 1733, + "total": 994, "by_step": { "coverage": 0 } @@ -1007,19 +1011,19 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 1665, + "total": 973, "by_step": { - "validate": 1, - "walk": 14, + "validate": 0, + "walk": 5, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 1617, + "shape": 955, "bind": 0, - "where_places": 1, - "materialise": 19, - "answer": 10, - "options": 3 + "where_places": 0, + "materialise": 7, + "answer": 5, + "options": 1 } }, "operations": [], @@ -1030,6 +1034,7 @@ "text": "This shows the 44 Least Developed Countries, each on its own." } ], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_c2f21170dfa9f31705e47ed60c8fa305", @@ -2826,7 +2831,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_3f35867df5a65761" + "capability_version": "cap_347a470e04c97eec" }, "confidence": "high", "available_at_place": true, @@ -5252,15 +5257,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A1ea84fd402e660f640baf08b43a6ef4ed031c01b7dc8a781237c1c3006a3f934?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A1ea84fd402e660f640baf08b43a6ef4ed031c01b7dc8a781237c1c3006a3f934?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A1ea84fd402e660f640baf08b43a6ef4ed031c01b7dc8a781237c1c3006a3f934?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3A1ea84fd402e660f640baf08b43a6ef4ed031c01b7dc8a781237c1c3006a3f934?X-Goog-Signature=redacted" }, "response": { "status": 200, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json index 2504dd2..c4edfa5 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json @@ -4,9 +4,9 @@ "description": "Fetching a spec whose sentence the client holds builds bare Parquet, follows the files route's redirect with a bare request, and returns one member with that sentence and no Search call.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "recorded_at": "2026-10-20T16:04:02Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:58:01Z" }, "call": [ { @@ -249,7 +249,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-20T13:59:17Z", + "prepared_at": "2026-10-21T08:57:50Z", "coverage": { "rows": 4, "dimensions": [ @@ -395,7 +395,7 @@ "graph_revision": null, "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T13:18:18Z", + "exported_at": "2026-10-20T19:50:14Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "graph_endpoint": "graph_release" }, @@ -405,8 +405,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_1e6cd9546fac19e9", - "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -580,9 +580,9 @@ "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "head", - "confirmed_at": "2026-10-20T15:55:51.543555+00:00" + "confirmed_at": "2026-10-21T08:57:50.475926+00:00" }, "warnings": [ { @@ -608,7 +608,7 @@ }, "bytes": 9541, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T13:59:18.050980+00:00", + "created_at": "2026-10-21T08:57:50.451120+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" }, @@ -619,14 +619,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T13:59:18.050980+00:00", + "created_at": "2026-10-21T08:57:50.451120+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -846,7 +846,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:50.451687Z" + } } } }, @@ -858,15 +862,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" }, "response": { "status": 200, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.json index 50d90e9..bc8d9b8 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.json @@ -4,9 +4,9 @@ "description": "Fetching a spec with window=(2020, 2023) posts the window as input.scope, and the build answers a new spec_id. The client stores the built spec_id and content_version, takes the sentence from Search by posting the built definition's identity as a dataset_resubmit identity entry (variable_text \"dataset\" for a spec no answer part names), checks the answer's spec_id equals the built one, then downloads the file.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "recorded_at": "2026-10-20T16:04:00Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:57:46Z" }, "call": [ { @@ -190,12 +190,26 @@ "schema_version": 1, "spec_id": "spec_cb5baa4161de718f18583060674dbca6", "identity": { + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "identity_version": "spec1", + "requested_window": { + "end_year": 2023, + "kind": "range", + "start_year": 2020 + }, "shape": { "kind": "statvar_schema", - "stat_type": "measuredValue", - "population_type": "FinancialFlow", "measured_property": "amount", - "measurement_qualifier": "Nominal" + "measurement_qualifier": "Nominal", + "population_type": "FinancialFlow", + "stat_type": "measuredValue" }, "slots": [ { @@ -238,25 +252,11 @@ }, "property": "nettingBasis" } - ], - "entities": { - "origin": [ - "country/DEU" - ], - "destination": [ - "country/NGA" - ] - }, - "identity_version": "spec1", - "requested_window": { - "kind": "range", - "end_year": 2023, - "start_year": 2020 - } + ] } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-20T13:59:17Z", + "prepared_at": "2026-10-21T08:57:50Z", "coverage": { "rows": 4, "dimensions": [ @@ -285,9 +285,9 @@ ], "window": { "kind": "range", - "origin": "query", + "start_year": 2020, "end_year": 2023, - "start_year": 2020 + "origin": "query" } }, "citation": { @@ -373,47 +373,25 @@ ] }, "trace": { - "facets": [ - { - "ref": "provenance/OECDCreditorReportingSystem", - "axis": "provenance", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - }, - { - "ref": "CurrencyUSD", - "axis": "unit", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - } - ], "applied_window": { "kind": "range", - "origin": "query", + "start_year": 2020, "end_year": 2023, - "start_year": 2020 + "origin": "query" }, "graph_revision": null, - "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", "graph_endpoint": "graph_release" }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", "revision": "2026-10-15" } ], - "capability_version": "dset_1e6cd9546fac19e9", - "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -584,12 +562,34 @@ "observation_count": 0 } ], - "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "family_member_count": 21, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDCreditorReportingSystem", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + } + ], + "normalisations": [], "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", - "served_from": "head", - "confirmed_at": "2026-10-20T15:55:51.543555+00:00" + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:57:50.475926+00:00" }, "warnings": [ { @@ -615,7 +615,7 @@ }, "bytes": 9541, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T13:59:18.050980+00:00", + "created_at": "2026-10-21T08:57:50.451120+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" }, @@ -626,14 +626,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T13:59:18.050980+00:00", + "created_at": "2026-10-21T08:57:50.451120+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -853,7 +853,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:50.451687Z" + } } } }, @@ -870,12 +874,26 @@ "entry_kind": "identity", "variable_text": "dataset", "identity": { + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "identity_version": "spec1", + "requested_window": { + "end_year": 2023, + "kind": "range", + "start_year": 2020 + }, "shape": { "kind": "statvar_schema", - "stat_type": "measuredValue", - "population_type": "FinancialFlow", "measured_property": "amount", - "measurement_qualifier": "Nominal" + "measurement_qualifier": "Nominal", + "population_type": "FinancialFlow", + "stat_type": "measuredValue" }, "slots": [ { @@ -918,21 +936,7 @@ }, "property": "nettingBasis" } - ], - "entities": { - "origin": [ - "country/DEU" - ], - "destination": [ - "country/NGA" - ] - }, - "identity_version": "spec1", - "requested_window": { - "kind": "range", - "end_year": 2023, - "start_year": 2020 - } + ] } } ] @@ -951,11 +955,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "3639b6a5b0924dad976fa2ff3a0a681e", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "63d251bca9014713ba8769cd3719b880", "warnings": [], "timing_ms": { - "total": 1, + "total": 104, "by_step": { "coverage": 0 } @@ -968,13 +972,24 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 0, + "total": 83, "by_step": { - "response_cache_part_memo": 0 + "validate": 2, + "walk": 65, + "reread_arcs": 0, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 1, + "bind": 1, + "where_places": 0, + "materialise": 4, + "answer": 9, + "options": 1 } }, "operations": [], "departures": [], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_cb5baa4161de718f18583060674dbca6", @@ -1402,7 +1417,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -1965,7 +1980,7 @@ "start_year": 2020, "end_year": 2023 }, - "capability_version": "cap_3f35867df5a65761" + "capability_version": "cap_347a470e04c97eec" }, "confidence": "high", "available_at_place": true, @@ -4571,15 +4586,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" }, "response": { "status": 200, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-operation-failed-resubmitted.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-operation-failed-resubmitted.json new file mode 100644 index 0000000..a2565da --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-operation-failed-resubmitted.json @@ -0,0 +1,1328 @@ +{ + "format_version": 1, + "name": "fetch-spec-operation-failed-resubmitted", + "description": "A poll that answers a failed operation whose error is retryable posts the same build once more and polls the operation it starts; long_builds counts one resubmission.", + "origin": { + "kind": "synthetic", + "derived_from": "mint-async-build", + "edit": "As fetch-spec-async-build, with the first poll answering failed with a retryable operation_failed, and the build posted again." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + }, + "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 202, + "headers": { + "content-type": "application/json", + "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "pending", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500 + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "failed", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500 + }, + "error": { + "type": "/codes/operation_failed", + "title": "Internal Server Error", + "status": 500, + "detail": "The build's worker stopped before it finished.", + "code": "operation_failed", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": true + } + } + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 202, + "headers": { + "content-type": "application/json", + "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "pending", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500 + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1516, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1900, + "progress": { + "rows_written": 14493, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "3" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 2377, + "progress": { + "rows_written": 41372, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "3" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 2975, + "progress": { + "rows_written": 75380, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "4" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 3755, + "progress": { + "rows_written": 108798, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "done" + }, + "manifest": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "ref": "DAC2aAidType206", + "state": "value" + }, + "property": "dac2aAidType" + }, + { + "binding": { + "state": "unbound" + }, + "property": "dacTypeOfFinance" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "facets": { + "provenance": { + "ref": "provenance/OECDDAC2A", + "state": "value" + } + }, + "entities": {}, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2024, + "start_year": 2018 + } + } + }, + "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", + "prepared_at": "2026-10-21T08:58:24Z", + "coverage": { + "rows": 108798, + "dimensions": [ + { + "label": "financingProvider", + "count": 172, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 238, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 7 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 2018 + } + }, + "citation": { + "text": "OECD DAC2A (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=dac2a&pg=0&snb=1&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_DAC2%40DF_DAC2A&df[ag]=OECD.DCD.FSD&df[vs]=1.6&dq=.DPGC.206.USD.Q&lom=LASTNPERIODS&lo=5&to[TIME_PERIOD]=false&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "DAC2A is the OECD Development Assistance Committee's table of ODA disbursements by donor and recipient country or region. It covers bilateral donors and multilateral agencies reporting their own outflows, and includes the OECD's estimate of each donor's core multilateral contributions attributed to recipients.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip", + "attribution": "OECD (2026), OECD DAC2A, OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip (accessed on 2026-10-12)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1960-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The OECD publishes DAC2A in April, June, September and December. The complete table is downloaded from the OECD each time it is republished, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets. The totals DAC2A reports for groups of providers, such as all DAC countries, and for groups of recipients, such as regions and income groups, are included as providers and recipients of their own. Where two provider codes name the same organisation and report the same figures, the figures are counted once. Where two recipient codes name the same organisation, such as IDA and IDA's Multilateral Debt Relief Initiative, their flows are added." + }, + { + "transformation": "Select figures", + "description": "Only figures in current US dollars are included, not constant US dollars. Only flows to recipients on Part I of the DAC List are included: the developing countries, and the multilateral organisations DAC2A reports as recipients, such as development banks and UN agencies. Flows to Part II recipients, the countries in transition, are excluded." + }, + { + "transformation": "Convert to whole units", + "description": "DAC2A reports amounts in millions, which are converted to whole units. ODA per person and ODA as a share of GNI are kept as reported." + }, + { + "transformation": "Select dimensions", + "description": "Each figure is reported by year, provider, recipient and type of aid, such as grants, repayments, interest received, or debt forgiven or rescheduled. DAC2A is a table of disbursements, so every figure, repayments and interest included, is recorded as a disbursement. Figures are marked as gross or net, except where DAC2A does not say which, and as grants or non-grants where the type of aid is wholly one or the other. Imputed multilateral ODA, the OECD's estimate of each provider's share of multilateral organisations' ODA, is marked as modelled. ODA as a share of GNI records the recipient's GNI as its denominator, and ODA per person records the recipient's population." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "ODA disbursements by donor and recipient country or region, including the OECD's imputed multilateral contributions, and ODA per person and as a share of recipient GNI." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDDAC2A", + "axis": "provenance", + "basis": "bound", + "default_policy": null, + "selection_reason": null, + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": null + }, + { + "ref": null, + "axis": "measurementMethod", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 2018 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDDAC2A", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 108798 + } + ], + "family_member_count": 1, + "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:58:25.535416+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 913395, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:58:25.500374+00:00", + "tier": "working", + "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + }, + { + "artifact_digest": "sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93", + "rendering": { + "statistics": "series" + }, + "bytes": 967921, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:58:25.500374+00:00", + "tier": "working", + "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" + } + ], + "series_count": 21017, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 172 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 238 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 7 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 172, + "covered": 50 + }, + "missing": [ + { + "ref": "AdaptationFund", + "label": "Adaptation Fund" + }, + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentBankGroup", + "label": "African Development Bank Group" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AndrewCarnegieFoundation", + "label": "Andrew Carnegie Foundation" + }, + { + "ref": "ArabFundForEconomicAndSocialDevelopment", + "label": "Arab Fund for Economic and Social Development" + }, + { + "ref": "Arcadia", + "label": "Arcadia" + }, + { + "ref": "ArcusFoundation", + "label": "Arcus Foundation" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianInfrastructureInvestmentBank", + "label": "Asian Infrastructure Investment Bank" + } + ], + "truncated": true + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 172, + "covered": 50 + }, + "missing": [ + { + "ref": "AdaptationFund", + "label": "Adaptation Fund" + }, + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentBankGroup", + "label": "African Development Bank Group" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AndrewCarnegieFoundation", + "label": "Andrew Carnegie Foundation" + }, + { + "ref": "ArabFundForEconomicAndSocialDevelopment", + "label": "Arab Fund for Economic and Social Development" + }, + { + "ref": "Arcadia", + "label": "Arcadia" + }, + { + "ref": "ArcusFoundation", + "label": "Arcus Foundation" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianInfrastructureInvestmentBank", + "label": "Asian Infrastructure Investment Bank" + } + ], + "truncated": true + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 238, + "covered": 143 + }, + "missing": [ + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianDevelopmentBankSpecialFunds", + "label": "Asian Development Bank Special Funds" + }, + { + "ref": "CaribbeanDevelopmentBank", + "label": "Caribbean Development Bank" + }, + { + "ref": "CentralAmericanBankForEconomicIntegration", + "label": "Central American Bank for Economic Integration" + }, + { + "ref": "DACACPCountries", + "label": "ACP countries (DAC)" + }, + { + "ref": "DACAfrica", + "label": "Africa (DAC)" + }, + { + "ref": "DACAfricaUnallocated", + "label": "Africa, unallocated by country (DAC)" + }, + { + "ref": "DACAllMultilateralRecipients", + "label": "all multilateral recipients (DAC)" + } + ], + "truncated": true + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 238, + "covered": 141 + }, + "missing": [ + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianDevelopmentBankSpecialFunds", + "label": "Asian Development Bank Special Funds" + }, + { + "ref": "CaribbeanDevelopmentBank", + "label": "Caribbean Development Bank" + }, + { + "ref": "CentralAmericanBankForEconomicIntegration", + "label": "Central American Bank for Economic Integration" + }, + { + "ref": "DACACPCountries", + "label": "ACP countries (DAC)" + }, + { + "ref": "DACAfrica", + "label": "Africa (DAC)" + }, + { + "ref": "DACAfricaUnallocated", + "label": "Africa, unallocated by country (DAC)" + }, + { + "ref": "DACAllMultilateralRecipients", + "label": "all multilateral recipients (DAC)" + } + ], + "truncated": true + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "financingProvider", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 7 + } + ] + }, + { + "index": "financingProvider", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 238 + } + ] + }, + { + "index": "financingRecipient", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 7 + } + ] + }, + { + "index": "financingRecipient", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 172 + } + ] + }, + { + "index": "time_period", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 238 + } + ] + }, + { + "index": "time_period", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 172 + } + ] + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:58:25.500506Z" + } + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "mint-async-build.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 108798, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "dac2aAidType", + "dac2aAidType_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", + "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + } + ], + "missing": [], + "long_builds": [ + { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll_waits": [ + 1.5, + 1.5, + 1.5, + 1.5, + 1.5, + 1.516, + 1.9, + 2.377, + 2.975, + 3.755 + ], + "resubmissions": 1 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited.json new file mode 100644 index 0000000..9e64240 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited.json @@ -0,0 +1,1221 @@ +{ + "format_version": 1, + "name": "fetch-spec-poll-rate-limited", + "description": "A 429 on a poll spends no retry: the client waits the Retry-After seconds, polls again and keeps the server's pacing after it.", + "origin": { + "kind": "synthetic", + "derived_from": "mint-async-build", + "edit": "As fetch-spec-async-build, with a bodiless 429 and Retry-After 3 answering the first poll." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + }, + "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 202, + "headers": { + "content-type": "application/json", + "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "pending", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500 + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 429, + "headers": { + "retry-after": "3" + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1516, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1900, + "progress": { + "rows_written": 14493, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "3" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 2377, + "progress": { + "rows_written": 41372, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "3" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 2975, + "progress": { + "rows_written": 75380, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "4" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 3755, + "progress": { + "rows_written": 108798, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "done" + }, + "manifest": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "ref": "DAC2aAidType206", + "state": "value" + }, + "property": "dac2aAidType" + }, + { + "binding": { + "state": "unbound" + }, + "property": "dacTypeOfFinance" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "facets": { + "provenance": { + "ref": "provenance/OECDDAC2A", + "state": "value" + } + }, + "entities": {}, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2024, + "start_year": 2018 + } + } + }, + "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", + "prepared_at": "2026-10-21T08:58:24Z", + "coverage": { + "rows": 108798, + "dimensions": [ + { + "label": "financingProvider", + "count": 172, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 238, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 7 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 2018 + } + }, + "citation": { + "text": "OECD DAC2A (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=dac2a&pg=0&snb=1&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_DAC2%40DF_DAC2A&df[ag]=OECD.DCD.FSD&df[vs]=1.6&dq=.DPGC.206.USD.Q&lom=LASTNPERIODS&lo=5&to[TIME_PERIOD]=false&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "DAC2A is the OECD Development Assistance Committee's table of ODA disbursements by donor and recipient country or region. It covers bilateral donors and multilateral agencies reporting their own outflows, and includes the OECD's estimate of each donor's core multilateral contributions attributed to recipients.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip", + "attribution": "OECD (2026), OECD DAC2A, OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip (accessed on 2026-10-12)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1960-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The OECD publishes DAC2A in April, June, September and December. The complete table is downloaded from the OECD each time it is republished, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets. The totals DAC2A reports for groups of providers, such as all DAC countries, and for groups of recipients, such as regions and income groups, are included as providers and recipients of their own. Where two provider codes name the same organisation and report the same figures, the figures are counted once. Where two recipient codes name the same organisation, such as IDA and IDA's Multilateral Debt Relief Initiative, their flows are added." + }, + { + "transformation": "Select figures", + "description": "Only figures in current US dollars are included, not constant US dollars. Only flows to recipients on Part I of the DAC List are included: the developing countries, and the multilateral organisations DAC2A reports as recipients, such as development banks and UN agencies. Flows to Part II recipients, the countries in transition, are excluded." + }, + { + "transformation": "Convert to whole units", + "description": "DAC2A reports amounts in millions, which are converted to whole units. ODA per person and ODA as a share of GNI are kept as reported." + }, + { + "transformation": "Select dimensions", + "description": "Each figure is reported by year, provider, recipient and type of aid, such as grants, repayments, interest received, or debt forgiven or rescheduled. DAC2A is a table of disbursements, so every figure, repayments and interest included, is recorded as a disbursement. Figures are marked as gross or net, except where DAC2A does not say which, and as grants or non-grants where the type of aid is wholly one or the other. Imputed multilateral ODA, the OECD's estimate of each provider's share of multilateral organisations' ODA, is marked as modelled. ODA as a share of GNI records the recipient's GNI as its denominator, and ODA per person records the recipient's population." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "ODA disbursements by donor and recipient country or region, including the OECD's imputed multilateral contributions, and ODA per person and as a share of recipient GNI." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDDAC2A", + "axis": "provenance", + "basis": "bound", + "default_policy": null, + "selection_reason": null, + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": null + }, + { + "ref": null, + "axis": "measurementMethod", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 2018 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDDAC2A", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 108798 + } + ], + "family_member_count": 1, + "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:58:25.535416+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 913395, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:58:25.500374+00:00", + "tier": "working", + "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + }, + { + "artifact_digest": "sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93", + "rendering": { + "statistics": "series" + }, + "bytes": 967921, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:58:25.500374+00:00", + "tier": "working", + "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" + } + ], + "series_count": 21017, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 172 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 238 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 7 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 172, + "covered": 50 + }, + "missing": [ + { + "ref": "AdaptationFund", + "label": "Adaptation Fund" + }, + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentBankGroup", + "label": "African Development Bank Group" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AndrewCarnegieFoundation", + "label": "Andrew Carnegie Foundation" + }, + { + "ref": "ArabFundForEconomicAndSocialDevelopment", + "label": "Arab Fund for Economic and Social Development" + }, + { + "ref": "Arcadia", + "label": "Arcadia" + }, + { + "ref": "ArcusFoundation", + "label": "Arcus Foundation" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianInfrastructureInvestmentBank", + "label": "Asian Infrastructure Investment Bank" + } + ], + "truncated": true + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 172, + "covered": 50 + }, + "missing": [ + { + "ref": "AdaptationFund", + "label": "Adaptation Fund" + }, + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentBankGroup", + "label": "African Development Bank Group" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AndrewCarnegieFoundation", + "label": "Andrew Carnegie Foundation" + }, + { + "ref": "ArabFundForEconomicAndSocialDevelopment", + "label": "Arab Fund for Economic and Social Development" + }, + { + "ref": "Arcadia", + "label": "Arcadia" + }, + { + "ref": "ArcusFoundation", + "label": "Arcus Foundation" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianInfrastructureInvestmentBank", + "label": "Asian Infrastructure Investment Bank" + } + ], + "truncated": true + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 238, + "covered": 143 + }, + "missing": [ + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianDevelopmentBankSpecialFunds", + "label": "Asian Development Bank Special Funds" + }, + { + "ref": "CaribbeanDevelopmentBank", + "label": "Caribbean Development Bank" + }, + { + "ref": "CentralAmericanBankForEconomicIntegration", + "label": "Central American Bank for Economic Integration" + }, + { + "ref": "DACACPCountries", + "label": "ACP countries (DAC)" + }, + { + "ref": "DACAfrica", + "label": "Africa (DAC)" + }, + { + "ref": "DACAfricaUnallocated", + "label": "Africa, unallocated by country (DAC)" + }, + { + "ref": "DACAllMultilateralRecipients", + "label": "all multilateral recipients (DAC)" + } + ], + "truncated": true + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 238, + "covered": 141 + }, + "missing": [ + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianDevelopmentBankSpecialFunds", + "label": "Asian Development Bank Special Funds" + }, + { + "ref": "CaribbeanDevelopmentBank", + "label": "Caribbean Development Bank" + }, + { + "ref": "CentralAmericanBankForEconomicIntegration", + "label": "Central American Bank for Economic Integration" + }, + { + "ref": "DACACPCountries", + "label": "ACP countries (DAC)" + }, + { + "ref": "DACAfrica", + "label": "Africa (DAC)" + }, + { + "ref": "DACAfricaUnallocated", + "label": "Africa, unallocated by country (DAC)" + }, + { + "ref": "DACAllMultilateralRecipients", + "label": "all multilateral recipients (DAC)" + } + ], + "truncated": true + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "financingProvider", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 7 + } + ] + }, + { + "index": "financingProvider", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 238 + } + ] + }, + { + "index": "financingRecipient", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 7 + } + ] + }, + { + "index": "financingRecipient", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 172 + } + ] + }, + { + "index": "time_period", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 238 + } + ] + }, + { + "index": "time_period", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 172 + } + ] + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:58:25.500506Z" + } + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "mint-async-build.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 108798, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "dac2aAidType", + "dac2aAidType_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", + "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + } + ], + "missing": [], + "long_builds": [ + { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll_waits": [ + 1.5, + 3.0, + 1.5, + 1.5, + 1.5, + 1.516, + 1.9, + 2.377, + 2.975, + 3.755 + ], + "resubmissions": 0 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json index 48f0d72..3957888 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json @@ -4,9 +4,9 @@ "description": "Fetching a spec with a facet the server does not know sends it in input.scope.facets; the build refuses 400 request_invalid, which raises InvalidRequestError.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "recorded_at": "2026-10-20T16:04:05Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:58:01Z" }, "call": [ { @@ -190,8 +190,8 @@ "detail": "Value error, unknown facet axis/axes: colour", "code": "request_invalid", "pointer": "/input/scope", - "trace_id": "da5687094d8240308063bbf016c61f80", - "capability_version": "dset_1e6cd9546fac19e9", + "trace_id": "a36e8b07217c4469b8cba617c14c6170", + "capability_version": "dset_88fecfec3c5b89d1", "retryable": false } } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json index dfc532b..6f503da 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json @@ -189,12 +189,26 @@ "schema_version": 1, "spec_id": "spec_cb5baa4161de718f18583060674dbca6", "identity": { + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "identity_version": "spec1", + "requested_window": { + "end_year": 2023, + "kind": "range", + "start_year": 2020 + }, "shape": { "kind": "statvar_schema", - "stat_type": "measuredValue", - "population_type": "FinancialFlow", "measured_property": "amount", - "measurement_qualifier": "Nominal" + "measurement_qualifier": "Nominal", + "population_type": "FinancialFlow", + "stat_type": "measuredValue" }, "slots": [ { @@ -237,25 +251,11 @@ }, "property": "nettingBasis" } - ], - "entities": { - "origin": [ - "country/DEU" - ], - "destination": [ - "country/NGA" - ] - }, - "identity_version": "spec1", - "requested_window": { - "kind": "range", - "end_year": 2023, - "start_year": 2020 - } + ] } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-20T13:59:17Z", + "prepared_at": "2026-10-21T08:57:50Z", "coverage": { "rows": 4, "dimensions": [ @@ -284,9 +284,9 @@ ], "window": { "kind": "range", - "origin": "query", + "start_year": 2020, "end_year": 2023, - "start_year": 2020 + "origin": "query" } }, "citation": { @@ -372,47 +372,25 @@ ] }, "trace": { - "facets": [ - { - "ref": "provenance/OECDCreditorReportingSystem", - "axis": "provenance", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - }, - { - "ref": "CurrencyUSD", - "axis": "unit", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - } - ], "applied_window": { "kind": "range", - "origin": "query", + "start_year": 2020, "end_year": 2023, - "start_year": 2020 + "origin": "query" }, "graph_revision": null, - "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", "graph_endpoint": "graph_release" }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", "revision": "2026-10-15" } ], - "capability_version": "dset_1e6cd9546fac19e9", - "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -583,12 +561,34 @@ "observation_count": 0 } ], - "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "family_member_count": 21, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDCreditorReportingSystem", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + } + ], + "normalisations": [], "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", - "served_from": "head", - "confirmed_at": "2026-10-20T15:55:51.543555+00:00" + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:57:50.475926+00:00" }, "warnings": [ { @@ -614,7 +614,7 @@ }, "bytes": 9541, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T13:59:18.050980+00:00", + "created_at": "2026-10-21T08:57:50.451120+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" }, @@ -625,14 +625,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T13:59:18.050980+00:00", + "created_at": "2026-10-21T08:57:50.451120+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -852,7 +852,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:50.451687Z" + } } } }, @@ -869,12 +873,26 @@ "entry_kind": "identity", "variable_text": "dataset", "identity": { + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "identity_version": "spec1", + "requested_window": { + "end_year": 2023, + "kind": "range", + "start_year": 2020 + }, "shape": { "kind": "statvar_schema", - "stat_type": "measuredValue", - "population_type": "FinancialFlow", "measured_property": "amount", - "measurement_qualifier": "Nominal" + "measurement_qualifier": "Nominal", + "population_type": "FinancialFlow", + "stat_type": "measuredValue" }, "slots": [ { @@ -917,21 +935,7 @@ }, "property": "nettingBasis" } - ], - "entities": { - "origin": [ - "country/DEU" - ], - "destination": [ - "country/NGA" - ] - }, - "identity_version": "spec1", - "requested_window": { - "kind": "range", - "end_year": 2023, - "start_year": 2020 - } + ] } } ] @@ -950,11 +954,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "3639b6a5b0924dad976fa2ff3a0a681e", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "63d251bca9014713ba8769cd3719b880", "warnings": [], "timing_ms": { - "total": 1, + "total": 104, "by_step": { "coverage": 0 } @@ -967,13 +971,24 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 0, + "total": 83, "by_step": { - "response_cache_part_memo": 0 + "validate": 2, + "walk": 65, + "reread_arcs": 0, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 1, + "bind": 1, + "where_places": 0, + "materialise": 4, + "answer": 9, + "options": 1 } }, "operations": [], "departures": [], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", @@ -1401,7 +1416,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -1964,7 +1979,7 @@ "start_year": 2020, "end_year": 2023 }, - "capability_version": "cap_3f35867df5a65761" + "capability_version": "cap_347a470e04c97eec" }, "confidence": "high", "available_at_place": true, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json index 0b09583..d703c98 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json @@ -249,7 +249,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-20T13:59:17Z", + "prepared_at": "2026-10-21T08:57:50Z", "coverage": { "rows": 4, "dimensions": [ @@ -395,7 +395,7 @@ "graph_revision": null, "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T13:18:18Z", + "exported_at": "2026-10-20T19:50:14Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "graph_endpoint": "graph_release" }, @@ -405,8 +405,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_1e6cd9546fac19e9", - "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -580,9 +580,9 @@ "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "head", - "confirmed_at": "2026-10-20T15:55:51.543555+00:00" + "confirmed_at": "2026-10-21T08:57:50.475926+00:00" }, "warnings": [ { @@ -608,7 +608,7 @@ }, "bytes": 9541, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T13:59:18.050980+00:00", + "created_at": "2026-10-21T08:57:50.451120+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" }, @@ -619,14 +619,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T13:59:18.050980+00:00", + "created_at": "2026-10-21T08:57:50.451120+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -846,7 +846,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:50.451687Z" + } } } } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-strict-info-notice.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-strict-info-notice.json index 0bb2282..4d9ba0a 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-strict-info-notice.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-strict-info-notice.json @@ -41,22 +41,22 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements from Germany to Nigeria for basic health care", "normalized_query": "ODA disbursements from Germany to Nigeria for basic health care", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "c37510c195ea4f928cd9dc72e7adf6b9", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", "warnings": [], "timing_ms": { - "total": 4, + "total": 4556, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 889 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, + "input_tokens": 6116, + "output_tokens": 408, "cached_tokens": 0 }, "timed_out": false @@ -64,7 +64,7 @@ "kind": "resolution", "parts": [ { - "variable_text": "ODA disbursements for basic health care", + "variable_text": "basic health care ODA disbursements", "warnings": [ { "code": "retrieval_score_weak", @@ -73,24 +73,24 @@ } ], "timing_ms": { - "total": 4815, + "total": 3505, "by_step": { - "recall": 549, + "recall": 628, "shape_arcs": 1, - "shape_probe_coverage": 80, - "shape_probe": 238, - "shape_groups": 142, - "shape_labels": 0, + "shape_probe_coverage": 5, + "shape_probe": 477, + "shape_groups": 22, + "shape_labels": 1, "shape_admission": 1, - "shape": 1269, - "bind": 2396, - "materialise": 226, - "answer": 227, - "options": 148 + "shape": 1283, + "bind": 1188, + "materialise": 11, + "answer": 381, + "options": 14 } }, "restatement": { - "variable_text": "ODA disbursements for basic health care", + "variable_text": "basic health care ODA disbursements", "entities": [ { "text": "Germany", @@ -106,6 +106,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", @@ -198,14 +199,6 @@ }, "measurement_denominator_unresolved": false, "slot_keys": [ - { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, { "axis": "how", "property": { @@ -246,6 +239,14 @@ }, "label": "netting basis" }, + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, { "axis": "where", "label": "place" @@ -270,20 +271,6 @@ ] }, "slots": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding": { - "kind": "unbound" - }, - "summable": true - }, { "key": { "axis": "how", @@ -382,6 +369,20 @@ }, "summable": false }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, { "key": { "axis": "where", @@ -518,7 +519,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -543,6 +544,102 @@ } }, "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 88, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 30, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, { "key": { "axis": "how", @@ -651,102 +748,6 @@ ], "truncated": false, "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsPurpose", - "label": "CRS purpose" - }, - "label": "sector" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSPurposeCode122", - "label": "basic health" - }, - "value_kind": "enum_value" - }, - "relation": "parent", - "parent": "CRSPurposeCode120", - "member_count": 4, - "served_rows": 88, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFinance", - "label": "CRS type of finance" - }, - "label": "instrument" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance100", - "label": "grant" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 30, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance110", - "label": "standard grant" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSTypeOfFinance100", - "member_count": 12672, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFlow", - "label": "CRS type of flow" - }, - "label": "flow" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 14098, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" } ], "entity_options": [], @@ -1014,19 +1015,6 @@ } ], "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "how", @@ -1112,6 +1100,19 @@ ], "provenance": "measure_elected" }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "where", @@ -1147,31 +1148,31 @@ ], "query_qualifiers": [ { - "text": "ODA", + "text": "basic health care", "named": [ { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode12220", + "label": "basic health care" } ], - "slot": "crsTypeOfFlow", + "slot": "crsPurpose", "disposition": "bound", "selected": [] }, { - "text": "basic health care", + "text": "ODA", "named": [ { - "ref": "CRSPurposeCode12220", - "label": "basic health care" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" } ], - "slot": "crsPurpose", + "slot": "crsTypeOfFlow", "disposition": "bound", "selected": [] } ], - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3840,7 +3841,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-11T20:09:36Z", + "prepared_at": "2026-10-21T08:57:19Z", "coverage": { "rows": 30, "dimensions": [ @@ -3869,13 +3870,13 @@ ], "window": { "kind": "all", - "origin": "default", + "start_year": 1995, "end_year": 2024, - "start_year": 1995 + "origin": "default" } }, "citation": { - "text": "OECD Creditor Reporting System (CRS)", + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", "sources": [ { "ref": "provenance/OECDCreditorReportingSystem", @@ -3896,9 +3897,9 @@ "publisher": "Organisation for Economic Co-operation and Development (OECD)", "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", - "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-08)", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", "update_cadence": "Quarterly", - "last_update": "2026-10-08", + "last_update": "2026-10-15", "years_covered": "1973-2024", "granularity": "Annual, by provider and recipient", "currencies": [ @@ -3909,6 +3910,10 @@ "transformation": "Download the source data", "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, { "transformation": "Exclude donor core contributions to multilaterals", "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." @@ -3928,22 +3933,22 @@ ], "version_history": [ { - "date": "2026-09-22", - "title": "Exclude donor core contributions", + "date": "2026-10-15", + "title": "Partial preliminary year excluded", "changes": [ { "kind": "changed", - "note": "Donor core contributions to multilateral organisations (`bi_multi = 2`) are excluded from bilateral flows, since they would otherwise double count." + "note": "The partial preliminary year published ahead of the next full release is excluded." } ] }, { - "date": "2026-08-20", + "date": "2026-10-14", "title": "First release", "changes": [ { "kind": "added", - "note": "Dataset added to the graph." + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." } ] } @@ -3953,47 +3958,25 @@ ] }, "trace": { - "facets": [ - { - "ref": "provenance/OECDCreditorReportingSystem", - "axis": "provenance", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - }, - { - "ref": "CurrencyUSD", - "axis": "unit", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868", - "default_policy_version": "1" - } - ], "applied_window": { "kind": "all", - "origin": "default", + "start_year": 1995, "end_year": 2024, - "start_year": 1995 + "origin": "default" }, - "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", - "normalisations": [], + "graph_revision": null, "code_index_stamp": { - "exported_at": "2026-10-10T10:52:17Z", - "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", - "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", + "graph_endpoint": "graph_release" }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", - "revision": "2026-10-08" + "revision": "2026-10-15" } ], - "capability_version": "dset_ac879dbf49857907", - "materialiser_build": "1f6ed6307bea979d38cc35c4e38e0da896c431ad", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -4164,20 +4147,36 @@ "observation_count": 0 } ], - "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "family_member_count": 21, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDCreditorReportingSystem", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + } + ], + "normalisations": [], "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261011T194155Z-80081f08", - "served_from": "head", - "confirmed_at": "2026-10-20T15:55:32.214385+00:00" + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:57:19.628756+00:00" }, - "warnings": [ - { - "code": "processing_level_undeclared", - "severity": "info", - "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." - } - ], + "warnings": [], "diagnostics": [ { "code": "processing_level_undeclared", @@ -4195,7 +4194,7 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-19T10:58:01.080848+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, @@ -4206,14 +4205,14 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-08T08:43:31.704442+00:00", + "created_at": "2026-10-21T08:57:19.589654+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } ], "series_count": 5, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -4448,7 +4447,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:19.589587Z" + } } } }, @@ -4460,15 +4463,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" }, "response": { "status": 200, @@ -4527,7 +4529,7 @@ "members": [ { "parts": [ - "ODA disbursements for basic health care" + "basic health care ODA disbursements" ], "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.json b/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.json new file mode 100644 index 0000000..48c39bd --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.json @@ -0,0 +1,1218 @@ +{ + "format_version": 1, + "name": "mint-async-build", + "description": "Minting a spec whose estimate is just above the 100,000-row sync budget answers 202 with an operation the client reports as pending. Waiting polls the operation path built from operation_id, sleeping retry_after_ms when the response carries it and backing off from 1 to 8 seconds otherwise, until done; the done manifest's file is then downloaded.", + "origin": { + "kind": "recorded", + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:58:01Z" + }, + "call": [ + { + "op": "mint", + "spec": { + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + }, + "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + } + }, + { + "op": "result" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 202, + "headers": { + "content-type": "application/json", + "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "pending", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500 + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1516, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1900, + "progress": { + "rows_written": 14493, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "3" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 2377, + "progress": { + "rows_written": 41372, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "3" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 2975, + "progress": { + "rows_written": 75380, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "4" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 3755, + "progress": { + "rows_written": 108798, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "done" + }, + "manifest": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "ref": "DAC2aAidType206", + "state": "value" + }, + "property": "dac2aAidType" + }, + { + "binding": { + "state": "unbound" + }, + "property": "dacTypeOfFinance" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "facets": { + "provenance": { + "ref": "provenance/OECDDAC2A", + "state": "value" + } + }, + "entities": {}, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2024, + "start_year": 2018 + } + } + }, + "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", + "prepared_at": "2026-10-21T08:58:24Z", + "coverage": { + "rows": 108798, + "dimensions": [ + { + "label": "financingProvider", + "count": 172, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 238, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 7 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 2018 + } + }, + "citation": { + "text": "OECD DAC2A (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=dac2a&pg=0&snb=1&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_DAC2%40DF_DAC2A&df[ag]=OECD.DCD.FSD&df[vs]=1.6&dq=.DPGC.206.USD.Q&lom=LASTNPERIODS&lo=5&to[TIME_PERIOD]=false&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "DAC2A is the OECD Development Assistance Committee's table of ODA disbursements by donor and recipient country or region. It covers bilateral donors and multilateral agencies reporting their own outflows, and includes the OECD's estimate of each donor's core multilateral contributions attributed to recipients.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip", + "attribution": "OECD (2026), OECD DAC2A, OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip (accessed on 2026-10-12)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1960-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The OECD publishes DAC2A in April, June, September and December. The complete table is downloaded from the OECD each time it is republished, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets. The totals DAC2A reports for groups of providers, such as all DAC countries, and for groups of recipients, such as regions and income groups, are included as providers and recipients of their own. Where two provider codes name the same organisation and report the same figures, the figures are counted once. Where two recipient codes name the same organisation, such as IDA and IDA's Multilateral Debt Relief Initiative, their flows are added." + }, + { + "transformation": "Select figures", + "description": "Only figures in current US dollars are included, not constant US dollars. Only flows to recipients on Part I of the DAC List are included: the developing countries, and the multilateral organisations DAC2A reports as recipients, such as development banks and UN agencies. Flows to Part II recipients, the countries in transition, are excluded." + }, + { + "transformation": "Convert to whole units", + "description": "DAC2A reports amounts in millions, which are converted to whole units. ODA per person and ODA as a share of GNI are kept as reported." + }, + { + "transformation": "Select dimensions", + "description": "Each figure is reported by year, provider, recipient and type of aid, such as grants, repayments, interest received, or debt forgiven or rescheduled. DAC2A is a table of disbursements, so every figure, repayments and interest included, is recorded as a disbursement. Figures are marked as gross or net, except where DAC2A does not say which, and as grants or non-grants where the type of aid is wholly one or the other. Imputed multilateral ODA, the OECD's estimate of each provider's share of multilateral organisations' ODA, is marked as modelled. ODA as a share of GNI records the recipient's GNI as its denominator, and ODA per person records the recipient's population." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "ODA disbursements by donor and recipient country or region, including the OECD's imputed multilateral contributions, and ODA per person and as a share of recipient GNI." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDDAC2A", + "axis": "provenance", + "basis": "bound", + "default_policy": null, + "selection_reason": null, + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": null + }, + { + "ref": null, + "axis": "measurementMethod", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 2018 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDDAC2A", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 108798 + } + ], + "family_member_count": 1, + "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:58:25.535416+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 913395, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:58:25.500374+00:00", + "tier": "working", + "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + }, + { + "artifact_digest": "sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93", + "rendering": { + "statistics": "series" + }, + "bytes": 967921, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:58:25.500374+00:00", + "tier": "working", + "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" + } + ], + "series_count": 21017, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 172 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 238 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 7 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 172, + "covered": 50 + }, + "missing": [ + { + "ref": "AdaptationFund", + "label": "Adaptation Fund" + }, + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentBankGroup", + "label": "African Development Bank Group" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AndrewCarnegieFoundation", + "label": "Andrew Carnegie Foundation" + }, + { + "ref": "ArabFundForEconomicAndSocialDevelopment", + "label": "Arab Fund for Economic and Social Development" + }, + { + "ref": "Arcadia", + "label": "Arcadia" + }, + { + "ref": "ArcusFoundation", + "label": "Arcus Foundation" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianInfrastructureInvestmentBank", + "label": "Asian Infrastructure Investment Bank" + } + ], + "truncated": true + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 172, + "covered": 50 + }, + "missing": [ + { + "ref": "AdaptationFund", + "label": "Adaptation Fund" + }, + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentBankGroup", + "label": "African Development Bank Group" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AndrewCarnegieFoundation", + "label": "Andrew Carnegie Foundation" + }, + { + "ref": "ArabFundForEconomicAndSocialDevelopment", + "label": "Arab Fund for Economic and Social Development" + }, + { + "ref": "Arcadia", + "label": "Arcadia" + }, + { + "ref": "ArcusFoundation", + "label": "Arcus Foundation" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianInfrastructureInvestmentBank", + "label": "Asian Infrastructure Investment Bank" + } + ], + "truncated": true + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 238, + "covered": 143 + }, + "missing": [ + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianDevelopmentBankSpecialFunds", + "label": "Asian Development Bank Special Funds" + }, + { + "ref": "CaribbeanDevelopmentBank", + "label": "Caribbean Development Bank" + }, + { + "ref": "CentralAmericanBankForEconomicIntegration", + "label": "Central American Bank for Economic Integration" + }, + { + "ref": "DACACPCountries", + "label": "ACP countries (DAC)" + }, + { + "ref": "DACAfrica", + "label": "Africa (DAC)" + }, + { + "ref": "DACAfricaUnallocated", + "label": "Africa, unallocated by country (DAC)" + }, + { + "ref": "DACAllMultilateralRecipients", + "label": "all multilateral recipients (DAC)" + } + ], + "truncated": true + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 238, + "covered": 141 + }, + "missing": [ + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianDevelopmentBankSpecialFunds", + "label": "Asian Development Bank Special Funds" + }, + { + "ref": "CaribbeanDevelopmentBank", + "label": "Caribbean Development Bank" + }, + { + "ref": "CentralAmericanBankForEconomicIntegration", + "label": "Central American Bank for Economic Integration" + }, + { + "ref": "DACACPCountries", + "label": "ACP countries (DAC)" + }, + { + "ref": "DACAfrica", + "label": "Africa (DAC)" + }, + { + "ref": "DACAfricaUnallocated", + "label": "Africa, unallocated by country (DAC)" + }, + { + "ref": "DACAllMultilateralRecipients", + "label": "all multilateral recipients (DAC)" + } + ], + "truncated": true + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "financingProvider", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 7 + } + ] + }, + { + "index": "financingProvider", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 238 + } + ] + }, + { + "index": "financingRecipient", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 7 + } + ] + }, + { + "index": "financingRecipient", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 172 + } + ] + }, + { + "index": "time_period", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 238 + } + ] + }, + { + "index": "time_period", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 172 + } + ] + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:58:25.500506Z" + } + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "mint-async-build.parquet" + } + } + ], + "expect": [ + { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "pending" + } + }, + { + "dataset": { + "rows": 108798, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "dac2aAidType", + "dac2aAidType_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", + "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + } + ], + "missing": [], + "long_builds": [ + { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll_waits": [ + 1.5, + 1.5, + 1.5, + 1.5, + 1.516, + 1.9, + 2.377, + 2.975, + 3.755 + ], + "resubmissions": 0 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.parquet b/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.parquet new file mode 100644 index 0000000000000000000000000000000000000000..05908d413e0f7e85e49eb687269e6cfecbd6895b GIT binary patch literal 913395 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%0AU5VJ0>I-O6F-u5ImT7 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 S^sgIS+IigLpmF)dP_`~YtYZK;oZ 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

w(QbBvDh;;L?Z|`ng+aXiwH^1yDW`9M98pC~$Ws zAmzWeDGRlLckQ!rG~{Oos0UmZWtbN6vfDREa(M3WrWgq@cyjPQ2ee5 zr3Fb!?;>ik`iKK@9fxzV6%%_^OOFMM?Jr~_zUN1(Ql;YBE8R(C*q<)wz}i%$wH^fE z-WCF=Uo35BQ<36JAt8XYq5ffl9-j1(X?U3Be#oXnFXG?vV*Z0Rtk0fP12g2pV;Gfj z^NM1l#7aYzt_sr40|Z57@>VLU%;2S64**9DYhEdJ)#=f|NE-@!MJcJBG+SQsTxmU=0-v`zmEcqq0qXt(qEM$-(>8VgJK`eA2CaKNV~mf%om| zD8b^nS7kFys&RY~cq!6pFy#_d|zFU8VG2Qn%C$Vo@s z%8kw@IQm``fn;p?UJquuz@NkM-Wza$A)5c1sC84P-bv}G2;)$y&eP027O-S*%2f>O zd~=l1r{c3D14i{f*9ti*QvN6s7vR0!n#fu6iiVGOhJc(_f(4XmKdc zBjK~o1bM4@Arnetm0ph5h%;pX_*(yn4lDgNwixaluHBNTsVgh>d<6iw9tncA2hUw@ z(LiF64il96ZdAKp35coPymz4aaBDj*0|S5cydH!%@zIGLSgx?@0qS}B(v%?|>0Mzs z60&O*#kt|S*Gnc+?0zTY1<$SLb0zVlZ!skcsY12Nu>4nU=<+B`Yf|CokRkr^3%Y;N z(edLURx{5e%myT|6?+c<;PV_EXTVDkZ>1Q z05?}p_?bl%-+deFnW$?*Mh^M8))nA&zLuqJ(256E0jsNIxs(NbORBC^m6hs@sQM%Z zmHMMnvq5PXK!(dCNd|H~v6<=6h{-YoC0u?9kcGl;nUX1Y=1N9(p4O)^wI#xB)K+Vj z1WF%&Gf9gzJ^rdiFZ9vdH344S{b>`-6k^`H{*b}BocXgcXzkiJOz2qoburWf_l}Uv z3{mNRdOTSlY_Ykh;QCORo#-(;3soB*vQ+CQ^`<}-s1|G|OCfvvd!`JMR+q-<;EVk8 z7VZkR?Sr3no2nyLhqIQCe)$fA$o-C`4=43iih6 z&Ropqp@di27%sVBP?m~x=ex19K+!^rbyH_?*NeoB#G{+?2GUX`GK2 zvl0g8!TS3Ci_+bK&N^6Y6p!PaEGT_dMVV5AS|sH%DSK}22wOZ2N^Zc)OGVF{YSN*K zfxtv#&zuLC7ww(Onx?$3{WHr&Db~E-qYX;UkCn;E=m@I^a(|z^ z6${Q7x(;njN!4^!Rx;_2R5+Kej;H`QP;b{0CG!Rg|gd z&;O3#sfQ2-L=+{vCfLI%!m=D6tOrioJkqF%%3vGHUBWVe3YOTgzKG-qTQr>=HUak- zN(Wg^T$kY);7ih2vodEHnS&QWAl}}Cu<8EKX8_7E^ELw_zNw#Znm^bXZE{P~lrb69 zFy%nLU#c3vlcS`5CvmspK@k>_@B2q&N}hkY3<`zekIv9f>?M`)`=rh!rTH`k-;WUz zN>Qhn`3RTG4Jx@-6lyRNgm$RSZXia&1eQMMTsBwhBXiZo+8}K@HPpmWp-~%{D0_L} zW38T^zguMTQN4kzuP{n&)H7q{#O z=0wzeB#TAc?DODSil|SF_VnAnWFZQ-WJ!=waNHLYNkdmqE-I&Dc}EKQPtB2qXk&Of zv>M%{z9wwnniUQ`Wt-kYiQwmL!E*}yV6`MIw_oc-hHru#nF1V#qg#*a7lu7A;B%nl z>7TV6?dowb%Srt@d_oTvO1V&zrFy&(I^#jp{_Ti0kA5IAf!G^|3kidy86%WFh+PjF z3Tg!4ygkpPUl9%za9A&dJQqs94Y?yXz{{9$xSYd7&niTN2R?px-zL(ntdiiO2c8^t z=%tRq%GlQQsviO>OOX4>Dw|WvPg9Ck65`5gVS5n=YN0PTIgw?h?3<-g;Lnw!R5XR4 zQi4fg9zy9)vakOk31MwNl*uEcE0?1{;MHX;?2i+9!7zfnZND-@D0jUj3@1|VfYR@8*}Fd?OEuTP6^v- zmqs7PbbMbYFkP~vLJRr+`ej=P2IhB5py=oqx+X}#gqQUK(7c=3hA&ytG|vr7yt$?$ zhsOTV6q2oY%InSpd+2vj4y&-(;qxL;)abJ-uw298%B(f*u|;TqhH$LL1F*06l43C0 z_x$xH1vPljX+v~8nuYE0TkhMuBs2<_MN8XlQ*y1T<8%jhT4yRJ)6?_{I66HvaGT7kq8m3cxO>oPcSl zR=jdTps2ZXJo53QK1e72jsJ-A4o|&^Z)+bJa}8iTFzVVN{9(bfR#@D~w968mf(ur? zw@;$t)vt%`!5!JtEAPe~mlsWi)ikHt#{>BDf*Pd{-Y-#5 zlZ5|anyXi^fZI@~OAs^F>dJXN>k zn~0yRefpue5Fe-=mdNfOv8g96-WEIi;)$Cs_QnVC+hGeX&OqFJJVRZzkSrSBscFoL z$zAQO$9?HX8{oCo-?i|1uwF~N?x=0VU;In^A_%7w7rCPmVB!69oa{QTh9+Bv_%Qc@ ztuLU4l-O_ShN~L*E*n(7EI}yTUr|`ymltDB!<{s|=N|Z;$yLFLX;&KSTBG7Mz(xj(QR(X(u_24w1xU)e36Hx4ZIzxs8 z@IsUE2XC!6S_5xAGo3~Ea5BdneCG2%u?6EQ@ z@2gvMq6C3}eIMb;oWE?oESYZIR$?ujtY;fMGC2nNjP&DMO*R~$>Z}4RgJM}4jzay5 zMU=e%Jn4)ko4^0IP8L25>#`slLocheh}EiTUw7XLEa;F*@Zz_+mQPnCP+t5i@r=x` zGmIGU$-Dc^(YL5P*n&dbx}`&=L`NMLSF<^J&bvAX(sFQ-giXdhj%5vT8?IwY{@twc zhtRwVG$nhgECbCh&f7A0&*>cG8`2HkM4N>#`=!)DtTc7OQyc?DpO(X)xBggSOQr{# zZs2{e^%oFXg&|cvF!x0Go1SEow)BAPP&IXgErV*!u7T%v=y6Jmq}Zc*Hb4F4TrP`_ zI$qEI50K8O%WM&hqo@vf)gR-db?oMo`QUz*W#y-1p#jrn=1hsN5$VQbtsakw^?|X= zV0W$d+!UZmMJH=444OlpgAr5laAtDy7H83~u~+Nh)tC1b2XnAo7}mN~i{&R*UIG^f zSyYW|F!oP5@)wqtFl`uQ1w;GWrVwQpUI>VYZQkSklp?Po5wsf}36nNArNO~;j;bUV zgJY4~a%T>JF-`e5X7aSh3N64|w^A>Ol^3gw>xu~*RAM)bBHr8Oa3Uvvbbss}$8YX~ z{U6lC;e>QN&SvE^aw}~Bn04;CGB>zo#6=vE$xDl|O?t9GfqM;snwaW{57-?`xJl1P ze;=?Cw7C1)Ud%Dr$?bq*oz_}Q^lGObZ1-&2LwMifMRP2CYK?(1Kkaq?i91WnCusb< zc>dmeEp+=oraIjGS;xs!5-W{-?t-j%m2a5E(QZ`B)KR6Rs-^_`G~}a6MVF-IGGV*CCs@ILlV~FL&oBhSn%Wvpz|^2@5eT?;41x(aw#n6D&>00 ztZ-aI4_dKMF3W^7&n4=poKrV)2;T$^wsA$NZIbxEwkx1nMEvXW$ez*~KJi8Z+RvavI($g%Ok;q(YxuMYh9 zq6)5Q84;CPZJp{BPc>+at9bay(T2G85^VlxT<@P8c)l5~hGRQ~*0_Fr-u@-48P_a( z$9nczzi{ub51<48^T=**aTPxWFMh(+)%)3vkGNWdEo<4;HFL%NAgdbu%Hk+SE>pK^`CtW$R`h9P&) z6n~c|D(F?91K2`4-;8Ia=(q}dM`=>{oR!U50G*yq-(#|pwu0Z0L2~C?_;bXLl}n`? zsOp$~(DNqM_DSM-PBL*XKpc`34wTe@Flv{Ukly+8@MQtd^YlM{Olef`D+W%}NYuIu zS;f@&*7{A>R)c?jajcic^6@nf9g_s9(y07&H%-lDCnQ(*$4!7;y#KBoIJNlsVRa~| zhMs*-f>UyP96fN0KQd{nHpuUq>b`FzO0DHKf?=-gvpfelHY%ktBd4z?mVus^H2Nlh zOQf{O5UgR;Q+B|nBBA=Rd@p~?RCSZYDP3Lbc?Ma}H_KP>0YgI;85gLzYZ-=ch8&B4 z^alIed?y+1u5*C=;ue79Cd`_d<)XGVmm#@G;XT}O(+!D}$_0KP?+NjyR~E3rm-MvC zJ*4nvWtF@I)}|gi&yHv5uBHKeuED=#7Rp%PC_S2rtmK)Uev zpvlSa-{kA5lx!+^PTH7{`1S3<@z|7jX%MWnP@`H}1tk|MWAjmw#$8y)i&2TgwQ6$x zr$~p{VnqG8kit4-`RylhX8JU`6OIS<*eXu~5}!`p&GZyVq~1Q_NmerLDS?QFU?*?M zn%5rU+Xqv3{$$lDRTcN$tBq^9<~4h=YD>F16raq3G}pCh_M8Q07S@)DW2jwnv;PMB z?0wgJUjhE_j5W;r5SPt=-#hf1#7?tI?FDuj2J|(4#*d06&*3arxW}y<9?~G`ro}N# z_(|!N={jE4$$1D|vEFB;mZRL*2NH$b|CfsYihudWD%Ue=&<}e3^e3*dG;s}wAtQ7h z4l+id$dERvkcf&~GcU7Bs$x!o_q@bHlBzI^^Gzef3mO$2?2^pHV&Q5%Z8jY*5d~|C zw`kl;7E`_t7V&wAFKK)4 zA>uN<2WoD3n`q`2SreXvZQREeP+0MHWmyjQ9{s^{zbGg&D| z|2t(b@Us((7S{%5s-idE1Yx)(bt|Xl@F~XdefTo@f5nd_iVEGL%fCt_CcutyOB2n{ zKV)r@$nitUuRD!fI922i*6O9_jmI+BFGsw{G{a*Mbx==gTiY()!+dj-tv1iqm|rZ0l!IV#EQO`zZ~O$C1L$| z7RrjIJ6dOg4Yb1C@~*FCBjR#+!_R+KfERlIdDMkjQI1?`YP9fvPqT~K6pAr==%yJ(~7(P>4xkNll`W#ZX$27gL)D#SM1 zM_rQSP?ax5B_hH{VpB3xAjX}Jab(lSasNPa4y}Q85w&`>k(DJmylYJSVr-|s^V2hl zBJZtvqY-9d-O(`jrO`t5nv}u;YRGM8%mgCQ-72hteulLOp3KS0Rb#mk+==*ft%v$K zwrE3C<@Bm7FCWo;(@tYD&1p3la+LSe`w@^e+}r#9@g+4t2g^$spgC!1bWf3uTbReD_^lD4(hQ%frDn~VI!FhD;l6g0&f_5z79U>h21k*DLC^2R?Jhc zXw>9EaWI!asE1UZiPc;~(K}upeXxbrK-~Q68c@;P(ciQ_y7VoQiBV(TF8fcz(YVh0 zjCO_Bv&DK7gt6|bL9Rpe#MqbD@^dI_Kt;I%&eizIM?sk9PhMcdixu^kS&=#J@2qPu zO!0&e7$zJcN&R|B6BA zitE1Z2)ILhc)iK;_+koQ;mwg@@|0o}QKUF7yk%EmUm_^~p1wV%WM5;N3-q;bc)wp0 zQi%PxWxki^Am%Q)DNYWnp~D$)U(T&wm!&6diCHECtvfw~)rwJ8yPmG2f>)KmHj2y+ z;&sH%ACeT_GPXo@Jl3Dk^%o0ovxc8K4f!T^>xvtglJ%dyn=`$<{Y9@90J3vrm1#eW z3A9_Z;veSjzuw6q@VlB8S|$PGxG-G&rEybB;oI*LtFwl$z)aL@=DwDg`Q&-IZ*U1s z8$cS4Pp;Vim{HFg2CBOPU$f_&f?46) zPtgKcg)`8c6`s{qe#7$W6J&Gq;X(W}RqzQ^I=Z8SL&w94#%#TM^MqDX06w~ZPM5-R z*t|a8(_yi$+9}!a>{#WMK7n}+A3YWWt2cx?VoyTWO z#f45Jm>t0LYG&5uOYvb6thSa%lUcLm^|r3q3Hv#R%*@kEe}=?Br_Q@&dJ38&Ogb28)%ryj)vT{ps6eJDd^)Rdv@gA-8# zEts;<$KNZNlnxXrwlj4XC@#suXQ}B}QX828Jw9uuf~|Ei@4*;Spgq{;l2ela;reNv z!8V(9yptbKPk+ucxoB{ggC>vk;y9&?sLaplOtP9$EH2RlhefR@78qOT#0*UWFJ72G zSDsxQCEFYRhog1f=Ss}`pZ%l2mQCBczrr}Bj|~I``PzPW1Zhn1CW!%_EBb}mus%HL zp33p!wS_NO5voVltt^S`t*@9ZM3XeNH5ODz?RFk2Nc;0oWo}CK#K__)>UClKQ@yws zJ0Evt^#h)jnalhgOa9cEGHCagiU5+jXmf1>>YZE%RK2s#p}WFT0bEDSNyLA>`=2Y5 zi&1D-EVL8Dr7BF%5VPj=2dF0BIWEhfvEz2&b^hi7HliNR5+In;FCb>1{X}PaINu+xz#$|4s4s<_p}e|QOVly%DZqJTwo{^3aQ-1%CV*7L($|^U zProhyPll;t%m@r={lzSJ>Ot8+Akpx8APxf2bP@>=Joj8W00xflIWjLYElv!D6gX|82vRs3;U+wLq&b#e1YayQmL?_8oRKncdGFfpOG3l&MqeA6?U(DArdg4W+ffvUZTbg2N`q~s(G%4F80z8+Fvv`bG z`xxKicCD|h(8ZpKex6Iod5Hq1lrE`h;;3d<34}q#vca=q(SA@v8zP_mnh*_+ z-D-3)wj-zO6o?g}&o>daN9JpPvNFEh+tKOpNcJcWM9Dqd53emAPXjxMF1edE!inww z+To`|&1y4cG_czzGZU8?ky9F=f4l{iVPHV0*Lknpm!GSDl& z%?Vg-+y`f3R)u~n6)Xy>ozL3S#8y5RW|vlO2=v}~^a`FkY(f8Y=zW9l!khH#`4v?h`X9H_MI^6AJ;{}kgtMRAb zslg8}3CRjlXN(11T02MDa>(_yh+rr|$M##uVNVDAbUlX46j{8QyWPy9)6UrwC|KvH|fdxW*zHa(Y}rIk_j1 zDpra&sh}OKh*bt(K=R|T+dx`R>qxDO9{S3r`}k(n|94d4qMtPaSyt+BmQ|=<*{wSy zSZmBX?9$ewy7T}ATGzCx>FlpQwrH9g*#Ug))x>KWP)EbkTTMDdl9jdTD4|FkP(q!( zNv7Z}^5b)Xwa#@BHWw*oPL&~t=FjrBAn8slH)WGPj2WNfT^CIrvM+s%=W%zo$y9u( zx^kh!Ou?~MOheS|0%tb7j0RSTb4STD5SPYn_=u){6F;zY6S2m$EKqBy@i^iUYB5y^ zRX{tV@z@BQ%!#msqVo(iN1Tk8Bf%VZ>0tf+*|IT^H!T>UMH#w%eO(G;__}`8PeMOOxTc-AsG7ytpx^&b>p&tK?&jc zZrXS&6F|+VK7kcR4)tCsv+}P7A6zSOl4Acphm{H{Y=rq?W6aK#pxvaBX04M{UDbGA zTAwxm_XA;@)=dMJbd;H;DQ}cWo8%TW$_t`k$c;RCJaFtl+#Nt%6srx2%fOnZJ<81C z#n%5TVNBq~!UHF#X5(^QoyVcViBBepMlfa>1TiCK?RwHGxgV+fyNsOy=zk_ZWfU|$ z?3~;z=ee2<%E=RO-JMsUHSqCe&ZJ5_B=(VF!&c_yiN+v^H8PRE3uG7 zp@9%9rw+m*xdG%hKFlt2lB|Iz&x{14DMM{~`ugK@zJ>Da?`$d*VR#Kbq`xo#T-dO& zuwaD{QoFKXSCez+9w3AmzQ_c&Q+v2WK~<;K%>$#KlS#68X{1Z3FH1Y7_rz4xv-@J| zxze*NK_D|@6$B4M`H5L(iuJSrc6eLP0U`xjSHb(xs64#tt1Zn^knYw0WGVE%*j852 z>)wfQc>=&86t4wR% zgJhjG%a%g1&XPcRcS^Jkk>0}(*h19u+DV5R+SZ*s&|FODv|F+r z>q-PM9sLrEE;V_HtLwkul6LqGYVsB~BUognOz91izImpNrG|@Hm8b0QO|c5~rMt2W zntZM#jvh<9KTSa@-{%R0oH30~%DmKJbvG?hiKZ`7G3Tv4ez26B&BaD(T*&8%xq*d< z4@-5>I;E3)qAWM+u$#WxoD`dJ+@>Jaj4PPrkjN4;kq+rT ziBq8jV|57#9DiM9;Z?4O$uf z#J%9qc6aq4W;YXG&r)(4>4J@{w~H$fCQG1Kl4dr)G+`iW_mjan4m*@&+6M~AUS3py z{OmijkM$|*QP`A0*60VaSoG6wz^a}2W*rh@OCm4d3}{*gqMwvTdcS;DHeI+I5$EH* zea$oSQh0B^af%QsNh?mQvSpCr>QOnBhI)CdJgbXpxb!Rz3#e8w2cWna3&b6+%lotySBp=_OW$Y#H{mHACQ5CAZX@ zzzJs>Lexh)9+%7|iF0(!4f98bNtWuUS&p_+fgJ8H$7wHW(}hK9udlSGgL_Vyo2WC% z@cl+rmcZQ|u$iGXX)WEP2vK?8c&n2X%UaM-?65URT!~YKVN5Gq0zbeqVlM8_t*?^j z6vC&A^;c!ko(uJ?I@(wLxYbRkqH{p%Ex$jAf_~~zxAE$UK!f(A>pG4_%qGU%U!4{@vW@_uL*?Mm_KLc4gmC>XlU1-JR!_zj`VB3lSWWUL z@{$>o$zn-(5Zjyn0WIn7kMbhGzqk)hsP~?U_-^+$J;6`PRtxy7BU41^q#ieaWMY7|PKaukPO2A1p@4p&L`E4x^j&9SQ!^gVv-{Id812bH9 z8f6%%Hd2)i0!T#3iesUg)UVi&Ei(^%92vPS)euIw>_s3`u&nv|bCsLI*7-2R4zF%g zXs6C|>f=&ZEq&Dx%$B_%I&+0(IJ5>w2o#jut1>&fjt5Hzh~L+6q@5-n-GS|IpWA>5 zVPj;070K?{qktKHjSl<5{r5A=DEN-mN34g7{==z&jyI*x$Ks&2S6PtG)3_@bR;c}j zD@4H)7-3tQBBS4_qohO|AwnuR`PSo97T~6|LlqM5OvjXh@OQfyAUl_{IFLbH^SJCt z;fu2XIB`RMFsZR0UZth;53-Y z#>JuWh8O?JkV!r6^#zmEI5tRa6#go|f2%4+Y3BXeZp^nF)+tWYoy83v8ucL)r=ql+ zfPe39qO53|xP$Ism4B~uqnI-9N;;d~)0uQx$ks(UYxCF_WgmC6T8P8?6KTFG^ z@YiV4fE9D@lVq@sa^t2qNIK2mk{Nj8FFQ*FVC*OdLQpJw&gRhFD&15t(94Wsprp#w z=H57^?j7b*Xp(i5gc-)QKjfk?Jnc4EEW4l_X#3+V@YKqBZn3BW@V1Iq5{(d{ z%dY)rfa5b{zTPM(L!Yo9*blj1N|8j0pB@h3x9*08v0d#(vXv8ltCf9T6{Y!eSyAO{ zE}o`=0rT9!sI1ZYqQV#zmHyF?Pu(M|JaY1k;vmk!1uYr;?(>ywl)zVM_0!^L)mXfUJ@=9hPKH{>nfCl`Eui?t z5qTt(`TghJsw^^RPtFU{0K+wxj?P{CfK_}ij>mO|9exwYqRsO&^6YfT!@$tmox229 zJ~D3xleQ20=S8W_C+G2w|4+=%L16rJeaTsh%ypAk7~eEq9f(q^lJ%`73S~{g!DeWB z6?!la?kWSE&uM|~GGwwkPEo@F``3f-b{JC^pFjB|-;065hggKy-}v^&L7CQK3o`hr z^;o@{lD9nI!3mUgX)vsG0@iF<{4Mh?oYRIFB4p3Gf!}d60s)Sk@8+m+GC}5F<&03V zfU9p}LrIrJmWNAV4D)9JT~&{iaWCOvapANiy#swaEhHVTJYp4ml9%hnU|Cd!?^|y0 z(WjTU&GHN3e{T#FZLt3DWDe5@h476IF4%U;!C6o@2+ zqbesr8^?(GRfX`b&i$~KAzwBTb+~Tr2^U3w6~XeymY>s%Xo~$L-D?uKr-dz4X0*@! zm>0tw(@)hQgkhf5#m^>jwZIXFE2)E2W#$HNKL4@;=GN1@la;+u`dYXOwkx}{8J6wX zdp`(BQ#2d_4SUc9DM5;a@;^`E3|aQsm7DOOldu9naP}(`jxeT z5S{J$Hz+22Uv-!Hyu~|~5j}!nesv94CzS;EwLh1Ljuef}cifXC>WpNs-py*Kov~7d z=!0I|(Hf&*?j|eRIe*eYSmk`LXPBQ81porps4L5+A8m>_1 z1MakwX1W-#hTuJZr6gp zP%4}HQU*GtXK`sS(IsW3*F&fFeFYiub^i=?oDM#Irq2|V)`o-G1qj7{^LchyP)42E zn#Q5`Z{+)QytH4@+hC&gjfzF|uM-;oU8bx^RfVqY z>NXYawFUqDrmW(m)w>?OL~T`}!;9>N>}xC3uf1Y{PUwB`SuHW5L)P@uFoXpQr@{&cnB$*fm#3iv1U5Qe_K(?ERE>oR>NI~;P-!#;nmUmn_ti31ZD5! z-Lu>f-@2+|1Q-p2F61z=xB1(_g+%T}EL8eK#Xk)AdtRDckiefl)=A6TKLH6SYwKiN zy2^|DH?NIM%bMMv52=IKhs77)5{)Tcw|{c7c?0}Eze_O-E6@1#N}2v*W~y-X)}OoC z4b<$Plt zp`W(z|H0s+b}y&1sbgW+MI2l6WNVc%+y$oTddojA~KVoKz5Iy?&Ruw{eCEE4L(^1cFzC8|E z$aSia2PS<`vCvKN|7}Z&^R-XI72@{)E-468?2AYm__2lW!97Kz0D(&UXa7NYEYerT zc?TWkATr$3hZVv&nct`|&c{Z{b{*Z%_?Jbk4_E#d+sh5vG+zWXt7T1In3WUh>X<%# zByxJ{y|IxLr+Dz*<*a8q!(kg~%7B-g{B|40V1HS94j|#q9bta{Sh4?3jWE_=coAWCA zbOE(nh2h;h?{)hIG;nG1dNJK1oXhIa1TU*!ufBkn|6MuM3@4da)*q99^^l!O=z^s9$E|Rlk zYCBAo25H~7ZECB%VHlpIAQpb~f9md2@>|mz+)1|L;elBUxy?Yj<@BFwOO%+1XLSafy40 zs7LSG8?7q4VDFRK0{VH+#%2PX6|Uba1axTU?Fo6Abf}Lx-7F|S*2`w`ggJrBtQvru zAuPHJnYiP_DuV|YCPQSdF?UVYp;;*!&>zo1QN?#<@Ssm;wueQLv_^_mq=Lfvthk}^ zsal}G)2+ZFNOnCkL7!*6pUqJGhDCk`p|3m5ayi_XlCm*@|My$jrr{@*mcn(YY>Cq8 z`GU@VX$F=be`s5qW)b|3gerl2nsW1{=%_9D{;l#KHq^It!G30QC}Ynu%6GO&kzklA z8}AHIAwab-2et#ZY84yTsZ2QjrOE*m6@I-QB;l)-0_xV~+Iu678SOCfJ+9&#K(kd& zLAU=1kAyTgY}4lSAm%R=e5H<(V|5}PpqZYq1Ut-qyJRT7p8RZus7n?$Z|-su zOPaJg>6_yUl6C!3MXDr3=QsK-8~oRG;ATh`f4yo}m}=&~|5Z6CJYbS!sf5A?-9o(s zeqc<;1~e)Ms{nD9rmYunl6#CldW*<2FGlS!2O*e75OMC6y7`iaT#1STM3A4=I`OmtY|7LJ5zRsKc@@$Ojc1 zkR46P*W@p?R>)Vymgy~Y{qYL5jkf%8%?b}-+GRG}jN7`l3arg5?aDLI0`5*7CrUvC z?$Mj^QY3-42r6$TeRp^t$S2rrybDKG)Bsk8&MjjEE6dfuLRg|ZO6RrVxYH|O4K8MCqkCEB4~nnrMj zlK+5g45KL+?E7@hOwkXsU}mS?QmhnR_WmHo;0@)s@Z$GM>2c%4AflO{O!z?z-l^A^W%2-Dc?L3V!LA;K&DdLA%XsNJS^5=m5P=MpC34;{Y4;vH*kKOvCPeNYF6quoE_gw;pQ zx3gXXWl)FiX*q%t+w##KDp+>;cu3&nJQM3FRqBffFO%}L3OoH>T`akN*|~%d$b@n%3MD zv8cAdjej8OgQ=EhFPpHM)#$IY1eG~8>xa}1#jxqR^;6j;{4@K^Qdxwo?KTGM7fReL3hQb1n;NcUYgM6Ks*P5?)IF*StAYL~mJLSLN(#8l)Vqi06M& zr(+#fFu$>VnU7J)b$?fvf=Mubr^8G!&Yo|D)GBJt>w|Q&alOYy{KgLI7=`bZvFd1i z?^fw{lxbbt0iIlRslHc3i-uk}t`nRoN!`E+xMZ0WFrMiyAEe4~mDaqtW01K+|}*l%0`v%>S=O|RZA zBwfGsSOt}kwJRdU5qjG?M~ast`}ppXsUlf;%xsV-Jft_I5;U7^OW>1+h~Y9qQBvE< z`Xa$U$eNjE!V;zygG}~hpIDow6<$;yo2pmPmbg!fnT2(&cFxw@gz%{uKe-&#Q@545 zwBh&TQfB#3eVDczxy@gS$px71yEi^NlBmwZzt#3sr%U$Y7-4p%42;M%?NIkB9CdHWDzKS{!n3v!hvg2766OdYrxM% z>7TH0X=H|44cq;L?qj_`>%ZVXalNm-hwRjLKUbJfzy6mj#S>|Uy$zdb6~1$V#l^!M zCl!<<+v1Sg4xsAg1~*UvOGvSD1hC!7*P#stEQ04 z@G=j5>Vo+>``%rMkG3zGeU$cR_m*WGxbNtDyxIPr0;Z70HtUS>PVm~rX3VD=cJq|l zSaXn(I|@cqzIcvNdKfoy`Dt3FplGvh>pcL3b2Pqd({Lq1)i0|u>3@w6NcJRpv+*h( zvP@@AbRYzfxps4&g%bW71dZujSRryeOVE8eMt3|Y=;jXYf7}l=%ybQSKzFqEFHBZD z3s3A2eK?C2OMWr<=>3l+LAo@-=0dw&vq-iX;|B~|;VL&dTLmAK|N1YiKi~HX;B99M{KS;L=IhT{kx1r@GKNg@f4$zD#pidC zL3#0m1TL7I}N$4!{a1vqA;zqX{R0t6EkYS?%|RW{>9pr z3nTjlqI7AJPhG$ddo4R^QS{3lIMw=J`wV^>b!@z$0P`i=dtotlzYBjX^{<|V3WXkC zg#JB}$3w&x@6-zm?R~YXwTQaTdkdQCy|kU=EK8BAudO+xJN}AKssHb|HiXcVOFCkUTf2d%H9ntiY^S zhAcWCj2m*uvuhZ!MUn+wnK3ugU}orrEn6D__rOg?v6+L8-f(AK9|*I4Sif6PrJ~qU}2MTSulBS zRUOXd?YTh)8yUaM^O`CC;EpvP;oI$A?AyP7tC5VqyYYS7UriapfbUL{+CrL7-%AL) zC$)HuldOJwI*f&)ZeLmv5{<3GK{*z!02Q1nzQdbOjxKW`ZJd8JM!7#9tj8)Vx$R3H zF%tdm&5u@&OfS*UU58HTFXk1I(%`k#M((F9J72JR9Ik8YT?#A7KX(sX8r(Y&Le_ug zV?yOc^Rkcu?>*JP{C|u9^jr<<@MFH(L019|@w;&Ad$>l{X)D-B)3gmNexFH{FncaZ zbJBpajw*9mpjKxc1M1F4 zdhq+Nu(pyu`4lm;EOgWdspKfds>Aro8Q7;ONA56Fq{Nq30&bc!ycF~$H?Lm}CP=%! zo1GmLxHGRVq$!&4#VJ1&%<@t6Onn?jct2{$Dv__@7>U-z8%0td=%>n>` z>-C)h5y|D-z;#vghp3By??1UvD|oJNo31j^`<<1UF{|6V$Lb*8fP9w0_f-4U3bHPl zHCAOLXWDUZ2s2DjIEZ}AUpv&G>}PXFsdP|#e-}C_x}V8tyNelLT8)sHR3^z}pxgf&ke!2uy!5)qR5ogNB|i`SJbl)9V^ns>W9;yvN4_*j>=kzfNWHJm zHxZ){&VMdh{;~S-#hNa6?ZBxQ$0Ph`SuuUYEWbv#O=rHZa*(-4_d+-Q*sx1BzR|k< z0-W56wPCJ2^df_C`3x?*Z|q7uuF3QVqO1E7E4VylX;h4j zPrh(?EKY#C+F0^eAb+FOHEv&kG+m^@8SSs~I(?$PH6TfLJzGl;PxvkA*XL~AkM_-89a-aVWEAGEFbzmOco)t3` z@Rs(nPN3HH)>|EX{oYbedz7+SMyJ^YOU|IG=~&TPPesI{U$kQAri$g6oS90VZR=f# zVP`LPDU?|!!2qMHwa*oUBLt@awd&<>f^PCpyhP+6QcBi#qu1*VR)xBiI1iO`strl8 zGJJ4}oLP-p-C!+7Le*bDuUQM9d!1xyUdfOn7`txsriCcltdc82AzL|6ia++;l?l8C zv)V5dc4`ODS>Tx;4g(Y`mg0tbMU1AQ#`L?d2 z7aeWTd>I)(s{mn?*BzNMzoM!TU01Z z4RjXwKKrS`O#Ocw0}89)jpv!^Z?_JXFPHefhN?hNX53w)Hq+aYrP!o|aPi&j#WL;^ z#3$DkW%o5G>gwz=Qnb<1Jb3Z%<{1hQw|rZOq}H9v!!s!|Hjym)o>dK)f%ZC@n$r4zBV9JykQVeX+{01D@H>tUueytufK9a(P#>%fsIy7@aGlLoz`AfQHvzt}s3w)BsWgVe7kT*p$QT#*2&wmTR>Rx?~9kzK?ivWb}7^Ip?B9>@g zro!m3)(IaoPA8+@5N)pg8thzjcdIK*wxcIpVg5mLnbIhEQ-2qt-cwfN{n)}5Y9ln# zfch#s5ad=$$oNN7*Fr!J9+dA0@D+f#FrELPErQvYd5M>rzsVNapmG0S~!*XG1ES zUs*0)BPegz{R82{6{v=|Lj36>+0lkHFE4|Wm2sC3i9RU86>Y}M%0YyB?cB5=+F9y< z%=k{o>Fh!y#h`=fID;X^@v1nWOm+KMtRgzIm(_zd<0q226m2TC6pH+VUj?ckFihfnW*Qa&Az@l7mlKowvaEl%RmXJ6u;V-MZH34VI!I3knEmy>mR zKlY*O&v_Oa6WSZVgZ(@d2idUf&#YBwUwn`X8-LZ11NCgqZvaUxww%l=ZjA#UyMmav zcmNM;?wrZcvm$+7xKKS*e-!R=JAA_B=Ogvy{PGkoeaw(01RK1YoR&|~cVoaD{&+X9 zLYi@(;8yYLZ}adl!otxiBWc#v!b&qfpN<1DMk?WBcga%*H)U;A)IN$|xP{U@!L)eK z484(R_58{ZB)k7>07=(v4JLd(AfKs^27`ZL>UYhFji8T`i*{Kpd^v-hRh#~4`F(as zP`c&`E+Y*;-rEqR8Y8x{ot!a!E!&PQ`_j}pYIWjs6q*TlCN|xx3enSWZxDj*$_uZC zHoRVdW0B6xR%gP)o{mQk?0sc2FH5?#Aahe`m|P;4O2<*N}j* z&K|D?%h`y1RhEu+836w{r8H0@clN;`XtbzwFsXt9=W5i;06I05~R3;baT9gnSh2ovmg^gfEmiZ^UR&X2wARu>O~CX z&wTvrf3piLoB4h#M84Ts3kPLCGYN!XR~Ewzbgv%?-CX5+IZ~F}E~DVvba}WTPQf=H z)S!sEeOcihcWF%?N4l+p8U9Al;jmhWTmguC<(lMTj^WELg^Y8bznrIcqfNBgSnRT{ z`yaDx0#{GE4v$J{s}!Yagz&p1qCFwB+es8|H9qe<^Y#SS$%80vh_w zchZ$bSLKmRaqG4mF>vI`X~jBfH90??HS!P3VrP97?^uJRY?g46`SEp=vfYBE zYRw)WHO_F-U|C0n>_P_xOPpcTBjW8_W7*+* zui*&Stg~OrFGsCf+SC@xJX`|g=r>e$5p6feSq4(ma|gn4;fQt*E9FpnWwsEb*y})2 zQ>Hs>t7c{!F==sYJA2ca8PX2x9T`HW{-i$e4{?3$&yp6Fh2F`LOI_?|Ltxv z%Z~)^_79S~q_8EU(^kEoig{V!EV?1>xKmJ$?e7FN!981SuoltcLtkcV1m$UJImn9b zH}mx-QhHo@93qwWlGjG2Cl)Un2kQ#6aEM~5edr}3uH9DISB`X3qu`Qt&jy3pOC?;( z%b>P#YEmLTc$GgujUC}HbX0-eV;xyB5~tLACC3DQh#+Aicf?R4 zPsf^D*|cm*8!VT8HX+d%@ySE*=`I(h;}q zgA_sAp|J+W!Y2vgraiJ)`=QRk)KLSIz5f~ zb)0C?3!ycMCHu(Uf{l( z4D3*3p5CP7`H8!IUectHl2KdADGgVlOrepKZFXyrlz~^pV0l3~(dTlWLjA2LMI#;~ zam_Y8@@M778`y^2S=R43_Uifo9w|)AjCuj6rv2srfO1%|u?<*Y)}Qwaq?N9V_J4C&lyPP5tdH9mj=Q&s?h)w_#Y0iER%@O{SHRN#BXN>gmpOnlEQt#~@(zFz= z^Q&aX@UCnOL#hod)3M-v%b!&OFp-oB-YESsQiF}UT>Aws+O;AHT;U-;VLPcs}CxS($@A>@ubmTn&jDOaHl5Nv)|KpvY8sn$gN}4I(jw! zHoMx2qaRoSL-jsgT`()+#aXeNuJ~tu7lY5NngsAIw%)QeG1KExxhrP zlJ>DsJ1ZY|_dS+FL-~3C$(?=4pm9q2Yuv|$3@{l169 zkQP?U>H&cuJ#N-IJqJhvCr3dio3`?)I1lIW&J$S?n}6Aqo}$SF=MV6#&L(_(%}7ky z&8o-jG|kL%?6KRuR{2SJ%^(n!0U_B*ytbkgLJN=5Dlf!`xr*VYm=-F>>hf>bsVVe#}VH?;h{CxIwM?(Z#x@%XnQMascE|AIyB@@szX)zKS)zw3rt9(YYuL^#Qz z?G@mr`bUVKwnDg(@4c!BCP}f=1})8M>K5J5#v2kOPj4Z)q5tOkC130d2Nl8Q@gtjfNj^IUkC%6-B4VUs;C z2cuK^Aq1t=IR=(5Fb)rJbnC@TwS)8(4ynQjE!IkA4#D?jYpC6H^5AM$4%MRSB3A)W zZ!gRRssd^eY;za#fUnf$W9>>CV`H(Pj}Te0{H|oFM$;w^H(*G~ynCITeCRI;rSu%v zXAp{A=`syBw@0V3QRH0GP8hYi zA0HZG7!-3r4eA?NHl5HrnYKp^HxN9oJ;U@lsm@u4UofCG``O?}+`Kgt7mMclg8#ty z3i;IDQg(OmdqWYKAIfauO{kRkA>*uQYLIt^x$kOz%XZ=4p_*tFvEpL z^aVdj=;zT6&nPrgX#F{qjPda@vU50j&IB1`y6?9bD z++y?mxXZU=VnHpCOX^Vg5uCH?MJa}>a{F^Lc_jxeT>cGFtDFC#q!rZXvA%;Qv6sW! z%FrSZi>KTN2&<%53qm#h;ynv$A&R%kXYK*l{J~n-jN#jx27E;H*m^e6g$Pfe6$|l> zYTg4BR}2FTkE^2}?=tgsCV4~H#;mhi%6L-|^(WsolMqSe#9^|9_#+W-oRpV6 zkeCL{deCbm<&q%f;1JgBm6b&PZg=KiDXBFiPj#{kT9kmO=$;a42OqwuhcWc^vUj2b z)ozzkyJUw^#!-{?Q|IQP&a^b9(5UA(^6!Ql`m=n1;Ir-cH*d&zY6S$ zoGutxqFXQf+Y3RZ*EE$Dsln5rNX?cKfdYg$hr*okw?Z_%A~fQnzKAB$o3;A1un?}^ zJz~|-pYBfhwx@7Eu9b;NV_Jkuwga3{2=9A%P!D=gw)-(UBB{s7Fu(H@*2;DI17y$b zRey}6Z9mB-=W;=WY&xN}d6Pt)$+Gg+SsOpEycDiajoS<0IM0OAg&O#uVM&Y8vqv6U zjr@ZXvavVK?TG2v7|xREm18Z*QmMHVC#23^8Ek@5YDTV}!?V7FNy00B^7RE|z=d zu5HXC3O8S?w}T`0yU)7$+gHV`#yG7tM{26Tv!xqi8>rd1WUrP6buPhByp(_33ne4c zS4UPJk0K4Ax2RzYJbpV1*BJasOEH9yYvo|+JZ#LkR546~PCju=^h>B<|K+HZB~W!w zgS3dCyEc6U!%1)+dR+Y@nwjoaXNFQAZ^$8kNOTJMFdW_cAEAEyzpx5kOQl8ulMtM! z&QJwOY2`G)xR}3A4JN7yl@2B@(%~)T`YMPg%eLJHGiob`0}7yf3ontb#{{*Fbl-o9 z3;8szLM_b8wpJfh#Syg=ePW-gw>p@Xru`$D%QLdgU%p`7K8_{isVe!Ue$Uq2s zH#7T8jf(0vc+ro6KDRrNG;x5I9`Y zepisfg*_6A_=;1!3Ve{wpc0F%(3(jF2SNxdauuFIJ}G0-+W~xiv8G5BARnGBG?+-a zJkeS}(Yotdt%s6)1{=mH;|C)Fuj6H|0dd*Kv1EVUXY8@LpU2ADy1csvLniR=eTEs- z^)+5lVX*-&+;`_QwULw(xspku=!lS{L6ZKtgw|8?wVv&Q-7@=spmS&DuefixAFJIp z?mmQCFn-KES!sbvlQ#yyUAUgXYH+Kjs|(27rZcPC@3#qGwXfV7u<^qN$_2eCr^CxY zh{DP+RGV1%)@zCZ(YTuHtav6>#EQFpp3hp+mDOhuO>0>e)U13`9_}fx43vxd zkRr~@bCZ9@rW7sz-*AJ5xa6t^KPmU_NtTXiq3>YL!f>gMYArbjzF%M=Wp4yE>3;2F z1RRZ`K2FN253muHQBHPD`-ZRxx6;rAzU8ickc?eO>G_%D!!)-)w;A$z%aDrUzI?07 zA7fzAg`Y8llIxWuWuW+D|7%1v#@ASo#s7ZwtcL&7lAz(Uj&v%Z;FTm*CdN~IHnM9VdOA8st05;0EaAQ~YcR_=}o?^N)@E zpZQQ4I+X~O7j3@XWhY(zF_Kmy-K%BTE$7g=xi~9xGPL~5a8J=GPe_QJ3;W~;u+yGwiZ#3YY@#7Ey;U?Xb$;$t_!Vt6$oHR8FmKUJjrfuUt6XO92DY@Sn9|=x5>O57ZX& zr`9z1$bR5=5QTrzOL#S0<*+(J%9%u?ak=Y3fBMeypYfE{)DPjGnle_pYWkZwqSD`ZYp;c*nE zl+MPi=QJ*|KMTCyjB_cu-m^M}@8hd7#(XQOb^{|pNJ8G5VE z;caIUGWo5ka#3l1p&&aF`ERsph>+VSbD^P(n9g@~ObYSmlM;K{NoaQfCxwa!- z*9u16x(iN`d6yOj3m5HgAQaXwQisTSj$v$iF7<|@iq5|c?X2vud3}O1ctAH5*zBuy zlDjMg7c>LjIOah74?jP38?{`x%K7|&laIJ%SnTUY6%}Hu-IIa7t!XF|@tKDf?vx^BP}ung9wIj81%%6@HTA(628Q~j1eW3Z`zBmP`2ZhHlwrGvyCkw0R#;W6 zFv=@cP$7z;t1xr)J3FcUnjT>vD>(B>5&WipOU zYcbA&SQlS&TddE^wx`iUC)k4^OCngyf%bbqk<| zVY(b+{Va<9Ad8TPpRP|S;-9p}cP&4$x>oM(XePtsV_A(6$E}n}!&f+CC;|gkmt%m` zd$B7e#9hVewjDBrN%ylujRWp;3cDU2cNW@h>|_J@EN6Z;UQ*J+^H%WtH68ppKYshLoNMJ2FBCyBoHBYVhgUwSGx;KFk(}i zC^&tPHimdi-~tA9Z`czR6(afN>vX^8UC z`4#i~@yE;ML2B*@GnZCrRt$Vv^Xt9%j;`Z&94W0Sm4_ne#5<_L4gVthX92LUBbyD$ zweOOE@pTbcIQCv$4yJ4W3#UM2E);$S@s0ilM?dSNC-x?Jwrw7^13& zs7v9MBXU7~*rFx93PoGB$60c99;evp`fsSO=HDN-n)&c3i9@zL{EoqKSp2)#+Bf~K z2HmWPvCe32xzAuk6Ys%XBj2KJVVsqs$x-5ac}7NfQ+YX`_-F)mPW<^7g)wq&83DN! zzA_m?z*#$oZRe?h5WN1Tr(90rK98tl6#cyq6Ti7X<5S(n_aHL`b^8!GzSjoqaPA!J zbG&>WiWiila!5zfs}ms#EQW`S$=BY>gT;2~*MtmyVn3vez`oBfxOBWS4Z7RjSSmvG z)n7j(#QDNqRuAdsw@y&_uD+4P_bth8*Jq`{M3!dTAj6zPWq3cjDY7Yn57&^R3H)0Z ztoLYNDMLfH(_a-vs7={9;Ld>)4l}T#XyP|{I&vrGOVNsS-}zqDB?-~jP4mUL7K<2+ z0gM7aW`8FHmspya`=c0mJhe)0h|kynN?MT)m!vb!wr{8J8Vcx_vm6M1f@?3lwV0of$-RefhO_|318Ea7b>qAvlzS zs41;R7NwaNl+ovamxO_>zde+WY{B=37;;*l5d$P+X}XccrXN@N75!ti$l3XGDO{fV zfB!4G>=9YLJi~=j-!5LOk4#0+13J=l@Is(ivdbG_hTooPwUMqC^Bw$cCbA+9#bBx= zn$aU#t=3*q0W8Gk6E=gw_wFK_)9G!WidHR!47()+?VJT^EGOzu-wuN2x}F5JHZm;<8Jb=nJ-vqbtzNFs3RwVjOo*$plaMOvNkMj*=$$PtP6Uy&^$pQ*yw zWO5%bu6Gl+s5>+JP6c3{PRoagjJTRJXxwWz%Sn!8O5O7c93CFI&Oks8V5KPA7gmP` zPU>?>vNxm$CzDyV^q6(cBwq@d?=NMlz%Gp|RQTxnkzwLy_b}v8bY^LQrd}T`+Y>WWReAFx6c<%Uo$*S1-lJTkbIdsN9#GHTY1d z6Eyp>TrEF+q1q{Mky8I4Hfx!NUm(Eh^C zmF5dB%Am9h4%uIYr()RQ{J+7+if~Qzlod=}ZcP;(I>Ga0+iIe%qM(V5-6v+C^rk+n zJe?4FXbMTP(vUH6Pa>Zdd3=}@Uklql9kpM76`ll_h`3h zugv>iO2z?TkILvZCkmIUl&hm2wTJ8DFf>O8Amqxea%o7n-HM(XrTNr>DqL6IQV4-{ zq!u17qvqL6{xfEsa;+c8G2#zQ31IgYFU>2!K=~*v5rjinZF;cWLu(Lly17y&`szOW zlnqQ(&K1L=;@{VV6y&NrU{U%n)<`}=Jff*LpOin_KQ{AQ+^h^TlDG|YG&k5Eik!iqX{NH3jv6#{OvU^2h8UZ5O3UCIaYzsS;uyp zG;+8M&y8U#bFZr)`D@d(Upmb)30&+IX2T}Zw5m(hK48xrUZA(o3j|UlXc>K8jVbo< zj=B($mL4@(z}FJEENRM6w99^QU-arrYm6UoOE%Br-}aHS79rj8K?cw#=Qxbns+QAo zhRBau%Iq>OsDQr0f9yA))5-G<#HatS@c%iw^1v4IFFs+yqhrKi6h(p%6mbW|6d@?G zSn5s@>RMqP<>#0p#2pqJ*Gf_1SmLf@nIe>R#IbZ2E3Dc&H&~Q){66EKOq*lo`~AN2 z`@Zje9t2WZzYV@>*l$MRB=be|wk3Jh-$t33DhJg{5%ZKgBRx#2n2W>k#(Pm@e7vvL zPWsZVt#ETUZ_i63$CM#%2MpeDtqHEg4WkcYx7!+^k5_66xmA&*FcsX8BVL2CD$sPp zbM?RPgFkM$*9AX|du9tIlYQn}wZJB=iYd=S;R%9P4?fh4MAW^H+E-ML8{A1|FO?A@ zm`1r=n71FxLF%O2^Um8@cHv_WduLS$Ic=9}!sV!N2-{s@>ag+G!)^M8u7;ci1-4!rHm*5^MTfbqN*M0-5C4 z>qdoT0^4OaSA<6`CGaMImNHB&9A)TRsK9}YbXf2;B)RNZGS4&|}DGeEMPj2^V+x!pwr zPiRaTs46Aa0)oo7P+H15zKA*lNo#gPgZsVlp&;oW)P^rtYPK^LyVhjU4E#bKgJbv^ zwHS8z+*%QKPdn^3OD{ODu&viYQKz|%sQv0!7#^$8sXel8st7R5lB^@}jo9slM3<3_ z+gkAjD9O2JUB?Hia?*{B4fs^dBgn~6)6G;ADY?dhG?4m0_nCNI*7X(ced9|* zHO#wm?G$T}-L+qg#c52BIiOU*8?=kn(I0;>kdoEoYwt9~(l5o6Rg*lSGU1ntA6`{8 zXV%H5d@Q7D@vPSBzgsJp61+{R#`nhsn}H%Xyg1@$JfiPKUg|UE&$%ad)op6jShRI>pKHG9P;_l>Vo z$9_$PlsbR5%m4(^_musmE5iAw;@Z5xmz3Qr_VJOH$S(X?0PHqBySc?nKCKS*7?{F` zzvcAH`lj=Wh4eM52#)@ozqqX=ZqedN+uwOg=J>nY4Y<{dDNWiU^Wa1J3835bjZd21 zR&T=dD$Ed#ynP;*)P2ZY{78T4(oMlun?Akm%cs`ka<^@($m_mAN5^$9cs<||7QXQF z=6Ei*--3s+oj_XwZ=_rf+;Hl zHlDn02vhB4cX*{fCtV!BQIpImozsUU>QOoTx+Zp@KQ`FMOE{FOSa=FgM%|!L=LXer zvaWMh2v=*%w@zXE=HZ5MLr?JrhWoOm-v|Imynd3mfsgj%&fRDzBZI|ZY+hLi)}Xzg zCi5N+2f%4U6cTgj;;(!f*e`3&+r$8;+_l!xm;eZ#xdr14?oQvyXVv0do!6dJBmegM z-%aCP#08fWeaq*V;=|vxoTH|ZnCpe-suk>!{@)?X1dCR1sEhy>KhUVTdUC4!al_Z@ zu{*XL!B>VR#;CF64lj;6Qz*V{#D%`i$EOEAt3YPDKTfGYrk?e{ z+$_jn-$uQ8eKjs(#cG+W>16%yr=q;R7v1`$9k1`J(^H`e|MDnrS-W!uZ;I#S z_RL#wB;(i(NCBiXl!aozrsCCft%s6~iv?eGK-Nsr`nhNFyaR?H`Ml?}VVb*WufWuy zduLPO4~_e~rNGpqtg9Vyq|^Ox(bj+(fBGKEHRo(o06elZR@C*UnftQw!%^#+sZE?m z?OP6I8tDFJyC#*)ip)m=O!D}L6*#jFZ>+MGmwSWxJnYbxk>5Sd9-_exvGca_ox#}2UE-&8Y0F6UFNCVu+cL`b z!r#BZRj#=H@^xI9E&E4~E0>PGK{tNl?fp5+f|jwosVBF-UY?$3dT}1UY65TX$(1?t ztbn)mT^uPn*U1=aPsxSDnd#0 zY_W@K>Rt5Gr8MNZ*scy3&&$;~^Y*cocvC&D#i=+qIC$8l^7GPz+@l@c<{`gJI`;Nq zwjKEKe_i1NB~b7CGLRwx`KV_J^|Iq`Dc({I{fX-h#G$DaGsvpS9#d+32qBPvdxuQq z*gad_0h@ays(FOrUnNm0&er(@hfAzJL&ycsPL5%rxs*wDKM20Mbm_}l!CajTZBuzm zI!C)_KLHz<%e8-j8{4b=-8(%E`vvZ<)la&9H-tbrs(vEZYNk%VwlFZnEVw3GM$(*k zWOUb|Z@2A3I*nMaS_eLPDK|!`77Nm>UDUas+OF_Mhlw}%;Gp;!RKG(L{J(g9_cIWk zAAKEW@bXfQtJL^$x{iBrI&H1N#1;Iy?;`&D(5{UkBg~CqPku;`sq0#F%ssC;e|fYk(FYz8&(Rq{SVpr!#;7`Wc}6P&hX~J~ld__dK=i?8!Ajd+fnAm)T1v2IXY;aw^YURQ*@laV`H@i4YP9XBWFGxE$mZI1pGOLF zUTVn6-Ed^=udQP)H_1QGV*}Ic#%^Oo`gi%xmQWg6N2J{MBd7lG zAk`-8%Ulp*OS6hka2U9#{)crLG8etL`9Ox33+^~FJ;lNW#|`L?H0clP<{FRyceduv zgE%LSeb{GxqK@x$cslr$`Jf8%hgp7?}gP?-Crup1R^ zt7574JX5k~nILDL0e`1dQ{=Vvv9o>Nr zFR}E@7O@hZ5Ij8Ook7Q?uCCD_9dJaUc~jNHb=R$y?=l=**z?$tXyKG6;|`!a#KdX3 z^HO7^Ob+`t-N&V#;e#m=E_ZBg;Qn&be_037-V_zirGL*0Qj0MIzNQjg%6SKy%?z7b zNQ>6-4;@0jnd0Yn(B@K)EgN`CJx&?4;CG}98g^Wt;>Q{4X`Byo!S}!U zG!97hHgjSQ%GEl-@*hTpQq%w9l{%c%sNZcoS-)Z_o*ZnyU&yVjqYB_x9}IU_J|CI6C$q#LAJia2}spTc-^Cu=-)TjfQrZ01lGTFBw6CSDKwz zv+veCz^tUVCx@!uj-oAYxB94n8-5?&+n5@MQ@otx{>wMKtplfwsN4YJ<}`xL^5$Cd_@T5RKE z(?emwdiwqt2-Zq%c}dQ8==N9sw68HA97dW=xmKSh~Z4F^tBG* zinqBNO_%P6j6Rm{kmtgQmqy4*=XT8dZfZt^JMOq$UadlwJIH@wu`Kls-{aEo+w`%C zF79oj^c!Z{w#+YM4SpSylUwk^{Z#6Ayc(a3WJ2!5G$DTv?Tf69vl|{0od^fDai7siCuVCL$nY*T}rLU>{I$P?=o|8|5BaRHcs~DPyfn5 zoWh3a~PE*(NUYUE07m<~*8h}IWKx3!9n@l@LSgENQ9 zztm*9IOV4?NI&8^_krv!d$Lp9*?}{-3Bw-ws9*inbzW>+*xSkEh$*V_yN4D7}vRa;hAvn zEnR0sLH`~#k}Kd#^)@!r;J;xf=3fWHTxc@ADI|_*+~=Y;LNmobGl9bK>vAk`pVo~K zClL-7&SYrPFQc`3`njHpf-8^Tc?cCRCgvh5#VmT}(co4uGbGfAt$eJ`|IWC@ z(6sX8D!McYnaq6pXUnd<2$kzOUmK<9 z=T*2xnSY)lrm|6pg_cOYG8E`~Wm*gQAlTHNGx4|vf0Z@{Y1G6b8ZUN|zYVeC&?Wn^ zkXnp3_f1t(%2GWQKk^oi%Q=Da0u$Gv;Fvu{&z<_oQ5}mny~>~)VAJrlAA7-@kq-B5 zfj4(`?y6d^9c%v_Wl*?=WhR)60m`5Iogu(gYqnp)H!4*d-Uj=(W&;kNY`{m_QIg=x zETCC?k}#BWXl?{J$}G2#&(p&T|EaaV3EkCt0IAk6UdM4s&3BH1jURS*%)Z1_E;yun zPgPZBwX1R>(at4Q+2l+#bHASREYYNL;=-PzHEBTKbnA_JdRBHC6#4>vclcBFCO5*u z)>&mhqR^&>f}BSIhHgK?^Oa^VIL|vq zaE|5Ir)Gm@2e-`5#)m^T_6Ku37_`mlqSkwwI)n7z{4Ur8FhAWa79orDZ*~FN$7~Tj zZBcz4O~DUeU0s(Lgr^}OC|;6sq<5gj^?rX_8Jgatg4(j_*{VHAM5QxXWi$}gG70Jf zp6=D<`Ppk#McsUA)A>)(YShyz(A4AR{R~Z{8z=@Fl3laJ9i|gK_848%`PbE2AKmWX z#^|H(G#|Axv6~C!A<`mPOU#gMJ_C*e>oE_db4#Z-T zj=zP#$*9fN=ui>L3ras!8lG*GB5}(3(V6OJb$3qzB8YtT$!;{OL8>o0Uv@yV_!mP| z#GTdb(63mn+svo2@>BLudVrI2{@ANl&XgClolCH?&l%|;M@szQZlT?k+Fhw zj=@4iN6hk;LToE87#?_!m*II$5h|$HXtnZL?g-7g>c+5`#Mfd$9Ci40t0urPi3jRy zbJ)ELMcY*Bz3>hgLhiM6yi=i(15|vCGmnymKt)piD{UqA>U|+=D95aboKc_E_M#u* z!+Oh}+=pN}u8&ZU({dh&f#Phqq!_72-fe$|Wb!pGi?}ZvtSfqq=n``v&rDgX`m5(= zJ&ME$`V#b4P9;32NXdukCg^wF5;!+Z=M4!49}?wCh|!+3_P1}qtui~!>qepFqkd|Q z-y2g)K3p2Du|^r-F)%3&r>O-5vCYeb6eOc|*TMlymjPbk~xzK@fKPCKoMaLS`+3?!A=+EmSjh$E-! z`7o{%TfkiM%AE_@UHUYiY%a9b1zA;q4>33jT8^3ELgOh*Try-$wwwb4k8~D2dIMMeLTaUK4gv&)23g%~>1)o9E@LERv0E?e9u>iW^CZ?1rRTaItR7G!qef3TU>wQh$f>CI{C zL8QH|n&Tl2s)g4VVo$Awe%i4CY#>cj(_pv(wRs6dh>d@sI*v2j%!cMK^C$=Q>9iD1 z1YI6>`44x`?fVLAD36Sf+|S~eKi=I>!2qx9zmkIgmNxz#0nt(aiuQpts{R{ofPPvp zXg$<+LB8M@XxX&MnF<~Kt(m$$v0*4G-@{v(7IuCYF=rXsdtb#nX5o|3L2R2b5VDIq zYYTE6_Tn=!wicVVT1Xp(Dm?Qt!H!^i#r7(a^bqB<)=R>inHoI3YoSvqIY^MMCO8&x zOkw8(RrPGo=m*B#xp!Y?E=?~U&dg$WnZ;;r)|w!?X0gsZ_25?jjp!dsRH`{FTZQX; z1Y22}GQYunFxBM)%~H%9^Wsn`K_aS^gl1;N>B*QIs-N76_iUA+Ft2`G%5Goc*v zZ7LNR5!mU?c_-DV>UzKlnRGSMhZL~jb|zdNYv=pyUiSktIm zqj{M*WKT#{mws2t7RCaa*kwD2U75=Q&sBw(M zk0oZ$_DnCw_`W=cp6IhVNt;ST7rit1(7ku77`9N2rjOGx+Ybk&uXv9WXD+`F-o5eJ z?d6o^C4M$|0D4_xy%GER?9@=0ew@W?ld15M;^_s%y#5i1zCR?!81gx0%FDrtvA}cs zX1m4@b`_pkfo(QxyA`=7dNClAW$;Rf?&yrhnOXG5p`bCDI&Yd_^|OuBMe_pcwfdTo zXxie-)_nS7oyD0-r{2GZMBh*zIVHOA`bTiA@(8KG20FtYzz2?`WrA0v;Eyq4Y!$X| zeIdCDPTJ8<97iFABq4x=zoVz~^c3v$23*6~e@Vg=g6|Kif~f^;f*$y)=LEZn9P zCFY-jEEL(dI1jz{R(`-UetK31){ogA0DoaWxoT@X*hUV{`%d*S53sYdQ#skScRp-U ze#Ab?VXCTE^;`VdmQHk+ z+h3RW30!#Rqv!B`w0CTRsTftM)myFRj@aHe#y7pC+I^$`Afa$iBamw=8bferFFeQ$ z(vIu4Ogp-+Y=qM5#a0w7G1TWtWe8E<{ZDyMDNgTL=+1`QWf`$mi=@I`7x`pV9yfl! z>^@>>zlUNpCQf#I8ITB~nC`MpKOObug51HZLV^zm{R>UtZ;QOpnM)7z&VcIPA4_L@ zAbr7yNU<1jJ6{t8q<^AlfL%GbU@?roV|>L@@Ejw%Vr>Qqp|1g@aeC*^E9*|C1J-9> z%cIlLABw8qZqAc{<}s1c>Lw^HYouBQ&3s(l7il5pCOSwNw;u`S;daK>unFSnLOK z{;1_lBa}P|$<-*Wj!j4_$5uZnCT}F&7#{g-t|6~~uxG>QN>@(vImGF}e}T1@kHs$3rqRfxabWjJ!@g+s zv^UxuJTPrWMXQH-($&Mh+ApTrDey7~#;JE{qdS-8_MYkvQ-yG<)sM=prx>9fH4;IA z7ROJuCR6n7FSx(Mxkr_B0d2?NTuf?&z>_?4S=E$Wj6MI0Gfb&RH>!>SlkxsghRn$~ zdb`Di-KCLP##0AH=t%l z0F`e~%Bx=OgsKv8(d}R>n?;w8qEA|Cb7Wa|TIC{vIKTSRA{`)OO?S&NsI8Bsf0oiP5$o}yLvyHRdD^Ix>3)vMH0!hy?fiAA5giFTU)Gp` zCMdxJ;g}Pl;dwUVe=8bt(f6fF3fQmYzFuTSFSrJOLJ94QREJ?H^YnJ6Ozq2F#5Q7N zBQd!+waGES7&1rOwZH<;AJh)?4d1w|Dd1$?kEP^kdgHoUdAP*8)Eg4wF0<4CIuud(2?k{6)r zGg_;?1C38wLjy70ev=JAe2x60^(RVne9Rb?3EN-XpbqI^6m3+5E*9c0ydJxWO z|D=)deC4ZIYjBaiq$j0&Ia#}R80Pt~?Aw$AbjU{YS)L-_pM~Jws4jt@l8fDd;69r% zD&%KZP8D;rr~EanL8ZZ9foX!`JJMlTIWiP7MB z{ZbofAkCFuim~OWzszLXGVN@l z1$7ZE=0N|;F*Bw)Jt({S+o%9YqPUvv8#WZEnb`6;n@~`bi=H|;%^*|o{4mjCVv{q$ zd)~@k?V=!LI6jWlXDEDk1O8tOkq4xaQ|U z+f%iC!CZ>`aj&$=Br#^R?nEZSTQHE)wz5@1He?mvUXSxL|ExiPNoxO>J;XoMt-v;%FGA1sxX>0_yUg&* zLToX5@ZdAjGoID$u0p8GHOuz|ReO*B0gvrCsl)wP>i{HV_TvGg1nio!Caaf% zM?M%`WS{i20DM^HUB1)K2L2WE*O21T2}o0O%@Ona(8Y)W;07VJ7#)pppU-i7sKsqr z<3VSiotLzJYE`Un1|B`z@&^7gGhkYMr%VYr##aOIjq&PQ(@}`6fYO+kU)$2m-lfHI zUn@N(QAht4p6x`)EyL#oQhM#*Rl%D+w^yc@h8P56GO>MLyIi0Z@egn8+d=7JY0@6yoOH%&t0c$Ry|1W3}Z7T*^fv469fjD~crFICVZgHZ%7Ny>(V6@YQpccw^ z{lgUy6bp7&Fu=cCWjcy(F?$S_W!ESFEa_%@OlJ7P!95Z{? zC4-&w7a6iX-N#8~pvyfRQ}%}#gPDu8D7_gB) zx=hR?QH&izBRrZ!83z5kWxNR+;oB$Y!rtxR|J1rDdl9EPTs5*l@{FPi8 zgp{)K7pV(Yx%_*LiEmy)%?tGzI7mU#Jah<%p_Q7YnK`s2c>u(G*E2mn2v=NZ&F9RQ z>wd36JhSN}w~Ji)Tb;?A{>kW>npm>+e+<>(zgZrv8Md{^G@;q2MP0OAf1^_`N4<(I z;B6c+qbi7w()8@XTGa&F!sQ@r(-%I(Tmx^IEkf8pKcVF~QSCnuV4SvFuS($(G>v+! z*5pSfwXDr&mEv@FrjJHr2zE?m!HiqJULjbp%N})q10u}68)BM3Q|wlQ0%cUqmx9KQ z{Z4+oqfuyemd)uSdxhT(VK_adCm192?}CX|qP)9R(sR&=`p`dC6YZ|w)@`E!1%GJG zT=jA-k7#V{Q$ftBKy4iLF--Zd9mOzaZ>K$48;z+pn`Z!8@YjJWM`2|(x^9TW$Z5jp zbQi~@CbkEk?thb;DN*Uxv$P)C?3o<$ljFf_AzXv}-^C+np!9Eq<91G2{mU4QousNo zg>YSpw0W+@lWJv-!oo5KR$?(D%aF?05QiQcU~OFcS_yU?xhi~%DWuJ53Zv|sbKDrD z4*RpQ{E>OPv{`hhNG+#}R{tTmgVY-xDq`uw?ZHkj{n@rBH2negIWL24lk-QRkb)gF zS}a&YWhyHwe^;G$D#Z?D$&3ZqKcp7=^cB_Sr0aq^K(R+9YlPNT$OcuEAD=c$%t7vt z?^e2lV}80@5^u^yJa1D_(m45PD4)~c*)WCoq8aGeF3nOL=tX;_Yj!@md{zef02kSL z`;K~-DxSw~FGUv2&$Cm0`ycY4&1xS~4{BnsB!l~yar*_6fu3cL!-MB;)bpkiXsdqe zy~c(#g3pD()69w%zLZ=}{^6U(DjJGnzj8qxNcTgLbX(`<;2yg>VMz-@^^}# z)7Pr;RO9Dldr23ZF8Q-+K?pp zysyU0UV2O<@CdMYAs_rfHh5vSO7=Fjx=GJ8L z4yb7~Q^MwuAqV-~6UE>j`ioP$dfr;?wd!el5w&jnimnONA#;Ax#S{c|?r!=W3da9b zy90`uIlQA5EOTUy<7;p!lzImWMk#yy1%9^o+Z)*EGM{_s^SosHw+!C$J$e92Om4hZ z&~p@Mbq(tEOy+c`($(uk4^OVHtHB4%jiFGBjHxP8Tjlkgf)wZixLw2=m-ZJt9Mv8* z4XQ88guHqh($kE)o|<|4eh{^`8Jnz8GSv^l*Ng8a`UjCOd|E5h(`IH(KE{zY1>a5W z?9Z0rG{32&c8h0>r+XN6^zKgKbPN309fE%e@QB_tO2>xcN#9j`ZY7+xe~21lIc5ES zS$qU&gvVaq;~6mbydQS(cCcU5iK`OroHVgR+jOvZ_2zD$-FwX^@1wEB8}R<(oPXT0ZD3}pY27Ed=GTOGH3{&Uz+pI9XC)-3S+`KFRiH28k*wHr&z#)cRX6Gvyq^v8_mYH5R$iYx;~$`WV^U%pP`L;Q%%nI;ao0IL0 zPd#wAUSXWyNB8fts>yT(r?Zw}RLn|EUt=yUuhB?|)v;B_i;+EK(eBU8rNR#`WkzZK z#ES+Udycu( z8Cz*J@2bTyOmkjmb8*N=Q#}%fE9*Xhw~#p)mE@cuA0Sl#$og znoGxulm$D;q13iu*O4XqYxC*j_^pCHhUV5S1&3>Ke|w1NK~gm*8pb{jJ8hKTwK- zf~6J8>28YoKpprf5TFNl6%xWo8ZZ1I51jwHl8^)Cl5P=#9nk7xgb-{>%F3HUG#=r{ zR57P9o3OkVu+PT}p2lRl<5unK8S6K|jASLRV5!3~(}EUlE=8TcVW2%jTk{ad`Sj48 zhUeTD{LN4xKT^nV0`D4q%$p#}$rm;FC_)VdDVFpL>Iq(;acJ*i%cJx?Bt+Vhl&~K+ zQfz9`9FzY7uaQ12QFy@0aVVjY8mL@~krC$P z*y($~dX8v(txz(aUO@~uWfu>FCSg9j=c71pV1grz5+#3)D6U`R&P<~oTmKOXP-fS- znM&u$KemB&xz=$czV*e_9mn=cmKZ*REclmB6DqP4(bIzB|7>lLPysQ%RxI28DU!Ag zm#qv9TR7k8r`{#%CMxL1`9M;AxuwrnYNHfrq8^P=m#Yfzf!OokbkUfw;mLZ-r@}dN zWv_BeY-1#X12Spa3y6k%{)>up%ubmmm{3`8t}P#_$Jt*QDx_y|_M|08afuAlEWkzj zp>TCv^hG!8)yvJeftbF(dfh?k3bsJcL#nU3N@xHtp6TqFjV(!JN*%OCB5Jy?GrlRU zd$E>}mgM|{`qvBrQmM-ZxFeRHr=Y|OUM&--9NCVhV?Ba}Gu%<4H#o*(eW_yFEK>HK zHQGpT3IH6G^qvH@?UqBEE4WZE(Sozes4OogkQwrw*};%Xnukw93Y9z2K@H~gF7C!= zYsC<3N62t_Ksp0RgWm<;aztIH|AApJ%mg9Qkz#jb!qE^O4s;e!y{pRwB<}P7HBs@} zeS?}i&D6ldIir-VeUIA&lfMy?QLa4x5^4d+lsqpppUg=oRWK&clX0q}nO3rkfIKc{ ze|N2!7>CK~A<5HuB&w7qfct$1&k8|clH9Pvft_@sr8}9{crRJgXvXuP>P+_9X0S^1 zP2Y{ySo&evKtWdqI}J5_E2o}}H4+`(`HRy|p_Y48ozr|t5YISsV36udGhRt_C9?1K zU>1vGFR8P*m|RvZ#hP1nv@w=U)7E8LXksHNQ%8>3kJWfkV}RJEqOJk?A}BTG#*1k! zSu>hQkmF{0$OKHVy4!QuDr*swkgi=8vRVN^YLMFj5VDqd^%v2q=Rg_vLh!^l4MbN4 zlCw`+iSj=+L!qPpZ!!EW1)X~2dd?p&L@cDNdFYfWP&?O{#yM=yXC>-M{>35$8u8^D zYS4na-{O!&i@Hcyp~EgsGVw7lRYrMNXdTruhSe@M_T7SFU8z4i)Bn*3+Ut*Q@zX61cA1LgJnCu&xP()q6y zSfxhB#dwpE|J#k~zP!$E4+=M%3y$_Aujvo}LOCQl+OW*P3g+Ha=E@=s%2b;sLOV0I zo4lhn=il`f9juFS{^uv2@cFoQn0GB*;#@ceM?$&{!ZeTY86$0W z3npT9bt?F_vp?Q&#sUzbh!8CS2=l$zG%Kw#Cu!1fHVNb}futoRtp(Jh^9yiS8TUiA zW18i~J_u9qRx|U`=*iYCdHJNR+s)`lq`iYHrPXaR0CqTZ4 z5~plR*Ku;^ot;%NN9tHy5=kBy;Vlh70Y^1K*NvjJfjNo#AkSPrR^s$^#)}yq z_zpe#WWWLEpInB~j+}D2co)#sF7{9|qEO=*GYvs5d`9-FN~+*oo(9utduEjS-{yhV z`x1=PIKhM>&HuG7a^C`9|HT*>L#c2Vl^s?d8wuN@N;e2~oHKr~#&Y^I z?g|ls`a{hAfV2$yr?-fSeL-MT3hv>{LIEFqUC$F-tv6QxbkL3ufD zJ>_l9IB9F;mG^P?AOC8Gy+Y)_?r*X^@DuAc)nE(f4j36uDz&Jd0mC@Estzv9&1%2k zA^tlfEcjyN$o=u^n?Egz*LrEsG$TH8@lV%4Q%D`2ey`Gr8PgDA#eAAB`iik<+KKjF zv~pN=;6}VUE$Tb6j^UkBS>^*DP2}XY&zh-Q=?BfV*$z$_dS_-L1GJe$A!{_+d1&T- zJ$xDLU#>Qyl^3PeNHn1~Y@F!ZM)^gDs0*u=N(sxz0E+Y7Z3z+t2rT_nX^ zgKrjSn4M{&Gi{z`Mu@fR-4T*{-BW>b9KU~5!4(ncff8V@tv7(rUB{2Z>aIxA@ z7hnPPPcZI4w~hk9rJr4K3;L>*bvIXwLX7S%BXn)7V2ov@Nn&hy(%-F{7a;qs_n}zU zaZHrw6a5vhmM2Q@4`?O2SbUCJCg2(*;P%X&yXt)3FF=5f%CvcG1ZZ`_2N)WY#^v_X zqpOY8E)A2L4N)O{7FND3#1^NIdv0S&oe%#E?o>8DSKCoWE)PXqnjO+W3}?}wzx+={ zMVq#=s#Z_RCATqv0?vRD1Bhv3lqly`53E8&hlo5DE~XfYWUn^Pi-r3o812N^r{Yz1 zUQjU}<$Gt&VI@Q;((Za*6_=)bS4y+Ng=xk9uZuzYnY>V>N~0tKbODh~ub z5X9e2Gv}qn5}){Mz!;0@SFCq zo07)@j{$}KFj)Q{YrBc`eU=KTJo=87!3WV$j!=MDu^g}_ljEm;#qwG2-?)?ixCaX& zZJnTva{k)4zDu-|l5G-f_{8!P7CDm2gfO!;NmhlFY6;q8HnLBYFQb>*aY2E#4;IyC zk)uZ=P*dOgXVssPemUzzv?=hwY9ou^XhfHh-^JJk^zdB3D#0Y}hUSlU5OqfKy!*{+ zCkx6vu*$jZK(gW#`{PHrZn=M)1>^Ke%mw9-kLv{B?#8P{*J3(wdO60C)FEiir9Y<^ zv%2VE_fINyb7q|uT*YYO7}gp+Elf9hVpaDeQ-KYq5}v2#$@RDKSHn=a+2E# zexmwkOm-1jxr6ASZq!%*lxZncWn@@eiWHKl%E(thxQf8=@4U;4KUUK#sEBWgcq zw#bV>Ty@4M*?y9>`4lZ(47X=WtQ1lSNRP4*umN}>)$Jp>-fTDO#ZT?G#!_nGvG_Y` zuZz1fPDSk!y){nsk0XCpEhFTA#e6s7NY{2+b5QWQ46jP_Ul1BrY+pT&7B5u8yev(y z=~(%gz~C@db~{8{0=ufa5a~|JpygIOixODxHk>*P8k}e&>G=b7SdCVrLiccGZ5rva z6)o1MR=S|zc(3zyA$J7pH;GCNt6wIXrjp$EFbdv+s72dtah@7Cy|KKZ3`%Yr4joq?J^!8$F zM{2=~-jV4dhrJs7CArhjK)-O^6w+)I>0en0puT-yd1o5wtNI|PsdL9$0nPLB5?GW; z&VYvYi~kkNVrGh|uyw|3Y8O4`kH>hH)UjD+0HE26)SPEV`A&6im=~2XXz7U_D|T!*TE$ZmXLZV@w8GT>H#4U?ui+=Tp;* zgE2JUqI4%_y%q?CG^*lKHRX^$d0JJxwzz>#6CJx!1`m+dy%7Vg*%MohW&n<-YIA@~ z5nn8q-BZ7=%rq5prvi_=kUN){7QE`<%Uv2-y*h?TTPX1(IB=zt}|Q8XY~MlBn>t}IhLBKC;i&eTCk|m;{;2|DAJ}#tFRSw ztGp@`8s*3BRx>BnExta5p`?f7F#hTrZ-Rqe34ezIl-4{S8`Rnzk)TiX>LZTPTg>TP+QT#tMSlq~q zTnxQ|O#;{0tB!D*Q7_lV=py+{iq=elD9-hXbUPgtY$Lbm}#u?doKqN1U*VMzk z)dMr8f0uRtuA^MUZS7-iC#7Oyr5Um0fTuFe8ZOZ+-BQ6cqMHgq3qQQ=RqwI$>{pndvOj1+?Gb%D>6uUk{cbjSoffyV`k|iGLWj=$mR`9D7&7GQ0kj)JpxVYJKx`z`N;dmB`b#9bOB1 z%~4NwCGTt%7uWpPAg~X^7gKpguM@)q*mKTez-J%xr`mj3BLTNdpw0<^R2Z*lZ zO-U4V0;@zT1V*tHyJ1>6JH_BU(yhn`k?rMox?Q9!9RyMbpVrY9kR46$5eej?+FYQK zh$CUHl0IcB#H4P7-*W?zK{hA|Igp>!8ryT(y_50Md}XGLtYBSFZIsoPhholJ+7KR- zxlcE3g!CmmKOgf6bSRDYBf$k)op{}%Ci1bwM=B1Ge?_6 zsRMFUo9!966yN-pDZqjY*%2%B1z!Z_qD)c)G~J-#$Nz_=s@}GOZ6%wXo(Ha4o(z4V zY;KYXI+%yTw6E=9gv3y7-^RQV?h~&BEn2$21jbJKE-ueGoQ%NtD1g8aibhRo}`DO-2>zK0E3c}X! zZj^|rMnVKG*Q--*%r16-%6M_#IUOw1RSfUJ4&Ock?qxK-ng)k=zHx#X1L&9`n9&6G z_7Y5%N$#m8YRVga63}r(`BFv27iTnIFqdls)E-^(jDAoO-nW^8jzdGHZK@mdv9#I| z`Qz0wnKs(eNu%0|tc;pi-mI-{pn1aOm4s6e8%n@^YOR8^hKZ1I|-o#;BbUl<&ppFp?(? z2bq;}a){6vw9En*lO;yRlK=28#xSd#5v6J5UwX=IqHr_~R!pgP5NgkLXq@1$Oo5_D zt#&#!j#nE=-dJ%^Z5NsUaEKt4qi00`>B!N!fiZaCmNHKuwKor+fl=_Z24p5jW$v>O z#vD3~H~kAfjXbyBSIme}7TmRW z_W6(t&8!;;juLdikRpUjQiWS_xJkc-r{R4uRSl4-Gu7XOywG%;v@ZA^n@2|2wQ3V& zX4Vyi8{iCmfrep9ctQ>YUCTm_%r7^%?c`su#2F;1ps_WJ^wTGTC%h;6xuc|;@C;AZ zw`l-{m>N6Pm_za3Ke6iBv`eCC0-XD<#sXq3udO;dv-6(T#73Wr`UAA6r_=8kX9|Ah)qA z9n!?oUQY(bv(J9Qn#?IZ&+WxqBkpam!k+8S3b_CV@7Ecllg}P=;2nW;FyeP)c1&Ga33*|Wc5 z$V4uWT5=>Ev|+aXb6W+bBAu}p0&&ie*;zp5u3Qky zZsW1Tm0co|8{}2Pzz43pl2#8f!3J6jC)XRc+@Qy4{6Yw5_}Kw0jBDz^uY1VdPu=hc z#5662a-~0_@+`d*BVE{6XcR*aEfw&oY56e>J#tpnYxCkz%}Hb{@)~!#*rx>CxA;Iq z44TIFwHD9>?-7CFDGn`5EL7nia$ATU@eZ#6*JOMtp?^20LXO}KqmHsZsaY|W8)e`1SUK~0R32W7l%C>Bc@{XdM3nNdM&rmRK_ zFw@kLhp?jlh!4`QTh&tQqh9_ako)lYn$|Fd+qSSqh`I0>cas-R&NOrKmr~smL8eM! zWH;ysiCJaHasQ$gL{3(73K;RG(E&*bbh5J>(7PT5NLTB_O?CNUOGgJV1m^Btb<%s! ztL~gq=c~@R7o(nK`RBG&y=#BJTTWQwoX=P%W|gB>KAUqvW))Kn2Orex<)*rXlZAZeDxhh%&D5X6ybdxcMbcH#IeJMek1RzSC`)PGd%VW7>GP!?CvyyAgGnJVRWQM)1) znu+Sevc%~&V+@~CFJhVdtX0E88$Wc@f`S9@Y0+M|%VQxchHPUFS}i2K+!)f);_dgG ze)9ZQ1_Ew+tar=g@B52j2ORZdbY3QV2PqULX?`0J&;R9uTOxD6dTt~c&Dfjir{m}5 zfi7$7p48@IYr5?`Ly^5G3?|0)|b|Dur|JyD`P#}OR zg%kvvlA!}42l{R&wq9>HSg~v})C|*aIlQ{SVHc#>Gs&69P+;DX5K-#bPI#Cjr>WLY zVKEo@iJ8BHXZ=fyE=XlJM?@TE*XwSzAqF?Qlb=1fM$M_0_q0#}L~0kpy_hRYK`>>< z_iFZOWM8sT4}#ZKSExaTy8l+Tsof{!haUv0&PIL~3*rHyeAQ}WbwxWtht2#c4_|Hk zUK<8{stEfKHTEzDD64fJkX!%K>jWy+Br!aWOmEhJ^m@xJa8EdCxzoft28qdtC)6m8 zije3xqFtf^OTH6=$fo?)s>XOt13u-USa$RW2vbVkt7>ap|M|grkjm1>oJe%*vK5j( z=462tNzr#67z^k|@O7Spn#L_w57io;{t2Vmm9@(Xdog38+8chrAM>;hHlaYwuS(OT z32J6YTCKAh53>DwH{i`UiKuw&4Ifcke9!S{%&l) zW@2nj_Qn8#X`y2(7X6f!l8Ow;9sRfeQ(4fpdCKBpFE zsn}}?AKQ(K-fCMzLuTFoN_HxW^oOh;hBkw>>r6GSG%R8*qfP8Tc4*^i}mOO?>k#(?N^t$2h%|_3K*X6#GkLjN*e;IDN&ElX!=o^PYOM zjrUjK%#Smg@xD6fFWO7+9_GA_>Sh`gol<^K)?*UnY#P%iNi`=X=!i;jME{C?e}_F zxU1?;SD97A4J~k?h}!Cl+0i3YPmKcruONcXa_#c zOiKB9w+$VK%Wf3%tEq?jJ|w62NwH>e%!R!!1AHswq}Yp5{>)THw(esKmUoVC@8@JY2@R&1EZ{uxqOeVpjYqiD;1 zYN*p!7riBmktI-9b>j!AiBodQM$uKAHM8p8kjZ)@gf?ST~{C5J;fRfF`tP516e@VfHz3hhstB%YkYQfk@x+aLMvaWI>Gl@KZ^#%G# zWVL8Ht3nm3nPBqtsUw7(s%VvUq z^M9#oAli`~g*^P9r0WiFDf|8}yl{sn;^B$WGEB&*(Zeclklh(yCCV~Z*$fk#QKLtH zN*Gp&9(6MaGs}`yqwX7ojJDC%uu7C6qpYw>SmpP*e*Yvh$;*BBoqO)Nr+!Xk!BPm9 zg5C`aF>LiMg*X_yPNkS+1>=-D7@6I*6fRTT(HBC6F?PloE_Yan14+ExiuMM|1bQ>T zx6f5HIoO5Bx*tUDSN^0G>N! zDFAA?zB7g};VY}2Fs-if_KL(XVzmxc29x$u=N!|v9u6(3yZP|FXU8X|55Of-avlWQtMZW<SQUO?>8FgTR zo!mb06uKhYk=i%<{ZpxPGWx1E?}Fp3@>Ez;jvA3{8^`24tZPbRBNx$P587PVPciG&OP=C3v@3%D)+URK3` ze6TEe+gAjrNK&E76UQ-%$r_bdmy?#(PENoxO@F!!`C&{eYfn_Iu#FZA_TEJGU<~$B z+K2j9ne1G20s5z9_efL}lAYR7Ix{hkH1Szw$Ta&X8u0mCD*`ga0=F}LtRa#5%b2&P zcny+;{Smn67BX(5Dy<$ekek=Lr{OH02DMSS z8=**lRC#=>7J3^L;OXuagp^$N=eL5R6DjCR(f1bp?OW(M*x(HkEkS@wG^VhGnLd*il? z*0NL!JM%-bh|JSix!FsKca)10Sn$Wfx2ldRX%$iL_2=!0yA4{@;&fMqv}OCNXPWMo**K3 z@bDd|GSW|dH{cn0j|`o-%UeEZLQ{)wY`PiMXO8|LrKG;YBRNluYg>}n)F*qBiWiDx zh9^*HBlB(7?`e@Tcc&9{=%gLItsTb<{Mih#80^j~ByiOLPLYNTV^1}l&Qk8%b4m+2 zem@zL_WYRpwfBI12UPdy^qEOHthT_E!^u}|(-kq|IXlPcB93|Q_!va65Vl(co;I5$ur^kcsv~684qv#xiG=tLq0kNg}>{~ki55IU2t#%g`7ba+}jaJHWF>e zCuo7b(LyId>OX9nHT zi2(KH)ySZI?Gn@+Yv{#mYJo@ln&25|S5X&4Ga z>UcuNe5;f>DP{FSaC*xBjtA7Fetsj~Q;suxI{}D;EUNvMp4?{FU-WQg1X^k>eb-XZ z^UQ|$@OU)<;6v!2ZcnM8t+mgn}VVqF||y_ET%Vf~PNePcebj&C!nL`?p^O z&X1K+gKT2sB#~WGQh*q{%EqO!o3;krMA{Wupk~J`$4(OO9iWPk{MT97wFSMp(*&lu zl7a>*S9%`=4D3XUps!Dwb-fiZk`V*?!@tk^Y6vLMSFfxPC}8cVC;pi=^Fm}Ak*oZ` z`^ys7ifK484Uhf28xEwT^%P}6PP$}*iiMzd5aFjn6MP(fA2^|--+AK9A@c6lUJ1zZ zr64ndL;4rSNY>#-G}D4KngFic@Q>iAK`a^PC_r}XP&rt(NPsiJn!5_< zWmbRuZVY0a`cmnE!Zple%3`H`LKx8g`9g3a8_ZguCQRvn!CrD6AF2fy^)`Y>#YU5y z8ua044GV!upG$ipe52FJh!4hR61MhcWeOhe1_owa2!BBuHEe?GnIzfDQKt>NZk<(+YpXzlFgck5Q<1H^ zi8oh;vG5CT9F3^1S1EF0URn>h*2cX7JsIOnK2nusw#92svA!X^5ff*ALiS|N1zv5( zARGB;6U6F&i?g%tPC|}>6-V)Y%utM=C73x;kS4RtQ6Nh<8v}tRr>%l4mF}*go?rDZ zIuq(x{I#70@Q68eFc(YK{+c^#yXOrPW++t#rAK<;u|JK0r^U-?JyV8AQ%lm>Kb!`$ zg=v$m^CS7=Dm3%_+ew7o*H7mM^g`OTOqHh&7w{$JY$iGx=%wUix-m3f>s= z9RVXGUe(}LeaMK{+5=5^{a)W1uN&qgHphjZPa8^y9JRO?{mH9qP4Ffiy5A934CqGz z!5^Rf?+~O?o<@gt_wgX+KP6$+~np$nF+B z@fO}YFB4bYoirT(_^*%pnGV@}@c?`lIh25bm)D12XF7L|3zFZ?H-)Gku%RJ+y8Jj7 zX}zTr#{2zCS1gvOE)f?ZGh=-eaEG5N0~r22T%3m7x@M;~kndG*TqAvlE-OTCT~XTQ9pjcm32;Auv6zl$TaUm^^kc_W_)N;EP4PM1xmDbF>n&QA z;qCL9jKg>{&F}RG-ny-;c?54y3e%3`O_c`^0I{l3ous5AUG3q4MYD*cI}>Stb{eGREjqI8XkU!3sTU z=f?aGH;~_=ktDFy>eR%&g{C8*ERvz=T}?4k=lW$+j5}4a`7V&|?eqA(_{M{7Suw89 zjIKV=m(iNzWb`)vpd)POylyc=uUI$s%J{uCC^U-e=T0n;!$^bFtCR+#LB5A4$ zOD=IKIwOkbd=?Oi8P}W&jcXN>a!C04XB|PiJq10X)2e{5zNsI3R>0aQ)#=pq)7I zLy}BBHSP>@8HSafO379KAwnoMJ1;O3>024vQqB>omzYa(7}r>?IA~_a!}>z;6FhCvoD2Dx+Wq_}Y5l z7bNC(=w-}#%(3YOdFCt^hH$`@ntCjV600p|T=u-b{X*Ljlxp^&xK7$*)HYXxPs z4LFk#k^iU_laAJM5>Dz@l#G>SJQaDmq*+ySjcn+s6%Vri64WwLdl&5JaxJj4Z|^95 zgqi!JH3$XmsS-r-6bnd5CfbhOW&U zq_(Uxj6+obLoxFYgD1ot-@r4;OvzCiiL`C9NhZvXeZ2Vm*A19P;YX8)NJmCsV;P>X zx&k6zEQv!NcOr%!7 zmJ2-?=Y3@X+89qp=sl^(!b{oa{d~0}J3OC_@)Dl{&3l#YRH)mmXmcGXiZ*h}q=Tl^?vJ=I@$7nwJ2D?GV&0y)IE-Aw2slVSQ4-3j zTxOgyhCMh@@DO(9aHWe_S{_h_IQdBbO^|`UEd@@A{PlXgNkc}pxnF1}1Ac0+%Ob<} zo#HK}h_S&WtClb;&6x~w7cvTwWd`J9Ve}2LkEE_aofe7SWdKjZyv)ZQb+?Ad@;q!X zO=09BMPrtLxbmoq;76NAO#`p4E<0({7su+SPE2@t9>~DV{N7|k)@W@hf24|8NLHpcE?2ZGM> zxEi`BYS>OYBdGG98)s+l7t^_r;9~fi8Q%JJ5gI%bY9TP^raAEdrz@a2N@tVF0bsma zkiPD{SRqCgwpxg`Zl*O%q|af{PyT_ytG3~{_>HKnL?5N=wSbmLT^<$b*+0JHjmU{V z?xQK!mX=kV1exp`u!ptw1dv$z^PZJ(%+d;N67;YPy@>3+udc%#-_c&m@{TP5Fj=E^ zpt-nguh))JRGSV8RdAQrN2I0~bMX+pz=7ezWg#iUS&!i`MR4GM|5@>~&aYtjJreY# z$oV#vFvVY1w*(i?{xjdkw#!P*Vy~h56=4IVDVbcqgEytTONe)Cq#}m>oR%b^V`nS; z-|h`0sk{m;UP`fIF#(31v)WPtkX*wgvEuN2 z@TX{0ddNRhz1|eS=0?^kL~dt;t9F%^@b=Q=VTfjDF{`i9BzSR$9UDSky@5W^ zPQBMdT9fpEg@o^K3wQ`aN+oGnm)#lTm=eBriZqm|l?Q)`8GKv;EB_7?i8xbTY^gYu zQ6`(6W`yFOV+^VC_c}O4Q-3Mc0uEw$VUWm;TqgMD_HG7`GWFAi0u_7wV``K=ye&0K zLLF-;BqCki9{|7Wa|9XunGsJVz4VZF8D!FaNhl!F2^Cry{d)yp)_fcnWbZbFC6V_# zgpSm3L8g&hRrSDTOB}cftYGoW&H^^&SDbIZRu*(V(sQ^afOLp=ZD^zWxrK{#b}r@p zX$e0FJyQjI#OU5mU9F)#@zl00xJLUg+D~Rf8tcaPKv~Lu8wPpMAWsl(0JF=?(11w+rsxAM*f8%TX@1_EH zA-_DM{=OpZg@Bz5Q%+F%RUA|DjtATK^!gjBEMk|3TzK;agQ_#G=g08w?=WSF0`Vor zZCL*iR6R1S)MpH9ef{#i!a@dAPk`f4jGf$dN#Wp_w#ti`d)KXX;p9VUSsO(bXDRV0 zOX1-}Vog;9)#9*GW3PaL9~NQPhTIKl%9HEx4T?wU8lVG}+$X4YVct@e0%2)RPffOS z;oNIEikO<|8tD;H*z51mwTfb1mdE7=6@jO!l>QcdgFN$>jd_euwVFGZA^ypapRsJd zvg<+WkM|dVrx_-=0An#-^c}Hm%m=kKMx;`Ox)3}*o2kVpb)AXg6+F9fM9JlqT@!+8Iblw#s|qbC+T25-K^A>DP!j7U{0*N9o08c80(0xh79ghdrAEgK3JYf*5j_jN z?9QV{mocHf52q(%-!v`iq7c>6iWN^z;|^q0iv-Y5y>h%Yjr6`X%IYVYPz@79jHG)#Z z4R}~PpuhqAq31m_C;qc8maI{SbJrev4n?-oykoCH-XzPrWLQwOzuSN(4mU3|M&Pg`@{4sa{1|2@U@n!F(KWr4)2Xz2b+`RLuX)lSyr}sMh!4q zPgKms5&ypVCW$Pae@B-_x;3tf*9P~udl8xj8ZFKZ?qCZLjE@UKRbk4aoPw)gZ`f)@ zkcw(Zw$QN^nHu)zH`uWDsdWmo2=ht|1flR&hMQCTkZU1ZZ&U_@wHxxubem+w(e!Cfu1vO8sSh$T!qrnAIAC ziY-@32~en%j~k;pFFfpN!)(ZaIw$vGX8sES@d-3z6zmp-h9J{b~ z@+E&#wgzp=?vBeg07$Bo3Sk4eb_g~+n4Ot+ZB`mk4L%pTh!iME>)PbmhrxuYrOkMT z=^NfB_?YRMQRbjc*8Q+=J5H0V$#-3AcVZ_4CFIH|sFGR{Ql<*QNF z9CGE=E8IW~EGT_hkwY%LIy1|_N%blprPCdr(h<)fRr~l`f?X*zaBaO}wlk z=QJ-M;3R|1%@{rr^)*a)r2&L`O( za;3w0+(0|C{m$$hpd?-$2!SDfoN^p^F!Eb*_}%O<8DIXN^fXS4yq%H`SvsV&UT5Y` z_j`;cE9Br{QD@it3u_lZ;&~jGyMetuv-kagC6l`DzH2QYmz-PD{owqgZb;zp@ScAo z9L997zcHZzxo78S)5Ng%OTa@oRWIIEhDqfmhwt$ zm&OeX)r0{)UkK^zKAM}vl-^;<_;G|JpMTWBNFPb+XPN;`f=jSrD$j8g^SQ+6eG1oP)O z4%3_p=D$utN*Q*|p-rjQ?o6_)c4SuZK7e{in+!+S#|21tj+9JOpd# zkLcH&o^2k;+GpoA5HHgAOX2ES$frjj3>#OD^RVR>35<%p^+o9-VKSUPeB-u!3YPN6 zdAb;}Ps$CzzD=0Tr(hv}Yom;!mnrR#%)Ds88`S{7FA88er*5P1gEGzdEEQKeuEXyT zrMO8?Ap0)Cw1z`M+k6uZYjgiQpUp#@^Gl&tHQD^1w&cZ z(w&bAAjci6AMU)B*vHt;$}Hlk^a#u&)?J|tb2+P$mnuBO;;yCi6GN-<)V>OjU27FN z`=t^<*Cxh{2e^IYVGWak#QxZAf@bTgfltis-_pt!F@nM&o@j@vK@{=uPQg%`Epb~1 zz5Tz#JOM*w48#&@>z&5Jg!Y~T$wO%qO=h&RX7Grw?nParQ)2S^{%ptzfIdS^(F>vEN*PQ?fxbtOL^x zo*Gt46zr7=vo<1F;#j`1U@1rbdR9jfgI%;;KPa5@cBIls>Y_h8?s;JZ){VUl?*(vnnwpF~)0(L8~v%$f}#)Bsf~O_mT}yJ17sP2{x*A-n1&x!AQk z!9mP`J8?#~)d@U@w$yRVN!w~5Ry##s2hS&+yK0I81oe3Uj4_9T)H7p6rw2y$4U|o*u{%Q-rDM;4kmZzX)napa+)mfT9ytfWCf1s zM5Gxenp~*Qu|vxEu(Ms<0)&b2VcCQ%nDmogm>k3vERT!KyII)rS!*yM=Hp~MsAqi@-d>K3=#sC~ zlE|uSDh(`$ozI8j+UPQaQVTEFREXhDniAAvyjA(3*GIw$Lvb>DvU_7^yPnO(B4#!7 zS!ELQUD0Vs{o}8#*c~(aT7i#N;c2qSiQRu1MrA=|)otDrM?TIESfk{h0SLUaBj;y^ zxteqN-3pn#au-oyqA5$e0!p3Fr~QADTfdvC7*Gh8U0xYfX-bpc7ic1jS{?)v9a*xn z5Np0_y)KM6Qp4s7GfC|Eohb*-%z4=H(!w^GM)vMu@Wr(1Qz&|~^k}sc()XtuCISck zb3sqoGaCXLA}uoWo(e=NdmCem6K~P=>)Z-no>?bpSw7slIz3uTS1k+^Y5c!fBJJ8) zlxd@lGWG1fElLCM9*#pwkYk-`mVtKFMw3YV#&x(pWxh6mV*V$&n6Kf*ELcg}v5OM4 z2q~3{&?L{dMb59`@}o1LFZ(+yvD&e`CSE`B{j`GK+py^>hIjX^4I_WpCEQfo;juD} zi25Z?A8{$X*Z>jLU&<5`E}u-FM6uZvBupI+Di5@q{ zIs@Kfy4?-<(B*flRV2I0{*&Zp_geT+1>$KU@}X+PaPq7bWO{1GCX^=pZ4DE#&lB3Z z$I~+ceO|2HJAga&LY^|NYT1!bL+P1mHK<^Cb5$84_Sn|cFxxt)a}a4jAP_|u$AxJ! zao;Ol#4~BS(m~YaC+Lt3xUMUx9(oR5ERD<_6jGm@zU}7lm>)?0|<#JUhQYu$5)q0*(2ro4lnV z`rrBALm7v zldHk-Bsqcu)&915A_uOX4d{XKg{~d6(J~r4%#RupWQmw z&x!}XdZ!Xm$B2ZC&0jEp79Ir~O3f0t=)z?A`C}?S0B1insG~BdIM1xUJ*a;BZ^@hV zUwP5+hAJP>#(aO$o_Ja{|AKz|u+Jj;soY_5Z>qkoc!n?n`LL{;N?j4{GltOMDfjCg z{6MNRW;%Yr)NfJ96ONo+*T9J#FlvQ21$A;1b#p*5qLOjJ>cEG61JZlQh$tMw+yIfxE73GDipF(skCELPqTT$;6=L!}kFf zi8QWaVpw;k5Y>=o=Sr!98cq%lpUM}MC92|nm9{LPuICG?a9Oo9=zjykXaYr6{p+K1 z6I>5fejtb~d>fYlP2PC)hb0Ohc^xDWCb7G}I%A~w?EoS(+7m68Du9LUDGqMYv>gIU z+1Kw?WeLD(U)bsE9rik8d|LfhW5DhMMaO)R_BD`uY3r-ZYEI6wqz6(+bWnoVLL!&i z@W$GN+0`CD*kFI4lyE+tRz}GAQ5pE8zES`i+DhLJc!+UXE@aY(K^1j=q?EE&Ke3nD zXH~Nu_6wG>Fs-w{R z@lz%vKY*Jw26#V|w4WznVP$ruHH6Z~5?FF(_x}nRXutcs7`cE5cEaX;rUt=ky?~rgF68jc`CNwC9^eRivO{tmeM?Z~~jcH=Wqb(84@+q^0CVWr$ zd;h%{C$8MvI$6VsNd+haEyu|XeydBNVDdKpi7S7-hhRKmOjCtWIe7j3Nj|m@6EK1z zd4gD-tyhu?5_L&uKtq_i_na~ttORWqMed`#eiBYxWYUwmWENgKnD1e0XYHMUBlJ}U zG7(7Vt&OU5=A$1d0J(k2+d>0L95vJwBZj4)aqG~3E2%PPZ?=}VV+uEuC}Jd2w`&rp zP~|$!`;?4=154NCmO@QhXL|TBPwtee_Z7~(cDaC=?93?b^^stSl{^7LSJ%?G^@ar} z`AALV4sW6mUFyu4^Z+)PW+`)!$I!OWPb`@MUSE|&|1QGS^5|Z8o$?`-f)ZF(%KcQ9 zN?iE+olR6B9%UINxACq@WN@tufMZw7qFnr?%2tUBT;B2`Aw)hcsFLpHq@LwRB)B(eS+nz5jH=suO4(%}$^ z^pA5ftK#joS@Ur)H+%Sy(oGznZ)Hc2_+hMNk~zoI`@bZ}ELc*TB zKmoA{N~ewJ_c-wSao!g^i*3kgrGq3^XdkcWgCILC0L02leJJX!?|;?3L0}P-#i(3e4PGO8t1$M*(ept^ zmtTUskjf0tjIv9{P^3b!X;tb2m)n1!1u)_Oj%O+p%WEEM8lF!paMh=tQFs+2ptA_6 z*}P6+0a|-o1ugA^409WFR8~PeBq@sg~$gR3!XA;>uO$+cv3!6 zz$x)`HujC&G#`?a`E@eg{Uv@K;!GnSzWfjM0RA74YD}7~+62i$DkbuMfjk-X7^-Le zfA8S+;mmlQpKRXO5Gt3u_sKw*==;^CI7;Jx`v>QI&B%Qvko6yqDg>41%)t-B+InA; z-LH?$x3eSGKOue6bZ3*($AMBNQpe5~|8L0g4*J|EO!^~8|QN5q__ z;N0knBUUJG#p^RKNaD8Uj*Muhnqng zllpw;%p%Oh_jwXf^HnV*2Bbv(%h4smw!)zt7x=eWNOf z=R{^EZ8^#GSo-B2-dg`UMy08Qy5SPv;jYcQM`k%V#?kr^-lT>XOViFo%nuhcX4wIP z{(DJXkUadHqOz4&OZSUiIioU{CEd^k%}nmao~!hz%S&0Ufttf?S{=h^;`z!t4PhD% z7eoykn2OaG^JehTI>d5dg)WC!;s(IKEmbMLTMD#Gi$GnDOHHFV-Kv;S@HcmD|9bBEASHOw3JF~np8T;Ej&}TxW zF9|*_{2i%>rxN!pdIrCyxOTv2&|Lm&{7SIs;Z--mwacns$4$fSnlFY|-BPxYHdc~T z7WP#7Np#m(g%6(NhwiH0G`4qT!JuL@s^mM!h^7^hn)ET|v~UdR%Oi86%|l*YifrK( z@P;y5#@?cs2`5LsO80S6j;BRJR4rZnojnJAaOA942{GjAJZc6axH|DpkvOhtAl|Zu zpQUvg1&uaR5R3Db{tBpxqu^JkgV-D;lzQO6-E!KAJm5!+$uKXw>qMmCR^`Xg5~`U8KdB0#2I?Cy_kxL*1`#*pd%YgKXBM1uj;4Af(l07dJPBh?EH^2Nf&d z5>jBVwD?1rMnq3z2qkIEYwTpEa}SIr8;3xHwKuC&=pp;oopGY%_{PveV2@0y2>~CP z{D{^GiBHC1)2r7iVUu`9`RMKKxxHY2=X`vfq-9&4r3t;EI!;^^E7Qn{@Yb~9c(g^u z-(izq4R-<;vm)Ci^C0{V z1pW$G060_;U&q$i@G6}%Si`Kgnh;HbgLSt~P2{Jj<^l3`)|B)p$i8Ba&OyQrD&c<2 z(S8&)nE7x9N&2h^K;&jD^PW~ZOJ(CD4cL7bg`7Axa8GF3X_Nha<8ccBHGsc8pwisdmmNT-KS2NG{mU?4wJL(PB6g|ZoTiTGI#nGtvkvU zauQK+F%$CEzUgPHk4QJ@$u3Iw!8GRG`)FB%vHxU~L?Yh|=N)B_C}@kl`;T}CyS*e{cTVK+g*^Ue?B8(5lAwv!3qkVC6ToU|pN*N`xY7P!}rtoj7=DAeOtU2({ zT;Ppmi2d|i9S+EspPXhQmYiy3fWKDLgu~za!30;VCJ75AXXffca6$~jO37zSQdfk$ zj;3Bp%v)WA$V;dsSNB+XrWwIDv!buY{39$<7>z4u(&&Dqn zf?%Y(aPzd=Eu>UqH|!1sQ7|(_hb7;+*s4ZaN>eMiZ?}a$Yv~V4(Dad*WMqRL@U3TI z9jvM}SOdSJxULvh)idIIT;ke7ojBryrMS6VObj z-KP|ZJfw;;Mzk}ma4XrXv^VLAq3dB-DAIa?&Sr4uK#X|GH^nN*SAM`e)Saoa(!Bxx z^vwPS%Vj=5yQ)ZMFQwX8-8*FtYgP!px+GYz3=-(uj%&Og68z>79DivEMGnFrnNCf> zkCXEeiZ&H5^pH|};=to_&v|iC_QypaVz~ZcWdZU0w;d`cv$qc}@x8u*2a68(Qmt>$ zAmmtolUzOuvg!rT3XU1J+pH+T;OJ#Qsbz z`z(qIDdu!nk=@=C{3>10;Z+=MG8u_wvrY#uS7xfIfXF@kcq(~7LaLg5v>c*C$}}l0 zAnP<hNl_qJ7DFvP)uVB?5)4{t+7-ukjSKXE0uasuR`Nl&m@XnYg|4)3Pv>*kF+ zlTz3!ov@zf&I@!%=2$ufF=~ts1Xb-2F?nhEt(9+_Y)`RD-AXUN$A3EERWpqcPkPWn^7SlZfSyDEe@Fh z$H3*^c?*IO(mkw)*zYK$!ySW828VxA`bhX{D=SQ-a^;nFp!DwkYDRR~00KnomZjrN zYGt(%?ea;6W+}=TQ0oIIc9hK++G8OsKU9JY zl;f`}bBNkj1^c1kX;TVi5z!yQwep_7sG0V$=?tuU=M5tQ4B_sM_QuH36V$G7{WaX= zW9|C{cMW2EJcWv(Uo-H$jz-@)(R`~J+}3Q!h&*L;u24{ocp4wUAK7Zf-=ne%cEi=AH@Ji;G$%A261zyT`6b^z79OWruER^Lh^Xw_ul{LE>s!*9y6}W~~l!iM^#U zeJQ%$>BoX!z!uTI%rQX>bTmVs^*Hh!EVDyECKOZY9A(jWHDK{+GXw+lrWbpxDd=Ia z&k2ru{4>O@Wt#yj#&l5N)m3#W!eqTK7NxPb{=p=}znPp4wu@H?isaV9CXjpu6{?s* z#FqYuw%F24s7@=ZV(mwPW27f2n}St%0G)W_aMsonJaO!*@m4H)`bR4!IxPq4fb`@Q zrY`nxL|dq6Uq`H9&A5N84ul46IvkcGM=C=&WOY_-f=5r31yIH_ct=CRoG3wKki%zV z^W2|~LW;o?1x;CY#B-E&Fx99-Nu19)Q;-S2#)}^n&Jo;kY`d2L#bDHezdf>O$Kg0* zQohAZL#-{?l;hVf!orAiVJ9QlG0m?tkbMIguaU&&=RgQLRta(i)RlkWjnKLN?n6@{ zU331Vt%1^Nx5MI)E(7Uj=EGVqI#`V_26mJV)#vS1h&axLvq0Ri%;`aB@PVK$&3;OP zBxh0|dO_)C&-oalP{rpKiU>*d!A`KG1+hgffq^ClC++eVvR z&J40^;S?s&6IU;AbK=IBsQLwj{RKOPy-88QrCp=FQRrogxDb2NrHrBWU5WhW!QFJ= zp%w-c^u5V1oH4TD-3*9rLS zI7gzGu^o!9qdd}OdO9r>)K1#X$27z;Q^cxh)72PI^rm6f>Y8<|pg`Pn5L{;e!MEWO z8Q@y6jbBGlX0`ksz`FId`ABON+?Egus<4`Ng1rMP4Febu+$@){Y1rUc9;&&cX^@6- z?LGGEu!UO%c!vOp-lHZM`yCa!7_nJH0jO^ar%I$`LmL87?zek^6hm#Bmz__#HamkLB@WZ>V#O$@LIu}T^~cBGvm)d z;XI}UCAH!{P|xu5T`TP5?}cCkz$tmDrKfEsP}9NlH}!l+jsFV(9q8Q$I%o4R!Bd3| zX)!B?d4hD3ecJ_lJZtgt+IFxH#04={uEm?{5V2KJz(qpOtpN)VWHv$qik79=OY#>9 z%%Q$S5$wateNHv8SBqka?6sES6YUA=z?b)L#pac-e*it@pAPA8@{j64ePr^+B&(V* zhbHT=iSAtSMu_;?iA&M!hH_l;A<72Yy3ce*?wr2sQ57iIkspq)%EX@1{)&6zZt&`w z?1Kb2QKf2Azo^tmf4yY7enw#cdhRuvc}=+!uF}bFdl5L9EMlyC><{t#brN9BV5o)C2FC z7m#*w{4Fm**mQ94wnXg1FmJ>>9EX)r;?J>q5wYHtrL>Tg=~tC@;wt$J>zAb*LUUlm z!){X$Vs~X>m{?}~rwanVBHx|>u)Jh}L0sZ|yrvBMU7nMHo*S2|XMddymdV)mOBuwr{b7Es%qiRIIuG3kl;w1i2EB%u9X znV8Rv4j9OW>#uPB68jRRnb`J4uze#lUVCAH+-!{3xt-jYtTg&3Qx?QlGIoquL5OuG z;=>C{iOA=gW1Yn+bqWovr5T{g&}_?-kbtxIVy>Vith{liz;UfV2i(WGa12Dr% zzDfl^JI&D%UB81`lD7vHn#F3FQix|=4Akti!^K zlQvP`I`j5IoSEeoQvb7brG1i}Jy$A|u(rWi1}QqEFhr!1y{sTaq>$b_^D)*}x=Q<@ zN=3y@xZz$usAnnF9kLf0nxKI^exEXjFqv*4#IeO53(+d<(e6Tun$6;@`0ews(glQ* znJp6>NCCF-qMDVK3KqD%f9!z$BfQi1Agmt<#_*w}4O04vxzY%f?D~*! zs^OUBck2N#d%H`et^w~~(iKQ0=JgV!gO#Fn$5NOkwlQ_b@iv6;4s`+BE{{0DK>eFL zB?NIeXM{-F=^z2)oToGsY4S~ql>G7F*Jz70!i0-fIzb8PjMD2umTOX`$i7=cuY5Nu zfM&rpJDVVb%k{*)o?T0(zO`qA%j+Vf!irUegorDOyf_CB*P|S||GYAdgyW4S?0)`` zE(|~3C~J(kc8zsnxZA(z%z#uBtS+L_kU$PGUV3D55Z94*-WUQ~3+cwtbJYTH$f^fB z4aAO;J6J^eW}svA$m7BS(j_#79yU_HmxWOhw%hQvM>ii*HTp-3dmhfeRo_sRCIY|k z(FSD))W38oxi}8*>f_;Tf_JH1icnUeAq9I+Do7XoChrv;2!r@(OjANi{!J#J}>pW3EbgkM!GOsjRS&(v#2gW&_FW z)E(3vT6HTLN2w*_jN*C877m@9P})h3_I1;Ke9N!Jt9&)pzFV)d-{BGT>Ql6y#^^2f zpQ@lWiS+8J%BshCe!kosaRlwEY1>sf^*D3uwu2FHU>L<*-i(-Vsnt$9xwz;UpQ0n1 zu5K_9_V9Eerx~~VSl)h2Mw8^@Ep<7rdc9o=HK|#$juIhBqTGpphPDvFy4Q*-sBE=~ zv>_;Dp>*L33Sr8VQ9b@p`D$}g(N6>dnd!4na5ZFa&Y+n=%wKurmwWa_dqHcZ)EAV*+ zP8z%DKb1kxiSxG{1DYf!xB71pA50(_UEipTZPd)QT}Q$S7yIcc@9L-)zv~&egJ*WF ze5uOPbD`P**3*leXG4191P>P;VEZS*qZTXn4tz=o)}Qtz_X{%DZCv)7;>mi{evfdb z5ZB_X&^`H+}w7b7gEUw=w=nWbAS+PO2o~N@I|-504Y_GG~)pr?^P$x z2T-r(xDc(#8nytol1z3U2 zVlyy1iOODqGp0098d{zzDY2LrL z)AgL^Qk7CF;NVzxUMN)A8ghnC-Pfzq8gll33!WtqPJ462W5mwn+cjDs01>R(@@v}C z*+VQvUf+lkX{s{t#yt=#WPF?Q4MydI&GSPZh+onLHsLKaD}E~lUyp@lx!W^(yy z0WHg%5j4$7ST|*s1qtf4uQ-FmJndK@LfTIlp@?$Qv(;8r6wo_e?$kvvPd?L#W?|Y^ zx%fyTN!edJS&f<)wNVGBg7YA6uFt){?a5O}L|gk7@2jtQgOMDUYO5lN z=!LyEx>tckQm^BqJaOiKRK?KabiI1MvVgpJlY{eN*`4LQz80Bt<1OkTq^)geSp+j_ z@qSf`j$>waJ*`BpX8EfSZ?SnTt$s3jd_AyRyJ;W!XloP(23G1LB z&Q0B37$MrkZC(vg@7t$?rav~DcC^WQZbiRua{qP{uSg20XobL9pvu=mVlL837m;;GKe?e}C(eQ$hBg>;Z`;6c&7AZLHL%Ym{SX?!C>H{l6a zk|Ko*J$^hP0lQ@O#D@wOC;d1#4gz9QM)_G5wZ8u>QVim}Z@n%FL5@s+SD>(P+TXU$ zQQ&c(CSRNt;iMZ)E6)n6rhc;A@SSFmjv_K$lm{PKv1tP6%2G>%qy49HLWntfI} ziAD@HJ6?j%#8Xx)c&_2sZbUl=6d^H?$Te$vwXi??ZoSyv&Yr0UH2cgZ3E$qzen~?4unqsiAYXis+U>f)V-4sWL{d^6#+4W|lH%h+y zNYnir4mHD4IMnGF@2E?5)qSM$Byn=F_J1VUki}9eL6=3oFXmQB_;7yZF$%q!@qKtS zDcJ%@gr)ekoSjSSoF-WW3&%eGIS^*UmjO;j3IYvqpXhfNW*4+zTq*OluUz2@1@-Vg3NK_RC_+gd!J^=;# z3pYx~hn;eI&|a&~BXw0U`I&h?_0!2@?b2#^%zb~9R$90QRV(`xMv`cb@_>alU|$um z>Q#cRHJMxaIwVDhk^Vdz$9y|Qh36Y^+BOTDZTW=XtZLFVeZ474%FlB_5B802XbPgG zU51X3l&)$%SQ+7^DmpDv-Ln8*$+{K_h`lr``8};+k;j%!^|NPp@^WSPC=XZ}q!%gq zG(^r?QA=Aq^gUgOFE?Ityy$46etA%d#7$3rt(&aygU|adlsXrwm^m zR_Gx1byIa=*1Sews;}(5;CR4+So&d zjHOK#O%;8X=uB-XN^EWT8fMgzwo_uM{yx|5pEr~3y?f6+=iGD8@;Psc-C`=PfonDE zYntfObvm!>MSTnBu#O&P?@EgX;8c%YkO{Za1t)3vkREK&(ZXaPFt`OTp%87*f!7%5 zkD3)Chh>-EfG|CPb!g0_dG$sR3%o!68F2IWLo)Qb2jC~{!6_F<>w#Cx|a zcIuR6g^!NzA5uqDD(<)~0m@`-^kbK(FzpgkY{R?O;lnM-vN1?>r?(aRz*^}?Swii& z(HF4S#0#yEpEJ|Xg7IoDyIbO0PoS&e0aq!t7c~X{lrC1`uFlzqEjc)Ly<*9x z_OlCF{>3w06i4;4z1VYtFIxpV%_pU#=9#;Oiz09xy4VV>NnWA@*P(& zL606B<#N-P6YsfDrvB+7Z2S9X#)DoED-H*MsS3kK@#~B5_^*Z^RygRs>OZp0r~1x? zn7OyfKdvNgsjbG6gU(glh8Ll$gtghsI@R8SGyIJGd?{?l8y{K>#5eNuFxl!!gK$TT;eT@YJe>`VRw}48#Sf4wV)Nn(WxPKX=p*wZAZfVgj_CN-U zh0G9=ZE1Yu-!9m`YelSRe)oX@2-A8by;-tgPYl;oM&s zaixGEH8C$uM-88~3I<4z8UmW5`^ukUR42_stQi6b^Yp00oR-atb*U-4oyASKDar&u z@hB1(rdD=gBmU}tgVP+SUO0ly+tB+mSYQwuQJSf6*Qqa}MX5H5B>JiUiy2Mr(@Gzr zQu)6uZA0pGC~BgnO;f?D_W6?DOvO=+p*y%YCO{{}J0`&R)@#R+$2E1S5U)yGR+s`w zJePWiYwQUta;h=z7VDON(lHk&0WK++vELkDtw&mt->ERroYXv41ZYhIY9Y0sE^(Qt zHF?&RPkMhU1m35YPdDQI@SW7l1i4O>HN@(V-Pj4&ll!+b%I^PZ@@u$MxE;hmqPHr8NTO-d_NM z=uV%<)%%D+Y9F07HJYGZHyj3WB1@eZv_CW(1k76f9p+v1*E+^?>z^4dK4R}yAW`k6 zqpYw|F>BxJ&SZt3VNc+^_n`8`?>I$1m4@aACAzSsQy-^|X)TMH`gU)Et!$e9rvf>g z2ap0rTeq49t$bR%fZ=bo9A>*`zYiz#Av5Z{F0d|}Cnjz~c{Hc^_;CrGxm}k)2`t@o z#ABt;*R&2=X)5DSOO7hXx$28<5{)#krSy`X%V02=yREV~>H126pqr|{&1DInbj~15 zX~(b{yfcHU(wA(FsJP$5tdI2uY%?i(Jbxf~W5uSu7)m2L8P_)^eaXsK-NxaVf8!Hf z^(m_UdZbzdt4DkFIzu9s$JW)T(Yiy*&Fja?%U?ZJ-B$bC(HDbe+|sB5A4G{-+g8Or zh|Xsjt{LA>#Jc6@7VuV7a*ep;F;QvCvtWoO^FuDQp=x&@X1OF^K98Zlwe=y(`B}W8 zDATHvGCE2@4JBnP45wLNL+?hOPgjeEI&M_Y%vVWm+Yd++RbpD>foiFpN-Tc4Wqv8b z!6I+asN{B&EAt_q=It24k}#h?Px5}$9samIioHE!GDPW&XOAKTN7?`j@~XBA&Q>(^ zZ9}a4>|rK=UXST3Xw`Jwq2UTYot=}bjww~#zV^dFo*NV2h3(4SI=zUQgNC`UP<1Z# zY<4MAL}_oI-a&(kTfgef%p_e#Q#gD```YZ%%c`;&6#1WY%l>TW-}#Ndf-N`W^BGWj z{oiVGcw;tA74$2zZrG#BT)a0Ji(82SBFGawd>pw-(JONx4>&-75hx938p&h(jK zanP}@x1urHa>!>c2c0cF!tn0gUW8@Kn?Ki;Lj#4gP-rf_+?S^C(u}+`aN*G%Gnof% zVJ9|~A#c2=2-D=OLOvg-TxXigPUBm0OTsiYT^n>#FP{&7o;~803%kKTuVFIeJ&q{6 zsK>holhjwEGFUNrq$z+NIPvUzyj6{^xl|vau^o~tq>8sZw<*(1bEa=lKyCKj;?dAS zKh}es*oRcaeGR+Lf-SbqbRuLvE(k9xts+nX8{-L=M6F*sZog9uo?_7*=4cU|@TuoAnOVNB@azc9l54;Rl$l{NrdQXo18ZnV|fH-enN3 z-RgND_Ry-GEdY~z)fN9IZ}xK8$@=|>(ZUt7=p?J!FKsl0X^c<*yH%=^&JJA?qoSRDEiADCs%sKhoFZq*)QxH%iQ&UE(HkOt8YKyX&7!4v@iy-|*lS zOMR|h5e?{1nMskzFp z_4r`R_j-xya!}tvORJ%$wTd&{8wQI!{GXtGhdRUeJ=k12Kj95EsOf4Mm|533!m|4U zZ$*ts^4^QrS&FAS=uv02@h%jl_PehYCTRO%ShqxYB8&~w9(25_OdsF+1q@tgbgfLR zOm-Vo9Me8ie~X&vR52MvZQlIan6dox6ISiz?tT?gRqndY`x?;WTa?j!QZs-Kob=9~ zU)2uOT0dGe47=U?Flsi(c z4x@-IaR0f&Ou|J%4m>W>w}RP7Du#J)Q*0_K!P%I5B3PYt+_AnMpg67bVUyaw1l&ys zP=6~E9op4(q-R2J;?rHHDq`gW6Bl98oV9;-VVheuAEKA|sTotl(($t{Cwiq^f->d4 z{~zNE(^3EjAnt16xdzl5LyZR5u-EV)f*NT*gBinpZZVu9dE9*_=$%-ZUE=2}7A)Q% zEf251^cLzlP<#}-$nLf<#HZ@0Bwv<2(@m3CcPXu;;y*zHo!V|bAJ))?hk3TGNL}kQ zKb!EaM-d0^7-w+;y!M{pY(w^ZCqz1v8>=AkocKN;(F6ReCSQu(<7+WNQ-e6h7DPx- zl-D8H-EW@KLAETz5X51(km*8(zsDmLl=HP?B_iP5D%ZtWyN>o{F1=-hEE;+j0D8{wiLFaM0LMp!S{3MwzR` z%V@*MmE-INV$}Q{Fb0||Ky^G$*MlrwD_HWW+PU>IK<3_qk0ySdZ zywsDHhds={8Cdr>pHS1(f}YVh4ITf_g$?3v2}IxgSA}4RdRxnCH`Itz{~Qt`&&ssm zWc#!>><#Vx82Cx*{SSC6@TzvyOr(HdPX}n=3`CTZk6j{Cka`+LQgyr#0lM@8P$EwO zvlBD_^rX$oUBLKfc2%T^SWgHwM`y=TV2$Lh{UsdI?kUucxa2AnPNK!vJQi5GIS6L0 ze50$!ge-Y8{?{c3GU6<&Cz#Vo+iQBXMfpeYzC{BEOn7$Sr`_0&W5*Wjom3iF3~kQk ztOuFIn@vmXG!bW=gt$d*lnIhkS8%^YCLe=Wuvs}!?Q|{=Ty6vE2H|We7IbdvGYnTa zsD0H)Fg!OvsgSAIArB0nkjFuRI~)BLg$}%)2bR{IoNpdSnnbzz@}-eYxHl zY&xGXJa!Vgn;sZImR`io;!6q2T#$&ef<@9IC;yFNOl^)awcvP!td!E*LMn%ro>aKB zWY9(4+68Xf9&vq$h=YYlE_MFzE}O)|dq`e#{=!Ro0E;-(CMO7-@Y}p(z-GarBQHC! zEBAMl0|iFsdXcO6CvZ32_xNygD7i`n9FaO!b#nCtUmGILR^(9KH$(MW>g>H794Ltc zcvCYpWc>lj4r6xarpRYK^;XK!%}lLwl20%+A<3sq$H|3)vkBp*38IVq@he-bxzh_m z#=sg82h&$BKyT<`tG1|p;SYcSDCycsd-?rRXH;A#uH4~V$ehU03XK;JnBrNBxVDl#}ph4GnRM?@SdkTrJ=gIZX5)paiAnlWnX7xr=59eG>`^O zEh+e9u0erGzYfrYc*t^y3nY*fk{{v97vaQb`d!d9C7~Pm{-p*OiM+w)2bKQ<(~DbQ zLm!X&8GJFs0pM0?AzzdQy!rn@1f8c}7pZWc;(v2CZ&&T{IjZoLz~6{l-ny52S`pokbd>Mf?G#+Jt&TokX0Ec%T@z3 zIlmh6DI`0uHDToFbo~MTj1%nOuI~N(-1h}CU|#B4tR&nMIVDRE*GU6u^;57`;n{_L zVk%)aNMIfmty}^Ui3>c>uzHch-QM60YL-_ZH$%l#S#E+n`OA_6 zJcQ}Uw60vaKqOAHO-t@xx1r_AY>46Y4TTanR?rMnNsD{*N&^S|Jto&r!bgn(^34F~ z&<7t|SUJy)p4<3{hW4$&s#a#-SHt&+mJ8V!=*bzg!I!#|rxiJV(PoRX|E!C!^knJ1*Gkn9RV zj1u1lmmdWKE%k1I6E{J|!qlDm80s2^c{so@G>aCYJ6jj*s9g8zd|(nF$E(6R3{O=%Zx~;j8Hg{uO8~SZ^6`3wYsi2l?qQP zP23`ZqIUnQcFGtRu5Yc(4H8m$#PLf(4#`;}n1_*Z^H6A?xXHe69jZ?fv7%t@fb6yN z#uRrc-831)&-D^92R48-qYPO)QWXro?i|6FhUVj%E9UTCxw~D7TR9dHR~@jsVO*uBc@z!KQl(< z?3Osth~0)M{8Y5&uyne_l#Y6^0a zO?TM}B#483b4()~UN}dZ(N4atWs}L&ZUUOOUP4zTO6)BebXz!C=p{KjnZo_M3QVSx z6WD0d%b=^=6;bg*P@*GsMDTP61}+}#jkN&HTohPhKU=`W!xhRfv5(`u0G#+4YK|Uy zt5K#5EBJk-mu&g6AWXX7gR07P!l-heVz$YpzBsdU(l_aTB{!%zhiF!-b?;*IpLK&G zTY4QkmZnRtM07iZ(yHXl+hDUS5B8+&qZrceyI`4mKNsYa;pxVFB2qPQflM{4-C%g9 z@@->%wLE}^#nyayfJ%2_ccHpyfQFkZ&nZ)jdV0R%8dRT(ovIAQVKh1aR8O_Gu}WO9 zMaIh_WoZv}xUnkI|5|{>kz;Gt^if+IQ_~M^_r=fX32V7EB6EtaHNX%Tmm zMJsYnFMr+a^cYflYE$usUyZ&z(%c_5t4jx}bX7{$BGjAssB^B`*F+_*e2*cwd~qlb z4k_{Z-kNINAeH_4L1(5!xm1K@FUY&9qeMwHV)6L3X*jws`t2)$373g>6yxIX@#~aTR>U@XFd8OCZw0xB_^2ez(w@P=( zs8xq^;0t>3IWN|tWBVP##?trLm%OGn%__TAVx@O#e#oj%{P{eFm{Gm!Et5+6Zd51U zfr^xFX+T)y3{@SOAr*H%P=gl*x-z_g{h2tX5A(Iz0zZL_^3dD7t_J#^YG7UY%;$NE zm}UM2y_1HY-Qcygk;uC;2<`sAS1uosUkX+$%{fy8qGZrdV|Ya2!fQ%1Y1WmMiUdY4 zi0Wu+@{cTS|J#jCz})rq3l%X{X3w+(nRc3Y=nIyXU3u@zV3_v)_IF%M+p1WLdhTu) zWNlK@$t-A2!}P&01QILX;N>bruE~1UHmubM`<3@%$^wsJ-VYY4I{eM^gV@pk?CEUW}+GS>(ma7 zO1$)Pvn52=3y;+K{Z;aq=FfR85@SeGovNjg+TU6eRddKpE>m@r(PL!$O|>Yf4)^bA zA7fUX{BO5}KiS>Z4jN-p`TsJyAw9mAjX%Vj+L8r@V@z~5*TrR4iH_iSwKYQ}HJh9q z6F^70Kr^Iv$#thy;T>7@{@8(#MK1jrRp%qsWkg053+joZr+Fvxd)h98R+X2AV6<<} zt<+6aao4Ox2;qu7CohK*y>WH6OGA4$uC0~~)HwpEA10M{T1$^QVNmtBIPcrEkjg)~ zMKg7g32xMu&%5OSPxsYS-2YWp$$UK2FntyFmDc`IdP>{wsfng@g!Cq4hPSY4W-;{NyM7Zwxk{aX(>n7Kb%*T-hGFnm4@ zY&QM1%oHM1P_s84?g_$q1TG&t(pEvLO!67ZPGauL5-9MG zs-vKraOZ_^KXfqJ%#O9Q6?$;JKhqCv(jLPgjncGzAFJc=>D+pmV2;S};)9^Zg5$Ww$dsSn>xPezcIL4{uS9RX&CTpawQ6-sY+5W{#MO_8y%e#Fd;9zpq_j>K-|PUBi5f!L>(}s z84Q$vYJQ=K6mRx~=(wI0@HYSLEX-!dV^a`bf&QQJ_WHCCQq#(p&?;_~!-ACI>t}-j6eHdXiX;xihisMfO*~UyN;5LhWiy>FTkzpA1K>s$ z^GU4!NT(n*rni?>jr!@MRWV%UCXIMAjL3a0EO4P#{1WF?uBOcNzO?fD*F~{Ij=&V3 z=m4ilf7a~X&935_zu;UE+NrDxhTLn(=b+-IKR)G6b?KL1mbi-Ouv@L7VcIBbUN_h_ zA8!(p88p)vxA^G91ApWC=c!d-cIm|Kc^&|R*PRK=#J|$6*U-?yOTjqJPyK-ZGj{fl z!rAy}9fqj8762hM$0n)G;P$WI^ah=D&}U`fnZ)%Pd%NjWa*g`+wmMZ}UVREs2=VHk zHSum?`g<)vd&3m`VY@&zWTP?)W1BBvh$B+!Hq2iAa>33MzHNyE5PZ*~5($qNq&`%v ze}#|Kq5=4P!{}b`N1h*XmZUrTlJHw<7-Xg_PU`{qTO>;@n^a-{&xcu{YvS%|f2nnq zRo(iIeLTO2Rv-OvYg{Fkf0xG~%jcRuI@>Km*XQm)SVCGl{u8wq+HsI+Pc%f^Ro%(- zP20Wad2Mrgy|aRkHK5N&FSN*XYIzerrz+iXsi!NS_MJK(v@_&9W(-X-D0n9RrY@RK zx%R-tsDd-aZR~0y(BkaCthzQN(+vE=Qnjd3#T;8cVe%I1lN_2RqpjuBED$R&e(I%T zURAi`T%B6iUL}TJ9oq_rcI_*CvV$u2^%s9(jpPSyH>4$0?t5SCOEbfqX#3?>zbfgS zx*b|d*Q?h*2q7iPLnf$5@yC)AV~SLAy(JUoODeHmqa_TTsTw$a9}5iF1x8$Fc4g$G(2 zN2vXy5J8+&AB(EXJJ9Z!K_!0o&P_E%nsBXFtf8iSaQ`?244s`8by8bftK?M$Bj)F* z0+W`(eypsKD@?w54^(l!d@&!>U(or%d>K`8)A_^{m0j%E9TRnKJJnb1tgNy}$LNse z<+M(o10zO^?RH>_fn#Nh7_Xh%Rf#Fxlj?Hhj;VB=j5E`m)b!;-!CQ?ScJL86qKjSv zze?sH zFXv0ssei?Os77vzf!7Mup1$o?0Nv(3>dBxeeBV{kTTySGhv5dcTq|+YaJPdB9nMY~ z-k?Mh{xDmTd^!xin&O%Y+0lCB{zvc0p&+$72OCw_$!)}5P=G@;v< z9Ku|<-c3EF^tPc|G)WgPKg|0Z(M5qQ-pSJovPz$#^Ue$o!WCCy)|=?UXY~|*I^~%I zo1;9iwlPM=8hJB-j0?ZgJ881O-av1g0m6b-d|A?pl9OSpxaj-^C&{p*MI>Zd^MztK1K(%>!bH_X60}_MbTiI@k1a_*IXhT)dMr&}+f0Ywd$GT0A5ay@f8-*T7wmPCRFa zmB#&91>x{q2A;Ta?-{+9E*jk(5_4F6$l|A^?|j7EiIoIhPdL&yTI?jeI6a9nW|8G+ ziXVP;%dX;b8V$q~5@(j^!-V@xh@+uO|Jui}535kgJeCex;>Mhl7sp^n(Khb^c6C&A z;+e9trYnJS%AF`j#ffHP5t$bhbTx^2Hy$h*vV%SpWF2R4s)4tgAm;F%$miFm$^8{Q zG5A-%z#X{Wi?D8TlQQ0qI8BYV3h-);S_+xk7rg1R!_D#`q)*Da0!oPoCjlLSh`R)N zH09DWF+*urE&N*S{*z$MAn^`Z9e2+We55uF5AC3!=+gG?gl;)h*Wn)6DAsWvoEC2F zb2wp%d`5s^??#OYqcxPPzJ$%hz)bfiJpn~}gEkxSAzA`+LKWT0`;BAilrEoxXY-D+7 zi9H&o6@EL7``>snS`R1q*)_~u5)bZB6j4p*Bk+7%{}xj1>45GZSwbY^r69GZ))JWw zg?_UoiU9egx`3KVc?D|=)F<{=_~_QD$BrdbQo%bb@C?=I^S}J8wpXSDBJA0pyyRSwLSh$|j4I|HgwS)+r@STuzRt~fjI?bI9>7)CS@6NSF?<59`+u*q zC9iRit#ZHNg8Lo1@m2e7;EpZ*As1uyy`q#Jq{qPWD_4HQD*qo&G(`<`&<6vce(En~ zS$1bys-ST5nzI_%ko~$VOfx>c>VZ!$dX=R#+k4fEnyCBB_o2LS`gMV0TeXaq($wxr z9=O^zJitmB{t4*gwCFfHf9T48#xobrd4XG7-%Vp|duk8w&=AKPg8LI{53BevMIYcR z7LK;N_MRt16VsItH*uc8jX^HgZSb1z>su};k2lX*!pQ6TkXbC6^`|gXx$6IW&9p6q zqB>;b0KFTP`pbDc!kNAX74;&?j`AE2mfIj$Gf8O;w0k9e>kCqC^7Xf@=${+1SMa41 z?uKCMPYe&>JoDBUoVAH=1#i$&T~S_%1Dfq~y@~4PU2(;!nfn$>#x!zzZVpL*7s72l zxz6GRM#)E@1E*@m=VSo=d$P?yZe^DkkdZvTNg9USsWm*q9S?7mx!GTO5aS=T4m()llp31f|7S;+kNO{M#g-uEGk`qvy=PFL z;?37m|MFhYOPop}zb6i3PfC197I?w5{OF5%XpuJ#SdzruR|t%urrme(NHIGN3p!pq zKAJ#Qr1KXdw%X6r>@6Pn|(gm*p?&Yp~gK!S)`b_Vj?uysJe&Mz(soY-P z5o{^1xQYb`eC-S7(75egSB(0;-OW6&*JgCaJvRT;7gNwy+GX+4J2Ri@DZMnS36o`i zh0FQ~kp~H(K~(d@eHMZk!#g!p_jIJ96s4wD_&5NTSG|fl>C2Vxf>C>KD)DG3+)geW zMhnwDGQD8m404w*H!D)~qoY;@Ci>P}2;424TNoin2@CKPE@fq7IW5&@9*2^r?OZ7Y z1r9J!Z=ci_+y9LNvvH$wEiN;bzI?hnv`A$09z~p{&pU+sd4(4sQ_{gu)U7r4x*T-r z2c0no-8>$9BRA5Or18;y3rYYQjRAEc_dj5D^;XlE*J06z+p#x=*A~F87SYv172Z6l zpj!yNh590zHVR$$s*@wxo&-=gEh#dG5Gp-Sy(7RXzCY?JRBg5N zFR+3cn*hD4qor$E(A}Q4NPz*b{T&Nglzhp@k=Om+n>dXIc3fjSn{%f@k4mYBHC#Eg z=E5!|RFyCOx+E<{4V@qB4FCW#;jv!NCs>%1pZtfLNJtLw0?_79mfy&2|GFTD2G93N zgH;j9Vop2m<_;l}L4K-%@5(cHCM~gY0$~VRF-y5-T-j9#F)nq z-g#0;p;qv_SG=wP%EKDDkZbheN>D-`_w8$6{+xC}@Zg)bTyEOn+plj)D(;^>g=!9P z&V8;mQu{P2Zo+goa6eSZzqq52!B@||M#ptB_B)~IZMtymo~VQVyxHVJQt{A$rIhY( zaG8%F-*f79g@&I0pHg9_EowJ}78PsH(VJP?Eru5Q;cX--?%yH!&7|geA=QGG?^}z= zYrB%xPC|r{(;&uuKLh7-!zxBKh#6(+!`J}^2x4PW)m-9* zvglSAB6-tTQG`^poh42O&FE*5(7)vhgtF3$hrGQC-Q(s#HlhqFlE~7wSc>Qrd(0J~ zkM>k#XN;V25zMl`V=t5$nY>1iWWRZBfNo4qekO=-)2w^f^%6P!tKc3&9hY{2IC(9t zdLM0f?ptub)OotAi015kj6hTS_bdTAw$4QbY@NUy&`;Vl43O7!$H2{aD@NM860}|U z6<%8v7_W=?(qK947wxn#v(|ebAAK7&s`s*hc(`onJ~`x+Ow2TXH$l0CC`1% zM>6U5u}pgUCfh;+w`Uv-+NtSAbv-iEt5#BYDZgVdgk!{qEsQa4M!K~T;ZlOX78!v& zoF>Hon;@%5>#0HP%nKJWASQY22!^B+nAI7IG^{_&lu+RCAuyVAXm6xk0KlZTB0v)_ z?n5t0A3H$y?2-kTP-+Y!u9azO|9!)&&<*o(^*2terfD#G+kt500{v}mmnG!M6a3=J2k zeh);DbY>(&=)M-5V-eQx!aT{GvzK7cBxbcfLSO!UinUmCK6t35 zKLx@mFRh6M@U{FC3ueD}6+6#ney7Dj_RJSd2AcJY84n-ts?EUL2Y)vx$kEyAH=>lf zKDy03zdi2s_n_vbo?vj(z-0z!ZMr`a{AtP^g#Z0pLx^1Nc#i3J{{5zE_;i07))(hh|dJ3U-i za3yKuQIApn8EYZrtfhhNT0RA2;uCud%p_69f@R$8A6aNtk|kEG#4T8BfeKT;gCULR z7gof`%dJ9S3sRz1SY+DxX%?odQM6$PUgtMG7$mm5WjTuGv|&I((d2~Bf&U??gve+r z{`3_{=F2?oF;Lxa)1Y)rn{Pvd_iufg=hU>k90`lmdMAqY-o1Mz?-c0Kiw^Mp@T3oe zj^wlqrsy`^Ea)(M?YamQ(O>_>Nl!K1XO_G9>7+GH)X8-COWj|BSshCz>5J&peeLw% z|679~LuB+LY(=HdXXAQj^a7}XJ40BDo1%(t(2zTq5rhow*@3Iv=sc@fkbfa?OUC^PQ&MotkqGCLb({#saFWDVq6Z_vs%9Gd$`U8{z@JV$N zkc4<1w#Q~z6nlj>yi}b!pWfvY@J1R!m@W75bf!AK>-_@E=Ix8*n0li=#B_>d7WF>8fnb&~2NB$24K`NDkc z2eo<&rs|}8KvbkQn}H8^rn~li$UxT{OSSm?I&|2HZhDz!PDEdaE~ss7fS8pekBGwC zDy^?Gi4P$u=Wib$sY~B3+Q7W|lQ#ay+jXk+JN}F6L!WJDJcYBlvjBs?B%S28! zDU(ss-vc~kD$+A6J9{E4FS^tBE3DUzuAf;%Y6^dB$)|_SJ)t?;HQoaEHJ1eojAT3& zibl~|B_Cnkqh&8Mbt>s-y(4O8eUh+3h=ODVfS~InMkZR-cs^6=v zNH?$_oEL?iDpbWo0&T8aB*JY-*Eq<4g&wec;R(o&@56;r9hGKQv7tZhm&IPPv}-Xm z&cmj90}0<`kuEOBB{)sUpytK4)D$bh?x5@3G3urHn{F^>TY1ezDLwU%B|-yh7qeRK zqR;-Z#E|p%kfHDRe`r;LZLU=TVhqA@K35ed}C4 z)4%owz2R7zNd)@>s@gCY^09yL2Npyd_XoCQ=Fsv|mBLM*984;p1N&EDRXB2u(^#9S zdGA1arQN&qS{g53$dszKXJ57(L?$9=h1lPTGEWgD{dU1ZNqp4_N_+15a{OFaHiudbK!v`dDz{AE_3ZvM6W)MdEk^9hS@{g5} z`~F~cG(mM6j)EJKy>~@%&|G>Fn}%GWZJCY?yz)ART>cpQI2UsPL6sb83mS0y`wF_+ zWDvl~TTpItC)Qet%WW@&S`udm!GM-&<6EVHcT6Z2%c9b{_m!o@uoYa%b%Iw2D_)r( zF_5njM3UEBp|lN9`nGtI)YRj7)Q*hqS}vTNm;Z)BES3DkH5RAEP(KEFA~w8-6uIJ{Gf*A8pdxQ30gob83-5 zGr?C#6P_WAC^v;-JLysf;-9GYxWquDnSwNtN}+`cC)#MV22bnOJp_*=3w}`+k+uDy zHpORx^%FFwZUJ+Q+mDKJWW3g_tq4)hx2}vMQ|2INNZJMW8fldWhU842@lqQ!jM-^1 z@Ezr&kb6Jl&wA2Jc zkn!)459b~VzklImW3a=4FCuF>`9AOf=AEFo-L^d(~(lgBrkf znW!v;x6?$~YDEt8;l^A9P*Z}ACr-XBL0+zc=_bZK97=1pVBF69=I|GAZoxYh8F5?K zomOuG|H@MupdQ5uyya~GE&iRs&2!rqSe!_eoFF(UIhd6jAbILs%ogEkES4_DCpx09 z*_xo0B)SWBfTfnz)yJtkab^%K+_JyIOMQvz3Y17JT&=)FNraJS<{G^lbqo1!p!arg z*{QEZf2cM2avPVH#^zeEIdchLNf;AZEl8b6Y>OavB8K~DQ%JZKhyW$73xUq0T6>#= zjtFXC;D#?Kfvx)vGoRC9E64nw}@HDJ$fFOYycbGpK*;=KR8ofbfw z&kea|n$g>yrU4$7MuCYv`=%s@RNYsFF>-1Xtcz(2kT=&X+vNk8YYy8~xZLf@=gf}z<>~~FUdGsEX_g@aE3hCd^ED(zg&6!ZftS~3YsV}3Tz`rc#UuvsH#Pa=8 zk4UA4&v^r?g?t|xy`^ z#_@()By>f-JkOAN14mj`=%{IX~gZe5IyJWzsu2;aE z{PQ*DxTbk?u#j%p5d7TUYTDYl~gin%WQIUEnYCJ{3Ja^;2G3jrP?{E{=<#%r& z(y)1*F^6nxR~RQlJbKX7TiqBS*;|a1teuS?hzsL-R14&?4sVmvT{wNU83NJP?LLjk zNk{+OBo2fHb7j&z#m?ID+g@g< z$Z{VBm&Ki{QK+REZ8`>1WZZCUwvlSM*xM*$B<~EQp4(h3lcFU8awW?<7NZDYoDlCt zykiBbBJyn^$4m^7vM`M2<54Z?-V@#XBz3wWkJLM%$1JmF8sQh|uYgbMcWhyRuPxLY zkQvdV5`565^KrjW7wlWRF2m+_HnBjx&URuW=WHjL3LUW(no0V&tsac@%XMRj{PZVs zDF}C{1^laXp>^uqeBHVdsMs=Tw+D9k;b~=B(ytd|CBF^Umb6ZAV9edGKS z#|vckCd@2@ObK{vK;D&t1}JYbOmg2Zj?^1A>sugFcM7(gt!ykCRnQ%am{Ld z4ixT<0*SnQ8+usIUxO8sp3a51aRWB7MdI3h%#P_?r_b53pKBs2OmL^|El7|Zmuxzc z^W0`7=X!#@*8gG@$@X&?=QO9lH6pPG1$Of22r|_jD%fZFkBxCM^_F1PlA?E&l$_dw z@ygqBvES%EuMKtMyc_W7sN8rYp6wjnHVB?sQqvWp^2=hafYHR9e6k@jXWusZ z$$nbEku%E?-tUxIU?49hVoK83k6=0-_TtShl^_`Pzc89f)*pH+>Sp`D2L6Bc66U{% z&SX7_h{nS+(Wlvh*;JSXMa&iHm?5sK`5Ow6sA-!}VyA(QZA-xPO}j#6IO|`;NRuZA zmpBo-lr14Dt=^*alCBY(mX3Dy>&5{uHxH+HY1R~dh)7q3oNN?Jjs^w6vgwJ{~K37M~A*vIUQr=)YWWk1wi0cbupW8f51)f5nVF2lz11rUXkjg~kz_ECirnSB~`yYo~K)x^;oYnm73L$z?49TmiKeDwzl z=qF26c)`7zq<2zNGgGNqF=W;W>d z`$_{b&%#Tt$Lof~{t8ArabCbTQwNlBF7c4k?ps^IQQfn?K-I+eGYB;3tP5J}LS?M@ z1beZDoT^n!iEjyPzSyzcB4Wx0gbZ=B2Svsh!$iCy*!vUnBQ`f^QQE+=EuI8_WEJ8;XH*W_3V>JuAIH)k^A}G-L>&ZpYAv$kidz`PQlu z7iO6)VJBWD8nMEe^g<&g?(QIfbQZIi?KL_{;+H5)w1_Qclzg`8Wq=9|F8i zVoR=_1d4f6AC#=!1rbeNWe#z722<2LZo|En;SRCmMmHJT2#hW*!OlB%Jlb zu>gTN_=VYmbA#y(rIRGy#>KfGM7?wqlra>5MdFD9%+!F}$KS!?PL*J^_ZSE5+;E68 zNqjY-0?!;!hRDgA$^cQdHKIRFL+IsrCQdYcyJIg5*uY-(4=7E9OhK{Ob|C?7Ieef{ z$EngybBJ{fC@|=6e0*aj_9%l{2x-XDPB<};9fjb)Cg-Z^xEff@OOs$e-@$C!{VjMY zk&X!(_5rE; zJXq;KQyciui9OTQo=r3fT9*a{XK$j?;X9H>Nb=;&@sbeb23cSsls?38UTpveXRHDx zGF!v<9v&Ji0y7`xY!Z?4F(Yd~JnGyote^S1 z%|}uT7>D)~iu#ejhoHaQmpH$0%Dvnj^V_$Ql_2&@u2h~8`1p=vSu9whqx=*{KT&-c9WKMlxFVa zLo?a9vOr6g4hLN))Ik3PU7!tWc^0zC7Y{D^V>j=IG21OvWP4 zT*wjYI%Sw7`WA}BS7bC0`4Gk!?ueJx6Bu5+C)Vk~9~fe%c=>}B(E)_wuP z%?In2etF2!ZMU>PmhhhjF#_eLC zD|3i;F<7}Y4Wb^H0Wvs)xn^`U$W0JwY*pZ*@;+3M`v)tLD^q$KaVybTrbDREtI%*< zdVD&`zJ#T%JQTAySZ;(8sf!1m9GQz=XRsS7@#ZNVT#tTX;)BmiiMy8tNb)=$#x;Wp znnWUrk|bzVEjJkQl{kUrqU&ri68c1$Jb~K^6_MCAifOO(gFxAwWrN5$J!ZB`)@BxNCSi2(kSZX!_eJ%vaYe*H2Up zA>BQ$;?{jXHNvlW7t7AoF(wFMDklD2fq`sXfE#2qQR)z9PAs6DJrnCIJpeCd`EggB zA3rH-Rfzp=9o}<(#sUe}Zy9Ny=7K{%D>R{c)sc@AZv}9%{Em=B2J>?pY*9VP>>h%9 zm_Ej8$6JAUOxy4<=Wb(|oGHbprFCs7a`-)?j>H~;yiwzcj zU2y-@Z9F}@4~Ub0Be#h74&u({8_-EB*Bb-m@Hkr$nYtM3x}AVvnr-++)abRA7kVMZP!7<7xk)gUIf(m=(`e-vhtdNWrhK%^D9AxdnzbFl>6Pf8sb zmxpg>{fjA0@qx1rzpa!>`3aD6n;qmZT?Jtblks2CDLg*gVT_Rd)4&`xYlDjRCYVI( zd?7Z0q2L3}pI|YV8Gd424n#O|$B7$`&4qNjWu=?5rpr}{HwQmHT)zP7S7s0CVv_(g zU6>&5p7rYGrR(<;as0%!Tiy3~xbFgL=cTVN0peaOfGmYp+Qy`h{Rir z!EUTANEEV+!Rz8+llnvO#G0QM2FS{T#cs41!ZLH41*bsdWUh|Ls8Fd&toK3l@LM)C zf{Nyr61x*ahg$cM95z93*IbU2+iWHxeGCrY-W9{0yGU6?4!s49dKGhBuP`RLT`f!` z^l5>CbY6?K{J8^2N}Gam?%o)IwajKFQ~$MvnYvXH|2vQ~vcpJ;xKa?Ig_1T(#x=)J zmL~8MvjDD=_Sq67ygC<5pN83#z6;&(@_{l=dd|X9pBs%aig$Cto1&l@MWm46H4{-+ z79i3fAzYhSpBhE3LO)8JUzPc=P1`giGzctj{*5vJE!=GTG>F!q$7ODE?MNY<$hQQ8 zl6<-XgWo(7G@arv^pk_t$_zx6ZS<2n9l%lk%SMs(5R?WIm;#a7W5sQ1zKbtMorLay48=RR=jU409X#2B;aY zgiDQmSp2{rHXpK`0}5DZmf?BasqY2|GW`#$ zzvn9umlw(fU3HV;PniO)7Vn2HlQr=R)ZY z6Inef7g{!IgD(9UbZ~qIal?{R@|J+FJMwekz&QZ|>}dmTy8Q<(CmYz}#IX(p7_vq1tORk->1&F&Xp6C4%?^-G2d}NS!ZDFZcczob zK0I^(DDXpR1YOS$rH7Xj%^9PQXf_rki2Oake2H#rv6-lbg4Xsexp8vgJDY>#6d1um zlOTpTPvnrh3M00uNs!O-e+sq4arys9y7B;*uJ3=t4L8JyXFL&GrbH74vBy$VCMrRZawWO-;D>Ir=zCzKowiKf?MH~B2<@dRM|70@B z%X@b@=iIY?jwY9OeTGSxWlKJF8*%H90U_-c_biMmb--J?br@!318(|TbKc@N@lv=WAmt1U`{uo|LRd`hXtJsxIYcOi|0+cYsl9QlEu4{r+xhp2d zP+heGC=~B~?*R{1<72FoBa!VZtTg$L500tY7CqIDvOu56!_J&s1PbbD!Q&VIjeB*e z#`E}EwMQ=knksT4FD8qxUFmZR!@on)k~g$?k;V?m>nG~E*S9537Ld#m(2ws8gxRx=-%8xBWf&_F?~foap0o34Qm~m zi615xqMtntcEr}VWjWbYdmdY{*d@x4JtHw2D!R&xo-(o|JM~@S`#i z?k;Wf1Q`z+*`JF+P3Vc2U>!XD*>0@b+8fy6a4XECbVY%g8jS@G8asgX3vUB6%ZJ6F z22eQ`*b9ETf!;&GGuD3S^ zQt88-2+f@jdJBu?E8&T4=7dT*4@BQVUXj`KzRBuAk4Er z6tk*Ozl@7h+d-$~p(RMAAc()bwi78#_wifZTnw0XgAYyN(s`KY)N~TaY7D+gwf(J;Yc#4F#MK2o(!bwC6b93o0^POfs4XY8+&b zA%z|>Z-PXWJ2`L^m^3z;ItKc`bQl}PIys@@95Xm-kX53!H4P8J;iK<|`TfUzJi2Qd zD7~*0Bx$S)9;WY#HCJZiGj@Z!{x5|vAnC3ctw9r`aW^F*#t>x=+_qz;Wn$Pvb4NL| zsDHC2r6rFFl|Lk!YKsk+GQ|fJ=`l_ymbVHZoiG22GhG_)Gt%%*ON?HcX-QFOr3P^& z-tsTf7;?ek11X0sPQ*Kx<-k@OggfXAAR^r#(EKkMtf%RNb{d$NKj8i}&!VTtxq@PQ z1H($+Sq!r`1Ir3^IEo|9j!cmEoI+N87XN&>5U-~-9(ixxRtIwxA~4sGMGET*w$@tX zh$HW)PzDuRCO8_gtj;+CYo|3jS}wtd?x886ysg$TA{J7?ah9Bm1hDAniOccNuG}AZ zTlwU@9%8TojSdx9Q)Ybnx0q}|b4Ci;_0he#Go0Sxi8(@fJ?7tL6H*N+F&UJ}w9ZCB z-g1Z%)Ryb1dc4k{OPlWs?+WJox?Nep5*TI5_I{#hMkUB*uqWDD~Gc*xO_wQX?>(J!eB! ztiJ%+x9bwte1Do4u1fVyd64~~?@vT~*#2SH1XnjEWnt-=d;LJr@X&*JQAZ&FE~9IX z5xIMx3#Hic`JY3;EZF5s(J9~HiDe6fL}TPeRuzeflB8&zNS}5UVsOz9$?~LVc)F-- z#H{`$n42}(M=%=UkBxJ>v=$vO`2nPn0eNsYS8awPPI?iD(6t_uk%iWr6!Jl+lgl|C zg!O41A?sB@flU*F07t9!J$A-8t(7U8X5SRO=b5he3Al>Q#&poO{(m-P*F^qkX^*qy z=5`)G3-$O)jiQ0}PwXk!+XHj*sj)XVaHn)G&ZoCM1q$6YHU|!Z|H`5a-?UGcuyYbukyD~$Cla#sJ!SKr{J(Wa8aENSR$-5w(RWqlv9PHooMR!dc37JTpwKZ>31CYUo>_RQJb-|bxq zE#vM{46N>G6Jm2ay5{8~dBiJZHD=P^yewAEuNOdc_N`YvL4fhSC8Qdm#q$UDa%Su` z1MXVmu4?vD=GM0sPzw^SEIU&)f2C-Kf`n9g^c>S)DRQy6u^KqRo2EieN`6!{A3}c| zb)F7P{Vg`n*uS>j1<GJ?+UICtnsI4-Pn<> zUwuZ1bYMMc9UKk6mo}nx4ex@6K)t<$??cebrKvZ#Wo(L@zO|Vi# zE?VdU2e}R37PFAbehs4ueN@$M1ETLHj56GBABZNo?-tl48GD2!b1z?tw4T%q^tXdi z@t?2)ZYeqAJkiyK}JKGD{O2uQKB?2jV-%12r*vc?yp$D_hQE zWk`WR|2AOu#Z*m-c!G3|M#{ly6K3X>0=_o{L4DMeha9Q4qMV10DbGEae9O7c2>rLd zJ;>ai_Co%v*pvBUyarX~i0-O1vBz#j2G992=zcz*nUamrJDh5yB;`%-kP%~~!+`== zvI8L57T6%;vhQ0$O!vlJRXHQT>@;er{0)wQWJkRC2jfL5=Af+P1MWq~n#HP839&0+ zSu7Uw)9B%1=!3~6&~{U;L{~GK(rBVIcou4I%=#zaRa=6_$YL$P)b5v|o}W?v^v_NPuGO_gXIRIbT8SSN$L$T0H{F{GjUKl0^Ly#)m1 z?#lH6vioWjs+$ioL2h8Q3eDUH;Z3wBKu5-%@JP4w`LW9Grqun8=!XUIrv@kB z?-)q@Jq>JC1Iz?s6c~j3;Vng2+IXNS0?1bqh%)!VHtIMq@smYA$DQ~5(NrKPQ__>z=t5+gOK%g!@r z;RGf%sCBI9s7*I7wdXTZdJ>jjlVAw})?*EOh!UqrS|LaGeo;A-lKsnqbj0R@EGmsF zwo&5~P;BshSZoa#v_rDcg3Z1y<~E`3KXW29{2%7Ecsmp)`Wr6nRTE2dWDOr{Y$D9n zV1~%>?E3|J+O{7qPwgvk)8~&tpQyeaqE-MK?iE8Vv1ZIb=XK5T(#Rq3MI;aUS2*TG z*zh74BC{R`si{}b7pHr=t8GB+s|mhAbk!K7gtyuzfVA=ZqJb&FnTE{5Ei zhRHC&F|nAKJ{P5KoQ~{a$Yctkf|UjN-moX!jy(v7ewvt=Mr34_GvN z8+>WJ-Ngga-*^r0rBM$(*hkV@Ol6XThFBeRic4hB?8QE~W?Wz{Qt5fIk-LQOgSWQqaAn!OwA3%` zaqS6dS>v_F8TEY}dnHKEA-@rw?4N=ilyu~DAp1~tjb~SfrA%l&*41Lx|Cs-`HwCW% zew$h#(Zb(z;&f0gNP(+A@nbOZttFezf9{j%rVHJ&v~s>NM+kdZ*H6d2Ea}``B;?}HwR_-wWQ9txd5l7#*f9YlUloprEh5?cPG!z2r}9BGt_|ii}8q` zlYd2BRTfrNO0(9`O2aRmNejOXWUj|mg!lyZ<<9TZvU+RX!IK}RmA|Pqeo$EfJl6*&;uJgbPgdsxaEFAU z!C@KvUsQ#7n_r(Nk{K62ERtZ#d<(`QwFlxLCLWtJm)sMhU6B2G(nEmf8O_5Ievm>^ zwS;Ww&w*-E0~977on02C;s#$neSanx^>!gI0#<6Y0Kb;*RGTqZ4p~e>o%3L0kdK9U zHJ18X&nrdiO*$vw{N?I!v!?0XX=itpWmuV|!PzwZcy0I% z$<-}e8?W1-dRp#yt+iTk1a=^~ZYIU2((0yF`Hl~n|22RdS&t1#Jaz8G(}J}xd#_j{ zc-yjBIcr5%Te_m9pmd>?45IBevbi=uCinH0m6BZsrlD4+Xly_?RmJgj%TTH#5re)F zy>>h&!K1nGvG*^?rVqS=6=1eY7K7)*{qVv31Kskq#Q))sCOtEcMX6UcCcV2*(1|Qr zI25zd@2JVU;+59vWwJ4EX%oSXJikDLK%9{e98luOXZMQ2Xm{}^-n)hU_&jX>+m7f; zM=^T>+t@f$h)!gGX#)W_yLw;8^2Io^chw?XzSuZ7&E?gSUpL+GNZPsSz7u1uY*dv_Y6ps#J3^Xfe^czHt(z2B z=`THtaI3`3JRK6dx|Sgp)KN&Hef8?4f;)|7ZxFp3nfE|>K+@{()()!N0DR)G08;-Q zCMyd!I0;LIq;!I!(dvw^%m7%-J6HuuUV8~)TeBwz9npPv#RFpdWSN-D$VZ}g1e0EW z&7NZ66})95>EU|Wi)E{c(@y3KI4p>-ir}sW4Y4xJSGdf>DD*!pNNLbpj~1J0xC%-J zscR@d$Nd$=u$Ig*B#g8$g{Ke)dZsfb|EBUlx(70lJxk>-1_*Al9XmrNS!yqnC++b?>8DL`1Z2II9g zCqzv3rUZ?yn<9^Mw<(M?&JIEnBI|lJ6L#VP6GIJXhxM=}ijL#3tJX^mrEKXNFd@U) zwM_Y#)VqNw#X2e-sIj{khC+Oy0DNg|U4&C@-9sU(Ba;UW`Fp>Br9%uOVE$h(s2vFT@-rRntU>vr`|dFBdF_=ezQl%w%V$B zjI8{?NA@s4Yd;PHkZ9ebt zM^Y=t2ZX_#&1_mBw;y}2T?#An&!J*`Lr(Nc2tkR>+5D>DsLh_$=qVUGvLKSUY#mw6 z{tA9I@ws0WMZ3BW=Yi~$XV=Bjjx_PLKx#4N+j%f`Ps$a*Cta$I!+ZJp&Abo_t(ySF zRZCW_%}z7-M+d=)KgPAvnWs_w3A>^V(p)~RBrBJ|Fv{JGIG)k*vrR(G%X|k)IJ4C| z-d8BCp^fxwwYr-FE&UQOW*2K8Z%t{*sLinT-(aQxt>ATA6C{`5a-*5 zBiMFFJ)R|9HVm-N2G+M%&;;-sWp7@J)tg?VPBCTnH9=RM{W|fW5b4hT*@4n%dUd?U zs68EO^qtDZVmB5QF}n3RinM_)a`OVTjV2S@sk3SREm69S=BX;s<+HITG3wf%TrSFD z`X^USS?u1{RiKk=zuBQh$|r6WdD*#9YLy!zV>#<))yh{tXvpQm>L)$zHs+6y7J>|( zD1)&zE&okKw&bocLIg0zg$CPvIyCG=`1cwtwZp4r6JzN=+`-dMEL@7IENR{b=7IFe z8$|%C+Rb6XHzG-2r(r90EZYlfCs{WO!_qwUZ!~;v4}F_!ox&eb?!QPg|6HoI;zmpqd5pg&Bi_8J^Wm- zA(`}~m{lF#_yXWVwah7}(NA6`($l(dJpJ%#ftN1+f_Fue%bp5hsCgOB!Pm+gfd8k; z52E!b%DJ`_nCa)A2>B3e-OI43ktX*7u)O~MMbN<>uL`(z19Om@&<3+)G37^jQfFRb zsvO}J9lGxZa0f=c3xc^SGa5$WpYXy_AQ6^q_ic%l5%nv9AoKSGXqO&Ib^k$>DfxED zqvDf!dX90G020o|zM`!TjUGdoWo3q-XqkNcenE(y9t}7Vx?jhk*a7FCU4!P&5#_pA zDA84mCd1H$VpVv?tF#UXe6;uMvJ~y5E_Tpmb-B@6n~6q7D|}*4Fp^gMa#bI^R;-|W zKHh|UWk_zPzrLo7v$@O-6okyH`I17b8kFs$AI4v-G`Z?uPx|N zn{lmT5nP*f*4kyHtr*Bry3AAJMh!m2;kEE9Q-Vnk-p`8yVC4fL8x~pO7v5`JIs1fn z%a+%D3hI=vRO5xW@}9>fdL~QT1v7)}#089zAJ;%&$^diK*JQy?RZJ1)uksoPt_VNa z2FgKr3kz=A_IKdHrq=V^ z$L$^-bu;`chO5&7tB?_=HMm+)u@0itWRgL@n08tX9qd9as1`Etzp(SERhCjphWYd~ z>4XP|=0A73VM_lDj+gfOTvXFT%x3h)EQ^aAH?ZDRY9oe$K9MDs)&>flW)Z|ZQW=r0 z_S}i+9IDTB%$D5(=@w)1U|>qb7o!JGiwc6Oyid#yjXJ^F>OU(2AjiGgJQ$ccx)#pG z33nd^qO9J%i-9mJFP~QA*XEY*$>Sh5lev4SbunzS{ad+hy3gXEu47_Uq#-qK2#Jwf zn|viYKxQRE)XRwR55a*7qK|_}I;K*IC_i9s-A=m|P1gi0oZF)k+zpuYekXXxSgjZAp@C2BVMGejf{eEse+3cCCdPTfK&put>#+&;ynqcrSjN5A@ss}%JX3t2`+^i!}*;%qqfJ}?&G zkgkiDcvQ?1ct>@mI?b)2(UVX$Mqlyx%Bgq-&9Ah?@uZO{8yOF}S7{_*NuY&*=&i+& z1chbxZR7}tq~>X-i@sBsW2EQjBZe^SPaz-3mA&ggG?O}uxx^1=E=Gb2i`;6(qsCRP zOoFfvPrm`#m3(qekg*4cKM>rEy%46tt+`{~!vd9=HT!-(cBg-h4P2?|wEou;R1Via zgBuXJ%^8d-X^1bRbJl8-w5O+l&@Ru*;?&j7XQf4Zb4uy$#ds&p60HU@#z3x6-6___{M?8$!Raq zH__V2>O~3A=H@c1BH~o&Qm>F90?#=-fwq=_TA&uQ+Fe09QmTqhf-CYDe8J1 zRJHV&1vJ`MB#c&BRh-2;Ewuq|Kd!m*K^YPj%fQ-FH((Xg-#_soZaD?^l+<1=K?z&| zPsO4+e?|T`B*GgxRFIj)kRC`u6E>`4CW1=NRkTO$cmY_2;ok6^WBc4HNY#r! zt3%rG*j1CbO17=WTeu)N&Vz5pi#OoBQml8wL+R-aL@M}dkb1%_GP#GQBzi@Ml_E8M1<{?@ zWyQ5~M!b%Dby?7xKmTak{`f=6zJCqB*N(*SWPeXw)VIbPxahmqZSi_xePceU=Ga&H zBFHhBkJMS^pFh-o>KeP~x$QW#}VY6K_}P#OC8aY&Qm7Pc|CWw=`i3(al-^TYKT;`(%7u@jcaVgr6B8@8ItwQ~KIz4%z) zc*}t`ke)4uqAWjSSX}biVIQGcHSmMV#sOF-VtNEG5>rxT>KId+Vs3C7ecFLTI4k~F zG1H%Kw83i+KPRFA+Aet9%56>@RBIrfp4CP`;mDg7H?!r{MuAq_D)6pdBl4#hlucI^qjd|lLfF>e()}OdPqJ{} zQe5`Oqeb|qR9Lf^?|6g9AK*{w#f~6`9CvX(jx2mF&#bjRswrcUYzMpHH>~d|=%fBV zS)iQAk1aps1n(B_s-WKeSHol0%4e0)95hAUv=44Wo_%h|>ePJ#y)yc?#mur+w8W@s z2Mb|qABxz0sT9=fziV+*5(JT-9_vyWnQqBEI~F=~)4P1PHZ6d`RXX*Pm6%7c@YU5A zrPTYzdfdLe&La~pm|Bz11D2L$d;Co49P@a!(tk&W zsT|m?pFK8h_@~Ht+@3UB2tzG-@B0AJO7FItjF~C}IMQnPgT87%^H=^iphrJD&>mCN zqw}DyeNzo;tlZ)fjCAEieT|C_E%hK)wp+lD$hnj+LH}17R~x-6@%zxSo!EQ%#19~= z=*lrFIrHc7i((M5@*7>nGni3EYU9uNv)#VB7>>~XU7DTbeo*t?bPm8?eCqTC@XOE! zlYk+vxGS{6ANl_3(P|re`fL|ot%FN(nNo93C43{b`tc`~O(!oH?)p{b&^9L(ud1># z2i*AjGHxkN9?~nJ%F@26-gXIdv@ictrPqZA4L@{)Gr)TW6R7<68##cwEGU*)?3aGn z*|6c)iCArKqb*CY+SWSz)hX?Q4^RA{@@x0+dZ^&5dQVy(!-Y*ZfAcN=>$`p0A^bUU zfAm4@;&Rmvm03ruYwCOfin#8W@io5NaqibB?$zP-+!B}8@?HhrwqWTOBM#uRF8?0n za%Sp0dz={uFEM2!nMR-ILWjlt62v99ZZ_qkE#Wt1$e6W4u_c=us1>F(EVApFeB%P= z%wEO4;j>a!Z-=W)DZcRz-`=@0&!pHK=!XZ%t^bwqAo9B<$IV)QUmLC&{Yq!2qgbB{IaiBt9U)uPpp2e18sgRc==mai zr2JJ1wvWy#mQXU46J?{Xb;6Fz<&l6xn>%#j3d}**Y7)53{j~1;oE*i%2WMy(I{KS+m@Lc)v_wRx@oomv%`Qbn7 zEMWP*s`v+%_rNa8dev{FCgs>LoJv z)B7GXbC-w*_uCz6E+U zGyjya@RyJ)lTBFgHOW?-;*aDBMnsdOk4@Nl+f*!%a{WV#nMMQnz_`VUw>^Hr+oWbD zUghkLaAQfMPk78sn(+*Ci5zSI^ER^gusX)|Zl6Ivm#1jA6z_jGXh89>K*0eaA_FjuGQ-8c+mw}wR*%M~z z`mX~n?Vk@;em9n|&IcC8rR)vabU5}9+n zTTn+xdbR~zNUm-Zy-Ih42^g@Y|MxfLmF+HNl*^cYdG_vFkvajk8bxtP1vdzVSEEv%TVPft2>e zy!ZF3Y;0EbO_>4zB(q$C`EWJ0n$v*n#zneLos?WZW&y=?on! znRR?DX!Baxf7sck|L%a9H>diD4D8p3XKUi_eOKDSTNxAA;3~Q0g6@!H?6v>*UxJ)p>CcnFe zrI&W{h}C<`CYmCw$BmZYjRvdunJG8_$Bny?yVs6jk3T&Brz%^gINoab^F0(qa z@^spK@9^bVR&uI3H%Hwq2XQ}#)NTt5eW`D;;I7KZ0rc?2AN4LgpH%PVal^T>pQ$D4 zM;xD7w+o;K_ph*&vJSwoZ_0}ObPz&SuoiYCGXQXZSKv4y%7$I)B%(#kqp)!GF*t{l z2Y>YaWEL zm(uu3{F%SXvIaySdvqPYbi_L6ftyEF&au)_lkwteBu1*yjw?&Dwes5|dVm(mC({Gq zapSt;Bt;fYepMQ|1L@>y`7px@`MZu2uW|WeRc{)4bfHUu1ymw_s1*s~_-S$zDtQ~hadn=@4 zWIj*LVD5>1i;zzG+ds$z(9X{|y$L4^v6-Pl(qYv&^sn3@(;mTg9|8%?N4#BkNMi$5eGR+~f5gRt{#EE? zt`DEVBa;t9onE*lx-@i6%YtnB)gM@_20z0xy@{fBAg&FCJ|uS`XpqOG6@#HqXLsdZ z#;i<_jY(f-cnBjZ3PzG%k7KV%d=JhVsbYT~DwNB%fZxg3s-7TI-h6Hkv7T)R&az;i z3%M$VWjC7+#`1phzCFrzHLT9PBgZ|znzG>+NnTRLS@`iT{LrSkX-^@L-&CCqEVQNk z%#bE3LJ(Wiz9^8(T(JtK1X6)`Zgkkqdv`0r{Z23KmFbDV**8om)iUFmx;UVeqK9^j zP|I-<<<;+Tt-V5|n+jK%0i=O~lUi^%%-`+NBWTst9z&q24eIu_p)=g@92w#Ai=deK2#Y7O0iP^c~6Y>eG<%b!3GtuRK`|I?HKR4mhcfJT_tKSBv{1uOjfl9mUzQ24e%C(tHeV0qeRirKZO`lk{-OZ9wO;(+^nygHX9ixdpY8@>nYBzj2C z$xSJnUV_77?m-A)#r1|sVbYdTh+_HYj?OIFwILRTbfS5sT4lz7k?If~^ajo=dDU@` zizS0MkSv*ZN)6U)_)Z|gQiBr!g$=tz9&LRjV92b(bm&p;`;$Q}5%nHCBm7GRwT&rR zs4!A; z2Tvl4#`FBPDZldcoEZ=DumndoJAtq}K@VPAbi@SC4{ZS@8fUzV&2o+Vn@g*+@(l^gbTr9QiXo-!vyZ@m^SG-A$aA0fAXD07dA?9{59+21(;hLSWzKdGDjJm{r z6s_s>T4i+@=WgGUC~}KxVW&u7MS-4vR0MN(bya+qESl{>iq@tzcrU*j%=1Ffm^D@; zM!y1Xm4qj1Ga%5{;uMk7^pLt}{DM^QaNcKm*n*2&!Gj0J!r=chVK)Pt-VLJCtEl+v}EJq|Po zW=?oF6Ucm|Yu^=9BDH)e$neNd<{m@&2a5&F_s@Qlj=u7lz(9IU{^6|I&X(t9$=oNn zefYY9D-(1B_>fpt2f&+om_LdjpFZquM-cuGo5#;eA0_ZA#}^>W&;45S zC>?S{h$0F(>;Owf3S>3msH`q$*~xl& z5thHE2{_GoaI-zZ$_YBPi>%A5({Yh3=^+tPEe6A|tNB_0nbq65Z4(|O!1qQ(d?)|9 z*pth2?SIAU%LjEO*uKjNo*rm@iwD0NOgHHOs^1VY3^((eY~adjJc#s}2y!sCiIiZO z6GQRd-#LthPZ?{f-OMeAu@&wOlRPqWHyvOCPRyyRc&?OJ)x%(P%s{g5u7hd`NUQ@u z7|QjHxIEH&CT{O9Nb=L;?GS#X6z#X;fh`APChi-95drJ{tyo^0md>(+j=D+3QM&92 zPb4gVRP3S^YJg42P>hnB$=O=3oYL^AL~VrLP3nhHI;X zu%LHDonF$)B2#$;FS78Xh^`7t|F2%REU?R0Vx$f|-3j?0eHEUhL5`d*_EJqp_^CT?TPP=s&YouR(?Dm$!=A6VNGRXFstO?^tQo{Mi6XzTA>H^KIzjlD z&rgFq+T)%E>^SPSixNojU4*|g_h@qI^@TWDbt`?SG24xKwtZJHrr{Vmt1_Xgupcy@ zQY$wsO2tw}-K%&-_U^qFg__IZz+CoaQ5@IqdZLa{_rWq7UEBp##Ev&La1p;KFrlLD zl^ib%M;}?T=qCv|o?_5xgcN={`*sP5+9keDdaT93idY3Cv*YBEblIr{5V6nmqqo z%;bZx7}U{yIX(wv=bnod#bXo;x2ndBwP2iP{Xc0uM0wOKva^T{OKN1r<8r_94D!ara9G{5OHl*8}p<-7A#V1Jr0o3qzSS??pk3?}E%6g`z(LIq8QXN#tl8lS}o6Aaft(Mc~IS z!*Ad|>O<-5JCGbVra_xAws?fQzTLwTq2aO4Bt3aX11B)x7I2;vtITXqJ3;5y{0uejWDSLcNexo6R{jMerM#ZtV)8 zJPo1UHn?GS@-l|7_?6KdQ#rc&7{`Ok)h<@+*^M`yyuqI0aDsfT!+8n@DSZInS%nuR zHYQE$f&)kS`cEz=mO$RnI-_tz=#Q-x;#Jt%nzE1-*p$laaic`n)dFk8%5O|7DQAld zzcWEu82u-NAPJAavO4m>S}hj}eng-P`(vYa%mb(=Evmu0Dd^7p4?-y%svra#!tOMb zc-i*%qC5#D+}#1YX7S~IYcu@lrL)tNK;XVs3DlWswQ+CvkzQpwdP>Pb^>YiJOXeP* zfF|W$IGG-w<;+Zk{X}l zwda^a*e%E0H=(h){wxk;v(k4?*b~g?dmZYov3fszUieolj~7YCi|uA6^+B~Rk_tYV zg~7^G6M_zIiwAFTK$-^XBGA|`NnT;)YRxOL0TquE;>e)_fD$IeEWAC3y~>>QvS{`2 zP)N~a;Z@%7%iSEX`qh~A{aGe>(}q{#=hetP*cudN2Ozv>+k^y?ZZmUo2(45fl0n+I z){~1ktB8KE%GpDhCn>9G$*1?W3Ir!&Vl6f_vczhFRp1`$L9X`X6QEEky=@4m(|b!n zc2e|15GblAvC_%sHms`TZ1!e`!jwy&2ME;Q41^Fr$`kac>nt9njv%Y6NdOd`y#7)X zi}e+wX;io@D99H6t&Kq7TX?+<#;Q}5V*~fBh8k-duTDY>c`WKNBxSeViu5HUQ`7KY zP8_d6!3`*i*H3s7DD>F;va!?nlRS4;F6YhXls|1^TuXziJ^4(kG7M{F`}7F6#CG=w zOIhpR5JF&)7DI4~jd)~_G2QHeCNs;gvDpKs)4*{7g?XoD2$5<)3@^nkqF?a1xw*5d z$c*YtB-XIfk!|gMWYT1c`5IdKrI4)6^xMa%;iWrr80#4=TCMi8@=YIk;MVwZ6P_UT z>=Mvx*-SB%A>)L<`%4C66M8%>3bM5WQxNgteIr0z^4UH@ss?j>`HwxxycKU^6E9>o z_DDc&Zk-dS)XP&9mY9V^b$EsD+hy=TLma(_TEXdU+^oE<%4SmIdwE<6+=mda%VGJ6 zJVgz?ZC}t6Vo|~6DP`^qo(plw{SZ4z&a6;}+5V-oG4sqVb4yZM+l^+QtK95C_1`=S zn^-Selwv!!=LQ(N)+{I>0VOeFvpU8`1fP0REG{+RhP!p00@8C#JK26O#V!~P_h6lVzn_0%C*~!`sO9;EMv@yPpjXi|LwOPAim*T^QLKK%+o6rkq!w8tPdgBN@-`dKHU+D&z>{%?a__(^9Jv%qGB*lgxt-;T{ z`|^d{I_yU16r^?VpLS}QgB0!UCE9ezP`z1)js%k;_3{jHWl}q zBCN}NlRBSm>hZ*+V-MoUZ(z|2KVmH&wEj_TWx|XNrWliR7KyfMbYDNGm!`ifhO~6a zUzknn4Rx_}g%8(YHpf@DQrqZqtEi;2BVC4KACpV#V5eM1b8s8^QX`JMPc|MFbG5*? z;Nn)=zuO*!N2yMp86n;~IRK0_q^i?H@0aPRw4fvk*4TxINZoitJ88ff3((gVlrwz+W!LbkgEr;b5)%W7yAmW3bJXy0@0C1d-Z|# zIPE4c#JsW>>LT)l;&jw)1dP9=LKr;Xa0&OZ7ERS8>6AA_G?lvd5p?ePefV6JdrZu# zO7CPl9kgM(CPpv3FL225uiV_*A-sYSu4`_`v(hVo0OX2qsU2uu`MX7;9eCE{vz|gW z@|8-5V+cQ7!^KKknVC*Mul6!|ZiQk(EmMmXYTu;>sj%5<1vK&>G-t`e%i(_6gF77D z<;{5*c^U(1vHNbzNCyWFKGi_BUJ2`ep4x&d?G})&bKZPdQsK-MfkEqT3(PvuD_{{ zGo1}k;OR_SQvxQk&eWHcBg7}lNUYr?#?t8aHv%^JA*+fu9Y8_(0&duWS2@}R3n+V& z9L3|;Uxa*6bH*^9aV>rK8RQz#{H}@9p(z*?#Z9nEg%dzmiLXm?87Y{`zt8*zOPp~A z10Y|tH{lUqK88~Cacl54Ik(0aq`~fJwgp1H*w_P9qAg`9=3a~Har$~M9Er+gl=swP zQWHdMaTp!th4*tG;Jq?xe2L8D)M_kUtNWZj<-$4voIJnZwi6~Fz5;_$ar4RKd<;vs zaV3ZedB}2zO!B{=&rCOSq@u$68rYT^1Vk&BTgtiRpwKmc@Y6s#H4p-vjQtrukjEV@ z&Z18^470K%gMYmG12xXT8v%6`6mH^4)nw@je&yZA{M_CC8N|Nw-53x7ncou%DJ7p6 zfEd|}m&LtR;*{yem>8-?jblZBP5Mb(6D94$upV_MPb^Tre-dLg=#XK!2eH)=V*;JB zKqH~mq!7U+GkAnM`dW@edu`%Fxz+|#cr1abX550>9ez_xRHdRFD6Pm_2JU9k!kM=1 zeh8X;bD2EdgDdY2#-p$A zgIc@gZxiU?{AL`IM9g%CXji``O0yd0fQl%np10Zp7?&<$c0Ec4 z3*~S#A9ca^p)>`*lC<79b;*_ao-m>VTlh4?Q6V9)w(}qTm*&hwqoX2y*@LI^tVLml%4(Dblpj{Oo1f=vbfMBN2bMENZFqSD2DwX z%VL`R(Yx2fo!9_rV#ArT^z+&^`kRIGkObN*hv=*@mAFRW(hX;z$sId zNo}rr98B3?QP9_8(xA`Etn_r@%h2G8HZM(3giPS@OV=wVIld$f9RUyhJ}oCi`*Zl#Yz+kH8|k2z2{Druah^)h z2*~oc;p_-IgTnIyKLYJ{aBb z_+?|UXOD&n`S4HlT~Wa3+n2$dvCpu+%A<~uf38!U2&!h5g~??DX+X2jV(9WWUDc&b zy3_|NE|mtnc#g?wrl0-~FMHP5B}U8_av0s-+F1%&1p+uW8^?uw?)_q!_NpoOT&vqhmM}TQ>~Ls0ZXyfS|6;gq2#k4s>?&Een47CHimC2}3dXDSso?{o-wF~LA(ABLyD$DP1`opBGWCdVxX>g1XdR*JeE=@kQu%x9U0TeRQ(%#S6!^2)YRMj zl-#!jtFyDG1{wCtfyE~;Ge8Zh^Nep;*SmJiA)0VTX|yCKNZCy=f_DYvar$Zvg4O3N zxpd_;5Smoe#?R<$4+CZ@&)V&#l}=-F+Krl0n)*U*W=h)~1+da51+1`Uk3Tfo=-Qp! z73)tH>*%Uairw@<4KCz5F9^V+_VkXKHm&Kwl5{*(mY|NDG8+oo(e}~pIR7&5MY#%m zO822#7_Nk3VI%0&!TqNGwPL&)o%T$VpmMebi3Ig5`82T?svq3Qrw}ghFk2mCWHg%o zFxvb(h$pgr6$ZAna{(6OoxLh6_Tpa?XsRe1Qkk^>8uTVNtyb&+o?m;1m4}C_u{)7hTX1Pu)we+wgX)qh7z=SV3cX=oA;t1tD7H#^g;2Wu> z7*C@U(y@}!B-Cv3egkN2BQ(Wvy5Wpdrk~ER+W;=h%SB{YiK*B5!pp%&bB`l)2* zhtsU5xcj*$qGF)WYnmWhy8i3QMb`d&PL-+Wc+&E@zBnD@EO66rX5w7G!Vl|9UK}x! z6XU#mMdKos3~({_4?Asi-b8GZoO2FJ)}!;Fq8S@CE_xsrYTUll;PG@L_?m<)Q8G+a znlbsIB@gR!IEB+)?)=PRrv27~+~r%PU<7B~f*?&@$GK3uI&Y^-vRiXJ?ExyapUHDR z!7U#%yd3=!&wAreOjLHB^3$!OO<|_|a!W*M`5LpuO83@7%L*W~<^m*S$4w75V%i-K zVdQhO$%ewfX`}zJf;J!LK#o^O85|Uj&FToUtEX9XH2+<&Zu{#6SPI)dlqt!mvu2^e z^}t2+YK}x(y`@3F7CYzl(8Xd5{LR}c8=S{0iY5BWNWSSa&w|veeT$c~w8#q#o8{1p z<@>}EqDP8xmGnKPux2LQn}qE7U6qCYEJJYK5-U%q=+685Nn4uW1d%m)f*;m-_5csK zaMx!hL`q)I7m|?LpBCV3m4{d6UQy+(yO7E~|M39>b}=TfF$tNfoNJ1soopz85R>br zi9|!cY{9pQy$8i{US+Os#v5?``}H{{h>rX+#8SEsSA#f7=^<4N4<86Nzv6+!Eib}d zo4(<60Z}ZHL2qRFY=Dc#%}90=pO+?fh`NU4FGH{@YE%IfAwPzW%jC+xSaQke71?xJ zeJ-I^Chb_!iyJX+W&L&&M&EEfc1?cK&H^mkLwuJL!!dO^UkAB#tUAB?=e{NaH^OIK zyXm3){iH!li^fhpJs&rfQnE}8!LKj(5Eb10RgBaCe7rpd zZ(}{Rm&pUS@Gbr`)0ah)j*os*<3CU6*%b6cH^w(E>Jky^;rr}L4~!O(6; z4LNeO5?*ZeeJ=W747X-dwQvHH51?njDOIEnGxu2lR#Dwq?zogsi)I^bIu=ZH`Vm-X z-dqu7IpgMHf1kejR)p+URi(roS8}UvmM|{TEmTEq}MWpujXM4$;_f zF`=c4mx<+QR}Gg8lb06S9q8FL*dBuA^8!>R*WwvLquO#@9G3}m41Fw`)2Xr+v8(VB z9jZ_O9UG?}4FIYx;YB{ zVhiNJ1C9<2kYXJdu{QV>FonNbU^B~#BryaW=YXMCUd04_~?KREH@T( z`(8sF?y|fT)|YH)fYD7k1{U;80{1DaMLm{h4xfpCtOa}K$T7hsd*0$E9~x}cX{GL5 zNXfvRZbZ)x!z7iNLZlt~nB2xLe?J$z{h)@$LBn%-q2#zZMIopTuLUsj-v4OKbZmW5 z5Be#^A$(#pKPV?vHenEB3VG$N@*=MsM?j|-WK^V$nA?&*Heo(4;>@OrbW@6vom(t! zsygaR(t7>HQXPFZQH<$mop}KlY=~V@H7c2)(NrwPSx90Ar7^wz#O_8!dMdv9LWk*{ zUZAnk0Y|}Eo2uh9d2=N;d-)-Lat&UhP5=nZkZMQCw16JRfF(OJj>f7qsKIU5lb# zVC(bF7O870H(<+L>EfnGDXsaOf^7tc3(Cy6SaK_Mb(<-i38WtU~5c=O*47X zRlE@5W!hjK)&6Q^36$uO?cp6!*8N$eFex5at#VEW$1~-xWvwg%90t|K?L!tqR?<>{4XA{vSzK9@ygj|DW>7e99x@QID!CMM$m4%u&a9 zN<&I#VUD7+6e0C3GG`p)DPpNJ8zb%%AvH&wi*t{olwmPfSP@4Fb981?$L9C??DtQf z=6asb=lyxqPnrj_0dMYRhXf45UD*Da;H^*Ve*Zlya%(bKB}D7d<=eCXAJ=D$XsAuT8H3~= zj?a_-i|a>*i;?g3Ada-(}=?yndbzZc8*Dp5Zh7FqvecZN(~~v6{(3v zHy&WCla8T@CDgJn=BwNYd$E3jk*{NQ@SYE?#!5NmKn){ePRm3s1}cgd1yg^W85CfyI2{^Cf3GuumL$JI?R_68G?Bbs_(*o$G9rNk4fUk@ zM2n_5U8w)qP>`Nx?qk8#7?XyQgeVfocB=5yvX}b>4u<*c{}sB4<64e^+-@Q&7$&Qa z1-Q7(UZPx$OdSP84SvpCw<)mT2RwgX-`n8s#aMawFBtM|aJ-iJ#KjhXKk~ zgFjbGX&PzQz^T761*i53$bIkj209C`?9eX3-e=IC1loXZ+l|Iu)SIb==G?ExBZzCq z&e1{yAKVTI=Js?z_x%FxLeG5gO^lo8_AkF7xb^)1o@_Z7W2Rdi{RNMnZaz>&2*S{smM%skjn!tX*w;mlw}RVuMB55sh53>feXiA(}DwD{C=5(r|Nj zg!d{}3X$yXJs{15@R7qC)m#^ztD5yPHNwkBe_gH4?4prt*Y12h27wcP4d5jG5!(tE zuFX4-+HQneAIqjCcw2~(_Eh>Y!-;aCf~XFmB`FuijmE4IQqaG1)LOxnME7g1s>-Q; zWLL13-y2*8x7D9s$eOHn56%-DNi-aPNge6}c{r(&VCaIeO5LF>Sf=&HU+%6 zM%NLv4XJnQcS1Okw*IH0HJ;knr8zy&$z4u6oiWJ?1nT!zce-hDO{3sxNR+)|xHa#6 zH_{3KC@cCvH&y)Ef<{LTU)2>*yy`7kA)qCog7KhT;Xm-}Bq}%VD7c`0_x_AI#VeLL zV-WZ#xdfcru9gWEN0}#&9d0N4O5T4RFr<^>SY7HR>(aMV2RlX@}fT{UT zQ3pQcWpUNzR1QOn2TWjyZ}v9J7oZ>IZ%x&L>$H9a8A-*L%@Xy5+b4#Q6*@J++m?*! zndjxbH$O=z{7YQ_G}F=nJO~Z>gGi|v*UU1m?J^YIxf%oQ{p@dx6vA!rmJGXS>W`Vx-A&Q&)WCQVxy|G{Crpm{x zY0hkMm9vcQS~1*ep|4(5w4&Qc{xN~;Mt>VT9jMLMRRlPjI99}HG;->TF(+dD^cT6F zVC%*g);)N-fTLYv@8ZPC4@U2TRvW)RUr(E!y3O`BDr0bg0ZqGFUM$e_Qs~`3c``3& z1U9NI>6%FG#rsPOEa-R{#M)-R%w_c~1w$UI&E0sp!-)lWv+de>1ukBm@?omeLVp>! zPza_|zm!15N{_cPRCvM>4{iqdzt9*jWMk5^LB=1d0 zVl}p$GNRQZ6FJ(M<+N|f63j5CI&Tt!Rj9nT_ZcXJ$kVApn(by~QjtE}3UKmIW;H$r zoY&kwBF4ij6STdLp(}hC^;N11Rf8m&f zjl>O!3Gk7tTMk0$j%-e9j}(lbulGc(D%)GHVgsb#4oc~VYlV~JahlQHYbt*DY@8(JXYWS1Jc(S(zijZmKbBDk+CGksG^UA#eZ;^(U z@6RbM2Y0@8M@Cn)!U+&H@+5>*VyS5z!4HcM9T6-|>3!`cAI2S|iDm<}bohY@-alj1 z;VL{Q9j}E9A>Mm__Q+HX(n@)sLbd-a0#2mY8;eXlH~Rg5#jI%6Q;jsd%2J8B(-T>| zu{JICWJrX99NPHP?fTQ+iayHo3*inC&?{6dO<0O<=Vi3cncZk?Y?EbK<&p z5X)o9({pIvPU<`mqiV7tk7W^XfBB)@XXV7|i9Z54o@|5Nr0iIc6%(M+f+o1JWmK$S zf$w#2)QII)*1<+5TN-0ZFICF_(FJ(RZ_U4kw<7Y-`%*8J3+iG;;o-AO5t(is5$s8* zyiCGdt}o^l*=gOF{~0-Y*&f6@l3OLDpk%7SYXDu2zf=^Zmwm`6!Y_Qy(95HV=uM*M zx@Q>8^nTh}kb&Xq93Qw*=nB4n(%TJ7+cxEMpM&q(=fD=Qi@Fnj_l0O~@&aF!b{+ed z&rRp=yC%3R)9X7*7%AobT4W-YPGYDh^{(iM)CuC{(e?qgPx(M7&AH9^{K9{%09Nu> zs7#SL(bWk_5@TRv4)35-m=TTS8tsz0LUDa6Z(In8!;SbaqhMt>XF0MWkQRtT9$!fe z$C15veDNqW4Z_Sb+mbLVdMTWfjrNL;Dy&twL=%cJ?si z=}!p0$^}M37H$|M8hGS8;w*Tlk9#E1kvG~Uy5YQ;08fi_`NVJ2gUcAnpZv7*X9OtnIdKle~nYLLf9 z99~Y-QSc21I=X!AwwCseX7gEFl3Pq50=(qb!UI7Dj#b=p@?AdM{#1_5~T-_42? zYVl>j??Ja4NZ_ImL@-AWcqm%lXFzt-Q*3#q7fX}s%>m4~kb&h~ciIT^GXb59xdp5* zs^Oxw44%%~j0m5Uv1U?=uDl30NsWQDmsfn?^zhQnxFLyPu~RUSlvnmX9TB6!?c3&P z$kXLIGm;~A>rj_6t$nGRhETc>!(peW|A@-NLqZhwe~0r`QCil;T59HVvv+?RW2W1F zpYJo%;K4QEdh=%g>of5!azEM}qoti@-O&|O_srD-Z9zM|G#CSP|CdXB4qD;eKoI%4 zoYMlWLd$zz$F8(Uow6hFST@X<3GZQ5tBp!0>KI|4-O%Y=2y=X3jUo|x7c>$1TL(_= z1u+L*kuUkM`00KAOOiS*0HxfUQoNY0C7H-){j7E{ z%dz;Z^Ack@T$eLcP=&UagM*oN?Je@t%x^!jx@m^(J62>-oRgu0DspJ45Y^CkN$rhc zdRTo9DCJJiOxF^}KpZ-`M{8Y>dR=9#DpP(k9Q2`ZyYe+;iy6n3`-=yT1F0dS7qQk3 zf{eV)=i3Ey7aE#xLl;IWUs??Bh}`;&iz?l_Lubanj0>;&pD_i~Qd#nsG&t7?lF)>7 z90I&fP=FHOQ3V2=(n_?q#q2YyiP}#+!uKuL#;7zjG;KIIrzv=l-C^h^6+qCV!5NO+ zyQuRZeo-4f!K6O`j9I_3)H`MFCM)>R#jjXGy5ZbNJW$EK4SZQX)&iV{MNO>%7_MJ3 zzS;Fxod#_TZS3KnYOLi{>9k0PzblR+rvMRmcXM*8LUW^?&P~gnRbt}Tv~ep$j`?OfaB9eD4DyJ)zr~`majIL4lBWF*U_{cdsxX0U z^tVtdFtHK`QTATM8a$yRB4kaE#VobNcH-MY4SD%NVL441R5cr@%3UaW8e#H~=t8{c zkr+nT>H(rHk&GFP$8evOp9vFTozZ~mmU*BMxq|^Nu)*8@%kx>Z3x_CvLPaY_D?F>o zl7~O2xrzyb4Wsjm+&KGArq=hZd5A^0-@Mq&ctEAUjR0)wet^PqZ(w?qEG}d>Ppt&E z(&<$!IxGElUu8#+%aStza#>$B#7!-fNN~OrSn*enjgYRDSi8H@T0$A6$1m(C#W0k& zBdjjkyX(&&D$X#=Dbu0%YXKsi-pRnIA?91Ff>hd{Sc1It87ri)ZB^UVut5%XfOGL+ zBd3KTCMvp;Ny1d*uxe(D$i+}{J_Vamd^#(*(VHoZ!jhqv5xJvS_9eBr1{WD<%DWau zEs_w_ILMl@1B;^6H28nmj%L_zx(E$qehgMy(x7jtiB=w^_2KxP-3MYxyKw}B<0G|L z$xVmSA!s)AXw!w=aDQ>F?xQaa7s%?O82 zazeY^766vL2Uj~?)bf`@g~T4p0or=4sMI2(udq5sx$#RMz;GZ9 z$5#F>Q-$OChsOtpK$js!Ce#IuciJ)fg!O<3>Wx@gF!41us=av|E7sI}q4HCU_arbi zF=d*{OQVi32tqsYpwWXE%BL!v2kiwX3Tko>fz3psRRq79x*H6|?E;c>BXY7d%O9L0R<@{naVM5JY9Ui}q@3QG~NSszoffwfkttZl4j$4wtp-#ro(78H|P zar9_yXA0u_9gKLgy)8;gxVT3FUaq!ybZQw<3PgBgyyqp>Bw5lf!bY?!h6yeR$5|?X zs_bSmPL*HzTjiz>^Y=O}rAxxPFuGkmuNGrQbfi*F8QFAM&_W|m>5N`zoFyU9ob+rA z?3nL@~{?Qw?k&IBwhKZWSs<) zbFvRdq+?I38@bK0F^V+C1S4Q%T?4oHniOo3tDVWxjru-eMd@7fbNIaj4RKDmmNM{K z_I*=qSl&_1s;AmptVxvg^fd^Vi$4zrWtOH0Y(93W2Ls(_0kPI$eq!6TU*PCa8Gl^;OS&*{jx zRGWm5NF9&c#1x|d;f4{@HiR?C0VZ)ZL`z3{X#2@hJN=+Zf>1sLUfi^z5KVdT7jQB5 zOd25Ed)uQ@4ISH@r6G>bd&rs=+p6tgfL`O>4anTCf1$LP?l==>_C~musPj{QFr*7n zd!4C94)XMOtA~~)AArO(pWcS^WtcSGnMsu$?Z7#t;|qi^%&sDBk%d@RBb}C7Ds%$k z%)9CrS*ZL$C7pp?tbo@vHy3W>7xx=KU~UKZfORTB*;t2vr+}1HkZbHX{+>s>gP9*4;S_X7&YGS3tLxc#tiqf}Y zd1aFIl`#b}L5Q`G>62p1Ngc}SYc*ro)Qmapt-!&u^{f$X;I^pIk{0uG!sOQAQkilC z$_pbT`KXv85amPB-h{MzAllJU@!!}o;xa(9(uuSIS++ui=fjObD2<3-F9wK*-eq6sdVma!&+nc?YEyah*ZSkfiu zm_xx{`(H$ahyR1mew)TpX}PPN(p{uj#TwX#o-q(Uc#|ZPO`oYEME)be(3$9D#9V8B zo`dYC-RTGt=iwmGPeg}~+^-@?XejAHyHyg}g10T0pVkhJWdo>;Gq}Y}Ojgq+_#2ac zdsKeXuSRT$EcAm(1iy#r=6xv|V1^Bcc;=KfVmO6xRWP5AO6|hP4Z>b!5^0N@)~R8o z2wxij22BL%SE0%9m=Ny07~h0QT>!|4UF4ET*;?>AX|HG=PB^Qm=|MDHl9{}ZgG5+Z z0H9bZ!F)Fl`_#eJ6VXrha&eM{%*eos+%H+Z4592iY8$0%NWXQ#Mi}e%kOp-*( zOW{?~q}xz@?gW6!Wx-sX%3Bry z2DSSO7OZwie5o0!P6_4~B=ij+DQ{1giA9$lPa=A}w0xakOuR1;*p_#Rn&udFn_fmN ze~$5U!*UR`UXfEqPV$S2xwk4P0QTpF0QL183$g7^3X{mFSU_3%SqEzR2x5Q0l|oR! zG@zMl2q0?O;b2(yAQa7w!SS^JlFt$QeSFXIGn)tEssR4O$*W-SS$be4AQcnQFE~?9 zavP^(1VFVUidZMStx`Uaq0A96&?Mx9$ndhTeKafIMIwKTj^>CSm!k1|xU=X;BJR4) z_1tGUn5Cn_joe?0N;={G%nuOx2e7z^1`Y~$IwW>RDv)-#9(bBu`-~a0Aszh*F9E)$ zlpF&wcLR@!oEEuca@mz0Lb}c&BpGMs3Sl@GBM(J=Gm>JAEhfs0LK6m$rgOy61_WlF zg$Jb_W4&PejgEC8FZz*($ZW1WHv>zy|Ark!R*Om-GO=RwV(tWRz;y*YP_7IJb_a|U z52&6~i%}&+@M7==Jx4M`dK7`fFwL#9>-e5%XNT9p%4csK~ z6GLv7BrQ?qqj4_W%!?lt6RwV^`H1MR=cf=;EzqHSAE!*Z{?x%O7J@yHJn=PrYv!uy zSnPSx^D)t8VMkmcP%npZQ~x*lIE7jGI6MXXQ~w#ZpxWpc{gc3Zlw1 zDo0BOwVK7>A&ag{ft%rNmU22i#&j12|t`P!y2KUu8&kUnsN>O zkjc=eDCVYdCu_0=+;3nJT=B<@Y>tygh_)K!!x_+cyl3AFK@BbT{1uA~`2{*KEoHz{3%6f~P7{sl z;q{urU4mC2>$d;bWuBB60lq69!B&fMq>d^?%@r)nbE~nf5)8OB8Y2Wz-m>wUE{OK` zF|5sxWdiFaDIMA^m^4)GT}_3(bsGppohyGTIM6fX1QJT|n_QhP1+7M9p;(}yxWUl3 zy&qp^0G8X8>Ee0wKdG})gD|mw*sST0NMkW>6G@F{d=?U%{wPe`W_Fa{{*Fz_O>BUd(r1$pMIOev zs1fSnghPTJ%HF?^8J;$OA!@-=LpVttVvVpAo@NOO=tuGAYl%4_JxCDcvY|%#LXJ=l z>uSSt!2nzSk0h%Z8r7em)qWLlDj^2F{YmakOe8`G>7)N@s~Tz;@74VF2$dE~QQ^g{ zNeFfzU)&UJ31o5%3(Is`kq!>$JEJ8pn}E%k@>wp0W=SD<)^|qymir9+jVl61xlNP6 z6`~2@PQ=}#&`vxpKvyaEr?Mn_eY>|tJ9SyN7|U_u7QmtpoogqQp-a%RAB+)_IZ6zD zN|&itI3?h?XcA9Bl0Q(ZnX9Uu4s2pl9#wU=H#<4c?W{MLVU1R}|#JB)B zLDogm%P_c8{v7S%naZwgt(+esO)44#NZIP0oKBk?U&3YDD;gh(7UgqiEvJ?N|x@RmLc4r4{aL!083t)}GX4u3137X;u-BlLs!g4G%H5wR*ukL|R>4!1!FN^V)NSR# z6u3XfF}BBL(sT{_)|(rX^ircAHr+ckek9V@N#)Q{0UYJanL4bu?PDE|(aHU1yyUA6 zz91Br>MYh6ekzzXC~s&1U~*j#17O|`wa$3B3kl(LGOu=0h{!`B*Rsm-xg}Y~{Uks0 z2PpIR3PGH+WxWJUBaolH&au#Wy~ZWt`!_!|keBHIOK1#pSwt?U>VP7DLXn$x`VLiX zD7X!&+0qlfXDIa6*eUpHP}}lEtBp#ho8oI_eLgWtl%o7IT!YdBO_(Pz_(M9ryl`2H z;HXIhlSTni%J2_-GL>2$(_wDSk=Ir~m1g%-nduC9sLBOq(ol$3)5f=XSSt5lV!$4~ zcDa+_H_%BR-Vwab=*^=0YFjeTb$JCty(Nt|ehCVRtoT_MLJRGQ;C$h|3t7!u&y55p z+Y)dJ+IqA^B@1W?A6mZO3WCVmk)x2MAA&-H8)o=WDSS5xwxi|O2|hi&nGg{?A|1Ra zP35JX2h3*#{EpFOMD1i{)zbEHLUC;xska$sy>j)CphXST8IjAOcEsze%)}Symz}lGLz-&(hY>nV~6|Y6|e{CA4?JN8@R2~)5Cv$%;NF#(s?*` zk)Qu3AVrI_L(%o7j87p-y&axUXU|}Hk&hCji@ASfGer&3q$Zs zutMM0G|Pcc;vP`I)z1)Z^~mN-r z#(GV1j-yTowFLVJDG6{ogq$8aH{ceeTD0Vq#~9DQoV~>pBT?y69(HqRn-dapW_uMp zV(Az#)qrj~6bmXlDIc-Qw7m6WpP#xWmBB)nj6KfSQ3k66y^eX8?h#!1~FOsOtk5^gH zw&XR$A@}C!qj*9(q-)8If50tHZA!Ur+7PQJ9sX6}oVMTMb5VKjEGwR{{X2Gw>u@Z>6M6Z>3cuvQLF}!ZxgdA{ zpJRcONZxNgU|^;d@RQOmvxW^Pa#S)kPksq|bJ-g)(3aXlUD?F9%q4c{5Z<8z_S!gx z;rW&>NkjCze0C@hpQ%7I+~1&BZA6D7zy&al58nyYW}3s08tFA;gK@Z1 zlYwrpA7iGe{U%Fz;T{wN=7C)qPPhu^-(@tN_3vw=hTh-T-e^EBMT!ww2RlqoKh@qi z2k?5=Myzm5e*K%1qv4|=sMW1*8tv$Hunt_o@@1Y6F|iKM1P}bE+}}xFa#+n$0rcD0 zOqO-u=y3XXoY%pfm@`V{q29UYv4-fR68vBC%;ZyO-TD8unoPj}NcbqxS)P{NZD=jS z*>49@@Dv{tQWEK!-PbY7h}w_75F80KbA*p|2~`fZG=e+rSnvqFip>92xjbg6tlow_ zoo1>$*pNo@b(=SJei}KvQ)j342J!gq+*BXd zD*kUI)Z_W&f;P_|a6%}%7K5iouD5ZTh^&bI3@Ycq8$;3UrO=9H9J|N- z=-#1yR0i6qeOq6YoZBLL2U6Or48OJ%O=6KP%c{97u!#g>tX%#h9mm`8JO*o1_H7XS ztTAq`&rBoxo3kYKP4$b+#5+MWHKgvC-nt0g+pd=oszVb_R#inQIUQ!x*~`X_0UJ=_ z)`M$!_bmmvm{Yzggl#vHO#xEcT!5#r?3-_~sFZbEK$_Zbni-KmGT5a93)N2sg1w)O z(m}oI*j1&_85Qo9MriJ^C-~n|7+YFQJ;y%M1!&{RzcBQFlbQpI43j-XV%mld-JJcV zU{Vvgx!|8eO?Ni2t}j~ic|gDSbE}}OPv`8YAOzuOn1<0bw0ng&x+t})TN@Sl;(Idh zSY|4iAg7=&Gf#StVkNfn;w9*_jCpx!f&raEtSgO~DBkbK4$HsS9@$7)yfGdJCY_lX zQl0Mqm5!C~W6f2#md^@pBsU0Su;+C^KuLy$FaNu*c3A0Tbx<$-Wv;+Ih+E8A%b)NB$js|3E#0V2Q)b*@^v4`V*5n~L;3q032KRfi5(wv{5+S}eYAK$=Nic!w6w1ki&H&V@CXe(afJOsxXjQz( zh$Tn*6*}Oyf{77I5KT47w)U_pg9+Ga#!xVwlz|tV0B>lZXb{Qd1A?bMDLAbM+(z+o|raX2bKm~%~o$1D>L5~@vpX@&LjYZ4kYoCgcxJ}ia|vJX6A^-xQ- zFN*Mv(8LHp_ge|2M0xK*)whBcGmxdKo1kVXYkN@{8eAj3F*t`K{J$ddKctRU12yzW zae~}yT6kh^nO;tkpX$O0+?Qi_T=u76VRFYE@L_C2@f-I#A(Txz z&4uWme;z8O>yF??BE?~m1HFu_-rUUfOt+AsSJ(ml#%RP1A`3x8?~F+@SzZ}Fq{V57 z-@;Zn!Bmh9myKbVR4Qt{e** zn&#VxKQ`7+{O@z%fL@sHA#%@HFL9s75tnbbEQ(V3d`yytyTG1OLa-QR=2Tx4zaLNp zC9TvC#!e!XX=dD~L(^q0gME?9FZ7cq!5kA8zsOD&JYYqLvnu;cY}$9(S4b2X%4CnS zcN`PtoIXEYA(2W+Q8KF{VBqzO_PT7MxbW3l;VA0w(-0Z< z5t4$YLs2zc2X5sZ+i=ob-*bXv{N9d*%avDSRb{LW9v{~42=U6z-3AF0h=rCZ%L7G; zC(~*%hAejwLYRqFxq{CN0NNn=p;d-%AQhKY4 zv>?#K^~)2vu55fX=f==X>@d_l37mFql0v|kJm7d<1xDikvk)`M(~a0j&$~s~ z!w2KBROurv40CQ9<|cr$9oJY$uV-2g;v3zQ%;ai3Sc{^o&lWTd)y-ANzZ0u^I0c?- zvoQ(uV;3`fk;|RI6sJpIQ703@W4vRsk%z*;=}5SVqPHPRwss2THK*fc@ zj%Vy-hg%pmP$Dh~0ep2nzW;3We{*2hoX(d>tApTN3IRQ~8Ns}aoaF(w{6@6*q1@TJ zOrxW+gL-na7w1;4$iHwFoJ3y(n0MTKbE zg8!7<1;!2EGJf{=G}iY|nZKh5vT1M~5QWKc2DpY^M&t?!Xl`?`1qv9Euo-pGRkM?s zdqA`JFXo9ZcO7D_vG#tc7eaA#Re3KVP?OqTZ-LNRH?W~Pv#Lh!Jg@RKwKtXCJvKz0 zlFBQ)i&F(tDn0G}L9Ie-w8@zR zg3^`x=l>{h)#z`z4b>?P$`<7MYqS%(a-8d})m9zXv>$1F9Io-Nr*^N2D}8k#t_H3t z9}n)yUWaEsDqvTB%g`@t9go@cG+)x~v_?H^|YTr>MFzriGipj5+{d4*AH?prZA0H94RL+^B&M?#*Zrq+hcw2u^|gb?+2_~q zU1|Oat|ONHxVjUrLA$=F3$B${H?G#TD<=oEzsyR*>jQmv?Kk48k4|mGUI#usezF|v z3N6YJ{>IgC-*M|5u3o=&-g{i_b$%JmuI9#<&a(Fdmh{dXe#dQEe*eHRH+>R+M;(vt zEO}a_=DKQ>YFl@NQZ=;l&*#;29xr!#F-&b)#B-}|vYEHbhWuoT3G=PDRVu(M{h}$; zVj_k}@1ph$lHM9yD%DGL(X%D5@ZsU#bBwsi_tyO=&@|fo0lL}nP5U%Eqb}=87cBZP z)y&I3$F@_`G+wUyK3VNH^74U8vtsNSaYb+UF^ox71|}!qO7>Ol6yxA`e7fV~L{swR z6z!#^Z2cD(Z9pN&=4Ul`H;K{Esd*2K#kA3#QR*;OefZ^{YDX_#Nv@X$eP`|MjFsybrCY~q;nc!^Sy(`t7H zM*RjJsA)RSO?>}%s-Neq>u-WFKJjiB!t?3Y`yX3fNT_Thgj&#mMS&6N*JKOc>U33C zp3S0kjed%#3|K)*L;7yt7QunOaxEvqfR@{~$`0_H?a@c-Xain4LzicJczJI(VwCBa z+^tq5ggv>YHmC8@=--mn`ZNu9aOV13*$RC-Elut3j?BULmaS|ikUz|KAzQau7m zAMg>u1%GT6Gc>=(`LO~QN7s}t6AUeAwBU}ajHYyNj<2O$%vWc|@yc)Am#dXDUb(cZ ziaM0WYk%1D5WO+A+l1N-qe|1hA2YCKe6=Uh%WHqBxEn*b23{z6+6EZxz5V8q7@E7d z|E(4&czN{x`ky-BI@#CTE`i{G)?USMKuzkRhP|Y0ufMRxF9e?k#_!u-5!d1aJ7!kG zwY>DFA1SW3;u;@)fNOBXhyaS4?8)t?;KIFIT*^8&t!mv12JMrHqRv3$2h}oCy6N;P zXoepS87r<-DlIH2;)e zomx!q);$Zk`un)Ca3yVVEyDk|#?{Z(^W4Y%1HkNo`B7k@eUUc17+7*Y5>p^jTONi- zglIaWb1BP>iA7jl(|3WNy+ZY$2Pvj zOZSRROK_wtmtS?nMY`4E4(OSCH>V{u9lkl623f41gAX{Ihkla7mlK zdp1VMY*-ZWsK6!-P>Sc^4icGTp|ypjjS+kS(Oy*gfrjm^-WABHN`g)ieZ|z z{mB}p`tJ&$h({(?RNHDL2Pa?K%h+Y8S^u%1U2UbZT`_oRU)T~aGqfX4pZEt$3Gdp~ zwF2H&+VeYNFqEy^*iOM13r)CGVhq#cb!)0{*R~IEY`#0v*yyHRpBsRzCA+T*LDYHW zZa`Kmro*e#V zsx#60#^yq#C%yDE4(9TW+!;mC4?jO~47fF}JtahYQvKD(RtHV_D_Q{bKk1OGGSlL8 ztDw}T_I-nV$ST@1T(DQC%Tm*XP%UbZzP9S=lV+!54458QRNxEH&u;$(x5Mm)8-Ofs z>xr={4V`JoDk$S6GTMP7Eq|iBr1r$}h7U70WxLFQO7G}jz<{^OKl_+?izeHOD`#tH zR{j@>Vct98!XR7%+q*@w!#r314cfjopx0JO%w5Jw-XUyZG-;b!X~4@{3JRHSdG`o& z1DUII#KWY9V+@Hwp4&NhbgGNjmQQ`3SIk?uor4k`yxe;3JY1x!1=j#Y%PaS?!~oRD z&0=Ug?RT^b21pS1&m#O)yOzx(}8t8(rD+|S+(s`|RTQ#)n z{0>GF?HY5^sHfFhT`<~cll|SCCMy1XMHQgkr#WK6eEFiSt&f?ItlIod>@f%G#m?f; zxNp!Me2hlFu<7_Jpg?z}PVX3u{%o}g5aV2fC~QBa`2wN5HZ5D(TCmineczt3x@i-4 zPqiHyLGr<^saSNCju~%SE@{(2c9H1?fVe0KXBo$(LjHHpicDg%91)))lwB+nN*u~{PJ44)MBW;=_YF? zO;Q!3>4S2x!>{a?+-JXis`m4|GV0q0+2Dsa1C!L+Pr>5H#tUIJAK&Baxp_9Kn76a) zq`<~>!CZ$o9M4`96R(%Iez+L)X zk&J7GA^PS+TpQ0C&F14qI#6YOeq#zksN(#n3wTuKkn9HqQQmfAc&fS#@Ok|4*aA@Q|30b->7%u^y9=Oc^-oRM zl;lixCfd*&5XY@IFZWIEt9Do6wFf@!9uuZq=?)d;-Gj9~)j{~RH;%KW>iM}RY$t)< zsAWxn8aO&h+18EySmTCkbRWC$zNtoz&KB0qgR=4WRy-Soj5=or)c zu7|idrVlvL32S<$pl`sRy?4td4Rv#8v`D*-t%#b%xua#&h&Nybhhd(nF^?n-W#iqQa;#jT@!V%GQW4)@lyb$bU$@3bYMfP z#-9U~fu=TZVli*Z{8H#|4r<>aRpjFIJ3evJUVx4 z)<$&%w?8@hHpKR}1ADE-B>1K1QPZ-y8+3ZQ8!esn^k}=kjX>|zJQeyL=%+K0`|R9% zH3~_Uk}=!vxOvMRS3`AtRbF~}cq)#bG~2^w5p!2Rbsp0|53R_v$kjxD4QM$1T2?Iz z&>79YW05KM^(wjujr?|u4GwFKBo!Cces>S|=Ui>O3#NM1@nonolSJx>nT=@Hm2TDm z_3U76SE9?$2(&ScPG1S>6nwkNsG;thFH6yw$2%TU>&dU%b>;L{v`P1A7>N< z13E`;Lvw~&#C}~24WL(xKL%Af>@9HkLJNPgnlWPHU8zhA)kS>|>X>p3%aM|fSlx)Q z$9n0@Z!f?ZR(x|R1kwG+9>|0F6u_(>J57Mi~O5jIkFA~KIuhLOB6#8rZ8NA4X}jGzEe+RMg!ejLujIT>tLhBsyiYsR6N1`C-D zY3NBeR@3MBq9eX%dNzqA7zT2`U}+;#+uedTo<>5Igb9j9hA&@;bJph ztIHq_pLs`Mk#ftp=P^Nzvipefy4tIze>R&OgT)+v*caR4=JxFjNhuAoWC73Kfvt_m zme1dgopNi_VfO@|HD!6Ra?)PrQO>N_8pk(aF`%A~pgKM!n~&UUG(Hi$;Frm)U6J?b zP#BID^FrJpa%G;NtwSaIY?l9E?>)|_r-AklkMHa8he!A>kcvIDxQtNp65>lhS42GMQqp`qW0sSNbV)9Qd>UHw5ET0>$EXkD6&4q51FW&93tOsWhF2o}6qeVU-uL6kcg zfu-$tV4rf^8VcS9bj{&jpn+}msupQ!%TdRi#dOHApP2so$(M0Hn13^e`ZRP(6%%gU z{oZ4k8)5Q;(@S4`+XC+#{Mu*5S)M%{JgPA|_GxIwrglD=uA1>0|Nrbf?sL$|%08<^ zJME%61K;5bJ=`j^^Bp!TV$rG?ND}3bEe?37r2YE5W93k_wIQ_~itX~E9###VTl6&} z%D?Y*O4TDKJ_|A7!K||@Q-ys@9?;kY9fCsE`A*pHE3g~Of!@1y)a`H}93f*&h zuHd5dpJN|G`#ww${Sbrq9-W4&HLkaS1-7u*u;e2_8)FwG3$S6!@t*}mAf-f6>!;qt zW2M;g%qR{|=#yGT8|`$vhB1ZOGJ~R}CRwyXhpF5@nyd<4b^03k(QD@tm5nYvd5Rq6 zn>U<023Ga#-XUglaKlWxY!k*-H`%U^#_`gxf1Ol21YQb0ybijJWSlNjYr#S5e$<1> z9dG@enXJ{)|FY};sV=TYj}N<`4yxg|{EAl>qc=C)q|uQOM45Kxq)JG|A-$8anM9bqS_ zo3n;GvpO#y>RWs)z;lOZp0H+OYJH~9L^JzOFb1fS|D_Mk-vLTd3SF2tvnZarn!w$} zOLbQCVK!Gu$*VkU@uN9=@+3a;^v-$qS=$#?@^I)bzkUHiUZq-@h@)^d%juA5 z0}3R3?pEah&4*1wXo+aTMR$wxJCDMyM;hg3d-JJ{2RMp*ea7EW={h>x@uo zS3t}g@!<(_Q3 zhh0{ynxb}No6qKrL+VKC$s9LrTdO5lFEzGw2I=fh?UC);x`Z|5oz`DWL9Kc3`>J?8 z%Pbl}|MB^3Zw< z7&33f4upQMj2biuEMDO{zGH7b8t=`6L@}&fg_CUAjiys*c$obwp60nW!xy5Nt^Tn> z74Fp)taQq@>4K&@{dwvhETh)r8Q5`n^gNdRfA#Focu`&Z5!7?{=^xUmrp)%p`eWLVX@085>bSNV#Hos!+gMGT;rbXMZX5f&7h8@-SC!Np%r#>{>FmRc$#;O2*nt&Cy24y z{}L(mA1+D_^78CkBSD(N@m~^cygYJICs6UxtR1W&VekgR@qKO=a-`Y+k#yw&E?wXM zMQ^wv6Y-2E9a~0)#2R}rh$SS}*kh|uVMb|VkNsIf#@5u>5`?Z0m>reyVuhPW%}JQD#eB~k3mz% zRdY87Taa#TC>V~FySP*XHGtUiLi%Ahl`JVmc2s*=S^^MD%pQyOlhanAozseJoNbav zwXFP#`t?mO*lvx-mN+~fOuW4&<$@OlXD7s_%iC$;sxXO#1-qks9F7tq%H_bpj{>e! zZ*M@m+lCCcB43g0JKy0p#{qKrRN|q ziH^Y;b3rg$?uo-OJ$K&$A1(WZ0eO;Y%|Xb}p-II)lCw#G3BQZ^oHs$2#K&4hloabK zM?ij~t&Cyud(UG#d!snHKl31R5}98NMw4R9iC^kvh3u^PPvhm`@9YS{oQag7H~%G?_6p+&i#)rpYAs% z8S}L&KEXc^>nzp9!Ts7mI!ZAb!MirKYf#{!OX{u!NLy%{=z`QzxB=__>%C89;C8bn z-nZn?+Db&#&>NA-bD^G|J>xYnWn$iBKzDgxD^%&ygOtOVx><=}kuW)Wv9zx&v|}^!Z?R8hkYC zU2Z-t{q!2-g&w!i4y8Np4rReJiaZSQZlf%34!!X5ELi>Qf_-eDb@^ekd@$^zX6Qzw zWot)R{IvI#*>jyZW{tDKN&W5J;clgQ(!K6%pIY}}s7p)tolM1aW=FDc{pZMIxraX4 zQiFM2|K4V*&WGUI@h%fxo3TDUOhvy<2=1oFS3$;%o}M2yT&v{b9Urri9>%|DH`r<;(?EAL~(pTCX(S>xf{b}|j}yEX;+hH} z^o4vYBdEWdx=;=8+TTS^8frQY2sz>EVc`1tnMb^^$FzQh274|YmzzWOALKQapgGsJ zb_M8#S=;0yeLmzAq=m}v&b&`agXazxnP}pdarh#`(vZb*@BPex#@&}TFemAF8-~Li zhlspYM63^Yr+Edu2JElIW*ko(UR*+J;6;Zwf~))gu_3>$ovbn7zAGY^d


WqUP?-I=H1pCd-RA>*{lC*f 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
{#x5taHrH42g(@FthqPW%~{1n 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%0D8*rg7ET zJ`!V*f}^cTP5kb-|KVEltA{?pMPiZ--W`j^(mvC}Wj zag@vNW&|`XdQJZZzbfmwdnZ<5VQS9TcsUn-;agmP-k0%kj7>WBFjvu_oV_*n0qtj- z!<=pJVjpe3&t^z6^QzW{JeF>;1VZ!u(5=lFUXwSni*PzQnQt}1bJDj!%jzv}i?!_b zLO6orlS@$e=1sOnS#p&P+HPulESzT1{rj*_DL-QPOtNYWjO7)b@&%cE?5M%aqWV&U z!s4#a@jm3?tmQblRBfRjW@3fpNqSzpW&Yl$(!)oxQB|Ueel=n_W_!-Cj@Yn5zl{P7 zhdTe|HnWlGK~~(daUGQzm6D4KT!4dE-^j@Z58(JlqMp0KZvQwNf-1SA4vxL1oyM`w z*n>FgroDnAY4|=mUml-i&yY3b!0`4sAvX)UEuD8V9MX`BkDEg1A2?g81KI=(66Ks7 z!#Vetbl8H>ZvgWW3gzP2T`NAbmS`OF;*&EZP3q6u`S^=cxe;hK?%$3X_0H;qn@NLo z1^IN!r&brD`qQjIjsD1;F&P%bNV^T^C)~N@hJ4HV2MPkYnpIRz+t`Y{^eZ2PuH30C z90ejwm12)!=HVOUsPmARE=} zCHS2+C2M}(m|h55?q82 zT_67HOS3&wGlUo(w$n?nL(1hYFpEc?^%alI3|YduLPe`{ zQe6(^R2`+W&lU%et@f8^QAnA=Xm$uWlw9LrU zkW0;4U=1VRsF4=kG7Re7lU)FlYWvHOHLeLKR5neZ;}$QL_JT?k(WDlhn21M}er#mL z<>DHwkEC1#`Dwq8xg~bs`U}v*WBL)8d)tajZX4@FeghXTa5r>2G`73ywHXe$AC9@T zz(UN%^JSl|2(tRi4Up<{24J_Ca^OYWYTji0X$HD*qp9hoX2l_RuD^M16rXEpmEl5t z0gFQRW|zk4+3h?WA@{4#yG||5Hh|5tPxF+6_aBFY8tL8OpbX64{|=PpF=^gpkSsa* zyz|K`FQ^@K%@i<$toLI0@_?71rgxc8VWFE3x$(KZ%%e@NFCSXLmjCG8xbXF^*g>W3 z&T$#2WdE`hvZe11OsAqB3dwlt6fvO6b20Jl)8E zQ1-uVAccl>1+qJ=$mtN+wjH0S^4PM)9R+M9@}ch5sD{X6{+=1Y{^(d3Cm$B2XoJfJ zJ$&E8OfEX?s1V^k^!la9(1sa6(~`%@%$ZP(0B2F*LX+Z)V2ti%m??S9F&vX${0H)o zuT`Mm-xIDS5laeRBtH*B9DnxihmEw*g8vbCIF0;u3Ck$wBkflneI3i_eOK*gq2qUO zmi}MvgC(8IaoqYrEeK1Z{hcSpOLwvRz)0c+p=7ce?wb!0PNc2_q78T+-(iT+*VHLW z%GECB?8=a1P5P+QOjiC;S(sjT3nxpD#c~uH{EQ~Fv5hrwa%`Pi$C4hnI;r0eC)BY8 zKtjsfr-3AvI~yQ3*6a_b;ElsQkZXEEhf$};lzLfmCF-E*nFj?)>irG2RQ|03BlTzD zx~|{5yT|9E2EI^Q#ra%(a{`Z`Uv&dtlOv`WA`&1+bZ;E`FYe{YG?}UXJhnAu z*?DlEJn%4n=dzk48t7D7PL;n+PNwyxL4IU$F~72@x{C_GU<@Q1YLE9N*pyCBQ4lTO z?M46t*e#4yKZ*yGpFk;-HiKp3QB#8E{f`CqmdipO!k1XBx#ZZXV z3|;6+$*fL|Y{+J*;{!*TxN|i+s~z?Uo~RBHF>`v@!a^Un1HUP^GkjY3W*YG*t8%fxE`{dy@O}9eO?qt=H_EejAZ1wcyG2S^8zR3K-COC5_yl>z0@|Q%!Z&A zZ^1(YBR!B6%@csywEfM&_KAa7&4|@J_GoG7M^lO_y|8&FQKDw1<~L1#s-5i7Q`ehn zguzy*C92%VchM~-g}M%@%~W#W6sg5qditxPa?sQTwT%V_L(~O^H8hx+bSf&CwJdbf zQjCj6Y7{4!l1hXXreCri8=my&9KatjCFnPirp8Y^K^FHt1uWj6udy<63Wocj5|e{H zZrcW&EU&6n6sMPJfdz^3R|R-CyCK9QIq)UMo_hNgC%I@hGW~0)$)e@=ur{G_AUkQ6 zr-bHj@>pmJj(s{L*AqfgEg}Zm{RLh|A}dr8IFJ|W$bX)Es{6bGxcFxgwR`wII50gY zTUV1ddxqJ1u*i@=F3ybp&|2h8m51={@7-&~`Aj|?0QHfs--r$kUGYRH$5QoN3t8mK z$qegR@?ZyW{D)((n>u=YDfnx$P@mU%rufX$I4xc=37IqqIqiiGB0E38PC@>wDx?u= z+Sa}gv`A`6r)(`lSIk%gUK{;Q+x|jXAt8a%Qzn2i=Fp_l8iF?={725%PN}qffrz zogAhP0q-j#J$aM>>Iw4dYphW`#}lM&zUMJ9Wm^F7zqo&*uE|T4rS<@o_Tr;F*px?; z=ZiqwixIT4+%B-O@{`q((VP6)q^HW=0+dE{EJ{%G*#Za6f6D}d9gks4KYI{Y+J~n! zSAlXExZq&`_b9+a+n_uu1Ac?&N9k(<;7WTR=gIvwb` z&u@eBglbS*>Z)}#>n~4$u6`Sm2O}z{RqNOptsgZp8f=6?I~w3z`Q@WR0Gq^E#1E>{ zEq*KZ%p1@#ApE*@fsb6y0V1h})Lw@$FI`c&AVlZf2T#bCN=ul$tO86YUEAiOuBrHQ zW_Qfdu8%xMx=b;}sq_o(YxeX)@`O3hw8w}wc)uc(6b&>v8zWsV$NgLx0W4}y@h zvXC2uysJ$H7Yq0*8~i|2((_03CM?t&rF9vd?jIBH#Rjaq$?gw-Yq-}B|w5!n9YH)&D3eGFPkx;JBgbzSHKx$QbQfbX@NxFVRm&>8YvKmKYMmO^M2 zNICTWcp+K~84qpMPSUF=pUEfx5z<-AyfPnJ2{R9U75%$4a{ZES{4u4u1rhrCY`20W zaj#oq%FK_gHl{!)$BrZ)q7Z=SDP9DfiiF|)=HT{TYUlZM%` zs`ONmAxUMI2|WG)A|NoS$V`*(JVzaS5fah$10;m>4Ni8{GnD`r)D#0$;Lp(6bnR7O z>v$78_;VT$YAwyKZ~%mHKa@f#n6HX6IX<2f^_S@J0c6vkeGydr)DVzUr*v-iyb=7f zV?K%Li+gZJ(5pQl66Mrl-bTWl6AFV^e{yl=)L&arEh_$_Yi=3dJ%&8zWLDD6NKK1TbcYJ0?OqZvv4!l&`E<^*OIVRS1>73>H;-uZ2CH zzhjtzu++b^-4=|j!skL&`xI-0#b4EcS(S!^u(t6H>%hz;g`!7B{U39yAXKM}f%*$8 z%ye^p5j2VF73DzYQAJsu1vLa+J=X2vRKZwJ(`i}8kz9%O+4iZB)@l5we=5n;)@{Dy zzgJGe4X7M7&5dVh*-+z{OmjVrJb2f~Sb*(&|56#7Ur$F)<0r1~I-720u;xXB-~AmQ zrEg0X{L0PFk|L9n4wwodS7&cQls2ymn_RXZ0!x$2_9)c1ju{r#&*~8rtw!mY4Y&@L zp35_Q`i*`=hziU(k#cGng*zmA`?8B5gLg zk{NMLtm_{?WjHm%YTerl)d4M5Jr3%)ZHMgL$#rb)I=J|4ZxK=o_6;=>Wt7kDgC$m2 zt3HeZOPvB}qlJ(rvB8ilm6xOc6U{mb{W{=yV2x0}6SRF>;RT~PHeT|Qw^UHFfeN#i z<0Ec;3`v4kHfc0%9L1A6W&Jsz-_V##9YAa73OywWuu2*w3mDlceNl|=YL9zK-O9{} zvaGML(RVtVWHxSZV{i-&Vhh-*b(=M|g2g-FN$Z!s@f9BF92)8G3f-^=dq8w)_*~)&XB-o)zL`|0hBSDWxwtd^#3dw=x`u7+>=5>Z!}=_J6D{1oJ+tkf`D1GACpUv-+8&nHSbGM{bo|GYVeD6!{WJrEd!ENKk`67rE9;+u<(BNGZuwN5Z7>^}6od$@rV@8ObPzg-iwK4kO8E85XXLR)01bygx}{uzxziy#mGJS z@!fpZM}iR8=SVxDd*6oi zBafTHws`FxNQU(L5n^xh)fPZhqUOnB3J)IiT8T#2pUput@J1h7asBLWWhrPJL0|!+ zPH0O8oR8yb7N=QYT!so;?!aSiFSd?9zxOMpM3?s8h zFJbbRiyr{Jg7w_?xU598@y)KqhvV$}fsbIRblw>=Ok8;o3i^je$h@&bdCfxSWn8K&#yO&~9)NN|Y>Kb~K%$*3NM5N#^ym$TkJ2sX>Q=leZdO8m*t{wUW z%7oN*pfAYMC5zlP7W(O1Rgx)R91)Cg7j56g>6$FNQQ@UofZu>CcM5nsy@q2ZIN!JD zp&JDzwcAGp4wQ_df*#P^00X9ex1ht2q`BFls`Txz-vcR<(bct36jA$`L~oa>fWRw? zP|}|xj*-DUBq}8gAmeG*efdnfVlmj@nynfRzzuQI5CB-wE?y_+BKtAnXvYXi89n$( zX+Ayq2}GH>$3So|=E;zz=1L4}(bcO(q>`?P6@d!G2+$O|XKM}g!UJ9qBpb%LK|y2g2ojXg zDI>YIOZHdDRGBYE;MwZQt3Crgd51u6OS_gAc{@%z)fM2PBV`(`{`5#~e2hc@fzC0YXcjq1`PFIu&!wP}17%TUc25({sPxjT zHW{h<7{uxv#Gt6M;dwTL9Onr{vR%~TT9r8A41YUzZJO#$kSRKNrF*IP-N|2qtPGLWy1vH?TZ*8#UA zYl)%yzzP7Pk~u2gzo1ufSqQ4~I(R5FIiQvNa~?*u2D~FfAl3DK)v$T>>J*BEUx|@- z)OzY#SrDR1RcMIv-zFC-tnGNHDmVcv4>&?{66O}%f6y8eZ)wRKfq)G0h{(An15FAg zzgB0o@T@9DU2j(;Q0r&H*jlTTv}CW{LO0CE)jHoQMd;%NQ<54N!OYL=X$sP47cfC8 zC2G|)HIU~OC9hym$9iDXS@ATSKqcz29=Te;KM;?NR^N>?KKX%j11=q;ai6vEOdv3>uJ{05CXz-%P48%JKk@GVO;PuLmpu=bwla+Wuhyq5CR1tMJ zJNhkmKGXqmOJiZ0$&)+^4Nc;LlnjDEle&vB7_;cE!N~a&-1&rL#i|%Irp^CW0b0qn zgz3?U=Np~m`b4i&_`}_SrRYGo2=m{47?xGiU4mChTGfHO@0H@=#c@VHj(UQ0>Q`J_ zXfs<#VSf$f6ve4#0*6iYMy&~^)E%HQGUc1IDhKjI+M4p{Cld`0*wrFITe43Fn^N@k zQd5LJe6QWC>NE}AfL7MRfpu*{OOy2b zUQo8zevM6e&Z{O!s(-CoCO7{cN8)RZhD&5&HY$EPJ>Zx+WA*;A&gk^EHAerla(*tTrgB2SY{q5vw>-!*oX?Y*{BhXW#DCgQLbZ7wJ#`)}0Q()= z%AMi1zcJ5Z}gqNlpSG=1={$wKFJ$F)A2 z3zbJ6mM!Mjq3=uD_s_CUf( zyRm`_Izm8r&&L)RnhqAV?NfyiZ{bRFld`(>l`SJyA)j(GBG5yZ7l zbk?DvK?R7s-GTtLd|ZTWLRXYen>WUM_fjx*%RV2QN9KF5v83%bsu_sWeV2VpGqUgR zQdvW)#iYzsbDH!)4xz7=VxJus<6-%ubA@b?JscaQ*rnLf-^Cm#4C1K ztp`Amem7>N{I*F)v~OWY?Jt^hX#P-;qgRb}aZdBVIytO{SNV05k(%#;7)a#;BURRm zDQLE4Y!v=2YBN3kHP;jiADZH{Q)L`3H8zwmSE`fXf=TmigFw)ha`A0ngz1M|6Qt%y zZdk=RDf%yzoCXl^tIH4#zjyRGy72v8(Aq-?9O{olMVJzH>xKUsp$VRzd3T0?UQJRv& zVhNz4K3Bsz`6JH-whhBTVpdF?G6G*V(WudrG@@2$tApxtDqk-Ef0rL}duifBgP)N^ z69Xjcr7jRqqi@(Hs@uz368{#1Y!6+^H#k{z@qgAJvOKSZv3?y|iTSl@wZRM^~kYO26yZas`4?_<-#j1bB(B7h&kgFYF^TT?|{Lxcz*Y}@}2b48lB z;*q(y5w4}^xEzjI<6509$f(;mn~8~wwwcQ@WystKz7Vst?hGV17P#C%us|o&A-c{; zV46Kehs?5C7>Ug<&7&#No~HhTTnGm~(C^nKn_MvlDxyf#+TuL1(Db5R~$ zu-;xmzaNE&o;>y>Owc(q!Lm^D(%48!c0uv#bd9TY>N_0JWzSC@J-t7%KnMIeY(~MZ zkhzY-3xi~`5NHi<+X~izFJ%mTAw)sCB?~P53MQ^A@+W8Dz}Xs@*vN{Hcsr)R+;V6i zQT2R22_4eB38e1#-kctH)O8cq?TxWv2m5yOYQfc!>7UKF1~j>OYom=~Y|I~rtr2E> z+EBYNt>DB2zxM(gcWwZ;F;jpG4sBq;SxB)Mu5LGRg1B#^{r(A z#JJkxy}tKR!IG_!&;I^?26o)c_pMlP<&}yM4dsims>nltC7=YvJk-68;!TL;rW`WG z)wc*+_ZKkr9dnlofh9$;6EepgG7P~#W9Vf8ZC!k*ClT}970)#-Pi!4vJuxx(G6 zj^mdFsV=*u{l({C+PA;)!J(6!2)e%Z?>3*79r#}IU8}VyfrE~ zR>DiIHYUxg&;63F&N6nL-#_4`3+R&oed#e|Ru_$0N7eIGc{H?L%KRqWc(CU_5w+E6>`%=0kb@j+Z*oI1S(RpeP=P}J zGM^cEkc)8fz>$PqW2WQo*`hdEEZ_g+*Gu@GDI9~72T`=mI zt9MPGmpxc<3Zo?BUV~Z@t-|-jc`m4MTt6f89 zimVo$xJL~OY%h;?T6qnFe0{1tpT7LD%EhAob8eXh-u$;%LeuRJ1%~vC--Zd1dgxpI za#+V=eSY`(Y3d;_pmj9>*dm;JS)jzY*ct?^JedIU_HI5250Y1_~ei04G2iK`ULA>Ecz0X;K30sgv0$VB|;Q^C{7Hs=Cgq9p-N$v z;nT3B!6S!#er9{c>m#WL1~MA_D6ZwGIXtj-Y9 zRco5bOQs1CtZPrT0Y;d+tW-~%zit4*OiKy~xXT$;J#jj-1NO!CXN#R^IKc|{#qo`<38z=FCCA^fEFY)RVXHV; z5v75K;LFhOKv^Z`Y=Z8o7&I`4mO^w%O$1drj61YPt3gABrE%&SEynR&_dv2xq@jA( z;Y>Zz6NmX>F;Mw)>;+06-dQNw87hr}7MPh-KLN{zy3S}d8fq)%Rj0Pg>Iil0v%}15 zR|;M17tx9O(Km3>eh-UWwBP0;i7qSTHp!Fw$XX(&c4s1AmB?F=kARjqKwkzf%rj(F z=$8~JXb-9KGAZ!24~qg(S;p2fg7O7%u6SS^Fw zmU)@w<(QyI=<+cftOwguRN7L)GbrSbux$eDpL=Y$M`imLMOxZg0GW|RfFh|%kCm2L zU^z_@U0L+Y0wKwe*?a}dLiRTnY^dY?fbwJ>smW|CXa4Df+>0bF_Sm7s_BY@}ZOATh z^k5U!-Nnorzr#Jt&sCVIJoI_XYjRnH$CdoG%iyPx@3IqB$qxlKN>FW8hmt4Hn{P~A z!gpN#2%L%jE)2bg63}|drx@){-hS$m36F6z+g}w8$Pi`#Afc@_X=}$aUJ-42CXX*h zI*v4wH|CW`INS*)S8L{mW^uS&^w*$=I|%u&u;j!G#R;a5Yj`avsj!71mzAAjIRG{R zgqunG|0M>{tV|x{ zl3JHaG(Dcv@SSdWhAT}*P&afX3^#XVDYX^!+0N?TqF6U_zPJXf) z1*6)nP|f2yaFn^k6F{tN5Axd3P)I?d3cw4NSJ$DPx;KYTKje|=qHJ}X-oAh<4Ehs} zi*q|*2(G(j_tOL4l_4Jgch6!!>I5eghnVy@0j75OZt(nQM@2S&AtSWb0Q0U#1Q$WI zxL55b&oEr+Pdl6$9<@R{ZGUdxX7R46-mxYS6KR3z)m7qsYaN9JP7=#z=p`Q!wY6xx z9iDd=;$={=mg86Glov;1l|y0*ZTXJCqie2YlIX6!urEV(7rKbAz>CgorhJ%*zy<)s zUDEEP=A_3+y#=_EyaVbV>4<}C4F|2;TiKMNp%QhH9s}ltK&9=x->vgB)Z4rXV0c$Q z{4`Lm#`t+)aLxuUfB~o-s0M#B2UgJk0YmUoBc!2|#3D>q>T{5jO>kth+@2Q%trKV@>3c0wb@j(am@5tmc1chqZ9q1N`@h&S3A=7A;+DztFw~;J$nkE~H z`8DBNgg{sBA*Ogk)HS6N?@LZL@adPgLjp*YO74@qfu_5|1kV|KHZEiN9_OS9-8@2?&MY5*amS5E=hn zL?T9_BbkKBRIcR8P)HuJkou$sVG@-pnKMG9A8AhN5RFt>dLf#TB$G)e(vWBo4S}rE zXDlPVNHdZpRh3jxoWF|92l5s^y5JP84* zgh2&D6%{QYRaDd@AOWQsl`1G&qEygQjY2K8YQN=szt8b}_jerMpE>rlviDl+x~}tg zuD!vP6JRW8CnOfc*HE#&7`zQxfk=h07FZP#AFtwo0x$1Mp(mek`e{DJz{tnIut>Nkt7w6UcCrf!G3ZhJLT$iybsZA`Am&4fTM^ zSP?8b!?+bQ0Qy!2#9v|EN>4BjMNA_{ z$U0zih<&jA5^&oT?jkbo#xJ7s;5VVuEYNuv)?@-nuL`b)&an2e z{JX6a2;O=v@O#iX@FKqe2Ix!CdR_2Q=x>UBVt$M&5hq--jkr9A5nyeXbQs_&}jo0Au$vWYbab)t5M~CE2@7B!S44_Hm!82aA`Zb;vO$;Df%y}mk3bf}IP5lsK;+0G z+3S;#m9P*t=;1mr19J84kw;;C_7946A}0kYS>GGk42xug4zF{9m=x)Ak#g8N_8CRA z$eCr*p&yMr2a92!Q*6*Vi%o_=|Gx;^#6GWx5xFQ#X7sa=*I@DN9~B#QE)Y`$wg@>0 zOJw&bVntwXwa3;Y@4!;n7Zq_jFllkI9mt2UUF@F}n?zuABxC!KPhsio%Zkl9H;7pg zb_n?rwvT;9u|?$0GV8#OBY%fwv#%+(>c9*)1V+aKESG&<5ijykn9X1pk^jIBvu`T4 z=|F%$;1DP{ynqb`iwI2O_Bav>3ol_0DugAM;XH_*tZmkB2R^RGR_-i1+QkS z6-hcUc8b8*p~36eql#n^m@GSR(I^-AG4>tBb{$h}F@#G-dBL05KPys1U?|PtvQTdD z2IXBy3eihyF^0=Q1;I~1@3roj_FA%l;0sWk!nSY6c6+n9ddlj(`E4tv68kT=H%j1W)jmSc4M1p~4rE_tRj2 zhk{qPUq!?hfEk<|(HayB#(R_A-NISuA~~15LS`#4IIH)l@OS7(@}brh6JYpX)q7s} z4!T6nBd;_EVd%ErtHK57C-Qf#D`UZI@I>!z;a||tfw7gXVu8SsL9*5-BFhWDO8%V&Asr3C77C3hf)zlu zU?vGAI}**2M_{X!a>zO&2opNGgH<7+g;Frjq!InlHV6Zi z9<+$aAyTS{p=bw$G3<2f`e~;nl2|_y?N~%A&=(dfIH{C=Vmz8rWL|(1mau{oO#1Y< zAeSSoRCs8q6g;$fVk+_{*k&b&I#L&niH?|yURh)ZBT~x9TyrYXumT-Y1m-A8c`G-T z$}ns~M;0xEkth{po{TCmJd2Jgaw)ht9S3nMGY!R_LXN{+Iba6s=1o(x3FbT>y^GW?1b7qJS+LMbcM(cavMfGI2D7Epy?_Di+*GqS}|g3 zPWxCRcZ{qkqJS<0li{5G9QGsfbHQQB&1n!Tb@qTDVcHODRgRK+0iWT}0$$sB2C+fq zEJ+YB80OYEA_@a9hPt$UKh4hpGiM^EwOvQZZyrgOnG`w+2?Se}X?%f?QAmv~tRZyrz3W9x$iAH}X@+Z|M$$3r8w=p@T z|Nl28b6oysOm3lEAa9g`k@ZGDyBNeX%8#uZrIayZDp;;sR=^duOM@p|=7~%CD~fIu zY}5WoY2^U0>(*k+`!%1Uxk10rP}Fj4MD1gdPHHPY1@ z+PvWs`a6V%lgjR6Y$DoAP5IbU#UPGCYo(h6_MN6N*dvJ5DjKwo7$&uk0AGXq9ucl` zfF4zB(%7eg_vIc(M5&fR>xq1#LzPh|<~(w}$_e_tlrM4{Fpb5WM@(?i*q4amGPg0K zR7_v-lY%|kOVV(K+l*-z_8RgzXRq?IZZpIk0V4DuGD+nr=@)EaxLcb^v7^Y}RQn`X zG$3FHnYCi?BVVhsBv%DnyWO{#bz>)yf2gu0*EAr0=b4?w{!;t~mIJ*?+$wdCFzdt) z73&IegagEQq6f)Lg`Fw>P;ihk(7n~qqt)yI_D%7hutROv6Sj&x2F!-By5gmRJnePH zwpOt78|=qo5c?@N1=}=WXC2l-@&%R;y{_5D@>nwaiiMOw3dKSNE5VUrZcf0VOAv(x zLXa7xGW^U_;J+2W;bdr)tSw>&(Ts{4LShE9B{#+KGKRqX5jNihg&j<59S{jw9#XU0 z*guM~gSlFjSSVsdn~i{<;6JqWL*f}8M6-_|Ltj)C3kL*SSd3(IZ=4m15L~Jp)CnP; zMIh;*p^Spdl|v$suy>e8<6Kat!IjEexi-Sq6SYx$BDa$ z%d0Fy@jsx}51xVkBHble-enn!Kabitcnaa+}_m;%L&$m5F*uBIA z?-RveL2VtpAbG3-S=DDtF+R5>0e+G_!AK+fkgTfkYE*J?uVkV%ZNkGEbqs$Sl@feW zIjI9V7T2l+{}8nc-qZFZVNXA(e1@@;s6B&+wT$jGbB{Do2t7mX9lQ*kBBm34tE`6c zGbQ`r7u!I7mII3FcKm}9A-qR9B?4uVtJN5Ot_0*~!e^|s1m8ZZDg3){TcOX1d!@c( zR(J7>CAo#ywa+zM6~5zEAMk&n@&>O6Ck1IEzEf6<_&-bX2CoZ$)uhXObXH~fFQ@~B z1Ik|o>7hPE(5in?;$Q`Pnjs?lk*slqhp2;tO34$ksLU4!cE*(Ez^_rX)9L15=NBNU zEDjzJY8hz^koj2>en*wURT9t)nNO>kE#Y-Z>9{2D$%glQyRNzKkktep zqn96iKsX^vkM-%ZA`=Yt$_IxeF9aFgep`TQV4-(pa9HwElcDn~GFwR?mr4sqgrE*| z^p{yj5*$nG3vUZS;g{;)Zyiryl*$UngrL&v^q;U!C-{}N6y6oiDl(V+7D0-+O0P9o z!=7VgkpoCJRfN@g9l;OSue-An0=z-S8Ku`5Jg)qWyk8a|usKV}k10I|e?4WL3l%hbQNV#RH`b}YIWkA&>%-!Q-i9~ z;lh{N_mG2SAbX`7)R*2a{7w5od~hTv)z-(Lr4(eZ+6721dPSLSh(Sl`gWxC1MNuwm zMTc#)L1XC)PDWdQcP=ZS+jf(|h0@3Hc?!sFWuUa(WpJtVDf}(;FXdyE$69G`S8s4f?^Q4eoH|ekbL~0|9_qab{!{r$^qpd5 zvR$9SQ@yvrAdc$3gRCmD8!~vQ_aXRiaf9FWJ_i4zr4i#rs|M_*4c_bh zJ@{GjRgmAkY6{fQf9ri21c|UFU$^Qr&?um2=n$j;Qk(0@GABPG=z-PyK&|Q#C$PN9 z)J3(*4&CQlB^v#^yt4w7hJv^AH&(d#LkW-pTSh^x?KE|G)w zEFyDA6ag`$jD|3xV%mygIgSV!aZTCypjwH^$j#xfDEi<+HHE)uY0`sboKVUsVsx2v zk;w~vN%08CxGxd6l(`p~y}-Vg2m-r6-$*F?Y4CL$rZyKHTt*otCYMbX>L>moC}9M* zP&CAy=;cF}FEG$z*@|w;6JmOqFT$Eipp<^QPz5#<{S(}#oggfgt(XEO)bi;b| zc<>u7d~JC*cMHhn2TCJ~=!wS4@;UAzGRW{GT7bY%L27Rfk_^7#sj~G5XR1jXQNUY7 zJ|LV!$8cR#Chsf6ydi3=VehxQAvArTAwX-Wy9_Ut^#wb=FqKq}@aCv1i91WT4(Sz` zfn(8&R1)k)8J+t^YX+@ybSIgSV9K&f5WV((og{&Wrj;0y%U-C|&_AWQt?rY=7L1YQ%Vjc+2f4#FhyJrhteZW2=%tN zHZs7Jak(6-XKia}w7sj58K#OG!lCulPKRdM2N~I6q}))By=NUctRCb|%P{p^KF6V_ zE+MSXev6R@M#hcc&^?c~hK++X$`{kZjpQurIXWG-2+EUHm{zWUPe)7CBrsiZA~Wc>G)`$IQc} z4!4a`$}b`|Q9_;h5}vH@eTS3GzHa zj;dcaW;}~o+`)vF# z2Er3_Se~t90m%_Z($h!q3OMYZ)&zmKqczDuAI$?LlxJJ3AllKDWTubfm2iT4+NK3r zjzJ_leIl=n!&S;sBmC&L#x#8+Ub%{!(au`i;TTPF(KqE)s(9~#7(e8gO!CsVte1{7F<`nJ3p)#~>^20%C!k%IN9yjoRgMh9!1y;D6YT%XPZ_160i@j9+k2Wh>& zGw*v9KLe<3$xeNw&HC;8{*-wA zkkbq)Q$K)rTosuCq`4WVMbaVtl{`?Ky*~|!MmQr(3iUa>HkBZwlND|6Ofsp|58=sG zYu|T@qq(3~JF3s;{h(Tx0d%}%XGfFo^}}!d09#*srZqa++0~>$KZ19Pv%crdbaa-p zx5E>#Z-%zn0d6u)j_N-uo6zqMbVgvGA`v&b< z&HtVY7XAKg!UlzNqDf0dWbvuQ_0Y4@4P(w6lfH_zw|XVfYtMFWm~c)v>95#Qd?9h8 z^4#2pCFjE?ii(8d?!;Jjmt%~%ORmY6;v{4*HLk5IHiqHS1X{U+ck#tKZPyZjAO$9> ziXF(lf*azl95Bs+Q|a%#)mN~oCp|SL+NI0n_mbVbi?Gd-^Qkcj;Mht1J;gnVn=`sX zV}e|=Os)Y%<#PLG?fIn`u}hwbRzKrbzbf|rdGf}3mod<)Oyt#q8>|bVpbVVDg6kr$ zaJC9Bw0eZPJTe)t*dN?qu=V~0Mod50I$Lp|xCd-KFW%T?)nxKs{~#}42sBXHMsI)w z)D_9R>#D7iu5R%2jmfi$ud0C;@!AV>G1D#|Og>e7hrHPiO2{QZpJ1l2N(t|#YFke_ z%Y*2uZ;GlcM5?I5w(eL^QCgZ3Doc?=)I>^;ELPy^Y-(Cri5#XTwe?H@bv3}$wz38} zLQSUhn#W09`KEMi>8(-N_S#-ST$gKvscYr2;=vcm+TPH(PS=$L53Gy_YSoNxR;;}% z$rM{DL*}znJTJD!ExLR*S&nVK^)qZo?ZwvEXxA*$K}=)+T$mded<1SI!~H&ij3H9)50D4WqD~#Sf^vC_l+I3Ea+_ z##Ej|KBDe!`)LAbzE@4-EAx>G&bIeIK{kIol@Qx=Yoa}ceaUgN%nf`wwGxz{iOD^e zWShF(o|vXrUcPmwJq3DMv2n)bh3US^E68W<>B?>0o2T4#pg8?Mt*X7O*{pHn0m*Kv!vJHf21a;W%4V#fQ7ge~2!vEasb@m{Jjl)VXY z5pKIoYbxKt?!fjLUXgBbbz8#zfjo6)(rE^QHo2!{C_89U`!S;+R37Zn!nPyFu zKY#oA?bvQtKeOZ5d&tM_yWd}#^B8w!nYCf_k#{&*o>#wZZ8dePJc@ix-QL#gxV77L zmuVgLSn-T1Ywbn9t$v^xu9Z#5HwD{kLCM_Z9&6@Wc@>%8c3pE-v~|GU8Y~)|;LZQ% zLL=_EriRdQB)A)%*IKt`k-wTIl|CsRRApyen+pkY`*x~!o)~(d_S%x)xa){%eiwGM z_$}u^&$a2Ti=h0zQTgkwcZmm-*C6rp?m1@HE1x0XwI479%^* z`U{q4c!RjD%45XrH|)Z#zhU3i-eASsd(@lV!M@@xs1CN>h~3uh@x<(HA|SKo0`Up*VwKJ(>itlWkod6J~#4 z|GM=LtjJJB6jm`p%^h&Y!$5qjRSAUV=BDN@IMWd9VDWpEV%v;Ig1INoVi?rdYX`f9 zQw)*0KMs^2g{Aj_Ch!@62sRGnm4#(%hZu?0o>KELoWrou%M!`p2q?z0&4a3JQO5Fe z?NAO-4BE}tRZ&X}UzSORLK7oAE6hWxfSy1rZyRb&jP~p@--vS!F-j7NTleDvhi%|BwQ5aLizjej;g%0uCe26U{6^x?GZ)&!UB&RZcELy6*a+bmCw4+POV&;T-8_svwD!AVBHhFtJ^Q-x( zs`V&m+V}UjO?Y%NV=TI=VoF?I0y(8@`v^0|qOWRGiQCI#k~<^Y=a|_R16A=Q9xs8q zf=)qul~@c_0hQyWOfnXl;^=kEVyp_tDK8tLKbNJ1dY!Tuui90z{AH8m=aH0DuS*tF zRp}+ZFPouv(L2h(UCW=r?G5oCY%%;f!M6p-E3a|;hXV?a-@hx`G2k_A@g8?@IH*vz zc8rl?4ZzbVZaZp){DkmcKLAf3EIw6zhgu~+slB%ZTnjKu*bxbeEpHWS`~dJZveZ9P zj0%>wX*D^3|5GiEj+74{mbBmB)(NB;cT4jlRV5)wa^?NG)Ew`XmgFPfq?wcV?}d6) zd52m$;E$rd({@N6NK-q!>6ZT>zen-pH@hDs?CkU2V(EdGg+$PPXnP>tIp&>exg6g- zyas-{_Mv8HmsPf9(2)}*Q7?gxgWiQ+USi2T(q6LmW#{`lkQDOrI!pc$AnPPu*Npc^ zcbVl`&ZABb0~}@uRGx_Cot7K$=Y}`H&(;2-*_F1u-*PMd$Kj3eF2hH}-BruMcUJHh zhk?pd`$(|6Yx#ub9{lCu&F~9`kEOfEmd{!4$6p)X3jeVdh(7bnmn^@--yGfs?>3wu zrr~_hR>k<-LgCA9$wX+HqmQXo)sgQ)k_LO;Pl(gHfXGpcA4P>F^|B{B!A}DG*pWM^ z6dI6qCelPc0ahoD+(V_(`Y2D#_eg#CR;P|UEaAg{s(m8Z)8!LubsqnCcsKl#;Zy0J zF`rbcpYTtI_rNdLKGp1*_sOxkeq?{)-j_fyLZ>g96nKXL_vf1*?CM*@L~%Yqih(a4lYaR!{M7Lk+*7>KRTKk^_Xf=jK38x^4C9$O7sb^m^@c!QL+4j~4UzPn<)8*WW)E?;Y};vFfk* zJ0xtdqvu}h-Y%S`? zJV<^xYdr#DbwRMQXF5UDVK#xsS1%S6zErY-D$DYtS{qek^or#wp|)R?;K#JKtj4Q< zC>Xr2)rs2reWba>Z9ZsN^@?W03KO@=~;gj79)hpB8GhGr zR+>5HKWCl4pAe`%4!>7BtI3@AU$Xv=uu6Rrt}&b=X5j+RHpPTsH9)1cbAl|_0CSro zgw<*}{DI+XX;wslqs{k(aP<%Hhn}xnv!VlBZ5jv>rN>|1mCTN0&iQ||ZX~QxpDKKK z|FteFFW@7#wOUZxnKaIR;|N5rNSn^;=+d)EfV!sc?+=K#>8_3~?MiyY{=IYmL_oSt ze>IT6k{&C6pWD9}5Mnbxh%f!|pVt1N$xaLGw|Pd`tG*1MGJH!sPzCg| z-w2uNEAVHvZv_Xs0w-+#ARJI%gFiQXCp|C*WDcwpr#=W3e`%u_WnEF0sA15E!Lo9_28hE@-`=j1!{kznsU8c@)yGQ{W%FiOk2yE zBYJB2OV4>-P9AVwQ4DI;BZV_-KQIoq0B4Ak!S{MUCjF-Tkb1B`DBhM)^Ir9hD=bJ4 z&YPv!de=0mdk0@-EGQ1n1ZCL<8k|^tFA1oLomsH~?lv;QN%cMWoZ%udH`b=amRr+a zdjI8|WHB_?am6v)h#GA0!@<`*+t40GW+!X~HJzp7NpIMHcIL*exL_Mw)1~fAy4k%= zlbg1p-_{J3w)#@=)1E)(a&uPPuuU+~51t5~_XMI|{faT$9R@E{W6(eD$A=#3T=B>@ ztp;d(FaLo4Rd#4(#VgyanyaPHUcQz5h4yf@`e2(|10=sfmFBNb_oWqIZN)W;(&;3f zVZ5XJycrBPg;c4Zw(EMf{ohj=oGaA6)Jc{?^SXc!tfJ-HKTgJ z$v+7H?$1kD$+T-S_@Dxy{63Hi^H#EesPeaJHh9q!aPvGfzFljLW_6Bs;r{=IAC-wf2e-!@H|K0S;eRfxCp6R`l|0Rjn zedo90u$`i2TJK%(k|#j$5WNb!;hLAFbHR&HYu4c|vpTy$gWuF23je+jgvg*(t#mTvU~hZm!#P)X@Vf2` zYelPBx19}od6A`RvS%A4KW*iJ-SZlq-iMcF?<jmRTL2^F2tTvGF1Z)2B*61m zRDLM^dr&D7&aqlnaqZ@67E3?TKC|Ol9yve(oh$xR?;rUW?N?Fm0B~KD8a!Y98Gc>* zRd=`uF=O{n@jt33!asoh@Nm7^E4#%SUFpTa0l~kafqB*+%$^(k11_x6#P{bnxGeQYI!JXielY6us6 zO^+fbv2bKPumT9ih4w;(VsDl;c|$3XTJ2#}XroxbawY?FH5z3PZ--8bMXUg_EwJFB z?GaR%1)!gNGF@tn2JW7ASe&GrwTbL51wyPniVAO(Xjr?*K2j?*a9Op(CnY*oE_tOC ztg^93QxO)xzED99kqSTIvD`2pj$dOW@%OYS#&{}Z>%aLqC#D)TymWgaDh-P<@ zHxgY#fuW}tsV&H250JMJL2As!F;SGldiEH32N9$WTzoG|SlGv&BJU;og#r1jmu`Ju!U50byK+xnGpV@uM6kMvW{(kc{*Vi>rXd`vYVk!TpqH#JwXx05&2RmR1FiP<|t3 zj`$;N>IiE~yMiYue-HsdK-d}?)Rv9~6DW()+_DujKo1@TgWx0Ov-EJ;su|$k056N? zqNs@4f-?3DkcY#{tT`kq*03Zrc!=_WC;{4~J=NH-A{1!3`+!=U%=M;P8CHh^wfKV} zw7iJRrP2)RLc@ma_W^g>5_=uhx%PW>c!$Faql4v|6(|a$R#p~~Oy?M%DWBk`Q~hdN z$|94Osf=HjFL4i3S+%WYf@DVy$q8u5)zr}1jxr!nsYp93{CFp*g4)h9pc`?3))ULS zK#i^KDvL=5((>zy9NrCTLTz_hY%(yBI91Accd4nhePx@H-BhMKEBkrRsiN9R))p=( zmD?)EdGl0IW`@RdJ$lWwm5aR3)O}3iDcdmv{CAim zWuPGFsC`hja|p8!*zr0-qG{(0AB6%T`h%t9$WTZ!?V{n6&^<#w`>d2lW4G`yPF;Bd8ATSo)0PS#A-j*H&25w|a{9&JfJa z+?6lBOn8g|o6Mhv|BQTxSXF0tzh-{*677rOzav1>HX<8JaiM5?q!D~n(gBx{!=#R( zruMixR2XxJ{edh2TD85sv5|gQ@epSpMJY`N3b&OJA*^&L_yYx6TNKK*rx_WAl@D?E z0l#4f5WHQCOv5UNcps>e+M&>7dq$o4DA2$6QQKo~9n3|5& zFKB<)Lc$K)vyCXDz^$_msN>_I)%Kxv_T_cSVJiEbb$($d>;-j><@L!xEI(5h3%ooV zjaF8k$mZkUD+@bF&O<%Hd^PpD&*%Vxrvbjs2CuraXJ3)5sDTt{Df zv@2}FevgswXfq{r3;SrFSGThK&yY)1j$u4d!&m`WH@r z*Nekg4sAwjM>~t6*8x?&g&%9!Sr=V?HW^roc7ET_k9X*)Cn;?9kGe7{>RASbq=@dwqq`K#JzAm zc#IX^?(m=v2<;u465XxM}4_I<_Rb`!}?PKX7xgZ29`_sO!($ z)ic0PifJs12%*~_tt%g$NiJZ9HFieC&|QxnE59?d9p+WuI1-UU*CLz3ejZBM2jIZG z*^(Wqq^10B@(z{P>&7Cp3M>I~a`YY|wZM93BVtVvJ=nNC?EZ`@!P~!yyrzzxuPv6T z4?_nu@tQ-9YmU()j>=X)9NPK8Thhc`(?MVV-xrQPdba$RnOz0TM*(Pfg57Ma2YKAF z`$NWD)0nji8-MgiOfEFd$j7j`YRw3JyYa=*NyMHypS8_h07L9Ksw;Rpvj^s@&7U`W zLH}&2{Evj z)ER3>fn}_B+Z+(bT5Pn%I?nr{oP9y;6ZTO!+&{%%V8v}9|I{5OnMD(|$luDJB9?l9 zzf8BPY1!SQfTY;x8pTUbL;$@g)bO&I zqaVU@ly4GNI-N8(ufTd4|DOlUi66=TX3Z(BS-^a<|E_&y+{x~!C(GU*1r)~qaAH9} zVHi@?pHqo;y1gx}KdR;k%A;jdymU#}o<-AYf!JlJYoPvB=L3qNcX z<$n7)SG;xz`00!|hHX`XP)7%n@ofyUxQ?^7txFK=*ifM>_zQkruw??==TF#wife)y zDlem|)V6*>yd$IDyaKnqZ9*}y0<`_-RP}T|;a2$vuB4p{ zs1tZaxxUGNj-3)TeLJ?o;I~p37t@Yjd)6_g9xy2fpz=<(&kJ%KL+SysDz1FMi)+tW zd&4oIo>5`Gy^0g!B$utd>zG>aU17QX$U3f2-nVwjaWBb_Z_TS_u5Oc$ubp>1Knmgm zfYrNND_>mu*)cz#1TsgSlo?9tAg#kWm6Eu80JM5Tg&p4Otet8|p?rH@9W$)0BYK^y zQv)f25BOGZn6@KpU69jBl7R2Xt7q~lKh&>_a5_zj<^$Z-%NPF8w{DBmkEB?>EAJRH zyzPhab!kqQNn7}Ue)WcHe^^|X=X8^lz-RDe%m~UU()ubVH7S`7U|4U2@RaxZ7N>ip zRK7Q_iMgijRP_2Tr^lo;K44?LYqY1b)(<%SN)qw?crDCG%IW&`V@|WAEIvSGy^+Gx zee0*3-jQpsJ7GN>*t;RBIWS`IqQwmo?cx4+38=Bn9t(1G6j@QQZ&w4&!mVC zKw7Ur*y$Z@?QCFD#^>_dnQPlRqoZA&%}lEJfUEVc)plk@2RYlBNco|>4(2+_nfmAm z=Vd1Ke1O?{*9p(`MQ?HTFp=>AS7WYkJ2M`g=Im?I!jI&g?p?1vvlyM{yvn4NFW_}D zqbX-e8>*aFn{@Ek@y_%{3(tCQXmO4*>EuWA&N4T&osHhm<-F0Piyy-~*9$0H)`kJ+ zZ6@9PSY8(s_$TWDR@-6H$KS*|-y0)5*SBHHd9O)7e+%ydb7R}N@eT9N2TTU|@w^{< zfxB{X!)NDw69qqk*UgNjbdh3kE~O?z{6t<)Z>+G(JI30j#$<$_%e65` z#!um0?2XfQWdU$@(nP~g<@GT)QO?)LM7W$b8Rzff{nWcjc)l-Yi_4ED6Z|yZCFbU~ z^W!mTE|*QF`02dMy@0YU#^kx&G@0g$c>PS^t|V=&a#5Si@b~eq^llMe@ZQ+sa?fOr zpT)b%+}d^_dSjQ%W0QG)Ht$;RR_%qXjRP*fn&|jBya6V#V%BdQbD1?+X{*4RWmAqP8fEGjUeCMD1TZKX5W0<~uHnaccY3#Ld$ZyOT(_Ar z!ezWMW(wtEecYJq4pZ;&Cf?7zDZ-0=aZ|2)P5r`Kcz2mQ+AfaA&Aa9wFbxU^h^}{s z_TpmPXV-jFR(LB=p?Y#TFslq<*P1bHTrlH{-ya&vkZGF+3T-_Q> zBf?Md9`^3k_GN7fayw}%2=C;LGXb%y-xT3?+B7=+Ebo`zUBaLGHf?eH(KI%^i}#2L z0N(hfG`Gv9Tf#5!9{29n{LSS-piZpO%q=7-rVAL z&oni>kN1SRr|nYo<}SC#rfK1qcu#wQyEJR_fZMO8qVRs+6f>Q2xqkDQ+pK9;_*LGs z-gM#RK7jY$ndXEK@SZdGwp||IJn#0GX zIrW=wA-JO(iYisxwJOmWK#?uo2@R##A%_>#j7H#Fb#^yxsKgFCyll^y>=$hbaJOx! z!Hzi0Q1@8?_{VprHyp*@cKEG*U)+`MEt}lk8yc`<4zH-0jlkr(%iX7;8GF}Zwmoz5 zif&7;`^tusSdGIRHOm6HS}WW`8syjq4zJs@;;u5bHn~SOoW_njyrJ%I1bFYPdrZSQ z>?4QY+xJfbym!?-zTrpggu^^F+v1vZ>uvXxhKtxI4u7;~$6f2*`oulG;WBp0;Vtz* zBe2iDanEkJhJEe;fZgOZ-PTX;hZ}BUryX?E91DBm8(_p+dQ>;4 zu`>>U-!%f9=j?H;0Wdg+h4zD!1ETlRC z3~*>Vf>vOml!9nOml@;q=}37&oU%J%6T@9*hQrYT`)gEc5_U0sWL7u=T~A&(snjLp zGFHm$a6~$qR%8L#Uj-vXM#CA=G4i4~6+_s>h?FhEk?8ug;zoc1&oW|U00q*q^5RLA zNO+YIFY~~e({Z#Ci$SUIHX}bp=7qDQ%5* zP+mF-NZ}{OVc9AinNFmYSqu>q^*u{u!8l+Hlb6K-aA@gSEn5w~%?4OtBOrFpp2uY2 zI657G!%1K@4)8o7i^4h5Nwf-!Thc_n=PB8GoHHF5I^u41CvNh*AOql#Zc3|cyroIp z<#|cA8Rt$nlUGjO(k144-jHp>G3e&BDvM!aQibQRED6V?Tga>8h8amso_A$CZ~y_( zjx++ich>WfY&Xt_ZY4i52~5maJ)g_=;{52=v}y~rH0ieID_JHkfNmqNj#GChJ@I@i zJAezK+tO+p0quL^`B8QVw~}rrubEWql0JEUmF44DbTUn9F+xn%XQCPlaU42DE{z*u zBwI2Gjiop)ol2{191$ctGff)-{G-$4wUZ;Fr z7dP6Syou@F*nk7Y5bbE=s3v(A)2Fc+7fD|xKRP+8OU`AkY&?k*&>d;@7PpDpE0`gT za@;z)le|9eHe-7eGqUkCE}9NlU?Z?cpJm20p2Nk^UF6?S-WF}Y%8YOP5f@8$r5&>X zPV3vul*Ws=O>{T;vA8?k+n+Gg8!zLw(A{YbjdwKL-!QWqui@h99`c6CJG$+kn1>s0 z;u7c#n#=;&vh}@68V7NSbWgb~4$wVIuj)oME}71xH8ze3Qk=bxHQvFc(7oi1lVhTk z0Iw5`_i(9nZ(5VZ&(ajW*Qv&bxLx$+@}@Z8(%$5Cq46;;jqXEhZv0u3vdimI<5OHZ z-B;c``Lix1*Xu^(uQ(CikJe&wm$;+CYq;?xZXexW-V%40v7^cBZsRO2iylBb-gsBA zg;XWgvFQ80k53Yh*AT*ZJP}6z?n#Ex416_2_e177+*o>$=l=Z zcc*Uhc5gDnSJ6Xg^2Ym`)Lq^_O;-47`f9m+^1d!L*L!7?9bQTgrFB?5AnvU24r!v{ z>*!(fj<^SmolV}6P0R2g1E>Aa_&~7ptanV43;q~AT>iu41JTZ_-udxOfNs(wXs0Y5 zN_XD&PHFPOH__L~PsKg#-uc8ky~!8fLXV`KZUnINjdylaApQhBN`89sp>F3V@54>2 z@U3(Kt1*YkapR0#mdmS~R^vP9>u6^h#|68bmmg~i$Dg9Fm!Fv& z7wrmIexfM~-${?AowWccl)wB`(|Y__`Ud&gxL>+=ZCZYzX(PUi9z#3V2*~KJ<(HZ^ z<1f%R%Fj*yqT7|b{6^C@d^bIo)@1=eX~pv4rX+kXJx<;g_lU8(Y5Coz9r!-_CffN% zz)jCCf7G-ae~G?XetzrxDa{x0Pw0E(m*Spw?|I^r-h3H9MNg+)ZUp%DjZb#-HT-k>Uisz8r@B3# zd=59?#81;jw0;X<|JU~|X&%JCpaYs4H^oS|^sR1I<7epmXjdAi1nJJc$C~fpU(qw= zS0=$~fB@eU&G+zg^eoy{i)YewzVE5#hxj-2{qn1E&$`n$`Ce##jGw1x)2=l>)1>e6 zz0?d?Fa3c0+T=4`damz{=3ntTdJb*C0(kZ-e21G~;y=(2$_L_}k8P0o{%m!vV&T<6 z`1Nw2Y@YHRZ+>&+&sSh!!RYhUy_bBan%^Gz>(wFn4a~1)dxw2znm-)*`&C}yjj&%k z_dfESZ~l1XpI6_(ZCUUp_Y@=I&+skWLu z0#}#69Lad)m(^k%ZlkWw1k8CRW6|%B^~y*)bm6=Ww>JW3-dWd{mdNU5vq#~# zF~61V3-Rx0Sy$~e3l>L&{noiJ#=om2rrKo|5b5&YM)sxn_qA-QcAGs`2o$EdecAp4 zE%DVJvj9+IUZFEf{D)c+t37AIN{X;oj+w{&$68XVy=DQgE`Jr8dCGshWmom`*`~su zM_;98UhTb4QOKhv_W+J6=-y9k@@%zWfO-;!M&I16BQIUvxl{1;nt zt5?jPCI&8M1@Ie?rurUFy$B$Kq z&jJu${(2-UCBXZ5Q}vozK)y#`&t+u?{MQi830Prs@-A5YVLWd52DiT~fM+AWyH@Ya z(ebr!T=#<>Y;`Jfz52|;xa18NNcHP&&PHxfpUwP5`6hXPU%+OY3y~Yu=N5i}{$8|y zC?LtEH!@D$l?kYM$Nuqv-8PpZH>=MtJd*rAw0|Zb)8=aAR`rEU0MTavL_cJ6BXXPi z#{~e<5!r~qLK{`2P~Dw5!JfCzCIwd73`ZuZdlmpw=Vsdn9<{k0xn13xIjNja&h`#$ zwz(U*Lw#{!68c9Gu&T>#9z^a`_hmj||Iv{h9eB>>QRHs*PYYm;^iXzk;6P!u?5^CB`s-JdzdertcAKJbpst4ILg7p5d{xqwAH zw0RS`Uwt+6neuJ&fxf_}Hg6*Vk6(BOeOGi~DDb7thscBKfz0RZcO3`D1An*q7zyzF z0$7YabYLcM!RAxscj_CNU@hm&fyKaoY`#VUTEFlsRENkx1i@`#Q4+NxbDFKQ&mje2 zZBbDG-Y-l`fN|SC$km2pH`gSHD|H%jYf;QW_M>VMLEc^yt zC^|S4lw`|{YE+M9zG5$Q92^hYZR-=&tp0i7m1JQE7y&YE1EP+r?`DGKsWS%`gAUoQ zi~>f01+d&4kqf?-X3L3cQ)@Ek*g!!gt*EpOiIS`DF92TvH`ji}QCoi059$Y*ua%3* zx!x<9Z6l*js~;|aS5p+_a#zT0*F~LCk7oj#Ku2!$igUIxQRmdZEWDBYIh32c;-c-Q zsPpPanZGOloXO2vam_Y9>PPkC1+cCiaj0m;plxDQk9s0=p8e4txCZXnrbJy-PcF<$ zK5`FrtaxaWj+mWMyTORLF50Sqa&D zWOl4`>~Rjq$X?mmN@NwGfjDGDLec&D-S>6f*M0v7UE=+DzhBSC!0`B?1HK9 z?u|eEfd(D@3p-#HQTbCTpA-l+=<5IMxuv!*?0-g?Q6SRbb^n(gUIu$~y}!INk3fP!fB(0gZHj|%NVP5qq!k1GIfH>IM z4LQ^dC{n&7Kr)!@CwuEH6) zSA#kB8I?GJK7()l+dKOqAQuR$ybu^N06f7HJSqD?c@@0Ch{5;%ogF9_2@lj%DHM2b zu-d=t3A92{povPEz?8vS|F50HkfWYJdzD&&8G|4Fd!FDbF9v$4yb_o<*zEtk^M~S? zDkxm#wZK<{?f!jF;1Ps_uqwj>%LY6B2Roo#X$BRkj0=zre)S)E9(5ht2i2*}3Tzns z?*FrMMDZ^?s7K|Sz)ypN{=c5bYX6FYCREl0_6+{?AMJpj)f2R+vLkS4aMXY72~zZ8 z(5}iKfn$Sz{r`6UQJkO-rcymANNGqh098xsCq#fSU=*Y=JUIaENugj*2&=LSG8j@1 zPOS92=4s=l^3X9#la@3K?p(U9vYzDg-V3pV0%?L zL2koS12kSIyD64}y;QFW@*AEWpxr%5Nl6_NuBssj?E?dJULb~vgkV*51uq)1576&Y zg;L%ODN?;72v+z26o_D~7fiwBS`k zsJYms2|d{xvZ(4Q2=dt@@jZNeM8X!_FZ~P>WENHwL(F#@Gtnb#JJ>TCE^Z?E}D`cT>B2DJk)1C+bUUan><@rT!J_uht<5 zJh2v-z~^bshCNs77qmCLtaYxA=>g4^uq?HAf=-5jMaZ8jpfL?ASDO}eF@z?Mx>H|i zo`kikEeJvz$BIQ*x%QM8I_=6EoMU|LvgOH&7|5^*S0-@I@%77AVHJZ@PUwa!pKz}6 zjmv;M(oaXD`>rhFJmQ;|ZNe(Gr%TXNSJrXf@vo4)^33OHQ^VejLuD;c1;5h%3j3?}PY@^*EkSvf^K@s!nbc{8!VQ6| zsAG8moDHw~X`yICkksUX&M*y^ROb|WZiv*nP{;a}?n(G{bpfFyLoF>~dGPU40oD)| zg7O9}kvg^q^!4F3>M}wZhI(2T<=G49CxPAgPbkX}^07Mhuk^pd{nb^3@(dxFkw0@D zGLYx$w}grejkUzX>n#~%BXH{a`9u~IF_2ntKz5MS&GO4w%)}5yXJ;7PBU;pL^Ix)9 zh)D`_a0BQur0$qs%VH%aRm5S%SRFB=?wa4oVk0Ik%*pWSO~i`&6CoI>(E*zN9&GM? z^#CE5IMH1?0~pAuNIH!OA(+R|0R?T$gmUH3c%I*v^l$~JkXR;dc#~rDhmwH%4F^#g z6?s)7D}N;E(TW@u$j&j5NR6WZ!C+V9!?|@%l}4Irl;=++p;w-sZ1p`w|JY8WS_mF6 z(N|4)YEI2Xx@mZxUB2x)P+7n;1DdU$MtlAOi(82wI}jzOqM|i=g+QdG1DMg6St=?+ zrcMZ$;o*5I>q%kK1j2#_NbZn>NqXsmVgmy;3Kg5D| zSrPR?Bj|_F@6l&;%4Y;pPQL~Ik zDUCt~RJ{brpMBhv6$G!WIRt}6gHq1e)s;DI=2SIr&LRXz}EVYwfDS(Cfq6f68=7ljT1Wl`5WU%<*5Q=(~qUWqk7+E`Pf z;4Eug$<4*{en7T7(7ar5j`eI5FdH>s3%Y44p644&h`u!epvzHou%_C1p|PZBKpHNy z@x>%*YM&PwONj<8&x7qoOrECEdGRr9G?;cZYP8%*d1PINZCMnC589_|_Hsrh1>G43ZCd-mpikS9r zxOwTbhlgTI7Qm#$^l!rlOD8--6}z+UGs_Y)9==gr7KE&LC=1w9V&=Cuz92ytD8A=a zHp(3Ur;YLqbu87*u=9{i4j6g?oFfu@=4RY^B&#AZ>*0vv_dL({isUQ+Pl-T_`hqe2 zRqfloxjKW|NV*HW33Vc*NB^gH7@pMU%^Ax z8ZpZvNh=Q7I2<5D@Eg2hNhK8vhzjB6M1ga1{fbq%)DRFv4L3g(xF$EQSW`(eaK^;- z-CQj2NN!%S376L4ERCDGxnAI%{A%Scl}s$>VBGS}-2%VlwiVlOnIX>AxV@Wy3j&it z7@@kvz(xO@21!*In%uQw7k){HOZ+(plBqB<`Sr?uD)1?^VQh4!5OAZF2jQ|qT&U+) zk-UWo$zUH)U1m5J^Bjp3E=)-tT(J+otOM|o8B($^EqQna;G@`cgU=n2@`bqMw=0g} zazp1kO*%ILO}cY| zWHdS8>~*CZLfSf{^@U2K=>hca6-u56AeDk1UZ^qpIN;)SRh_3eegcWU&|ow>fZ4qo z%F_$vlIMjMqqzZBum8Gvmg0Aj&n~nZEkt*G`|ps4B7yQ&Xki!Yml8L71tsun*>1%a z_OinJc2U8PS1sZEt(3w+R(NOHE4Dy|&*fXV!ndsO{99B!4$q{2y7V2T%&JhoeXY;RQ+en?(-f;S9_?_+}Nt){|H$s11av>*cn6?m(&@N@E( z6WsVE_|GLK+!`ocOa>sg=eje$Vq(s%(ZZGFT_?C6llUzYD{p-$Tupcvp{p={H?9R{p7z+aP=Yyd`#T9wO{x*`Pd0= zL}Y=3#N%5hicX}QK*2>tLhxJ?vld+uRSG2vt`E+Fib?!hEJbuFR4DkWlLRf3q_wz; zfTu!*^{9~reUp^61dCWw=ult`O9*8q>1&A=p@XDAE!85y6c!X9dJ^Z)B`0WU6$z)Xp#Z*eKChUZqh(kmmI8lZ znm0-3Et4y?EQ%yk;5WPHCi%Q?a=VsY5wKV&V6h}FWG0Vjfmo5kje`Gp=L^lr^IC32 z3Mss(1kGEd3m=m=w0wXo<3}a-+#&;-b*vR!q?#g#0vJp}_*@FJc65u0+8IT9DHl;MdbG*HzA4Juc|`zjp}=yM5Xnr@*DfhCNdf$+ zN5@&DImK4Hs>mWm5|yT@OA`5*;;P+LWRoI|O7GDniyWi`YIha^$AtnVTH@ll7YW(} zMfNF|QJFn@&KDJ50PrDQw0u#i{h`PuD!0dgEPC+bSo=hA zaEdAlWNQhrbHH@a6$1l?%I`6B7E{FX>#!6@r)Z*po*;=?Vx@JsiUA2j74{gB#eA{K zI)cSXDOxBnvn9kG0`+u6MX<&?+Q20|5URYEU3PiFMKWPbAA&UmNIw zuj0S3{yHimdB%o=dlyW);U*uc^Gcw=82B+Su)0N3u{ydU1min{5bB2l>`+KulGLXJ%-Ne#4Fm`Jzr{XvMP)g?vJ&gjO8^cg=KgtR#n zunJ+_7a~K(4ucRNcS|~?$?M`pMvNZ~LL^Kn6#@T|g(B~bQG<~3s!J88ndp{@Oc|pG zA-D~d>P@rPtreLu#tcFh+by+}=B4{eWZwAkVB;<{5K^ay>%JEGYV1DP)t*qlDEyH&iO;*VF01}7l?}0Sx zAR|yul_2;c2{rIPpFY;iSUn`+0(*-1U=c(}vY9wNeS#=ER(wbpQX!*ElAaj>!JZ~Q zTm(UnduEHCEkTAoL;Q^}WH-r~Lwb$`Id+`*+aic#sxxQwTnYcNXNivpL&7qaN!Ifw zTw~7>e^&&d$#&+UULZk*Jx_d87;+F+9K-EM0^oGwV?_{c$l|zfClGG27m2?YhP1*6 zCviKCpvz7WA1{LZ!5yb`JBMJvULrmr43R=IPUkj(aEF~FK3N1QK{d|mb|t}_yCZ@E2Bc+B1;{z(`{-O2c&+sgz`_7?HEBA8xR z<7aMf5CE?SzP(3y#@;TzQ1p1_zis^C?PEd^d#CtkVK;6C)+`2n8X~ZE z;$Mo~tQ2Ikxb>NdQS3e9UxnRq3PxEH`W(bK_CE1%MeZ{S?paFu{6s+S#9`#ht(Xj8 z%|+r1_95}5A`dI58nDurCZ@B$5nmSe#KD!$S^p{#&psmly~uM$aXZUTUzwQ8J}SN< z?8OaWUaWo)l32+8UVOF4%LJ_7!m$LUG?n&e1U-5XafctKCU{#y2W*EDS0{r^nam_s#&-_cq7L zpk8!#{0IGS?6dbbe&qNVw23Z^Lwmv*e>UY)0QvQbejDGWKfnSZCzYFF@K*Hu_zwNy znSd1K+qoqMlcHQdDo}i5Z?1gO*Q*lc|6JV)7IW`NU37K#9ZIP&T#rJS{^J zG4=_12I|yMW3`Gr3qvU}&Iv{acv+{Yz0GqnyduUkaf$(6xbM||R2H%l*s95iWhJgJud-nkIYIP6RW8WfgrX- z2MZk^5ivvX5xZ)XRicj-C9_k0>iDC!ak$L5)Z5*nKvRq=T>Rq zl+k*LHx@2=)QPdT1`C&sc1!%QaBqu99J;kyxM%dYBoGT%G3q1+E&3uFW2(|nEZnXl z0Fo0g;xJ|^jl{x*i8?t}OB)i;Go`UuxC2Eb55Z^osxfbA0v4_{)F}+wF-1sY;nEZ= z+*Be`bhJy0%#0;V)39*)pnegnJy_&u93)?g!@`9k;>D2mYLU0`_0k+H+!3g;3_A41 zk;a;(1z7m(M*xl|UYusES4zO%A&XO|#=;k$U~E!K!kUsLB2tHRP{j?#Hl>wVbJ(ez z#-JNh+-GcGT7$JDOGc#W=#~~w8M~A=V6Dkek{GKySiEfPRoa3D1}7qYNO!e(&)C1T z9Sh$o>I?=wdIHUz@X~H9e10N;`x7T{+<9KwhlMW+HGD#}A=AZ{4q+kwkASZNig5K# zR_O>9(s61y=wk@TJ4L1Mv5*}{z}a0&FuPM;I)#O3l^TxYL4xC*y3!deB##kr!mbj$ z@3fZAV;__MqlQD1o)~$jr}QhEj`8tkyWVk7!2u4XiTU`l&K+P)d(ON#Y;F$m`F6KVPrMx{8&S6 z2(8bM7*e5MFCu@)5LI&3gqOse8b#KiE?_WW+sv(j?_3Z z^h?IV&C1b4p2VFRPew)*4jHYMc$-`&@uwz|Z&4R97}J+VnrM>FrzVrNA^@2bFHJMi zBV9~=LDr@&jy2XUC776yBvMn!IuXS~#;DQ;6C09rYC2h$n!s=;rnJw*o^&}CzPu3x zojawaQzkB?tEuo|q9(?|6>izYi=>na$94p9=+0{Co{2w6IW?DTKwZLMLQkSG4JWCm z=93L0fXx&qahN_QAyW&8fcKNk5fHzC%r7FpVK0 zO^ZmzsikC-2$GIzDap*VoMe_-Muz5;Shy-Wn%0r5QY*;Ni8*AtO7b>sCE2FFB%4#0 zGnmnrMVj`I9;8;2Eg}E{6)#IOeM53gttDGhSHzlWmk~@SNY1JCWUGjZAv082gXt%d zYic9en!1v~JO;GsMUqEqGZ|`Dbj(Z3rcBpK-l?z1cd1{-!ku*4beH6p+D5jGcsXRg zTDE8UmlT-VLB2;_#b7~SPGd$@7Mcnqcm&X<;^iD>Ol6U&ugUkRt79#+0XsNT7Mt2j zeh^VTWPvKbYW7s5m91ar8V}31 zayv6wMCRn1SVvP}OXten%oGvXlOwT@CTo9M9+d~1sUh+wM`N8#0X5~TNHWt#6i>d7 zMNQUuSly_|Gc!VzPEN!+n*w=yx1!3-5>YWZ6^ov%|7jIa(P?%cQ9bz~*2NS+)a;5; zGZdnJawZlt+2CQ_R`J=)9nn1bDc02#xYW6dEi+$4+vI%ghs_P>1WiT^PA%fG z#MtCYtd}W3tl5=@=B0?qNpkFy$rg{hZIyQB)rgOi>#^RZz_iXmxZRAHo7{+fI{E77 z-J{B2^De}f$*ou)Q$Sq#UM86jB9f~;$pD7TpcVAYSe?3oS+4j>m;AN-z7sU4DeyqPK0I=CFN6l9ezb2tqX0qMmUfavh=G%ya$-l9Iroh9_ zz1%WCKpagT#|BMy{JeMc@`MG2B*oN;xL{MjWBICBEa)Yvr=WypveU!vMwOrit0est zRa~ek(6V={E?JzDJT(QKG?QIF?E;`VMo5x%iY_kP6yVuxC_NRIJUhh@7ctrGalfs~ z&O%o5+!Rw>q$#kpb5(8@ijsU&P+&9p`se+ls$dH>Nuep0xM)*AYx$~^EVLy>rr6?Q zCVM;{+^Ej8Fp?CXIujRb3Z(7b>M9FMNvSDlyP53$`5*wg#QCEyrE#GFyp?#ESv_Lm zR4$*!jgIf_bAH%dJ#XPwu8_uy1`e0>@MHCcg-`kQG=6kqZ$J6rLG`gkaJg!lAR4e- z3Hx(3%$CvRnrY|J$-M*4_KG$9mPzGWX~JlrbV>G>HPV(D<$7rs(Jy)j$@acA%9eTM zhG}AGfOaJyyw|rZDTjd|I<ST?aOIQfZuAnoW}iv5o823J`D>ce zg}Q;tI!vnD?EY}o6KJ&+0V+98s?Y4?_wkB0fa-hrVmuCDhT@4ScYbri+V9FXCW?KMZ z_ONcLnB#a{*0?l#h@of^LuM@#V?L$Wo=9Ieo(#p z)%s_}0Y^YtyTd{Y;Lks;4=av1g33CU77ia%G*Q}6R#I?=lmY&%8qc6SJMNV%a!Lipx9y$JpO<|+xGZ0Wlhm3rv}^my+o*~_;@`EFjNVR{LA;wD)F7;XK#C6y-WB=lr2 z+4)Ixi|yU2N{jSz^wiBY5+K{Icbh70(ks!^y=&wr2Q7hjJ1gzdtI$x;Bmo3>!rg&N z`}7+0$KG{kZ^c(RcSkFo((BMOH-C@-=&ro`q0%M20X^IMgY515s{QWgO1JbT^rxE} z62NzN3w)RMGH=nHtKWF=wEoqnyPMKJ=B>K(4vV;_WANGDt9-`Uj#wz(oO!za>hSJy zWe{g40_bmUAJ$d|+aQ{kVVvEFFU4C{KC-Rcw#+Z1IC~I4gX4URS|w~bUdD0uA-)xF z&-l2vD%tYCOynFu036N@T~9i;7hk^M96~G=|FrV0Znd(Newohs1_7)%&UdWU+4ky7 zJm(1Fd-2YU?{=%7t@6uU&QS!QG1P4t;`BHp`RuP0 zzuRpkwx%*=)02#AslVR)VcME(@5;QK2C)3>9^13{wgFoQncC@(j6YKMjGt9Nixftt zaT+-Dv%gcGy@g5s6PZ`jbBvp*zu!Om(Y9|JAk#6uz_@jGpUwYNJKenqnb*@$43)ZX z>@U^MbuV6~e;O$Cvj-{ux7)?;rOFIXLjzUn!Fzv9yTZL}nRn9wrJp@y3y5#mx>qbS zKE2BLEA`MgpaKf1DrBaofl)vECnex*yVJdTnc3+djK5R=ybt&RrBZD&3)6tCpZ&`g zc&a1%Ua!oz>21b?)W61oQXLuh-pYKR-eEjEdz2D*yQAdZq|Dm%FUCKqNACkM9ZmP< zWHzS(Xg_<*78KtxaBoRwXZnEgDD~JlsG{S;y&p2ar-5%j`|tgu!H(s7yDtyZkJgSO z{tX4KcI@5z`x0>XwSUwn7=!6MY3!(~C^KN)P$U>F;+-6JOjSU?uT#)a#06^uaCxSR zA%l9IGLm8#W@cCIc&h-0Uq4Ah$ruvTiL?{0V#}akhh8k*kkU>wJIN|w)ok^8M#@Tg-NGL)>bu~bz8i4fcP@=^c7Sq*dXJ2(Ww^B#mxZY1fpU zOBHbS>!)aFXF@_5@Q{4}{1m6A|7H>L@ zaFOma_v0=hEiSxa-J=TwWk>k_i%U8dB5&Bd>0gICbj#nzUjn7_4f`JSaYevTu<(+x z1vJ`wGiXEvILsJpBjy0nZ@zT*gYzVr-RZqFDO9I`GhaNEU z{h+<7XI#pX0)*4EQQNN%?;lqMaj8lI?avd<+QaaGraFvET@t!#t)pdoxF0ZAM{#LN z0{oAM)-Z_&9My4LNXZKX)>$a?QhLB&oyesn2`&H+w0G$|xLEyyOGi?Kz-Ap&-DCAY zx;mXpPZHDse9Tyn^Mk9^crJZOQ3CsH%yy681Lf*mE<;H$1$bgvdt)CUs|&fn?jxMB zj+O1jJ`^*4I`YLjdkyBd0<=pk_*(SiyS<0$-P4l9II=& zKrA9~SjScO&OC6fZsf9&1g!ucHwKRd@9I}vP%B5^oQ>P=J$w*Y-N9ui36=rRbJjkF zhmqBxX3M_&01g5N zH+y`1pVq@-+3^o3rYmXOcj7DhEFMARF_i(ZLXNK?k^+|cJk zTYZ=ju&x{_Fr2vBzxVKOwSo?me(VXHOrjp3vOjqlsyW`MdJAeKi42^vXS_^f35dp? zU>Mv`h3%uU^qJ=!pi2~0q+rYs8%7v1g&k6ih02O72Bht|YM3&ieWFijEy;I4*e_zt$)+tpmk%y0pT9069vh`m#dd?wE2b|2iEn+NCZ-D(svL4-z%mVsokVeeCO zJrk7UKGC%o2ZP7m%cF3zS%q(#+K}sON$k2BvsWHhUxtR9Bjl6lt)}gA#BD37Z z42dWMLBrLdsm3O=(#5c$!u`3?vq+e^Brz?2>M*(mf7TDgOo;q&N1S!Qsb4`;&Qi7 zy0ENn_>;rtWe~6QY_EddF**D{vL)D3O!v}c#?yZc?>ih_28oHuj^h%0#;G@Sj?{AC z7BSsVyL1QEEpR!Wk^|$1=>doAi;UZE#2nAcfr!KOFimzm1M^0~kxvf%7$$p;%j}u) zZ?qgmDeCPV<>WvCdE@9U_d0XwjhEv!IWRNc zJlc~xiKBiS?x-OL!o(XVZ+Q)z$Xl$Vt{i9#Z%})%B*<5=0rBDVhR%eZ^HtDDOy8C} zn#=uUn0nKia%CKcdE4Z8R}LtDCKryY?D+V%1C9=I0N*oV(yrdYSG@h;h>-&(p2?Nt zzZdwoZ&w_j$N{R(^f>Lmar}?B`;Gx}9Us9t;ZR`DIyFM~C_?V_$1hC4YTwC{8sT~r zFW3JO6ci4{7g@JQ#2%%}4S!r>@EBW2x_Mu{;yW(4`DsP=v4>bh5? zl5Tb>+}g`)K~PzLLUS!HdvL_@QC;m!=8tvQNHCneI^zAPwHADp^`|t~8FT30MLz1O z{hGPG?h^^tr1-nEM{jCDUs?C1xe=G6{f_WxqL!TbYuzvM#&Axt<%A@fdS%L(Z}QGK~pL_xks>ljY6Jc=0tq3nW|hKADA%o^3*d>)ia=jem=vUT8TdKU zsEj&298^5?X|EOezE?)&)qxU^!6J1KpzG+PO6p8-5}4FJ9dvQ?ds|dhodr%3lZMnS z1AE6671UH`gOkRj_vx+`AG{Alb=KM8E@7am5CJkz0&1Yn9(Ng&*{6plD30f#M(dn# z@)#WQb{YIpRH8oAx!|s1pvZ8I;5*)q`dsIRQ@~^)^%0=@jG$KPyl_gG>^^-ov3YzR zwN>YXyN=008kB+gvw_;L^T$Dg(r2(nJQzPlov07SL9l@|M1Tmy>`Yf5j#J0v_Zgx~ z6eswdS?Z&4niv@Lmw^`~?aWpG9EZff{C%y&cS6}&us#W=g@Lg+0yH6gXR&%LP6q?S zYIJGygstN24=`*U=6uCE7WJ<^f55nT`N792y|Ah&%+sFVB(4Zi73HYtG)RWNP7^r4kD?6Axb`GxZ#Mxo0kQN9K zkeJcY^*y);nCdfCv%~Q7Ms`?K&7fb`vx(sY3S9DW75Re!seO#+JmdtT`W2iPrUiMo3|yv4^oM%jBQekrxmM{r-H!fT zzlHO`v?6U0pf-)5SL%0h@Mh_=MZavGo=0!h@8jSpfxK4+XW#~Uzy2={Zuouo)?OY= zAEQq+oWKWT;HHfL@rl`mu7L_4ih&C-x=Qf_zY9wP9X=e>jl5q59+b2TR|6A167#z6 z{#upq2W1z*1{QoYrU&@|0a}#4i&(=Md@QE7?*Y2H`Gc*?r3NlMTzQZW%fOOybx~;G z#V26k>akXR@FCDewLuV{gc(5EBS4x;aM5ZI#;0Hg`|Qy*iXU@a3>(DoSj-U8p$r_V zN*9X;Nqib+xX)p&#`j~pi(SJdJbYb{jtEeyMqHd4O8%LV$3^jEQd0#1~-3`kc`4XU~sGYS6+L zVcsKQf?_!%jmc=x!xJ#$eW09kbB)c&+hZ_84=bF&N*8`HXZ!fa%5T zO4k^U@5X%Tb3->Ne&Tm!X^h7AV7?+@>|^;!+Lf#EIld3`t$*?6gXr&&=)%7>eyJzGb8nb;BEb?dTz$mwXu=slN2ar_*Y|dWLNLTS3L7l zn}nycueM$&O?^^Mewt3tDd)dT-i9yvo5uF z@fp5tY~J~CL*p#ZhSYDuvsox6^?TgjxWKa|wSUo{r=4{n_Hke1H=dtT2LylXcG(5o zV=ud8;!qt{z@HR48lXHDf#hU;~$=5sego^*^X@(pdB~<<2fOHLNu7Cll3!$ z8%@(mUP@^SVz70m>}PH_<|bNRDrrj55PYZ6X9+isCPrQw>665e*-m$uw(&Qe=B1OS z5)I|)N`{_`i%smj4AS7eSwlanm78=ECohvUjc6FYYwWYL+tnr>US?^~;AXqFVKk@Q zB*4oeO(z=8)6M!N)(zQoffx4S5yP#!WxwFu^qWL^&qyJliIa(|v^X53tx{^RA9W)_XYL-Q)x&AaIu zFTXVGUzvTq4MV@cCKX;mX%^9Fo*ve(4DOLl8ocMFS&7lsJ+fc9-4mK_@d`_`iN@f2 zjJ`^^r#0zju~D(7$Be@-xq^GPg25+I<};kJ?7h@q!rg*26wcegdcddQJiW9gF1qC-7=#%{~;X;4vH?010lP50}dlD0@`>VgrxNkH)<-IP=FPez&ANxjj z-)jPsPg;POINQGsbIjwWAYN5zLD3|h0oFwZ51M8W`=o`4N!A0hi`*W}%~8CX(&t5! z@dHMS5*{4Q;Q2{kASTa3)vS^Se{&+Qmb9>F3eR9N^qO332JKH;gqUItD6y4?baOhd zp7cf07x=-kMQ4wz&3ImYX+Vi*2e)BDs@$B*YbY%yiscz%U5fQUHWvcut@xEe3viY+ z54~nW)}0M;+SE9Z0tp@_%>Wv2NJOO$522PCJZzdPv&=UTv}ugs2=;l{Hv@OPAsLmX zJ6yUn<>AuYkY&9gMVlT6%HXnxS2JM98`4qf!^5jfdmjGH?OFFWWN0%O!62mZ3~vT1 zdE-)4hAwb39G=gc`?4Nx$kJxUflzqS6Wa`s^2X(;%;7hv<*S}q%_CWlHsok=jNlg{ zJ&T&(XQ4Laqj0)!OP9?&%bTaN&>L51@o}IVI(pVM&tzdXu13KacXip@v$c6X>+!~a zv{{T`A4YoiG=I%<-+-l0x+6D%^?9M7VqQWE#Qf4z#1z?kRT(yG+WMR1K1f= zqzeF2nwMV7#cbdnX^Z2)i6nTLv;b$lp%Ya+{2sO1;APVyoeh*6ErAgf$v!Xpmdn|h z8+uU$-SN`ZDKD3ntJ(OC+qA?uFeaD1yjqm9vp4jkh{NNnt9xGlEy~%s8(>T_PSBHS zo&<%rsAuPIK$WmApiUf5p0^;g3pc=^jGNGgj|sL#C%bsVII47b0!6<1B&$U~o49d@ z78du#kdaS{T8y(xH%y{Px|5}3vnS;(X4z#MrnF^olY?Z(Cv`1W*%ceGiEDUrmF)eb zRcS|^H_!Y(+O5eWa`2NbB?tr)EX>R0ruf#9o(w8E%+(}VPJ?}UV=eE=m=bEPF2TyY zqIT-;TGf+}N|?EZ1nX&#F$2~*pL|hrpMyqY^GdntY+%M$m7dJCB;1__H?s}4%x)|B z&b21kn!l`_o?F{`a-bA2*Pd{18dS|A*Z@XxEo81U!Opx&?gQUCi#Po>82lyNp9XXD z#=4+4>$R9UXhSxyuKjR#{gU^&Yw>e^2@j`1^%lC8JU5VFZ(bw!F?-$6Tl`w; z+)#qUGvrC<*D~kcBsiMa)_$B@ck@=fmOVF;@Msz|&m&khrgjY;VF^y=b#gO& zKa#w)uNBX|Pe4tB^?Bn*p10Ap(z%HQXY=~nnY%x#ye+R)%uOYrr$GV@_|fTo|629j zhXfb%2D#bnAEVx=YxQ$837BbcLfc@CuKTs-xlakM=8dldKm6G6_IXvO3W{iBwxrQJlEc%Y-1;c4Wn*L+{4-HA=spJX?sn^=3AHc7JY@E z8{2Sx+VBeWQt79}SF>~58-7pQUoG%$N&ASl@<97@?9;wiV4F(&5?ih3WjAq8M_zsB z+m-ecZNtwSZIYf&y#o1E`WdlpcHVun<>~yZO}>3;f6;axsEQtXy8H@UROtX>yY)gf zBpw^De)Ij64ixRcFN|%HpYFZ-!*?tlMC_Pd*xo#Rdi?4i-wByu(M}%dm1gjvX$4bN zCWP2&{aF^`5$0A}ekz$z(JuUFqb&&^j#dy?PhaK4zj*r=gy?hEPtDULhE0RV8nC76 zBXk{B+a`vacguar-ZJzNzkYU}Au(bawAQvQJ0IEW=jNFbBh6peewo{H^HIFcH_x0H zH4T>Q(N?gJS}Qq}<#F^a$X(8DC-`W!3g@sr2I&?3RdGAV$FNl_=gi~STfJppEw?Lu zELtUVINrUf>eY~Q+ivl(ZI$8Yl6fxL$MY?Dd&tMJ6^vM!cw(RRw`$02f?QkwtlWenJm!}p6|&! zL%z$cpyJA86GyDSS3}UW(fXACx=fDfJN);t9kTCUE10=5xx{y~-?w)TeUDp%_*G@{ zL`Qj`v75n5t9Qgj-> zHuj6`=iLTIu*^&1^z7R9uS37Uwhn$fnJUo_JnO7`49_ClKoFLxCVsGnT5;}Y32puS z_A)i1AMxu(dlJvm+Q1i+jfSeQh8Y z%QO=|S#QYx#yuNp`_Atr(;_;D-!S@3dN$RzX4_2hDt&Hz1M|D-+1!oI`KPB_Ip^6o z<9`o4Te`6`?|Zr}eg4j7#qST#e%$yy|Lk--=faE4x4&1O{krjIKHzjmI*_VAe(yg! zy76y5=yWINXZEdA`*i-)$|n~>PIsk$z5`DKF8@=?P>O!KoAb+yt=s!z{%4gL7a~r- zPX98#h1pl|=Tknt5OunT^DFyyJk;%qD6{AO_|jwkPkp<1ze+$t`Q&S8MxO?YxozLh zUsn0t!t=yF^KZ4=bFfHJQJHTcArXSao$aIjV1G4bp@pQx0rN$N{@ThS3n__% z)8IJYILPxiQWjspCJvb|)&9JDP~~r_EVYo92&v=F&wztY|DgNIvI`lBZ_JnFcCrsf z{ZYzS7I2Agr$K>kJNWGH)z*@8ce65TI&Nq1fcJ!_veLcmcOy@~zus9oIE4J{#zIaa zM3y@{M+YYYLX_1OppxBuMQ)exkR>2S`Q}1F;@C9!(l?;6Jy}_Mp(yda`D*R%-NQ=( znaZ~p2#Jty?(7B}ss`jM8!eP1PMDMBeq|pT29zqBE|3x@r@^LfJG2X^R<>LyPn2(7*uvxs7d@d4X*W#KY0OT z%BY39#2ND+wR?B}R0Vug#w;`>LUOvZ7x1Su;ES^RLQ~==^9{M*+29$jDnD6(X836^ zvD^N94%k-qU1&|5H{Y!NJqJ4}50nEI+7lsW-T8g==R_cdO2|Uz=C{roK}cPh0%=vk z?}4Y?xb<-V%3t2V(<;&TdJMk)w_Uhz`d2cLQ{{QC=VmkQT-=5>JR{Gk#4kX}{4`kH z0e@8kg;bIk1`-#|e->WiI?xL=quuQuG@uUose4fR*DO%7BQ1A$bBT5*?qKk*W1xHo zF8A%`a@5Z7!RlY{!0R13x$ic=)9x}J(jP?zYIYRlj%}_)?dl$iAEgEAbr5pLH&wcqbB#`=6ckg?w``5sX&*G zhTPfBAGE*Y{tQC7idRQV?%d`^)bHUxt4Di*{vGYP3!9s?`;33-k7;4r#<_LP;(U<#e6E<|l{nduoEVg4PcWD#K?1%rNj;{t~b&TYG-`t@+WIT#FMg|pi zyw6?Tgl>D?qtauupz@BX+_g>UwvRg+Ja!DK>zK*?vAGxZXZUFK*gL4TV?K9t^Ed5Z z#^dVq;X$uezTVq@xBv971~jn6G7bS~^85A4uD|GG#eX?Lqa7=`yN?fV9hDth{;Lf7 z(6OGo_ZURm8uIfcQ_EGwMs&Gmq2=RARCG23| zxDRy?r6Wasu(hgm-bx{(h0PXaAVpX3eO1}dTuDq#M~IU+3L$|)_c zE2OB?I8S`*Of-WYHHp$Zq`cEC53zNYj`7ofJs{rKs#@7ejdJ)f_E0ZVJ_&iHYWw+* zL2s0w){R}tfRGMVJ3Cm6t-vHq!*Mb`q+iwE4z&CxCVQHzC$mG|sXE!o8&V6M%Azqo zSr#(Ynfdw(3s1(W2^!av%^`EDk3av%!pp^chBg68&6hyhAO6a#aHv5W`0srPx$}wO zwJN?9W`A(_zlHql^cB2O#qV^wmG1ftAyLLFqpkO4$`6s8%KD#Bv?B z6|jdgbVUeiR0*xH_=DkpA(X8vM(}3Uc_-FZx(8Hpq1;{Zg14$Jtg!y23#HNsJ>Qiq zs9h!O#CDy&fa*@DL|3YyZk5Oin?Lyf4?{0^WeVP|x~LWE^KX#X<@D7qr~|kpTEhN` z{wI}M(2XwGLpj=-qK+_p}hO5-sp$2Lt zb|!`r3TKNL%&03u&DDT;HAFO>U1ad4R$;bP6B{%i-8;d-#28E6A8OxKlLxEbqdD{# zNz~J!E?o_I)>~3^oX;7DsK1ALb+zQd+Vp77H;iQJ-=Y3p?RodMU@tBc69Y|S&{{;7 z;QdR>Uv|ZqxM@y@MR&nYFgMt~<-(*yBM_FRLnHA5n->@zS_BuD)_)=hl`+L467~Md5*#!oN#6& zZE@JR8rkm2s8Z7rKCq6nGAvd#joSMX>|p-H>_Ph~Y`zO>2rgY0Uvm!kxP1^Kovs zo8WMfKlLFTqyFC)mZjTtqR*k@`g^!nw^DxgmVUITp4K8gCmT~tWVpsxp?p}a`jh@o zcwjg5E?hDcgKep742%(x-5U9~D2?b+=(MAS*&?9xKV18(a0u*}C=oVei|xKCR9I!S zBIbW47JfaFy0!9)+@PeP{EQWYOhiVvp3whZ?KgVHl|eBgTOG=lSxmTKFKGgUc0{o{ zbRfH343YSs&VN_7((bHq{Rg65Q1ZVo9LPrMHWezXGF_3N(xDOwXVahuqqAFVTO#~y zAA>_gtva*~kDB=)dd@C0Jc)Rv4kf^&=KHYNgN898;$dQb)Pyq5)QDkqXwWruz4Tumj{@Tlns@3>_vcj~SN#{wp#uZeiEiio`Yo$ysW%+X zjExbWx}hs#%bHG_2@2!;BNn^6)u8s(M_QAUz&IJPrtW~|Tp z^^xh}TxR?g@kc%IJ~T<}!$J`nChEwO8lm^0Qq<>?CX|4ljbzk_ybr|^`M*Za|&x?!Zp$E=;hy8@pTV#O_WE6cxqp_BTH7_kXYN`K~{64eYaL&sz7r z)|#0!%$~K5IR#bb*1J}wThTq~H%D#CbkYd!ZdRyldQqqJk>A@9x0oRb_5YSPKj(So z=i~=U9=atlC1PsPv+3=#w?{hJ{npg)8nL11?ex@^yK?XTt!KU_;-PcO9yGF<&yqq; z!TOnHFBE;A-nZqx$k@l-#x^+Tys`BqeMrmS&7CVktt0tmrG#qX!?F)WKAbu!q+w{e zpr9YF(JlX+TvCW(8it032L)%0%|4d-s7KFJ4ZD_W92Ai;HTzViQ&Q|!(%Xoi!G!{R zTu#265l*g@1gH3UY(`-x?@YI4y-xj85V=~$zX~FUyC?a=N1R&0#heK};W3j-oEmpF z@@bDoM;0m-6P#04(CBlKuE>!~8|9Si71ShSarVVXf1f_#PP&iDPI-@&*})^7GGJpH z6Xn+h;Z7=Bs`=`}{M)L9!i)Y=4;q|tF#AE|+k^qJP0Kl{LMCLK$bKB@)X-Yf)TmH9*m?bN+|$et zZyUdBdX7pCzNcSq`MlMDR?gRe4HdND%^A0{UuJ&p;Z&=7Sz%D{p^UqQ-?r*sX-I6M ziyj?A1;mbim+2ibL`m!#IXC!XMt=5tz`5(#o%px(z^#mz<34BpckMm|>K&*eLYkZlJMRU`KJ0*DXojHR$e1GNso|<;cNoVpq zcv39vT&GK|oUjdex9n}PK>=Zf!XCYIg}r{~sup&5w{KXnF#jR{r{#$7DVCP#N^&K;n!8%K3IRTVFA(7M16)86 zuN&|OJb-i10$!j95a=!H4e|zii+Mx5c4$gytI*b=Z9?0I1_DKaARrhh27~~ptGKs> zH`E*EE$J=g4fmGzmhqPLmh+bPR`5o6ivuNqP#_E_36ugDS2$1_CF3qL8443J$T#-N}pfV5zRPx^Pz3qF)_pWb_?>*o9zR^Gx zAO?s9sseF9J6AkV4X6&(0BQmWKv!2Spf*qks0-8s>H`gciG?Q>o?LiJ;mY2IKqH`v zw=vKJsOpXL#(S%It9xsBYkCvBO@U@WB9H_m1I>XJKuZ7sKmY<@00B?{18{%P24bTAt zFaZllb#-%fclB`DKnl>?)yLJ>)e2}0v;o=zgIw)^_CN=qBhU%x42*D*Udl^*887SQ zyu7yy&=p7px&hsR4A)p!51=Q|3+N5>0r~>{fN`$=zyM$%FbEh7OmVdfZ6Depv}0(e z(5bFzuIa8Bu9>b`uGy|RuDPyxuKBJ7u7$2et|7osU>J}F3{k;Rc8(d3)O|H$ZOkf$X&9xj@0jvbF zT&sZ9z#bPEI?y}Fy9OBIT??!O(!2?QwE}Ag)(NZ|STC@C;Cf&Kuo2hT)hPP{IYUnm#JFo-T31k5! z{6hV90VVx*1ABndetTW}T>D)ITzi3iz<%I}>!|AhaLjcOI0T$@9R`j7M}chM7;qdo z0h|O*0jGg8z**oNa2~h-Tm&uwmw_w5Rp1(M9k>D91a1MhfjhumAP2Yy+y@>24}o0Z z5%3tu1D*g+foDKI@Emvn6aX)QSHNrF4e%Ct2fPP903U%*z-QnK@D=z5d(EDu%yBfyGaBv=Wo3`T*`U==V1j0LNLabP@H4Xh5<0BeE?U@fpVSO=^N)&uK< z4ZwzABd{^p1pGIhreHHL5ljM;!RBBKuq6n9AP9jlh=3@FfjCHjBuIfY$bc-!fjlUH zA}E0}sDLV{fjVe_CTM{+m;$x}TZ3)DwqQH3J=g*42zCNHgI&O`U@F)R><;z-dxE{d z-e4cFFW3+44-Nnaf`h=p;1F;qI1EgTNsdVahl3-)k>DtBG&lxK2Qxq-W-K@k91l(a zCxVl}$>0=lDmV?C4$c5)g0sNc;2dx+I1ii;E&vyTi@?R;5^yP)2`&SdgDb$5;3{x6 zxCUGct^?PD8^Dd=CU7&j1>6d51Gj@az@1?g;9Kw=_#XTKo{IShegZ#(U%;>6 zH}E_71N;g80)K;lz(SA@MDfNDXt zp*m1qs2)@wY5+Ba8bOVrCQwtT8I%YmLCH{as0Gv#0w55AAQ(a*6v7}JA|Mi?AR1yI z7UCct5+D(hAQ@6171AIbG9VMOAR9`7T0yO$Hc(rr9n>D`0Cj{qL7ky4P**4w>IQX( zdO$s)UQlnS57Zax2la;rKm(zFNADnLFf;@j3JrtOpyAL6Xe2ZW8V!ws(xD7!EHn=K z>)r9t1ZW~O37QN|fu=&!py|*IXeKlZnhni?=0fwJ`OpGrA+!iu3@w3{LYdGqXgRb3 zS_!R!Rzqu`wa_|fJ+uMZ2yKEkLtCJ&&^Bm0v;*1+WkI{3-OwIrFSHNZ4;_FGLWiKk z&=Ke;lnot&jzcG)lh7&XG;{_!3!Q_`Ll>Zn&?V?HbOpK!U4yPeH=vu)E$B9M2f7R8 zK=+{g&;#fplnXtA9z%K16X+@Q49bU|Loc8L=q2VFX5D48~ysCSeMu zVFqSl4(4G27GVjNVFgxU4c1`;Hen04;S{(P+!}5Jw}som?cok^N4OK*8SVmig;U{f zaCf)|+!O8v_lEnxec^s^e|P{q5FP{%hKImI;bCwZJRBYYkAz3Tqv0`dI-CKIg~!3; z;R*0WcoIAro&ryWr@_vhi||);al)+_zrv*&Vld2 z_u&WdLpT?H1V4uJ;3x1?_!*oJKZjqy1@KGw75o~01HXme!SCS@@JIL){2BfNe}%un z-{BwdPxu%78~y_qLVOTk#1C;HZp0t)AOT2W#ETR`0+FIf5E6_OLqd?^NC_kq2}4RE zrI2u>G*SjBi5|30vsv|X!nn(gt3#pCN zLFyv)korgiq#@D>X^b>Mnj+1RL?j7GMw%lnkd_F5fCz-Z2!fyphTsT+kO+m)2!pT) zhwzAih=_#9h=QnyhUkcan23egND9&lX^pf&+9K_c_DBb$Bhm@!jC4V|BB@9>q&w0B z>5240dLw<1zDPf$KQaIrhzvpoBSVm($S@=g8IFuVMk1q-(a0Di9mzn(BIA(p$OL2} zG6|WCOhKk1(~#-N3}hxU3z?0~LFOX!kom|0WFfK$S&S?}j=Ps45uQvWEpB++GGsZj z0$GWyLRKSdkhRDyIg6Y_&LbC)i^wJ9GI9mEid;jkBR7zn$SveHatFDK zY|L@S|{(I_+;t%Am&v1nB^4vj~vq1DkEXiYQ$ zt%cS`>!5YfdT4#L0oo94gf>Q-piR+cXd;?~CZo;K7HCTpKtU8jVH8186hm>8KuMHB zX_P@(ltXz`Kt)tSWmG{`R6}*tKuy#_Z8QaKg|T1f%Zgup}o;QXkWA++8-T&4nzl`gV7=AP;?lYh7LzZpd-;y=xB5dnvQ0mW6^Qw zcyt0f5uJoiMyH@t(P`*(bOt&TorTUu=b&@ZdFXs}0lE-fgr>z0j~@{~GJaJ2==d@5 zi_s72SqzM|Yq*(JXWqx*Oet z?nU>Z`_TjFLG%!M7(Id>MYGXk=yCJ}dJ;W_o<`50XVG)$dGrE$5xs<7Mz5e((QD{+ z^agqpy@lRJ@1S?l9P}P~AANv6M03$c=wmbweS$tkpP~8abMysTfWAaup|8<5=v(w1 z`X2p&endZ^pV2SqSM(eD9sPm+M1P^b(LZP*%m?$u{4f{h#{4l47JwDTyjT$|5G#rW zVZm52ECef#mB2!=Fsvk23Jb?dV`Z?iSUIdbRsoB^Dq@jXC9E8 z@mMviI#vU#i6vmQu-aH1tS(j$tB*Cn8e)yG##j@qDb@^2#FDUNtU1;KYl#6Eh(Q>P zAsC8b7>*GbiBTAhJ##Y{i*Xo_37CjUn2afyifNdR8JLM#n2n`it+3Wu8>}sMs8~C! zJ=Ov1h;_m`V_mSWSSr>H>yGundSbn>-dG>3FV+w1j}5>EVuP^3*bru(8-UY&%*gR}Lwg6j* zEy5OKOR%L_CbkS)j;+8}Vym##*cxmtwhmj5ZNN5So3PE;7HliF4cm_Gz;?C#yJB^*e&SK}V^VkLKB6bP8j9tOf zu431)>(~wKCUy(EjorcSVma77>^}AYdx+&?kFdvB9`*!#iao>fvFF$etN?q7y~18& zZ?L!6JM2C70sDx3!aiePu&>xR>^t@Y`-%O+e*f25f3QNh5AKWm;V#^b`{N!w056Pt z@gjI2UK9_)gYjZ`2wog7frsK@cuBkz9*&pB%iv}4a(H>X0v>@^#3S)acx5~akH)Lu zF?cLq6_3N?@oIQ=yarwqPrz&8wedQ5UA!J%A8&v+#2ev_@g{gvycwQ|C*jF>bG!xK z5(jV)hj182a1_UI94BxRr*Il)a2Drq9v5&Cmv9+Za23~Z9XD_jw{ROz!CT?2@iur{ z{QnDrc6fWd1Kttugm=cf;9c=lyc^yf?}7Kkd*QwDK6qceAKo7yfDgn6;e+uZ_)vTp zo`w&{N8lszQTS+l44#f>;A8P|_;`E*J`taUPsXRO3@p<@s zd;z`?UxY8lm*7kBOne!>9AAO2#8=^~@iq8bd>y_X-+*t#H{qM{E%;V^8@?Uif$zk# z@Ll+Bd=I`C--qwV58wy!L-=9*2!0gL#*g90@e}w-{1ko~KZBpe&*A6s3;0F+5`G!K zf?vh2;n(pS_)Yv4ejC4o-^FwAd-#3)0saur#UJ61@jUzq{uFvP3zeJW+v&ASx1(L?xm!5k*83 zRfrfOmZ(a^5%EMdqB>E7s7WLcwTRk89ilE#kEl;HAQ}>lh{i+{qAAggNF?F_)M} z%qJEQ3yDRbF>xm7-Mq(4Onb<;XCAJaUi5*1R zP9lrgMeHW_5POMz#D3xcagaDf943wsM~Q6W7;&69L7XH`5vPeW#987Tah|w9TqG_L zmx(LHRpJ_Powz~VByJJ6i95tyB8Rv~+$SCo4~bmj5%HMFBc2dXiDyJU@tk-;6c8_o zSHx@L4e^$EN4zIK5Fd$8#Ao6Q@s;>Sd?$VoKZ#$&Z{iP8i1Zx=DZ1Lk5tA zNiSK13?z$^L1Zvlj0_=*lO@PdGK?%qmLkK+(qtL3ELn~$PgWo!$ckhnS&6JnMv>8E z6*7j5C99HgWIS1otWMS-Ymy0MEwVOQhpbE1BkPk5$cAJivN73&Y)UpG6UihpnQTtB zAX}0E36c;AlL(2D7>SbvNs<&vlMKm{9LbXcDUuQ?lM1Pl8mW^8X_6LclPP2?vNhR; zY)iHy+mjv0j$|jYGueggN~V(C$nInhvM1S#>`nF|`;z_0{^S61AUTK}Ob#K3lEcU} zayU7H97&EMN0Vd7bTWe+OO7MQlM~2^FVdCnfy-3sYXI2o>Q8r1l3FrGltnsu&eQ6{kv2 zq1650FzPt@C^$2?BvpzEr%F?0sIpW!sywyZQ-LZK8bMX0BB@GLWh#n_rm9deR4kR} z_WD$He#cSqR5hwPRfDQYB~Z1f+Eg8?E>(}JPc@(#QjMs_R1?bU)0ApP{R~c|lBi^= zIn{z{NdXi{K@?0O6iQ(fP7xGIQ4~!v6iaawPYKj&k4QOgg*(mGL{sV-DkDwXO+)e6pc?+-}z=}z^adQ!cp-c%o|DwPwE z>+VbSqxw?=sJ_%N&p_(9`-giFHJBRWm}RJ=F2ZM+12rcpjfxH!PK}^OQu{+jQT>{X zrp8d|R0cJc8b^(H4EuNQ3Dl8*iIn775;TdLOiiJ_l2fT^RHGu(sTu$D&ZK5hv#B}M zTxy;pIWAznBYCwa%V{m37E()s7Ez0-CDdQXId@A`Cbf)OPOYF;Qmd%{xc;x>BYYmX zS5s@KT=&o5oTRnXiln~OI_jZ&0u>h!7qFg6^{MSy?b+|NH#lvtPnKs6wUOFHZKk$R zTd8f-c4`N;lggrYQM;)<)LsY2bw}SmhxdMJeZT>#MDgS9QvL_2Lk_1b&td8ab=0v$ zPJq|P?erXWoc|>_n>t1vr%q5OsZ-SHf4CR8hj|{kf4R?4XPrHFds2P=+GBReIVUIz z+(UyWQ0J)&)J5tJ>GiopU3P*nF5rrTFV}sQy5{J(PTinxQn#qvPWui;1n&^^5vV{hkrHjykbWu8p4yKFIA#`!NgtLayVRT8l6dg{NrpwS}>2h>=x&j?RSEM89N_1ss ziK3(FD*s1D3>`~XrQ_)DR6Jdcu1+@&tU>RszPEZ!I)Sd`$lhDMHeH9VOV^|8(+%i` zbR)Vk-GpvRH*>ZmI(m}mWV$)sf^JCzH0bm}G)yBjN@FzcvTT(EbbGo3-I4A@cc#10UFlT1 z8{M7m;V|t<_j0yI(Y@(Dj)uN;KWFVv512dVF}FHrzfY)rsvRe9bzGlE7Fsb z=y~*fdI7!AA-;%S?DQb?5_&0}NiU<9(<|te&bZ2S&40%KH6Tl`qF4V9oicQzz%|a6 zwe&iAy|c##r@fKhL~s5_$`*R7BXgUhHj3U(?{JK^)6u(>&Z2iYqjuAK{?U@@j3MZ~ z^gen&eZc8INFQ<}ZFkJY(ue4f-az6(y!>(^c(su{f>T5f1p3opXkr@7y2vxjs8ympnuZ8=->1o zx)9^T_%eQsi*YmljE4ze3Nv1&2ouN@WrCPsrWg~#6lY2>p-dQ4k}1W6Go_g_Oj)KJ zQ=X~7L@*VZNTw1~nTcYenJP>S6U$U(;+S}*8dIIA!PI0Dm|9G2rVdk=smIi38ZZr+ zMoeR-3DcBm#w0RHOfu7)X~DE)00v|r24)ZjWiSS32!>=RhGrOsWjKas1V&^eMrIU7 zWi&=-48~+E#%5BOR!nQA4bzq>9n+3!&valqGM$*tOc$mrlge~sx-&hPo=h*MH`9md z%k*RVGXt1`%phhkGlUt+3}e!m;minTBr}Q`&5U8vnG7Z=W-K#~8P7~$CNh(l$;=dH zDuc&NW2Q4Rn3>EhW;Qd2naj*$<}(YJh0G#mF|&kO%49OjnB~k0W+k(VS}b~AgJz05vlKXZT?6myU{#2jXhFh`ke<`{FF zIl-J{PBEvMGt61$9CMzzz+7Z5F_)Pu%vI(ZbDg=t++=3O%#N88GdE^l%>0-IF$-fB z#Vn3l60WpbE%%zfqo^N`799x;!ZJmv}WlzGPFGtZe9Oab$fdBwbD z-Y{>Ocg%a{1M`vj#C&GHFkhK(%y;Go^OO0-{AT_zg;*cfm-S;^tef>`J!}A5nDw$n z*g&=@8^i{)#n=$GI9q}ZWy9E#Y$-OJEzOo;%d+Lz=P~8k3Ty;hk&R?4v6a~9ihmv7l}%;4vEA7oY)`fq+nepf_GSCA{n-KR zKz0y2m>t3nWrwk8>~Qwq;XQ&K$&O-2vt!tFHiI3@j$_BO6WEFDBz7`8h5b(eOl7CB z)7cs9Om-GKo1MeXW#_T;*#+!Eb`iUnUBWJ9GudVAa&`r~l3m5FX4kN5*>&uCb_2VS z-NbHYx3F8;ZR~b-2fLHaVt28-**)xDb|1T+J-{Ah53z^YBkWN&n?1%JXHT#v*;DLk z_6&QLJ;$DBFR&NcOYCL#3VW5k#$IP{us7LT>}~cAdzZ~&@3HsU2kb*Omwm)OX7ku5 z>{Ip`o6kOHU$6!2OZFA}ntj8*W#6&y*$?bT_7nS={lb1_zp>xhAM8)|7yFz2!xrLv zIA6|>b8&9YpYw15Tw%`372yK8qFfLc%oXE8xZ+$1E|d%7N^+&RaIQ30hAYdJG*^X-;bOU}TpSnARpY92HMp8w0#}Qx&DG)Ra`m|STm!Bl*NAJ( zHQ}0a&A3D^iA(01b1k@*9KeAb#K9cGp&Z8H9Kn$s#nBwYu^h+ooWO~k#L1k(shq~? zoWYr##o1g6*NSV+wc*-w?YQ<_2d*R6iR;XD;kt6ETsN*ex4H6`%00NATraLS*N5xN z_2c?;1Gs_QAZ{=>gd55YVX4x!fb}F_*_Z z;hu8OxP0z8_kt_nUUILv*W4TKE%%Ol&wb!Na-X=*+!yXE_l^6`{osCbzqsGrAFdGZ z!~61nyo-19{=A0|;0yC!z6c-47v+QaV4jUC#)t65`4W66AI6vDOYz}+X}%0!mM_Pb z=PU3Ld__Kzuf$j8qxfjP3LnGA@@ZB1I6j`Q##iTS@HP1az7}7bufx~n>+$vZ27E)l z5#N|^!Z+oc@risApUgMsTktJ;fCqVqhk1lYd5p(-f+u;3r+J2Fd5-6Kffsp+mwAO( zd5zb3gEx7LxA_#l72ld~!?)$z@$LBzd`G?$-@O}Ay ze1CobKad~959WvPL-}ER8b6#L!H?ue@uT@Md^(@OkLAbl<)`t} z`5F97eilEQpTp1P=kfFT1^hyO5x_ zU(2uK*Yg|rjr=BlGrxu3%5USh^E>#Rd=|fp-_7sg_wxJr{rmy`Ab*HI%pc*8^4a_` z{y2YvKgplsPxEK^v-~;!Jb!_|$d`%^k1icuCi)V8nZLqc<*)JA`5XLA{uUn<9UXm} zzr)|tbCyW;+2or@#!en8JFjbf)Oc!PdGlf~gY+;TtSC}Wv7ZwN$g+;<* zVTrI*$P|_d%Y_xfN@10-T392j71jysg$=?+VUw^~*dlBdwh7yX9l}l_OV}ms7WN2x zg?++);ec>ZI3yevjtEDEY~h%2TsR?|6ix}Jg)_og;hb<@xFB20&h3Acqi!d)RpxF_5f9taPGT;Y-MSjZEe2v3D)LcZ`^cp(%BFNOU0=kYJ%3*ukK z|Gks~RbC0Ng*U=m;hpea_#k`~J_(wVi7S=EGhQm_WyG>#Iph`Qid`p}0s~EG`k3ikadvak;ocTq&*+ zSBq=JwcyTsjMfqRd*SKKG=7Y~RBovnw& z!{QO~sF*Dt6OW50#FOGF@w9kGJS(1a_?&mJTo5mcm&D8B700Fp?yKT8@w&6z5O0dN z#M|N>@vfL7-V^VO55$LJuJ}lNEar(%#HZpjF<*Qxz7Pw1q%bL5DlL_f%1Y&= z@=^sULaHc5N|mI_Qj`=eRgq$(SgEQMC&f$Er0P-)siu@5)skvUb)>pdJ*mFbKx!y8 zk{U}*q^43cDN#z2lBMQS3#p|9NT38su!Kmcgh{wWNTftbw8TiP#7Vp)NTMW3vZP3= zq)EDDNTy^-wv-~Zl3Gh`q_$E!slC)e>L_)RI!j%ou2QPhP3kW7ka|kJq~1~=sjt*e z>MsqD21Z0URm~lhUN&(gEfWCTX*@McOKDleSAcq@7Zhv`gA8?UD9M`=tHS0qLN0NIEPXk&a5)(lP0{bV52Q zosv#VXQZ>zIqAG~LAoeik}gYEq^r_3>AG}7x+&d~ZcBHhyHbvHPr5HXkRD38(o^J- z^jON1o=8unXHvfOTzVlDNH3*V(rf9Bw9}c#_Evf)y_Y^nAEi&yXX%UdRr)45o)M_K|&MKiMU_Wq;Wt2grqGuUte9l#9wYz#utTE+&V_#pM!ms2nDjluOCs za%s7YTvje8mzOKZ5pqR2Qm!OdmZRioxr!Vk$I4aZI5}RfCRdkh$Tj5zxt3g8t|Ql# z>&f-y2698Wk=$5rA~%(r$%%53oGdq&TgWYCKn7(A+ZgO|Ihul-{ zCHI#5$bIF0a({V%JWw7a50;0>L*-#|nmk+{A&-|?uWUMw$>m&%#)GI_bYLS8BV$3v^+ z)$$s7t-MZNFK>`H%A4fP@)mikyiMLN?~r%OS@JGgOTI1Nk?+bm@;&*! z{6Kyv=gN=d$8w(hM1Cqilk?^0@(Z~@eks3_U(0XgxAHsrz5GG`D1VYa%U|TL@;CXr z{6qdJ|B`>pe`F^wzv8R-DK5pW_$wYIKq;(vl_E-@Qd9|2f|X)Qh*DfBp@b@7N=c=Z z60Ve1$|z-(a!Prnf)b%rR3ep1N@b;FV3ZQAR8i6bVw6~=s)8rQDe+1*rMgl>si`C= zwUpXQ9i^^PPpPjoP#P+Yl*URErK!?PNmP=QWTm;%LTRZ03aCH|tRM=iU<$4f3aL;E ztuP9!a0;&oil|76tSE}AXo{{Fim6zNt)wWel-5ccrLEFVX|HrpIx3x%&Po@htCFg8 zQ@SfXl%7g2rMJ>Y>8tcp`YQvJfyy9durfp$sti-o(v;!K2xX))N*S$;QPPzRWvntz z8Lv!GCMuJZ$;uREsxnQPuFOzoDzlW?${b~`GEbSWEKn9Iim>{0eA`;`640p*}_NI9$= zQI0Cv$}#1*azZ(&oKj9JXOy$bIpw@^LAj`0QZ6f3l&i`$<+^f1xvAVzZYy_`yGo97 zPr0u=P#!9|$|L2mlBYaTo+{6jeC4_FLMc#QDzB8+${Xda@=kfLd{90rpOnwa7v-z+ zP5G|;P<|@El;6r9rI6~Q`l^1aOLeRMsz(h_3#(qWh#IICRfE)EwU`>B7FSECp=y{~ zQZ1#1tEJU4YFV|MT3)T7MyM6lNVSq$S&dSo)hcR?8mm@St*6#k8>kJ{MrvcViP}_crY5RMYO>l~ZK1YQ0Toms6;=@yRWTJ;36)eSl~x&* zRXLSc1yxifRaO;MRW(&t4b@aF)mBr~R%&atjoMair?yu+s2$Z#YG<{J+EqOggnI#?Z|4poP#Y3guwggR0krH)p|sOf5kI#wO0j#nqB z6V*xTWOa%Me1U8iMmwHRF|pC)fMVWb(OkW zU8Am5*Qx8(4eCa9le$^mqHa~UsoT{Z>P|IF-KFkU_o#c-ed>PofO=3pq#jm}s7KXo z^_Y5GJ)xddPpPNXGwNCOoO)ippk7ojsh8C&>Q(icdR@Jt-c)a?e@|w&)jR54HAlUt z-d7)}57k`tk@{H8Q=h0$)n{tH`dodX7N{@PSL$o^jrvx7r@mJ|s2|l&>Sy(f`c?g= zepi2}Kh+G_2z_F4z6qt;35taZ`4YN=W` zt-IDk>#6n9(t2xsw7yzDt-m%v8>kJ^25UpKq1rGlO&hL_&_-&bw9(oaEiEox%h1MZ z)q(WYwCwCUOmZKgI$o2|{!=4$h_`Pu?)p|(g{tS!-&YMELaXqmQL zTcNGgR%xrXHQHKjowi=vpl#GPX`8hz+E#6wwq4ty?bNcgUD|GKkG5Car|s7cXa}`J z+F|X8c2vvOj%mlW6WU4bly+J>qn*{xY3H>I+C}Y>c3HckUDd8>*R>nkP3@L;Tf3v( z)pE3Z+I{VT_E5{!9%+xYJnf10RC}i7YtOY8T7mXbd!;o}Uu$o)x7s`Hz4k%-sD08t zYhSdl+BfaH_Cx!r{nCDGf3!lnkM67c=`P)^`|BP(KrgI&^&)zpUQ`d#gY{y1h+bST zp@-^WdP%*M9 zPta@Wwe>oBUA>-OUvHo{)EnuI^(J~#y_ueW(fSxYUC+=XeLlFy>Ur*Q`gnbUK2e{fPu8dCc}V$ysrod1x;{gnsn619 z>vQzE`aFHUzCd57FVYw5OZ26V)>jQP^=0~UeT81&p66Mq?+;j|uh!S-YxQ;ddVPbw zQQxF**0<j(6M`XT+WULjzqzS@)T zt`M-=b3{L?XY0rGASc@gryti(=qL44j;&7XXY{lBIsLqTLBFV9(l6^*^sD+c{kncb zzp3BSZ|isTyLyg(PrvUVlspgghkArhgio&iNPn#7=}+{h`ZGP>v2C9Fx&A^g&|m7W z^w;_u{jL5^f3JVgKkA?K&-xertNu;@uK&<~>c8~g`X9ZJ;bZt3eum3%8~%pJ2rvp8 zUZaQ+XcRT(c!P{!qnHt56gNs3p+=Zd(kNww8>NjhMp>hrQQoLvL>Lu~NTZUG=dNr- z8PP@+BgTj|sv2=dyiv`lZqzVp8VN=%qqb4UsB6?S>KhG=hDIZ!v60rqXli_L@A5P= z5{>A92%qEbBqP~qZnQ938ht!~k?%|!NOgK6JP{tyi10uLY#_#g0Mx(?+?YcV25C?R zZ7>FFa0YJ(MwUl3Btte*eH3R^4b9LE!!QlYu#LZRQjAtcYom>kVyyJGHQE{NjSfaf zqm$9u=wfs=QjKm#ccX{V)97XNHu@NSjef@7q`x`~+{c~eOj3WNyz_K^zk{O#(v82NlwpiD#u?*{2}Y#PMB^`;eogKNPja~Y zT_zh-jH$*nW4bZJm}$&1W*c*ixyC$WzOleqXe=^Tdw#hW8%vC(My9dMSZ=H^RvN2} z)y5iQt+CEnZ$t%D2>6R`gR#-rWNbFJ7+Z~P#y9tNV~4TR$TD^ryNx}@USprJ-(ipw zeB24u1ICengT^5T!C~Wwan#5*jv12YxN*WbX`C`n8`quL5NC|D#yR7>alyD~Trw^j zSB$I1H6zn`)_>i&Vcaxs89O{roTvJ?jXTC&BgeRB+&3Ql!!E)zs^&u@*Rf{jfJeq- zBhPqZl=6RSJTvl*=f(@8z|r;6cxAjc-WYEkKfR%D2EQ}j8y}31#wX*m@x}ORd^5fq zKa8KoFXOlI$0%g_n7(EN|uD#B4(gj)C@9D76~@zd5W1K zW^uEG8EO`|=Xg(rq!?jlNi)}(8WZ7DA)u5QZk9I7m}SlW`YU%i)9dv0q{^EW%-6vY zW<@j7tYlU;qs(YC)u)Q-4shllI0x&IfEY8zyiCQKRn0gv-mGR;H*1(R&2;^Ta~LL= zwanUP9kZ@k&#Z4YFdLeU%*JLDv#Ht4+^*L!6U`(u*=%lJcegPA&cA4B0w(Ba{;T^? zK))uC37d$CnwW{3gh`r|Nt=wxI+!_=Hw9BPB~vzExfN42HB&bY(=;v9HdD-2W^1#J z+16}lwl_PN9nDT=XS0jh)l4<}H0#@}U$g$r1~lttb~k&NJ7O!_5)qNOP1q+8kr1n;GUgQb%2;Ksa#ne( zf)!!K1td`wtw^hqRoRNNqOB@cj1_BDwc@OJtD05a`Vw5js%a%ywXE7!9jmTY&#G@V zu>S3=K8g9w`z1EC1|&AJ8e2`QrdBg6(MqzCt>#t>tEB~4paog5g;=PCS-3@5q(xb@ z#aOJxS-d4!vlHheik4)}Pn0diQZ3EWEyFS`%d)K$tCiK-YGbvv+F9+b4pv92lhxVk zVs*7rt!`F#>zBKS)zj)_^|tz0eXV|0e`|m>&>Cb7wuV?ktzlN0HQX9ujkHEtqpdMk zq))n)VU4xMS>vq<) zEwwVOW!7?Qg|*UJWv#Z>SZl3y)_QA$wb9ySZML>pTdi%@c58>V)5@}TS-Y)0)?RC$ zwck2m9kdQvhpi*lQ7hXzW*xUqSSPJh)@kdEb=Inw6l$HbB+q&4f_2flWL>tdSXZrU z)^+QKbQtw+{lE6;jjJ++=$`POsmwsRN%!YZ&{TCc3v z)*I`s_0D>4eXu@SpRCW;7wfC_&H8Truzp&z3)^11 zh#hDbwS(+nyO~*E(k^9(+okO?c3HceUEZ!>N7xnZNV}3<*^aWK?J9PR z9cx#$mCMDRl?Amr6yRMyY)w9b7>`SU|A4qCoH?$ksJ&eY76PpZZ zYB#h0B2ToF>}0#S-NJ5Z12$;iO@eILMr_o^Y}_Vn(xz2`)a)*fe% zwBSX=mBH>>uvk_8xn$ zz0clnAFvNPpAXrG?IZS4JKH{HAGc4~C+$=AY5RK7- zzHZ;JZ`!x)+x8v%uAO7wv+p}dAJ`A=T>Fvz*v_+`*iY?ecE0`Geqk5bFYQ%V*Wke+3M4ByB)H3Tch?o%-QC^Y9fG^NOK{g9cZPlTIsZQQ z;lA9rdq0*!!ZAO?s9;(&M{0cZ>~0h$7dK$7=)96sP{pP0mCpc(L^&-^9{ ziCL{VkeJv4XbH3eS_5r>wm>@|1xN+j108^lKqsIxkoBIqE zM0%xZ0XEgmezzAR@FbWtAi~+_1wyixMqm@L8Q21B1^#n6Zv(aiJAhB2JAqxmZeS0v7uW~v2Mz!S zfkVJyARRaY90iU6$AJ^TN#GQ48aM--1F)20RB|055@8z-!8@EgbmW(RYCIl)|D02l}cfx%#IFb|j)3<2|j`N2@I z09X(#1QrIvz#?EcSQIP2lAi*il79_paQC(2DXjYK?5{F3$#H8bU{Cu2KEOBfCIrn z;9zhFI20TP4hKhoBf(MNXmAWT790nT2mem-1n?Cw5u5~02B&~i!D--haK?Y7aV9tm zoDI$a=YsRV`QQR@A-D)!3@!neg3G|=;0kahxC&eit^wDA>%jHk25=*|3ET{B0k?wN z!0q4;a3{D6+zsvlcL(nU_ksJt1K>gM5O^3&2akY9!DHZY@C0}gJO!Qx&wyvabKrUK z0(cR;1YQQOfLFn5;C1i@coVz@-Ujc0cfot$eeePJ5PSqa2A_aW!3^*j_#Auzz64)^ zufaFqTkswD9{d1)1V4eF!7t!f@EiCY%mjacKfzz%Z!jB_9m)aagmOUvP#_cp1w*-^ zJWyU}C>R3egYrY6PywhQR0t{zg+WE2aHuF$42pn?LnWY+P${T1R0b*wm4nJd6`+bx zB`6ZA3{`=uLe-$^Pz|Ui6b03SYD0CPx==l+KGXne2sMJDp%^F@ii6^z1gJ681ZoN; zLP?MhN`{(2&7l@hOQ;pp8fpWzh1x+WP%6|O>Hu|wIzgSGE>Ksf8`K@@0riA>LA{|q zP+zDY1VA7JK`?|sD1<>cL_j1&K{UibEW|-PBtRl0K{BL3Dx^U=WI!flLH{%VHsnAq zpg|0!@p&QUm=oWMvx&z&X?m_pV2hc<45%d^( z0zHK?pl8r?=mqo=dIi0P-av1mcTn1U=mYc-`UHK3zCd50Z_sxr6Z!%DgnmK4p=@w= zI0u{)&IJd+fp8EU43`9R!+GGma0r|a&JTye1>k~kA-FIc1{Z$HI zVF4Cl36^06R$&d+VFNZ{3$|egc40r92KR>tzyo0p90U)BhrmPOVeoKx1UwQR1&@Zu zz+>TY@OXFvJQ1D*Pll(!Q{idwba)0l6P^XnhUdU@;d$_UIO}>_0560W!HeM~@KSgg zyc}KuuY^~@tKl{9T6i729^L?Ngg3#P;Vtl1cpJPO-U07~cfq^iJ@8(5AG{wv03U=8 z!H3~=_y~LyJ_a9$PrxVPQ}Ai{41Ct>55iHYXW^YSqf*bo=iv+R#eZ8~f-l2Y;H&U8 z_&R(8z6sxgZ^L)syYM~uKKuZF2tR@!!%yI+a0dL$!y8}YIs5{C3BQ70!*AfX@H_ZD z`~m(5fAVlXdq`ir{ww?q{tjotKj5E#c>aQa!`YDRNDd??k_!nyPQrmm5E6{!M)Dwe zkq{&wk{=003LpiMLP%jG3@L(yBSn#7NCZ+GDS?zkN+G3@GDumZ98w;sfK)^(A(2RB zqzY0MsfIlFI92!h&u|T-CepSE6!sjBLUzNoklIKcq%QK=<5dqy46BXQM;driLvOFP zr+?bx`gfFxVU3VzZ!HFiMdFZnB*D{r4)3V>9&YSeHt}|vB8f;6av%12n9t#4BpcGq zlM=(4BT=a>kgTk>L|P%Okv5)XTcn+5m4c*tnxFsV=DC-j_DBb$Bhm@!jC4V|BHfVg z$XmFFr|~+mr`PvFdV75PAbpXBNIwKXKm)w= z$V6lkG8vhIOhu+4(~%iS+Dv2?G8>tL%thuQ^N|I}LSzxL7+HcWMV2AUkrl{FWEHX+ zS%a)a)*$A={B1$j0EY(L0gx(Yuh{$R1=bvJcsh96$~thmgZa zI&uU#iX20ZBPWoP$f^G#ei}K0oJGzd=aCD@MdT848M%U7MXn*&ksHWOWZqRnV$vHMBZf1FeZhp|#N3 zXdSdJS`V#{Hb5JqjnHT`2CW_wi^iexXad?8ZGtvM6VW8phbE)V(B^0hv?baKZH=}; z+oJ8z6f_lWk9I&iqMgvrXcx3A+70cF_CR~0z0lrhAG9yp4+T&Vg-{qpP!z>b93@Z^ zrBE7WP!{D-9u-g#l~5T~P!-is9W~Ij7!$Qn8+A|@^`mKMe{=vk5FLaLMu(t7(P8Lt zbObsQ9fgiY$Dm`;ap-t-0y+_$gic1Mpi|Ll=yY@jIuo6R&PL~;bJ2O|d~^Z25M6{W zMwg&V(e*LQ(BF#fEC0FVTG|UtOyp46~&5S5m<4o1XdC&g_Xw2U}dp#Sb3}hRuQX&MPik)Dp*yl z8de>vfz`yKuv%DctPWNetB2Lc8ek2vMp!f!gT-QTSUi@1HO87?O|e8Q3G-peSTn3S zwj{U())FhwtQFQ8YlF4L+F>bJD%KwBfOW(=VV$uqSXZnY)*b7C^~8E%y|F%6U#uSn zU?2uzFos|#hG95HU?fIiG{#^o#$h}rU?L`AgJWe(!O~Q$amvV84bw3LGcgOZF$Z%o zKbD5|#|B^nu|e2iYzQ_K8-@+XMqnecQP^l~3^o=UhmFT3U=y)P*ko)9HWizOO~+(gDu$$N|>^61>yNlh!?qd(I zhu9?QUJdyT!p-eT{t_t*#QBlZdVjD5krV&AauSSI!Z`-%O+ zeq-72?0615C!Pxrzyt9hJQ&Z7=fSJT<;6qre0Y956fb}m#0%kt@i4py9*!5qi{TM? zal8ax5-)|9#>?Pk@p5>1yaHYkuY^b9mGLTgRlFKr9j}4c#G~+9cx}86UKg*2*T);+ z4e>^JG#-QJL}T$dJRVQL8{?rvPT~|!;|$K?9M0nc zF5(g{;|i|g8m{98ZsHbh;|}iPemo8Dj}O2H;)C$P_z-+3J`CR+Hyj^TF-pMlTBXW_H)Irvfsz8qhH zuf$j3tMN7XT6`V89^Zg(#5dua@h$jPd>g(U-+}MMcj3G7J@{UHAHE+yfFHyU;fL{b z{0M#&KZYO2Pv9r?7r%$! z#~`8_%Hl7?tRfGk%P!dOf(~!6D^3AL@S~- z(S~SCv?Ef8RH8l6f#^tdB03XkU5KtkH=;YygXl^0B6<^jh`vNW0w6#FB47d`Py!=x zf*?qOB4~mkSb`&XLLlm*A|Vknp%5ye5jtTICSega;Set2C(?-i!~kL-F^CvU3?YUR z!-(O;2x25LiWp6dA;uEpi1EY(Vj?k#m`qF|rV`VL>BJ0TCNYbcP0S(Y67z`pL`M7q zVj;1JSWGM-mJ-W|<-`hNC9#TFO{^i-5?|ui5$lN!#E{89)Y-L1ZwQo6JMz zB}2%3WPUP~EI<|{3z3D%FtP|4P8KDLkr8BZvIJR@EJcPtU=Z!qsUrhZL$tom#jzDCmWCr$wp)}8AHaBab!H1KsF|ukWI-%GKut& z$z(IKIoX12Nwy+elWoYhWIHm2OeNcs9mtMkC$clyh3rapBfFD5$ev^`vNzd>>`V3| z0TLu35+)H6B{32w36dl!k|r6FB{`BO1yUp>QYIBr{V$#xsgnk2k``%`4(XD9GL7s{ z4j>1TgUG?;5OOFvj2upmAV-p;$V1Vi$@J(k9k+;b^k#l0V3wxu^gt zkP4!LsoYc^DlZj6<)iXbp;Q5?AXSJeOodTJsBo$%Rg8+Dic=-1l2j?GG*yNwOO>O_ zQx&L+R3$2ss!Ua(s#4Xc>QoJ?CKW~1qH0rhsJc`=sy@|#YDhJrqNx}vEtZO-;;96x zG1Y`>N+nWBl#fcLno-TE7F0{B71f$*L$#&aQ7Kd^)t>4=b)-5`ovAKVSE?J;o$5jL zq!{D3#JEoiZqs zvM8H!D3|h6X;gn|05y;rL=C2fP(!I<)NpD9HIf=d<&GUqjiJU;32)Cy`PwTfCzt)bRZ>!|hA z25KXKAa#g3Or=vtsH4;|>Ns_RI!T?P zPE%*7v(!22JavJ(NL`{XQ&*^~)HUilb%VM|-J)(&#{%zAcd2{Sed+=Aka|Qtrk+qw zsSN5F^_+S^y`)}IucKpZ)%A|f!KdE2TZz>y|oz6k$ zq;t^$bRZo>2h+LfJak?A|i_qb8QMwo%K^Lb>&?V_obZNQ_ zU6w9Km!~Vx73oTJBwd-VLRY1$(bef1bWJ*nu0_|T>(F)SdUSod0o{;pL`TyxbSxc5 z$I}UPW4a05luo3RXdj(SH=~==E$EhXE4nq^hHgu@qf_Wqx;@>2?nrl{JJVh0u5>rL zJKclsN%x|A(|zc^bUzxPK^mfA8lh1dqj8#`Nt&W*nxR>mqj_4OMOva|TA@{1qjlP# zP1>Su+M!+APp8rS=>haWdJsLB9zqYLhtb375%frU6g`?ALyx7$(c|d}^hA0RJ(-?D zPo<~P)9D%XOnMeQo1R0@rRUM}=>_ycdJ(;tUP3RWm(k1V74%Aa6}_5XL$9UR(d+3A z^hSCUy_w!ZZ>6`<+vy$jPI?!;o8Ck3rT5YM=>zmZ`Vf7XPN$F1N9kkqary*(l0HSB zrq9r4>2vgX`T~8CzC>T9uh3WNYxH&c27QyhMc=0H(0A#3^nLmP{g8e{Kc=71Pw5Q$ z8U37oLBFJ5(XZ(@^jrEJ{ht0nf22RrpXo33SNa?MozA3x&_C&4^lv&Flby-IB;nBdNX~PzDz#`U_b_9UI$hWri`snGwuLW)w4;8N-Za#xdiW3Cu)h5;K{Z z!c1kRG1HkD%uHq$Gn<*i%w^^=^O*(ALS_-Om|4OsWtK6^nH9`RW)-uVS;MSl)-mgu z4a`Pn6SJAw!fa)>G259P%uZ$(vzyt&>}B>b`~zou#8^i{)x!F8yUN(fy$L424*#c}qwh&vG4P%S2;cQX17#qPBXG^dp*-~t2whUXA zEysQiEzee9E3%c?NVYOtg{{g~W2>_@*qUqd1r*jP4> zjb{_s#%vR|DVxY9u|77LZN@fdTd?IrTC%O!)@&QLE!&PwVN==mYzMX@+llSWcJXFi zy}h<ER$*0EV|CVGP1a&<)?r=N&qno0WBaoM*n#XIb}(Bjq;60`{NCdJDr`u&SYn?JDSaA=dg3xdF*_40lUy!U&JnE zm#|COW$bcx1-p`6#ja-8uxr^l+1Ih_*$wPQc9WOK&FmI-E4z)|?qzicyOZ6;?q>I} zd)a;Le)a%+kUhj6X4Bat?9qQke$0#fxEJ{e_9T0XJ<#uNdyBp8Nq5-0>^=5A8y@n2eaJpyAG1%`ryg1c`;2|gzF=Rnuh`e@8}=>x zj(yL5U_Y{-yr{>rpV=?$SN0prX8-QtrDd`|*q`h#_BWf2%g*KCa&o!20Iq9LAQ!|1 zbGf;}-baaNLFMJLphCEOTz)Q;E5H@x3UU8QVPS3@8^#sk!nvYcF)o7pE6K&V5?o2H z6t_I3G*^Zz%a!BGa}~IXTqQ1&`zzu9DT2ye6|O2*jjPVp;A(PF+~Ov+xZ2#olsa5b zwk}tXtIsvy8gh-eXfB3}<>I(_E`e*zHQ}0aiChxrY%i`i*N5xNwd&oE12~X_IG95? zl*2fjBRGKac+z4(YH|o!8G&hDD`#Luh2km4B~_N+Od;z{7Ux+Wvhw(-Da8IKsUyP67 zi}NM;l6)z?G+%}<%a`NJ^A-4t{Iook_;q>z9y0^}=`E6vLZO@iy=9uIJb9^#_6<1$5)n1Jd~Z`~ZF+KZqa9 z58;RM!@NB|eKVei}cWpTW=M zXYsT7Is9CH9zUO7z%S$%@r(H-{8D}yznovee+*d3ui`U9R`YB4wfs7MJ->n9$Zz5| z^IQ0>{5F0&zk}b&@8Wm!d-%QlK7K!cfIr9|;t%ub{1M)aKFS~CkMk$^ll&?EG=GLa z%b(-V^B4Gw{3ZTn;AQ>_f0e(+U*~V|H~)*rE&euthri3;{xScAf68a@ zNZ2#}Isbxx$-m-X^KbaK{5$?V|AGI=f8sy$U-+;5H~u@H$^YPg^1t}sd^RDwkVD8R zO3>QWSBZX1IXkm;nRv0IY7bXZ3 zg-OEYfXTuXVX81qm@do^W(u=}*}@!Qt}suSFDwui3X6or!V+PruuNDktPoZTtAy3U z8ey%lPFOE&5H<>bo$l6tn}p567GbNfP3V(tyRbvpDP#of5_St;LiY%Jg?(PzFB}jK z3WtQlLb`B7I4T?yjteJ*lfo(Cv~Wf^E1VO~3m1foLWXzhmxRm072&FIO{g1mUAQ6K z6mAK(g*(Ds;hu0`cpyCVT4&*r@L0GVa64dF=)T}l`JM<*g$&`D@LYHyycAvuuZ1_l zTcK2NdcZs3z3@T!=$-o~FP6{37vZb$P53Tk3O|IO!Y|>skWI|)wH#tjF_#!128u!A zs^DNTx0pxFE0zup5%Y=p#k5edfLKs0Bo-FK#3Ew27%3DLi-{3paj}G0QYj1()2Rm7@dHLF{`Lw1$+$XBkqOziv7eMDS!xykO+%f93rA3CgLI?k|HJM z6=;zWS&mi&bP8Vm0GsRir zY;le_SDYu#7Z->~*g|oUxL8~wF7@~=6PJrC#FgSIF+E_lxJFznt`pab8^n#`CULX4 zMcgWG6Ss>y#GT?Uakscf+$-)A_lpO_gJM>R9ug0W>EaRbsCY~~E|!ZgAAdqTDV`Ef zi)X~M;yLlWI7PT1UKB5hm&GgMRq>j5IpDf@L%b>85^sxl#Jl1>@xJ&#d?;oHJQ5#^ zPsFEUhWJc;F1`?7im$}i;v4a;_)dH;eh@#3pTzBXK8s((ui`iHyO=5d@bdOk{3ZSt zvq_7B^9$Lf98yjxmlPlcN zj5JmnCykdTNE4+=(qw6hG*y}=O_yd!Go@M5Y-x@(SDGiymljA1rA5+WX^FH{S|%-* zR!A$QRnlr{jkH!;C#{z@NE@Y1(q?Ikv{l+BZI^aPJEdLHZfTFSSK23~?UxQn2c<*O zVJTfYA{~{ENynuV(n;x*bXqziot4f>=cNnMMd^}sS-K)!m99zGr5n;s>6Ua`x+C3{ z?n(Eh2hv07k@Q%4B0ZHdq-WA|>4o%CdL_M<-binychY<5gY;4QBz=~?NMEII(swCS z`XT+4eo4QjY;txvhn!Q+B?riXa*!M>=a%!xdF2o}pPXL~l?%uPH zb>(_;eYt_$P;Mkg%Q14S94E)i336k(iQH69l#^tioGkl`cwfaMHm&+^UmGUZiwY)}NE3cE+%Nyj4@+Nt+yhYwBZPk3HhXaN+%ixrhH4j zE#Hyv%J<~^@&oyy{78N*Karox8S*pvx%@(YDZi3m%Wvej@;mvx{6YRGf094TU*xay zH~G7qDgTgv%D?2_a#DCUCA*SC$*JU00+c`{NC{SQD|wW>N{EtA$*+Ve1(bqHA*HYq zrW8@am7+>9B|<5#lu$}4rIgYN9nOTa;aoWH{bUfs%P3`)a!Prnf>Kebq(mx}l`2YA zrJ7P*siD+VqLf-nZKaMY>8tcp00mSa z1y&FRRWJot2!&KAg;p4aRXBxL1VvONMOG9=RWwCc48>F|#a0}}Rs2et(q9>%3{(aw zgOwr5P-U1hTp6K^R7NSIl`+a#Wt=iznV?KmCMlDZDaur3nlfFPq0CffDYKP1%3Nih zGGAGsEL0XLi&X@?3eLyi{H( zua!5-TjibdUiqMWR6Z%6l`qOy<(u+d$y9zQKb2p~ZzY?WUCp89RCB2TYM>gV2CKQ% zJZfGwM9rt>S3}hTYC*M-T38KJi>TphQMH&Fp%zz5s3p}>YH78MT2?KmmRBpN71c^= zq*__6qE=O_snyjQYE3mtt)!@|rdTM>Of!a`Qq(-YTYOETk#;XZxW3`FeR83Tq zRG*rxHdC9cE!383E48)SMs2IMQ&ZGbwY}Ow?WlHAJF8vPu4*^6yV^tTsrFKPt9{hI zYCjcFK^0PA6;V+YQ*o70NtIG*l~GxhQ+ZWTMO9K|RZ&${Q+3r)P1RCu)lps5ucoQ} z)dA{2b&xt(9ik3ZhpEHW5$Z^FlsZ}+qmEU_spHiN>O^&tI$52fPF1I=)72U3Om&tz zTb-lMRp+Vm)dlK8b&PB^wx>?<#ZdJFb z+tnTFPIZ^MTiv7XRrjg;)dT85^^kg4O;?YoN7ZBMarK0HQaz=fR?nzs)pP23^@4g) zy`)}Nuc%kmYwC6NhI&)IrQTNWsCU(S>V5Tr`cQqOK31QoPt^?dnfhFPp}tgKsjt;H z>Ra`l`dTflhmR-xC<kXBd=(~4-}T2ZZ-7NHf_N@yjuQd()Pj8;}Fr#OzC z01eb24b~71)i4d$2#wSzjn){A)i{mU1WnW=P1Y1m)ih1l49(Om&DI>v)%;qT)?XW- z4b%o{gS8>rP;HntTpOW{)JAEewK3XQZJahX@|9R?TB_%JEk4iPG~2!Q`%{*LPW)gN)eF}l_RP| zRE;>Joz>21=d}ykMeUMyS-YZL)vjsRwHw+^?Ur_1yQAIJ?rHb62iimJk@i@7qCM3z zv}f9L?S=MId!@bB-e_;NciMaHgZ5GTq*g(Np#IdI!Cu-bwGQchS4*-SqBy z551?}OYg1s(fjKCbU+7nNQZSqM|Dic^}`YA5l149MjVSc9&sXq&`F)rX`Rtoozr<; z&_!L+WnIx#UDI{l&`sUaZQapb-LI$V{q+I*Kz)!tSRbMf)raZB^%43=eUv_0AES@e z$LZts3Hn5Rl0I3VqEFSQ>C^QY`b>S6K3kuo&(-JY^YsP#LVc0GSYM(q)tBkZ^%eR` zeU-jiU!$+p*Xir^4f;lXlfGHsqHoo=>D%=k`c8e9zFXg;@74F|`}G6*LH&?^SWnlF z=tuQq`f>e)eo{ZBpVrUlXZ3UXdHsTZQNN^L*01PS^=tZd{f2&1zop;S@91~+d-{F- zf&Nf`q(9c5=uh7Vs4`d9s%{$0=1f9OB; zU;1x7n~~kfVdOM&839J15o81#xs5zVUL(ZFXXH0RjRHnNqmWV92s4Tp;YLxTm=R$V zH%b^KjZ#Kwql{73C})&6Di{@wN=Bqn*{EVvHL4lajT%NxBg&{{)HdoEb&aiMx0T&q zwq&VNrAn77Q>va(-)LYoG#VMvMvM__#2N8Mg3;J$Vl*`pjU>ZoBpc0)=0*#nrP0c0 zZL~4k8tse}Bh_ecbTB#^os7;#7o)4u&FF6QFnSujjNV2cqp#7=01VLUApJUMF|Z%pvuCK{8B$;K29ZmKcO^Y$Om z>BbCif2J|Zm~G7QcIF!MjQPd_W1;7Nk+IlV;;k(;mKn?cSg$Zv8ml}8j{;VEj20Se zJe{?FNUt;28|gX7KbRYgjepiQc`KWY&BhjEs}UEH#V9MpET-Fx?VkPUKXMk!9mdW- zjI%872kbI-d%Jr)oGhCW9)m2qb$_I+mA_-l2-s`v`&YdCjRVF(lcM~!2~ zapQz>(i^>h8a7TFXN!MJE#GA1#7*CD=>EV!(;bA;8o*OTWm!5}L#%oV{W4!&d_9Ndr9A*~Abt9)YX36P);<|3+ zGG7~If&$DRMxdEx5o89N*FD@H`Er||j67!EKdafy5Kk}5LoPF)`N+s`hMHMy%LElL z3z~(@!e*FR#0)o!n#Ifrv$$EpENPZ9OPgiPvSvB6yjj7lXjU>K&B|sKv#MFmtZvpY zYnoAJEwi>+$E<7CGwYiT%!XzoGun(XW6d}--b^qXn@!B7W}=y7`pjgrnc3WIVYW0| znXSz>|CqP=FW&{twq`ps#Y{EZn;p!KW+$_=*~RQ?b~C%1Jan|;i_WG1r`D&NmmB3(ZC5VsnYP)LdpRH&>V|%~j@VbB(#yTxYH~H<%mE zP3C5Ei@DX@W^Olkm^;n1UFL3ckGa>}XYMx-mOn-9!~<|Fg5`NVu` zW|+^+=jIFZrFWRG%-7}{^X;E>y))mNAIy*DC-bxU#r$f1Gryae<`462&z~OoU*>N! zo0Z+lVdb<&nz^h1E6@tEg00+E9xJaEV*Q=wd{%xd)GA;VvT__qE*R?v?^Owtg7CunpNGZVb!#vtXfuW ztBzIIs%O==8dwdjMpm@d>wly>#)`G#tavNIYHT&JntD>Am1Oy>WUHCg+-hO9v|3rM ztu|I$tDTi%rCRN+4pv92lhxVkVs*8;S>3H3R!^&!)!XW0^|ktWvn(Cpj}B--7HlD& zHfmuOZV?t~Q5OAQUKxwEIE%LgOSB|QwiHXXG)uP(%d{-Zwj9f~{8pOP-x^>Iv<6v& zts&M>YnV0MnxB1yHPRYojkd;EW36%4cx!?+(VApU_Pk87rdrdi>3_V;ux47btSsHx z)*Np(*JC-)nr|(z7Fvs}#nuupnx)nhbtwYvfE8RL`9kq^G$GvQvuufX1 ztkc#R>#TLoI&WRDE?SqY%hna^s)upSy6$1zux?tnJWjW*JJwz6o^{`PU_G=RS&ywJ z)>A9PdS*ShURW=!SJrFmjrG=gXT7&RSRbuV)@SRB_0{@jeYY~LAJ$Lnm-XAqW@oo^ z*g5T7c7Ppd2id`PZaa^i*Ir_U*!k@IcBoyzE@&6BVXLqmW*4!;?V@%uJHjq*m#|CP zrR>sn8M~}q&Mt3Puq)b?>`1$^UB#|ySF@|zHSC&plwHfNZP&5u+VyPc&uQ1U8`xR3 z(9mvVN82%WtQ}{^+X;4KyNTV@PPCJ3pPg)HymC$5+iaphyW>2?g*fZ@}_H28OJ=dOR z&$nm)DZmBxLVJ=~7wn7nCHt~{#lGsXx@KShH>(@=P5YL8+rDGpweQ(`lBy@& zw;$MlGkIt~vLD+|?5B2y{mg!Dzp!80uk6?M8~d&O&VFxyus_9w)C8;^cGkJE2Yir=U~FDeEieEAK1p zggHf=aHptK%!zP{J0+ZwPAR9AueGm@udT10FU6PYYwzpe>*(v`>+I{|>*_;%s1Ng% zb_gHoE8_@0(O1?f=ahFUI2D~rj^CH&>+g$nDmzu2p}t|h;l2^Rk-kyB(Y{r_)xI^p zs!lbhx>Lic=|nlToZ3zur>?Wzx5Ky7SI?>MG;kU^jhuf*6z#+~u}+*5?_BrY@C76X zCMP(JohD9GCvS3{*1hcF8HpsmYy^ zJ12KZ?wZ^!xqEVtWFc8hmXcdJt(`VbTc@3q;-ot5oeoY%r<1cPd3ExdoP=>F)G!dOE$F-cBE+*-;$T(Hz||9MiEJ+i@J%@jGcwe`kO*&>7?mc7`}Zong*!XM{7- z8Rd+2#yDf0an5*Wf-}*X>$$FCJ^0waz+cy|cmD=xlN}J6oKs&NgSev%}fx>~eNHdz`(_K4-sk zz&Yp~at=G`&JpLRbIdvJoN!J$r<~Ky8Rx8X&N=T~a4tHRoXgG?=c;qfx$fL>ZaTM| z+s+;5u5-`1?>ulGI***k&J*XUli@sbo;xp`m(DBawe!Y#>%4Q`J0F~n&L`)y^Tqk< zd~?1#na&UAr}NAC?PPPayE)vPZZ0>#4RnLtU^lm$$Ia`8xcS`tZm3(pE$9|<3%g-% z5jWf|>K1b&+~RHtx1?LjE$x^5vNOcW^Qx0h1=3?<+gU)xNY5b zZi<`gws$+Y9oI+emBkS?+$PWx`W)o?htpVJIo#K&I%sk zj&w)4quqa=^%!@oJI)>NPH-o>libPf6nCmS%}tx`&TwbCS*e}n&UWXxbKQCFe78rf z1@1z3k-OMk;x2WUxy#)Z?n-x+yV_mju65VB>)j3RMt76D+1=u9b+@_O-5u^ucbB`{ z-Q(_c_qqGs1MWfhkbBrocaOM7-DB=?_k?@WJ>{Nu&$wsZbMATff_u@uWy zbU(SD-7oG}_nZ6O&2)dbKiyyMZ#SDiyFZ6Nr$3iJz#r%j@(25K`}6qo`a}Hr{Q3Q% z{sR7j{zCr3{xE+Lf4IM>znDM5U)*29U(#R7U)o>BU)EpFU*2EAU(sL5AL*~`ui~%j zuja4rui>xhkMh^@*Y?-(*Y(%)*Z0qZ8~7Xg8~LOCG5%P8oIl>5;BV}2;&19t^e6d! z{$zhMe{+8ee@lNWf9wCn-dhGo@on$I2{1_r5<-HzLvVsy9BB!z!QI`Z-Q62^cXx;2 z?hZi%!5xC!PT+UW;k^G3Z`}{K>Q>!M?cIAXdDgSm+A|b0lQaS%5CS8KNGqf@(gtaZ zv_sk>9gvPlC!{md1?h?;A>EMfNDrhZ(hKR0^g;R}{gD310AwIC2pNnFL53p3km1M( zWF#^Q8I6oV#v4l470rhF&;T?L4MMY{!DtRNCz=b*jfS9k&`>ll8it0W`Oy4m0kj}m2rY~j zL5rfr(Bfzbv?N*zEsd5z%cAAb@@NILB3cQJKr5qF(5h%Pv^rV?t%=q`BhlJu9kec5 z53P?jKpUcs(8g#Jv?&^eMx!xkEExor+FFr=tjpq8N&!1WKY5N}~+Qq8!Sj0xF`YgvzLb zs;GwQsDYZOh1#fty66maCOQk9jm|;mqVv%C=mK;hx(Hp2E^eg%eO-H|@ zKhU4(FVqk7$Fg8qv22(R3%~-gAS^o;jOD;`V!5!~SO}H}3!ff}<;B9Va4a8|A1i@rW#p+@8u?AQ}tP$22Yl1b!qOfQz28+ewuy`y1Ylbz)T3{_P00S`ygRw-c71kPS zgSExlVePRFSVycA)*0)9b;XjfZdiA$2i6noh4sezV12QESbuB)HV_+x4aSCGL$P7l zaBKuN5*vk$#>QY{v2oaVYyvhBn}kiqreIUCY1niO!B7mtaE!o6jKXM)!B~vLcuc@V zO!BTWreNy7JT*+m49vtV%*Gtd#b#hLv02z`Yz{UTn}^NE7GMjpMc86&3APklhAqcd zU@Ngz*lKJIwia85t;aTC8?jB;W^7AltgYBKY&*6C+llSMc4K?6z1Ti%zsL9hb`U#+ z9sU=uBUmza6g!3;$4+1;u~XP->*DqB`gjApA>IgYj5ooX z;=d~zg-7Etcq|@=$Kwh3%udbl=6DOdB@W;q4&lEm3gd}*E4(${25*a_?eO-Qi~s2w z0aOO609Ao%Ky{!7P!p&HL;|&eIzU~Z9#9`>05k*|0gZtsKvN(Jhz4SSSRf9F2NHm0 zKy#o4&=LRu5P$#}NCa8|PkpU{Hb7gT9nc==0CWU80iA&^Kvy6M=mvBLdH_9vUO;c4 z56~Cr2kg(&9~b}(1O@?vfg!+9U>GnQ7y*m~MggONF~C@0955c3089iX0h56#z*Jxw zFdaYu^uO3(01glU2~YqHFaQg101pU&2uOeoD1ZuRfDRad30Qy)IDiYx0A>QSfZ4zt zU@kBZm=7!f76OZa#lR9^DX2zU%U0iFV>z%$@EkOsT}UIMRx z*T5U#E$|L_4}1VV0-u1-z!%^v@C`@@z5_pipa1IBFTfA<2eW`#!EB%p{QK_Zxxn0D z2$%;91@nSoU^ti$%nud-3xb8f!e9}wC|C?E4we8*f~COHU>UG1SPm=?Rsbu4mB0wF zGFSzy3RVNFgEhdKU@b5btPR!y>w@*b`d|aFA=n6P3^oCqf>B^J7z4(FabP@{05$`g zgDt?8AOM0O1j1k<*a~b7wgKCM?ZEb62e2d93G57Z0lR`pU^lQk*aPed_5yo@eZan8 zKk%P3&>tKC4g?2*gTW!-P;eMH92^0T1V@3R!7<=ia2z-uoB&P)CxMf}Dd1Fa8aN$9 zKorD493(&zq(B;EKo;ac9uz?g;9Kw= z_#XTKegr>(pTRHSSMVE{4t@uJfIq=spdaK9p;@4;P&UX11wesN5R@GXhH^kTpATjLdBrsPzk6cR0=8$m4V7a<)HFV1*jra z35tL!Lsg)vP&KGJR0FCB)q*0S+E5*+E>sVy4>f=qLXDutP!p&r6a_^?F;FZN2gO4P zP&24G)BlVR4r&i|fI32*pw3Vis4J8Nb%VM?J)oXYFQ_-v z2kHy;gZe`Qpn=dJXfQMc8VU`A{yyZxp%KtXXcROW8Uu}m#zEtu3D87n5;Pf_0!@Xc zLDL}wLLm&oAp#;H3ZfwfVj&LVApsI036dcNQXvh}Apn zh2}x?p#{)FXc4p+S^_PFmO;y*70^m(6|@>!1FePDLF=In&_-wzv>Dn0ZH2Z$+o2uM zPG}dj8`=Zyh4w-Fp##uC=n!-mIszp_N1xoA=mK;Rx&&Q@ zu0U6zYtVJ*26Pj;1>J`3KzE^g(0wQcdH_9y9zl`QZX^LAVfH7%l=Ag^R((;Sz93xD;F(E(4c^%faR03UEcZ z5*z_nhO59;;c9SoxCUGkt_4TJwc$E&UAP`xA8r6Qgd4$);U;iXI0}x2W8hdg4vvQt z;AU`hxCPu224E0|U>Ht>Tfwd2HgH?G9o!!70C$8t!JXkQa9219?gn>5a%ggf9J@lJSWybInHPr|$5-SHlHPrMi28}Ebn#rxs?@d5Zid=NeuAA%3X zhvCEV5%@@a6h0asgOA0>;p6cM_(XgXJ{g~aPsOL<({ThxaSX?C0w-|_r*Q^naSrEk z0T*!zmvIGGaShjT12_LGf`!|-gS+?)d?r2%pN-GK=i>A5`S=2SA-)J-j4#2L;>+;m z_zHX_z6xKBuff;i>+tpX27DvF3Ezxw!MEb*Hheq21K)}7!gu38gZJQj@qPGy`~W^E zv5l93P*@<8x2a%J=MdT(zh&)6n zk(US~!ijuDexd+TkSIhHCW;V6iDE=?q6ATrC`FVe$`ECVazuHe0#T8uL_`pki7G@@ zq8d@1s6o^uY7yshM-sJ(UvM3wE>VxDPc$GJ5{-z)L=&PZ5k*83F+?m8N5m5eL^Gl} z(Sm4600c-t1WY6nt%%k{8=@`Ij%ZJGAUYDAh|WY8qAQU^bR)VGbNzb|J&9gKZ=w&; zm*_|ICk7A$i9y6*VhAym7)A^yMi3*3QN(Cs3^A4%M~o*X5EF?>#AIR$F_oA`OeYWm zCA1`rzzKpN35uWzhF}Sf;0b{c35k#ig-{8N&lzVkNPPSWT=U))MQ8^~45ZBe99tOl%>x65EKnBeoMe zh@HePVmGme*h}mq_7ew)gTx`?FmZ%PCXN!vh~vZw;v{j3I8B@(&JyQ{^TY+>B5{eh zOk5$Z64!|9#0}ymaf_(tcbm9F+$HW2_lXqZ0r8M{L_8**5KoCz;u-OrNF!blFNs&g zYvK*@mUu_JCq57#iBH65;tTPW_(r4?--#c@PvRHhNBWal$gE^GGR5a3r{FI_0?0s8 zObjCb?qGH@n9M=uBy*9u$rrv5G7lL_<|V_(a55j6pDaKYBny#+Nnbz_vM5=MEKZgn zOOmC?bl*c?X|fDimMlk>Co7N@$x37dS(&UtRwb)>f3Ud*S(B_qMv}G3I%Hk49$BAk zKsF>Bk^lLOX-qaDo03svG#Nw2l5u1_nLsupo0BcbmLx!eBt*hwBH4;;O|~K1lK(!( z?a20I2eKpCi98eAne0M#C6mZ*WOuR$*^}%=_9pv~eaU`ge{ujhkbD|4h#X7~A;aWiLQW;8k<&?pL`jUqNrEIvitI#_49Sul z$&&&pk`gJC3aOGBsgnk2k``%`4(XCJ$eH9UayB`KoJ-Cl=aUP_h2$b~F}Z|XN-iUp zlPk!T*aviyz+(2$5H<6pkE#y{m8@Zj_LGC1Xk-Nz~Ip+E!B={Pj#R=Qk|&I zR2Ql%l|*%;x>G%VWYH`RygOZB7rQv;}h)F5gwHG~>U4WourBdC$oC~7n{h8jza zqsCJcsEO1hYBDv2no3Qhrc(%oQW%9(1VvI5MNSra5^5>6j9N~upl(lFNv)z*Q){TT z)H-TCwSn45ZThbaHd9-ut<*MZJGFz_N$sNY`Q>}?He0?|Z?jd&cVI`Be0lN(FlyHXXlF&6FDd8-2jyg|Wpe|CEsLRw9>MC`O zx=!7o=&CoVThwjp4t1BhN8P7Vs0Y+T>JjyrdO|&=QmJRub1IE`LA|72QLm{t)LZHu z^`81beWX57pQ$g@SLz#;PJO3-P(P_(lppO+XQ8vw*=QdfKnK!6bapzJ&Ozs-bJ4l! z5IPSXO6R4+=se-!bUr#iU4Sk~7orQ(Md+e*F}gTif-XsyqD#|d=(2P6}l>2jjm4Dpli~#=t#OYU5Bnq*Q4vx4d{k+Bf2r&gleaXdYNo=8uk zC(~2tsq{2@I*rgMjnOzw&?HUKG|kW~&Cxt9&>}6-GOf@mtkJBgUlk_S2G<}9XOP{09 z(--KA^d^ z6jPch!<1#pG3A*GOhu*=6TwtwsxVcVYD{&e22+!%#Y8f-nL12erXEwDX}~mO8ZnKT zCQMT%iiu`om{=x`iDwd+W=wOY1=ErN7?6P&m`P+>F|C<4Ok1WM)1K+TbYwa)otcb! zc44|QNlZ7UJJW;d$@F4+Gkuu8Oh2YSGk_V$3}OZ|Lztn=FlIP2f*Hw-Vn#D#n6b<_ zW;`>2naE6HCNoo*smwHHI)gAMgE2TmFeF1UGYOhu7?$A}o)H+4krB4#nOgjvdz30=l4XI3yPnN`ecW(_lZ zz*=S&&#ztA@8(6Fkv$EM(9~;01vO#QiHki%9=45lRx!Djl4;#wnWy9ETHXr+Y@owgOv`t;9yKmDwt6Rkj*iovp#vWNWdJY;Cp< zTbHfJ)@K{A4cSI)W3~y~l#ODe*%&sKjbr241hyI5oNd9jWC0drAr@v6*;Z_8whh~s zZO67}JFp$uPHbnk3)_`VV!N^3*&b|9winx*?ZftE`?3Am0qj6_5IdM1!VYDJvBTLB z>_~PLJDMHCj%CNO_T=CyO>?VE@hXo%h?s|N_G{y znq9-LW!JIm*$wPQb`!gq-NJ5Vx3SyV9qdka7rUF?!|rAGvHRHr>_PSrdzd}k^$45H z9%YZQ$JrC?N%j7>&{?@`oR4!y2XKL05SN_`=5la3xm;XsE`-a&g>rehFfN?S z$K~e=a0R(STw$&VSClKp73WHDCAm^uX|4=cmMh1V=PGa&xk_9FSDCBARpqL2)wvp6 zO|BLf$<^lSaCNzQTz#$q*N|((HRhUdO}Qv8nv3CLxi~JKOW>Mu&AAp_OAg>b4&q=g zk!!`Z=Gt&=xprK8t^?PR>%?{Dx^P{&B(59Ro$JB%N*8^8_Z262PA zA>2@I7&n|7!Hwibaih60+*ocLH=dioP2?tVlesC}RBjqKokKX3!#JEHIFh3{nnM|m z)HnYq@pYdTs-^k=w*==C*KKxozBbZU?uM+r{nX_HcW-ecXQT z0C$i(#2x02aLL?J?ihERJHeggPI0HXGu&D39Cx0(z+L1nahJI(+*R%xcb&Vz-Q;d@ zx4AIp4tJNk$KB^rxCh)r?h*Hxd%`{CQn_c`b1sd0!M)^Oaj&^I+*|G)_n!N}edIoI zpSdsGSMD2^&VA>8a6h?UoFDJcXW_H*a8Neh#|Q9%d=Q_V59V|5Ir&_CZa#$1!-w*D z`7l15&&TKI3-AT`LVRJq2w#*h#uw*H@Fn?Dd}+Q6UzRV&m**?+75Peh1Yeo2!dK<1 z@zwbnd`-R+p5?dVGDp0pIZdeNpxQeNpxQ_!m{t|NU>O{@?RO)rNc{zA@i~ zZ^}pU(R>Ua%g6EYd;;H$Z_c;iTk-%8@(>U6iF_-*HQ$DB%eUj(^Bwq(d?&uMr|-gd z<&(V8jqlF)@aCR;FTOY5hwsbxKKZqa958;RM!}#I+2!13#iXY97;m7jh z`0@M%exmo=E0g)E+!TH)KaHQxBRtAuJkAq5$x}S-=@_2nIgby|3%tlnyv!@SKc?~; zuk!|P@)mFN4)5|a_?i4Hel|bH<2RR|$Is^%@C*4x{9=9yzm#9bFXvbAEBRIYYJLsB zmS4xO=Qr>h`Az(0eha^q-^Op}ckny;UHoo-55Je+$M5G4@CW%rUS@~+BYZM{lt1Qi zJIWvDPw*%CQ~YT@Pt7y@S#LhapZDY!_>24{Z@$c5;ji-7`0JkLYG!6PJo^lcoBS>Q zwkN&A-}R6#c;g;_pHJZ*@DKS%{A2!!=lj&dz3l0)X2wh9pYhN6H2wwul7HpZHZ2n~ z!}m4+CNts%FZN~rE&q;xpNW})_ksV&f8sy$U-+;5H-2TzNIpF?&O!b=|HE57$@Kl1 zx%Rr@E5WOd1_`AGEg%{HsLbw69PP0pb#WH=d%kJ`CwsXOb#KZkW0ud zgn0Wr-u@yV>aFq$r}!`-T*xQn_dE&+-8{rzd_m!=$2Frz8F}TYSx7kONxypW3kyFz zO-B48!sKp6g&Z&+cY*RwzUuw8ynk3Xe+c6+6x_ojzTA)^M8SL z5xNRVLN}qi(8CMgQ|Kkki|;M;5&8;aV*3gGg#p4qVURFbsGD<$FjN>O3>QWSBZX1I zXkm;nRv0IY7bXZ3g-5`B%D@U<;1m3NwV6UbbID zl4EBHvxParTw$It-{XHKHr2O4Sm;$?k+4{Zid`Zs6=GwT3Co2Q!b)M4uv%CntQFP? z>xB)%Mq!iiIJRug%|eB4TZFB`HetK4L)arh=Jm@=pZq>2#@#~ z5-c)84l$>gOUx~XhOWimNX+5F3h(#KvM1v8fm(MvF0G ztXLv2PK*~5#Aaf1v4z-D1Vm7TL|9A|TZyg3Hey?`o!DONAa)cxiKb90zI1$Nv5VMM zOcJ|^-NhbaPqCNSTkIqD75j<(#r;94z5(JuagaDz93l=Chl#_*5#r;Jk>V(^YkX3C zxA^YyJ>o};W5luIIB~oLcsEV4Xi-u^5mS~HP=!!GMnc^&Qwm3(eE6x+=i#>$};=K6z z@vMKxzy{Ppagn%KTp}(Nmx;^872-;9Q~c)mE%969x5fWHzpKR6;x6x5Q9I`vajm#c zTrX}AH;S9Y&Eghsw^iIGqT9tC;!bgwxLe#K?iKfm`^5v|LGh4ySUe&oi$}#{;&JhW zcv3tio)*uDXT@{kdGUgHQM@Ex7O#j`|I6c=cwM|9-V|?%x5Yc+UGbiHUrZ4nc)=fv zk1~Tl_JW@kpNLQYg`Vo6Kg&cvmq}~AN9#Aq=VF@p!i)A&d?mgX--vHLpLZUk_hN?6 zTJeL2`O&le! zl`*Sheu}?DKgnOpBJK6|S*2{!>X^Nrmrn|i0;T(6kn}*zCS{j`J$()-r<6;|Erm#V zqzvDcF*n4F`S&=RiTBU$md7Df$}5FQ;Zi;+zf?dfC>4?lOGTujQZcExR6eNR8A@{Rgfx5m81x%vQ$N?DpixJOCPeA- zPklQAgZ-C8)t4Gb4W&j>W2uSMREmQ2@b15Jo zB~#PF)3lTT36#PEnn{p{21|+3-wawwt)(_nTdAGLGBU8eH+PUaN}Z(6(i7j#UR|Wk z{#~Uc=^(MpyN7u<4>{O>SyFeYhtyN*CH0p2NPVS#Qh#ZHG*B8O4VH#TL#0h&pM3$| zj~kqEQ|w{VaA|}zQW_=A&pp~3?WGL-F;ZH{SkH2t)Yr={ARr=WycF!+_V{h+1Zko) zNt*2Grbt(O{etcU1q4i$rb*MKT^u5z5+>nZ9=o_;e^eqQQlcbUVkB1LBwk`eB0TGe zAVCr(Ns=W+QYB5&rNM!QWJ)X8w18xvCE1cAxzY@2rZh{MEzObUO7o=o(o5e0X`!@8 zS}ZM*mU>-W=2c?3H`077q?OVtX|=@qCwqT_a*ecBS|_cSHh8*?(k5xMw8hh$&AnCH zCT*8?NIO0GE@`*4N7^gxllFTRIpD=OC>@dxONO*SIwGa}lBK}ztAp!FnUb9oA2hzh#f*H-7;E_J!;b#!?{#4zc z=1uZ^fA}7GhpyVlm%cRbzTz3FJ(iwGPo-4pne<#rlU_(KrB~8x>5cSOdMCY?K1d&> zPts@Ui}Y3cCZ$W?z2o;o`YHXA{A7PQi=0(X^<|TNa)2BtA4&?6v&+G94mqcsOa2EZ zw;UqpkwfLYa+n-0=acix1>}NqA-S+zL@p{9lZ(qG;HpFE2*3u-f7RVc72Ym@-}(9yu*vT(~|~! zW0$;J-s4^0`}TU$-#kkBr}(^^0Lc5~{hlVpcR*ef5*c>T>-|PKGVqWmJ1ifOljWn{ zDl+hxH+!cz)AB?n#!2~7rh=`@~%fc`^)kb`Ko+P zUL15?zTxd}dh%QH?M$RQa{lnhzASiS+QgSOHN**Ot$*Y7Z;YvOwzfwRcs1#BPD@Bx|N-?FlQYs}%1yDc*QeY)fX{EGQ+9++6c1nAt zgVIsyq;yugC|#ALe|dCMx+^`Do=PvJx6()HtMpU)D+840i362E%3x)PGE^C+3|B@d zBb8CgXl0BtRvD*^S0*SEl}XBEWlClRrYh5v=?bEt3Z~!+p^yrt&x8 zS*@&5)++0i^~we%qlO!mP0D6vi?UVOrfgSsC_5EX*rn`N_9%Omeae32fO1edq#Ra` zD9OrEr4)WlIj)>gPAaFAkML>bjB-{vr<_-Y`-l5qP@a$%l}pNH<%)7uxu#rKE)Ke( z+*EEUx0O4}UFDu~UrA9OC=ZoK%46k;@>EGxo+;0jH06czQhBAkR^BLYm3PW}<%9B3 z`J{YSz9?UnZ%VrIU8y|$hw@YTrTD4-Y8ExCnoaeo0cxNcq-Ixx)f{S0HJ6%O4N>!` zp=w?=Obu7_srl6cYC*M-T39Wj7FCO>#nlpONwt((S}miNRm-X6)e34wwUQd4R#vO1 zRn=;0b+v|CQ>~>&sCTHdGs_jnyVJW9PI!qm|j!;Lcqtwyr7NIt_ zim0fHskln0q)Mr@%BZZ$sk|zvqAIDfs;H`}sk&;YrfR9S>ZqN<73xK=8kx=-D&9#9Xeht$LB5j9yosvc91t0&Zx>M8ZKdPY5~o>R}O7u1XDCAFD% zGSJKF74@omO}(z(P;aWY)Z6L`_Ktd2y{Fz+Q`86QL-mpRSbd^CRa4bxYF7NYnx?)` z!~I{XuhiG-8}+UFPJOR_P(P}l)X(Y{^{e_#O;^9GKh&SYh$#re<4O|)q(WYwCwCNh6p&F*)8ljOIrO_Iru^OlGnxKiAq{*71shXzgnxUDRrP-RJ zx!MeErZ!8P?ad{^r)qPwx!OE!zP3P{(8$piYK#8xTC6S6mTJqi<=P5urM602t*z14 zYU{N1+6HaopWHWTo3$<4R&ATMUE87U)OKmR|75sF+v{bxPus5@&<<*cw8PpFEm=FN z9n+3$C$y8=Debg&MmwvW)6Q!bw2Rs$?Xq@7yQ*E&u4^~6o7yeywsuFmtKHM?Ybn|T z?VWYY45cU+DGk^_F4O)ebv5c>DqVg zhxSwZrTOWvy$bp3S@f)WHgEmftA$U`$S^<;)PwZwo-A0;q36_d>ACeIT8N%U57qPP zVS2cpPtUIx(9?Vaw1Rpe{XkM-y@*~^Pxlqmi|dOrJ6J+5sh84A>t*z^dO5wkUO}&@ zSJET&f_h~ScS55o`e3c9UQHjRRo82Ho;CGa9&)5!Td(8U)Ya?h_4NjNL%pWnNN=n+ z(VOZ~dbH;mqsQuTx=)YS6ZB?!b8q$9>t9BPTIel3oM`>L2I!y;>9C%tx6)hdZS=N! zJN=)Yw$~SE*J9Fr9rTWRC%v=IXkGMwcdDz0o1}NsyL+fT^qzVzy|>;+@2mII`|AVr zf%+hQus%c|st?nL>m&4$`Y3(0K1Ls_kJHEN6ZDDtBz>|zMW3pp)AZ>&qN6&d<2s>} zI;GP(qq91v^SYpmx}?jx7_I24uIajN=%#Mzw(jVzKI4yeranubthtuO`h0zX zzEEGJFV>gnOaCiy4}F=wTwkHD)K}@N^)>ohFUmT7y}m);sBh9Y>s$1#nLAnE=B2b< z-=Xi+cj>$JJ^EgKpT1u|pdZu^>4)_rda{00Kc*k|JWuE+^;6z_T0f(o&0KN%IsLp| zIQoKqQNQHji~42#ihfnUreF7RxS`+FZ|S%7JNjMyo_^nBF<(#dB0SI^>W}ot`V;-B zo~l37pX+J*3;m^6!dIE7uk|LSN)rwu7B5m=s)#e zx}V{1WHGWD^Yx6@WHWq5fDvc}8P!{5H-e2EMouG_k=y8@hZuQ`P$RDqW`rC0j12s3 zdVZsTQP3!46gG+&d-S44F{8Lq!YFB!GJZ!YZIm&}8sGJDMtP%xQPHSmT+k~R8QE4a z&g(7l2&1x5#Sk<1JF8YTsu|Ud8ksgVjatTwZjnZ9qmEHGQ&P{U|Hrd|QO{^-G%^|+ zO^l{Slo6e&k1=9BX$EqfaZaz^D&9yinip#(< zR&5N;t8822q2A7DZ*(x8dR^&gbjn0*X>>Na7+sAdW2@fH=>7-eH}8MCS2((dm!qb4 z%w*Bi@NRf-^fB5PeT{xbe`A0#&=_P4Hij5OGrfoX!T8N)xG}=$X^b?o8>5WT#+W}D zWz?`i&auWgW4tlJv;S>7(PPxpm}E>grWpOgryA3Y=?3yIZN?d@_Xm4j=DDh1pnvuS zr*Qi33jIdH4BTVW4Oi) zW2Q07m~G54<{I;i`Njfcp|QwVY%DRB8q193#tLJlvC3F&tTEOa>x}ir24kbK$=Lj7 z{u?zT{_p5pjIG8tW4p1#d!RdwUB+%>kFnR-XY4l)7zd3*#$n@#k!&0_jv2>|6UIs7 zlyTale#SU!obza%H!gUzE*gIQE*Y1NE5=phnsME@Vcax+r}aC?E#tOv$GB_UGwvHH z#slM_@yK{=JTaacsh;2GFm%3?Z3Rx^WBHq&PYn1Lo`1ew{*U^9oA)68WaHFBFF zW*#%t%xi|3;buNFzgfVO7c>i*h0WguD`FNk38R=<+$>?1G)tMK%`&E6zb!^tvzS@V zEN^C%>!0#fFe{ps%m}lxS;eesRx_)cHO!i3Ei=-rZPqdCn)S^3W&^XK*~n~cHZhx; zQD(FmW5$|sX1tkTHZz->EzGx}|7q9K1WeF`OxR2`TX`NW&DLfcv#r_AY;SfjJDQ!$ z&Sn?0tEXEOm4VshKVl}C-OTQ053{G)%j|9TG5ebR%>L#8bD%lM^BrssF^8JN%;A3+ zkH}>F8-JuZ%ESM?9-SF$j5*dEXO1@~m=n!O=45kz{!Ozq zJ!zgYPn&1Vv*tPTym`UAXkIcen^(-M<~8%W$K!^1)4XNgHt(2s&3op3GsSF_^MU!$ zd}Ka0pO{b0RP&kn+)OiHm@my&=4~s#(=7^rTtC zs%f1ulYPsgmPf6Ks%1r5wXHfc+G94iT39VDzydS9APcqS%ScI$K?=u2z!O&FXIT zuzFg(tlm~1Z-oT*_3*#b{jC1h0BfK%$Qo=7v4&d1tVTJ%csIow;SsK8?elKSGRjI1 z7;TNQ##-a7@!ooZHPO12`8LxeYqB-Pnrcn6rdx=GT9}1fghg7EMO%!;TAamOQ8`$D z!4fUWk}btjEzQ!cRG(p)mSv3&u`S25cdZ}38P-g1Kg*i!?dMp{!sc3uA!l>Xv*ug> z8D)XBFq1*K9E+^QR*AqR)>3PkwcJ`^t+ZBItF1NGT5FxP-r8Vov^H6rt&i2WSX-@a z)^=-$wbR;Vy$ShP{qv|wO)ED|^OXqPZSAr4TIag$^EBJ?ypH&p$S%b=o>(aY<+YRgH7jA}ih3G4Q-~!MbQ&vMyU!tgF^F z>$-Krx@q0A=2^F`JJ#LII^MJHTake&)&uLI^~ic`J+Yozsn#>=xs_(Uj*1L>@w?h# z{en6MzO-IhudO%MTkDzkE}O1HjSKdimEe|ju`StS$G zd~+>Sjtp~y(*m}{WaL^P;B}Or?QdtXv)bw2TWW@t&0b{r>;OB^4zkMzrF(r$_uc?r z5R%>A>>q6BuyfikeYxzbA-U}kJC7Y|9}gwSympxV!}mIBd*D|q+|xhx<+Hsr5%$Q- zI?b0MeHxP0&Tkj6A6W%$H+Zg9$Uc==*e+tHcwSp#c3IQ?pTum5DQf4UirK~O`~fBG zlJ@$T4KbxWR$F39+r<-Kdi_ZEl?^ImXIO5DN%NJp%h~1a3U)=ik{w}JwyW4x?P_*) zyM|rUu4PBswe31~UAvxL-)>+xv>Vxt?Izyb#BORw+0k~49c#zg@pgizYn(Zn+0E@1 zc1s(u!M}VV8@3beR(5N5>-G)%rhUu4?Um(@ z7vYe7*S=@pw^Qr~_QTB5J+dF$Pwc05s=c$%{H^auN+{mK69?Z0?qsQuOcW~bZV?H~3}`y&dQ+2x%nb_J)RQ^|>NDmzu2s!lbhy60QNsp-^mBAwb!9jC5S z&#CV;a2h%Xk{UUUohD9GC(4O-Vw~7Nx;ST*74IAj%Fre_&79^=3(vcy12~NQ+YfXg z=X=O+JlIKeS~;y9!>>rrHqPCUXs4}*R6S=qr@hm`>F9Lw=FUzRZ|>?Od2=_XyNA=m z>FL?_a(X*`yc+a%`gyzl&H!hs_wN5dXOJ`40Y~pn9O5Ajb&eC>hjz|z&+dtDgfr3^ zFGQlq%W#Fm$Q2 z%vtWNa8^32oYl@6XRWi&S?_FcHaeS}&CV8QtFz77?(A@OI=h_n!GCN2jq&f*zdd$4 zd;ZJ+??_YSy$-t1+3y_if**7aIfuOf8N$D1zoGxX^WTB~C!c>?WRTBD^>3>qPO@{< zIp!R9PBQ_gAUjC0mG=bU#gI2WBu&SmF{bJe-#Tz76bH=SF~ZRd`2*SY81cT$`O z&O_&s^VoUfJatl?XU=mc&3WOx%(Q&vymsDrmT#SRf9>C6@0}0MN9U9C+4=Hc5xzR# zoOI{A^TYY+{BrzUe>aPp)y?Mm+yFPw4RW))!EO#Wr<=>o?S{B{+)y{K8|H?)`P}?& z0k@!A$Sv#^af^C$F}Ju|!Y%2Ra!b2q+_G*tx4ipzZWY{$ZY4Lut?X8DtGd
tp15NvCpb>W)&v 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

C=2%LUOb% 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

7W%e;i$TfKpW#zhjrWD5Ln) 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

J3ND7A^KKB zjkWW0P%trxItyL2*cd@xc>_+xeZh|xc&9yYL`5uBI8J&FN8`3^U9Qjyv*AW=(Fs;q zJxe#*QrznC;_!ZtAd$RpIVeMZX`4fPmHiZ4o|}b(niaW%}2e@ zU~oJ+z7WT<`kK0!-SwJtaAdyRH0?1B3goW0z)7yQ2+|(Qv7~R`ggct<&pX!#PT1mr zk;SlYiS)-DDVfk^1v`?t6S6j$DQ}>kHQs9G9t4o&Yaa_<=P*nJwh9=;?*tfIov6F1S1^>(!s(rwv7dlv|S<>!tHzIH6X z)nNQ*`s*Y4;zn-ZY4D65t@U?A>f|^$k}x}h4tNg!?vbK=M(yLpq>dJj7ty!Ua+!yq z@r_=PIU7q%^l@V`Rhb^FfjgzvO%VvtO?g29fjFh(8mIx~@LR-AgXPJL_Pbh|=F~|u~ zaWrl&q`y@a<*Jk}h3*;IQG|(gtEv#tu*A?=JYy^`#9S#B_;@x)l4f%{!v7<0y%jRC zRKpdg$PGkNR~*z0o&=#u|9@4d@{gAI``h zHPKd|N@>y66J6tuqhf~ivo|yr)9@cf;O=}?4ur+sz9@T^7cRBqKV(%4Y>NETs{m6p z5*;4ca|?@H^vdp1i8i?eW4F#^QQMd%I*O(`v_ab<2fb7c@|?91U45wOXb2kyU(QgQ z-dazcMj5R!V^A8( z#LKV%q(`D*6sWY>GoaD!fugPs9W@@|rmek7B)Y00M8-88cMPIl*R6Z>_IxywRw2+r6tO8a^4*JUCOhT~EuBI=&D7q?>t~>{zv{(#R zFz`2T1QTrJbjR_;enK*rSw1f25!m3Tn+l5QkQl6j;5%<(5%S%w#yCses^PY>;AaO#7Iq7VgTG+Aoa(Funj zk#iNB4kCCJc*vEr40lOwKdZuBj;d@fc<57AcEkijypfOc`!D7It%k7%lt8BDG1tGx zuqbKXSnQ;lPv(IbQ= zoI;`r+^?CrCiDVHQ{Om2fiIP=Rb-{3CxRQ~*fto;#M1;DOuYKwOqwZy=8nuMa*#TD zdsBqXg-m-!WG2a za142as5z23jW%g8G<^kS3V5zpMO*XGgBt|5F;CzsLWc(p=D^62|x-f(zBMNp#V zl~NruEv{|D6r`;P_MMuHhh6B7Yp%3X%k<7Z7zZP-mj_WX=$%cYQ}}|U)(BaskvE}Z zzUEN(eXde3jXoCB_380iU_-e?F{j`QvV}-Ze`&Uo@p`g}CLTg=z226mjG$*;qpx2? z{QOP|M#KPHEDD@V6TI7!RyG5bZ|TE>Xpha3!BzN+5WPL?J3kb6^hIhz` z>s@(7E&=~aUlbs&z_I#sOoY0O18EBi?ncz(sd_T)=3bHaJmdWp#>f zIftJbRf-{S`kkm7g*d>8eAI$*n{XC}`67C0FLPiH#XKAg$?h;a$p%rb2S;m?+JtUK zCYz4VXbU0;ZiW(D@hi-htUhZcNAKAwZHXKl7MmDKk$qFPP&tRUwkKQ6S~}w@WR1Nr zKZSDJv{6UbUcsW#ABfbX4_|{sl~GAli9W1=#X(pD^-ac#!G=`J>vmk_U@f8&?CmIo zbQC-08v?eJlh}NDX{m_@S7AZqrf3-t;G+>Io$4*du{{AXSwQ74#juqI-!HOK%P#CZ zd0n*PlDF^V05zw4!qW&5?V7S;rd)prDW|QrRY)V<{$wa*Z!#+gX@EwmO%r4-Gkl0b z*E($1>30NgS5`crgd?EIr)oD0G2;n1Gp;S;d9nGRo5zKW$SlQcco<2ye7Rt#$uypk zyi6>z)GeeXc5eGD?kd!2Hdn~B0?f-)f>eO0TMT^9HLlq{?5A?!{LBbLXv?P~d4(5u zbVheeg4av^ya}?<@WJoA*v0X}??MuJsNVue=pkf#FG5coF`~Ta$rWyPo<+wSG;*8$ zL`XJe-bb?pB>aoTJXM-?Jr4ZNE6kc*C+OhAb@?18D{s?#3lXo%*V3&nXk__nGdGyJ z`){RLnw$Z#bo?xr)^Aqwr>Sh$Lv{A5Efz9b*i_|Y(w1JTh{iB?u@|1i+B?Q#CRcpd zt<@-FwHSm=caZ!n-Q7Mv3D}ZuB;7D21bNcK?I%qBwvpO|zSo$M1aR8MqO}!E{l-1!6jCbKN~z%~sGDGT>ob&K`vkOoK);)JDe=a3;OW|W zFL13Ty;gu3iAPJLRR2nNM3d_v5k ziSl2D@?v`G7ED=bO+#LrCN=vAk8!D+nk{sG4;!4*Mh<_Jd7D)gQt&V~?1QM*UOm7s zHAHy8hva^xf+4Iq#Cv}#H|{`*OnhMW(s?Biw!VfX#cWxVhCrWQJ8n#}wGZN$EydQJ zy@PKi=Ho2|HX)ng!>}ekb_*GlE-hG-n9dB0c?Rn8r+>5$0$>G`)J?*a=@?#UbI;e@GFDuMvT)0ZzbS*zZ#PRgJrVH z2=qmTj&2KrKR*kmN(k^RFEg>kpPh^lt5v4K81z<6s~jw`VFaYA^8A332zA9URRQx3 zMCWuC95Js9LF7XR^25}+9q|nE$9RxO>cd__DwjphR1u16F^g@3UuK3+OJJ1{?FXFN z&#R!zPA`dJ*<(brfiB*RgUi=&-}0{LU59+*-9>OwTk132=>3|!3dMVu58#>c0roR| zk=rSxZn=l9_3;?4yi_lB0#A7{%wZ`u!E_JCsti~H;37|KkRjx6(KUyTuU%FMA%9c! zAndC`7f&$OllF$pOguahj95aVMXG38 z+p`QwZBeSRhZ;?+sVY-jUoo0dG}IDHHI^Y`jeRWTQKK`hB}Fwlf*lm@xLK7}qmp)!Aog@3X(e=6Fpq*?@mo7ksQi?Ytskc$cKTVe?g zNv3Wvfq@jb=}K+V9R8K+Ln%Iml$d0Bm8qUKJeWk-xZVewe3qog)>Z&9()UlHg_hJt zG4T}~B;Vd$vb;g_|KfzBT$l?1Qb_LRDNR;iDh!jmJB+e!V{Q{_dkiaE>0|T{rp$CK z6QR;_YY~{gr!F=7-U%_Nmeo$Jzsrsxb!q_wDrHR;c$08=8U%m^21p`TE}kOlNv;^5?^&?8zT5ini7)_nXnh0d^){ z$~X1b>lL_|I_`2A%=&jEcP@*cGJ?MJKXLG>4Snm29*F;o+Vh-o0=r|0ZBY<*w$UtAVqQ@+0gwjsW^9=Y7EPw2QcEyyNC_hghb(jjY9lN>k>{p8ET znN_nDtV{imveBQNJ|1y>;xnHhtTU$Sk<`=-=K0GF?!VXnOJ77tRwN*K^x&-L>mN{w zaJd_#0;TbMjEpkpSFEGeZ^ku2_VbBHNR7pQUETpBklOKu7;Mb;Tr`M9Em*bgVU7*u zxRNItYBD9`Z^&av(~uot@)H>1A$_mr#lNe?nMf{LCAsy~>C2p4s6zS_gJtdZiAB{| zX!JF1e)a#`#T;RKwg87qH_~;eupa2M#xV#BJNjd(q->mZbQxRhLG0Gb0`#xu=LOjQ zYVE|~p<17j#dhRU=*saQ2EQkp6(F+|S)plal${IIlz%bnB~>A9ZunoBz=G{0&gNGQ zH-o_=yuKwY?aNg<*1|<|9%yu(HbC0tZzvL_@Q(VIS_vRyzlbnSX3Z9P&>`Z-I)CAai zu?`rFZrDDY)Sk>=Wlpdq6+`gdrh%h!CD!uWO`^-f5}ystR#^DcO}Ls=kJTmIHYTP~ zhn7;T3YCX7xjMOhTX#LU_Iy05IEDj9Ax?ZnKbFBJV3ypynEt=p99*JpXonerqx%zJ z=q+FQ0-Lb#ZF+$TYqu`=d@z&yeupb-SR`j}x)hHy}mMJj0-iK^E z{Ykb7prRiD*9xF1?kB}DVL0E%vNkJXGQXh*#9(o2#MmR9P487a75gX6b zEn*C+qxjZB#!d@*tl!kV4y8!}h9KrW12~AenO^ z9vxBM+%GD%SxL(oC_45=dvlyT$EBEyrHtG72GHYg$zF%XR>iI&@2{S1gLQ3)CWXj= zUDjNh6?BFO5ohpW$iRVIekvugb9}&K()#{h7@`e4!bj=63p__iOonBQzKwxj*shsG z8K#kSgGE;sW1s#fIt&yaC6&)&p)cEuZa7B#_?pHs8BCQeHMjcTnyo33;RjUduKBjl#^`o9yku zC;ZO?+752-4iMP;|7C+4);tAK0-nWfp|2!$xlyi(^sF2v?|;8>Z%}2=HRyELW|;L* z2QJB0A%#CzfN6NMC#3wQT`Cy0=nA2sMGc>W{4K3v!3-2BXaRhZ1&YW`5Z=|}JV2ty zUmVo}aB~QhO<z)Kr%}E zkx*n5UgIM=?ayqL)YqlhOvHB_;7t-Ak+j+zeWK z4_>p>X|mP?N!IlVtw(xzEf96e(34$l053pWTZ32(+db%;ZTe3jpV-U&v*Dw^Y$Vvd z_r+%pR*k>F|0TOG;q;x0lctp^`vOu*OXI5NmEZ_}N)sbxzr-d(IBCNHIF>H22$KH3 zHX>{@rsk4oF?z#hJ%fk2QxhASr`IQtJ>^0xP9w^12SM-Zn^*Hd#mN_QAnMg_kCRpX zyI7HO(;H<$xbSS{Ud2k==baX+vmApcPdTZe=l`Tw3Xdpu#xK|u!YOCJ)ej3pe zELmO6QGDd93PxC{XbDYDljh(-!VBX#ms>ZKA2{md<>--e>Y>JqxT@;fB$ZXNGT{rz zS4_=rit#*C2hxOkYZk`yd{U!e4~T(NDj6QA1BQrJnc8Yp$f zkGGgHz>R-~z#&YM5Ebk{I=3bc|q%; zf9n?7fP(88L#6|m1;ZyiLtN?)(GMR`%XY4fSaS}KwK!M+*P>u`o{`0~ZMqn)%A(Ql zxD$(hq5XMZ7y;(Fn42BoIy9ndsJ=GfHQ?ltEW-fSQ8;37(t-`jcV}{<3{}tPb%e7SvC$%Ck|-JnXU1+qRq-`S7h>_K0*Fc zG{H6`?30R?k?B1^Ey6Hm3~eO&rc~aYB5wkuo^^h)Ydz4zBri@>>!q9skf%-nYmMXq zQv7Y85qwt+@VdH)1ZDE+K3wGXwBN(+0X9Q7a{zjkQgam2$_F5x<=#e~CM#l z+i*c8(3czORNcE6saW(B#?~`t5cp;C&j*lp!s|tifvK0*n9GqlWPdR@Rr(H13F4%> z;$)C`rMD+7#G(c3;a^8WbtyQRCEpEdAq#$$V?uEAHz3RC@BSPI3q1djZ}g`1Hqj1L zsh@ubLF+Hh)SzWExbYydG#AwgSD)pD+1yyv>nIkLa%EL)OdkPqS4Ymz_T!8Z1xrhORmKk&i3L-{KqhmIX$(;}n%t5Ho5A=iC|w!Z23ii` zMTs4Tw^EX~AfV&9we{VWV9l6vQdkuJeQUt*{4e!1+jWM_ho9DimzzA$>}K&}gPtvI z!5QObfz(0{gXFJCM<<%W_>`~Uf0~3ZXb$C`%Ln*;-%>`mr;8=hvz3qDGn*)!E=9nvD}4%G`yb94W06@xOTs|OHkQd*N*U;Q=OK=)Czz1>s{uv#mAXm4 z9=npJT*u26O|DBOo~^c!F%#$VXUNIfKx?RST5;=Gv7jioB3X< z{sGAC=I;m-RfQ%-S2KzYa~9FU7cfV6ty<)5)MLk} z@&_o-bXx-+e7jiVV2RL{ydHRHMLRUyreY3!K67P@V|a@ zBC*zc#vsDS5$P*fv@Qe=T}DPiCEb{6K?5^1Zl)YNg+flvc9zp0_wzzt0d^9~)l6x;6Tmv(*>bDSon`+oY-BWWg9eGtdznRsGnMhGw6a+xy} zpH6siHeF1#XH#Xps7kDhro9*%&PHUtiY{HJJ0k1As5dla2HoA7-6Cl&cH-)LVt5op z{+~Gk1Gs?Bwc_jwG^d%W6$9za?@3{qM>Q4+vg36Q zoD?y8pXL56+Q$W*=)jfWrreflhhnjI4vzy_)4CD2nP2=S4XpK72>4NwJ4p8KfO#@< z&{A8Q3eZk)`9rQhP`=6Lrn8boKCM^yR*H3pS9!7+8sv)4i%VEZ?5G&8hQnq9QORJ} z4ZmT7R2Hp72n!WFMq`vycd;9&NUDse+jn;%y`9ce{m=1fAo7pnWuU|*^?fnwKhGDY z?dM<@1uziOTVyXR19|@UQhu1m@9{-w<>*pD_|h0#MMKQk-i7@h%!E>OUaJ5H6pmY_ zVi<97Tw29_3fvQ`aoOvuWjwrDm@yk_IZ`tv`y$c=E0K6j; zGM_hdMX8kAhq;W$$XypUFHcW{3bXl$S{5A2QQ{$~gugnpCfF&`;;U z1>)SagPnbWlv|H%V>q^(a;z8UZZ+RPbA+CuQrPt#h&E)X?*2@z9^MWuKlR$8!Je)h z=jYsYMf}(v`WP&EmRgpAVQ3h{HKFFN0-2P@#=u}&4yg;`lPsHkiw-20)`eUU?si5jhwye=Qs)w)SJiFE_47NI z2-GYeCn`JrnBxV8$*~*-ImW&hnVE&}=&)%0O5p z6Jr>;;-R9q79iZyvr8!1MY0!CqQ7Js#KMUg9JbT*{H$kDo^Kkm%bDY5J^0#?S|KGv zKnpl1hG9?oy*dCD^@8ADs%C80k>gzsP^b(#1yV_@-;@nFvd7Os+LsU9!&xX{y34oi zRD3QnL-|EX{t5{`va!*Jt-A``5EmNfV4PcBC{BQd&&~#M$hDs7+%Hvx$aPVQFgket zST5AfOImPq@I4E69H0KJ&rAAGkmQw?Bjp*yj_u9({}*;}0k<}H9+G?V(Bp%{v?kW; zwZ_?qCp^jh{Y+Ned#Q6pfPkIC?Kz7(Y9NE|Xa_N0I5i9V&lf*yZ8U&z3>Pk5mO!)h zjh@-m?c<6NG#uXUl(7Z++#^rm`FK1%M87}9nP2(rKJP{OR0$jR+CAEUP;B&Uf`i6q z2&zqn0ez0W`#rc)MgK~47m4k$H&rtacjR+*X~u1L|5@31vl8e-G>APb5) zq5j`o*?0E31T^nFTQ1{*VWP2U3Qcd;^3es#hmXrhEq zrPu+IzsTeBaS%J{^pB8kK#@_&T(NB@Js>t8G(%WrT$8f_XP3IK-} zR!YHR6x@#8HUlvH>C|hCHb7-xa@U24n=#vhX(HUoDZId`7oIbkno=`67U!4w5KV$Q zZ1d0UN0S1Ds9U!&I~Qi94NjTHmSfiuURw)c>Ou!6JT~6PL;qbxC4aZX*x0|&THps0 zYCv0`qPF>IP7`%~8%si2`=%9<*w^!HaO}Q~1+I*LQHoZg@()q|gUL=QQSD*~8gB8eD|V4&9BR+A|y6xa0@Ws{I{n z2@T#0N%*(15Zn42lOIwyE9B2f9jqW(bqdZdwtEshFkRLZR)HH9f+|$h1M6t2+p5rp z9BYE+AeROj@ecQk0Wj!bs7YdcUmFYs6Ox=510M=68-va1<;mG#YDm_$`ZO?DK!P?vlI8DIlMlJwh> zJrg)Eq7BSDw$Ue3v=1cAl+jX1;ZBmiDcM3&uAWja^RwTJo6y}^U!!jG0PJ?(N%DJ8 zedLryVHZRQKPLB$R$OBxL^ond=jkPbmaKh|_D&}>Tw^W{391x$g98K!W0|rk`b;W^rOcV&A)l)yq^OMp!%QP|F4(ojI zO@yKC)w(D-K~n^4o|q>CP}%ma6_zg`@a&aOWt!nuP|2%uZ5E1 zis(g9uGNQCAt;ylwk98+#eZC%A~{6zhDrtcZ<5v}%r$!VQOf93>0Wj=$mC2F@RQY* zxs&&sh)7{0kJL=Vyr#H?KwRTX(B|rR;P7Xdt-HIq#@g}|h>bM{O>UiyJ4-HOkYkDb zA_~5l4i6fiikRGkIU!+=(Y}{9WP>9%ynuFx`r_M~HefUTn_%l6dILW@wLvA(+S)kX zuZ3?5$K#B3Yp_+I<5~>g=L`p)dslrHa@H#>r)E3x->n6pNiIH-Gz9flJAsISmPXGP zAn5pfnqKC#367>FQofNa1tg4?48T{3U{HaS&yR8luK2p`|?KgKN*pt#;vWz8_`)qmu8~ch*@O)Q> zl7usRfI+#(7=H(V!jc=wAgo|~Eqh_&6~T%rQT=>DA2KQi8eM|jbyOh+L>YuZpN|D( zlFC)Yf;k-&_^VWp^LA`Lt7fgzu?Q~zvpH6}<_DpvbH?(6ko&_tNFiH4haQU(10=)e%&|8BLAI!STfE`v z`YTWFm29&AVun{_Eg$vAPa&u%XVOBf;p@+f-bJi-Sd$T`q7y82o1^sHk?loS6&8Pm z|4@;e0>YH-JCXl5So;|iVGoB!FDO~wI<)Dqm;w;Zh^btUCER+Odk3=HrA5?&2a=Uo zCi142T|S5(;kgDew=vVd-2ue(c%~Sz0K0{+2!B=+u?PT%ReOnn#;j?-ZK6eFkB?^Z zcT_ufpD>;2%>}ze3@A?cl`o0@I?Ti-V_wu%21&`Fv{MBFw9efz&jUZ;-s!6zVbnWH zcF=p}hCE`f#sn$ch|-3O3`}C()#3<~x4es%)U#u#gX&flR@T9n^iSCz?v^hg- z5b`De1bAWoRp3W5)oBF^WS=LHDoQ12Gljpa&d3H#rtf>8Q8frV9A%<&%(6{m& zO2S9K6e<*YT}o6Y`$>$04g#aD+_d-vPMBxT??9!oX@|vFb$0!ujVLiPPMZ;`j=f|3 zWo&wh^)?Xh?fY192vAd z@-=KFx9g&xw@x{2G;1agc@t*#wp!>$o+u#gO*Z2cCAXR>hO4s;KYoB><;vqkp*1s& zaq$Y@I%ZA)c3>yJG4VH%RoBUl+OAGZ;@tIt8Cs(wfAM4B&%ANUj8}6K*bz6FT_jgX z_WA$<7{b9@dS1D0|A8Xb{Y;{*AfH{VZiLSywl6r`# z>NwGj&3nR0zQP1e&1bNubNl6Zm~!GM=>)UIY58R-Vc0zu&C@Be1No*#*>uxdqTk zJrJ=#g#7b3OQ@O=Tte%YhGUsHe{yCg6urZt zY}pweF6)BP26X)SR#9Jry|tn(Dvf2no>RhHZ4zQC7cdSZIm&u?w<<;?^52zmSF&hF zkwfRmm;=cWxOxxy!OWX`b&z))o?%8u`U1?RCP z!{6oWX+=(PoY`Xn{x5npfotGN0D~DHjf_C7m%X<+D0n%BlhCz+HAqvxtmBw!mPwAA` z&P{@hAsm1C8M5x-@4;ST!;!zmG;>5KO=jUC@A$m*@axhjb>o1WJ!ZEu+~KJu}d*?n3YS<@qZLfuCX_^;_3JUqH2+Jp_P^+TnQxiZGmuG{Xxln znR!aw<`h#t86lQ;XW`l1!8SapOK95+J}w>vV1N;H_zs(f!#@P?3OA1Bxv;O8^6c;j zdqJ`osqiysUnnynsyNP-Ow9AZkUh;Ar=M#3An1&DCV<;hw3!5hRNew&3O7Wg{`Q#w z6oU2Yf0yUY3$N#Sql3to2pL53e1#a7UqH3NmRNG-#@tS%oWmJM=z+~FXe_UXZHb#V z{qIOYJ>`GTx60J6yf9YJ6Rddou9Rfdiu-Vxq`ievI^;lqrk*Y=BJB^pq_9y;}=_dxYFhJYDT2>#+DQ7|%k6*aw$QS70)dEaNL!lTu z=^HuR@?aWZ^$UBAp4XA%sGx``o{q&Rtj;-btRD4?@yF*R#sP`j_6P24eDo279O2k+ zd}kY4QC0#^!8)Z0n#YAyS1l`}tHLwITx6!zCM1mNQtY_?8sM;M8@P(auYhfKmIUC# zAUZXJf(1B6dv;3^5fCYoH-koW1Z)TbDUDt|+*+*)k6y5or>#{b6Q?)zTakf1Uww~9 z4k2c*NRR)EvF@OZ@QB2YL;bSV(0Mo}cwJSf;S=3CIGHCGCn(2cOh7Cjg%nw|@G?zE zrcC6!gJs+TSzTF;w%2>)L_(#%AbCgoqS_>PGU=n)#6vr@8-WQ#8~A8dka$IxUc(LA1gyx6ejhXZe8VvzH&nUHh!C zb&cj!H=u(gXsH>`xKP){cc*_YL2CICE){T*26tZa3GQS<1|-iCDbN$}mFW(897hF0 z*+#BmI`9~=_4MY~Ihc`#UyIlp~mDp37A*B@^FvGQ=#P z+ktK7AQNl~_R*NZT2AjgMS(@Nae*ZgX~>i~hCDe6FRF(iiwExGI8*M&@l(Enw@pW^ zxfE^V#9?xx7JlcQagpE04S!p#f#6yAa{^ixDuK0_3xA5|xUZYkLaeKz^#Ii)`2qHd zqfR>ova}|udRFTd1Y@!$B@L)F@(XuSPSvnt?q+c$qHrUti6b}Eq9Tc(#japij;_=y zl;rRi2w@;0^{ z4dBS#U9w5k_NbVuLudm0XuG!J{?IRPsPItB3|tK9Qcz2FmGAOO|K(7GmmA$%srKhs zV{LOK6Jor!Vk&`67l5YpBjAK0Rgo&mYk-vW2>^@$GklvX50&Y^V@B0U7Ow4eYjMy} z?n|LQKw|jCst9R7j3wbcDUO5OLMc@U@vmi?J2Y}jKuR3kyzlU)VmSFC7)ycCV3HN9D2Kww0+>Y{YV-nu` z6%QuHbA<6XCUU=<7cS?!0K%@oalhkYE z0xNT`FD#+xcR1@NpMza7VZ_~JYbzMXpQVWAX@LDYa?}^4`)R%?&cDL@B$VRpoM@^o zqVkV<3l3oXf2@=5rBi=OMMiR0bC#3*Nb91a8>mk;2HvD8CZB=aNxWiOf&mG~AvOq; z@y(FtOHlL(7JzB`VsNnw|ARE*v4ObvttgBMxkmpDT67K^J8KM%o5oI}-^An9^~=Dk z@}+=|Mm9mofV4#nR9h*k6WSVuFX+JlH0g^9G1Q6$+jcJW(#N&IKa@moeqNGYeMJX0 zv%DCG$UJuiD_)Mqb1c|lGB6&{OvT7EGv7qPxAJkuMmV@m>2skMf)i2=usT-{=1bqG zbSJ|PRvVSH0}DH`2>&G($YiSy0#WVxc0x+|I95s`i@Xh>!&BSwgWaiOd=1{g$_cM; zstTrjKm{084DeVioSD^pE^=MKH&+Ro(D*Sn5LdfK&#;giej^6Jse2e5GpNIw3Ype_ zjdAK;6{}+NT5N{bjfU4KE`tWc)xdZ4%M11N-8{I}%T@l0N`dwy^fIb@Y2Iw^U>x6> zpCb1-AA^F9@xlVFD7K|Tl0p^~Qt5{QBVi|Rut zQ9jwgr4QR7zP*GYF!?WI37Ljr77llCVtYx~g0So6V8?B^I=_fY(okXiW_~U?9%^kg z>Cb!*IcA|{sa8%Id`6y5n-Y+GJXt*CTzK-#P|p~M`8etyLrVE(9GDntEbxj+c?PQC@ z3&e6k%FSg;r}A;KFr`$X!;R4jQ%79nCQe4~MG%RV-+s2LH0&~zvXvy)Fc>nSE=Q#7 z;e3Peo21_j1l%7ARSMXgF}Q=o;BWHCDp0fvoCC^@i5R$isf~`kZN>+2TsK|*xl8gE-`LpwzYQ) z$^lbno3@a$Js)wK?Xs@O*E{!xv0+5JFdeezt1wNetLq zUv$LsP&%h;!?dQA)qw=HAeg8z@H@G9=%~I6X2O)?GZFJyWwKxAWc!vG(#FBjQUJTj z<$RSKcX*6O`KiKO8u(FujP`5+b|0t!i}Y6xoZX8h8(%+ba(vTamc5qqe7k=!g0TR@R63v_U@22FR-1}MM0X3Fh=3md;F928h zQi|u0(p-wa4i)IJ!T@r`Ibj)1SW8HJqA5a(38&RYKdaikxy>UzH7V1cBCrqPF z(A0@h90-Nh1Hle$#`vEAcX3((9aZY0gcjB6Z(+U-=>?$M!AA=nWamcn=wysk!-oZ+ zu_;F}m$eT#!*psJteZUdx?f9CEB;6pW67G@I1R!(MtLB0tBxK&xdvs2Q2i~g*h_nW z;hS5G@l;0D&kF&}xf{4b|Gn8k=$wuI2EsBaI)e$D8)^|~n~xQDauDinea>m3Xe&%# zbz?Mx;*+gj3N+Lv!7?4KAQFlYx0GGR)Ok9b$*rBW1&~v}F4}S$Il~8X+Q0?$8_j$H z0CS|;LIe%pBlQ?MnaG6x@H?X(B5r-oi~n{yD8elO8)6VElA9`UgrC)Ptqn@=mPQr2 zJ=m}kMm8MMJ}l45!yn8Lqe3S%n8vk}c`sj>hVP1e6Ps1yb*%pCQqcxHHxSaqjza}W zq($JRTMDq2l*Lc+wI@%FpuAFmuS*Z0)%9;;7EM+1!$`UTBDMXRAHkq%!f;#XE_8

da$Ql6OaJs4dxx!p1OG7VF1d-QT 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 6EJO=t>N;IkIM;QfC zbnzKkY+;JJdx=bYPbn}V7qoT0j(RLGN##3YC|5(Go+?I}*0}WMxa?^sF;RgYu4fL> z=mD`1b@l&>1bAZlL@#=Mm>De^CyA1UUYUru*-Lo%C(+Fur%HF5fxfIIrpnNIbihN1b===# zN=>81h==&j@>14w4MeAgbkxT_pzg-DAbq>C&5bab48i$Fu`$NvU8l_{s{DDddspk}Puqk&uiLv`>Fem|C{s)|Hyr z(7SIgob}9qY=!ju7KpU3(}(WUvh6_Eq`?yopL(PSpCCqt z6{ejhHuSBjhwhZb;M6n4?YDIS$YHE)0PDaIv zhB^lGR@4ocM@Q=oFo$V_HE_IA7x0ilbKf8o{*+Yv*s|*lU4A;^xlPBTGBao|9<`rQ z1rut|BiyGN+K{>7L$Gq|cC|$3+Cd}XJ+>6R`7SgYfduABiJjRp;>)$d5~uTN!5$7=k|)_>}BOoJ?6S3?CecbXBeHFC^& zec@?Yrl8Tf5W_MkhB$ zaO!4bwUfQ7Sc~t&EVayvPB+C{xUv@3;}5VX`~2P;*qH&1aHn2t-c!MkEvsekG-!#- zu8&q5*pT%myxq_N;$?Cn80+asFhFPzfFmb*tEq5;HV-k;VgF&B|LTUXd&1Mw$U|y( z#8>iUz^WLuZSebA{ZQY(emJnY&^x^$l-SXH zIznfXcv1~jagw(f2tBKbE0vC*HwVDW*walSKGj{uNi8*fWCmw#(_tv7Qusyx4nS9- z=Wm)NI&+&5!tlXsO#Y+CYA>C!7i`hLJNgdEKa{fqtYGNZ#!O`S{f%1=++n~i<6Y|E zme=1i$7m)8b+vPdtgG2(^syg?$u0XH)g#uXt?<))hdMP>b?-SGmW=pvT;Xk*xaWhao7%|x;9CUbHhOH2h z0-&VR+c&V}S58*o(>i4%bj1L$?})d}3Ho?6o_uOCP*Lu8t`C3Xa#$TU z%q{oux3CaWocDo{PCnx#dQ8QaM*0oz$|Z>8Kj)jh+zog+2h^WiG@Nvj4R) zy7nE2*%wD_UN-ExUge+{PUI3A`4saG&czC{5}TXaKhCw#9c#=uzZwR4TKh)~rfUM< zmR?}iQg1{ZpdZc7jj_Ak+o2R-S4%K^{z*)KV0+A`6i4{XY0i1}iPZ$Ntrq0Ns14=> zJN{eOv`mfMdSW*WdYU5(ujjV(1Z$H0yK@O!&}#suv}9&yY>~37%MiX(U7PmCwxr+- zXe9Def9#ZWzRoCq!HcSc@E^%x!})csei(uO4E6P6@n3w@)Y1H|!9UFk%^C~!mR`md zr=^pa{=L~)-Rxr?3qANSH$>-BaMqo9Se&sQbs?SXaKU7@)Wgh8<8drR?tF--)1KC< zLVQ|?c?|m$NtGJ&yDC53Uj+fj!^f*)TSJr0DSG8A4?)?g*-Nv}LKd|JchJ2B7(t`? z<_LYF^<+@z1-$ECf|dHAye&n~j>B>(Ga$XBhBid6x8P^N*Lde`4?uwoS-?{!Kf>B? z_y9(~tZVB@u@!6DgB<*ydUUjQ9ArPXiYG~1wZ^-%t6fQkV|;LcVPI_#(x~1r-|S(~ zS-CLg=Ijai;p+jdJmUlG_PR~n9=>Qc+iChJvy*OY164;{53!fQpRsutw%Py;l@5JK zCY3hB=p0rVUfI&(Tm#d+3wMS-@?wJF5Y{I!4w1)k3&8wsqiP-P(HAPM^)+JvZp;^m zmrghenrySIz>Q8;DtJAzGQ(z|cNgN=C&Bwge|6UrqDNkNB<8I4BF6xrUIeb`ORQ4* z4&43lhqy7D56Q5)z8R+wom3d-C+$Gglk@QR2Yn&gUU>7fY14mk;mz^z!55nSNOe(R zzU~?MgicIg4X%DEd8_DxHA_e#-lx(1RFz*TY3% zq(3}P(zh&9Rfl<^bZL9On&a+*x+Z=Gl2aVmaKlybmG~$0v!MfK>knXO&*O-f2I}CM z_j|*>_|5sls%)6Z}D5X{}zI`~I3A zrqd>Z+LVg-_}%jKk0E?S29zAJ-|?2FVP zdNSPu=+zN$hY0CvBed@(geVAmmFI)YO)%2)6YguL~I=tK4~{@j~Y6r-!=soY3{&gB!R`Ut`( z+}&oP^Pho3Ca=H)GW&UCsv8A)WuGFtfuLK1%OZ^xE5D_M$3b^?0hL6{fL^xjR68ge zWb@M%)A)FI=7BC!lR=aV@^WRGT?B%uUEi#u+0|`ejCr{FF-KY_Bk@^k7xwqnYwUEX z#xOvh{|O47f5RrzYVYD9b$EZfQ_d2FPI=$~)c9U}@#m*5C&KSGO#0RUF!)oW8E1Ma z%%FNj3|Z3=FXLMjF?Q|K?p7_`d7ngWaPqS8zrJZEpn2BDu-_Vh z5n6`vQe@o}n}c38Ld$3U2>zPi!)&4pdO&zur-AVd*`gN- zI-lfwX~ttv(9JS7Mh!DhB5gWIl3GS9&VAIlcADF4jB<%CkEc_XH zSB;*_dbkq5tjBc?0vJ-QOi<+aGtGY5;24(KA5q)sGT8alQ4R85F4>S9q)V3Pg4e3# z!*}U_yCyW4eRM-0b>7EH$kln*A)Fs$J>rMVcGMjvuvT|IftsH?k^7UMJm-S{?-~$8 zk6L5fTOY%SU3b($T5}zw((-)h3G!;6%|ho5$am8CMo)+)n`04H0p6TuKl6C$sJ39z zgh8!inf+NuY(o3yTzOufmP=?gl}({<^KNXv$goce^nNYc2;KewEPC$)Y-sxd>JW3ZD-ZM0n<$A>pOK@8 zl5a7UNMnzie$WCOaPxOQl|j{Wb@cfz%%_DGNW@su^Qt6{#82Sbu1&2@0Q4R=;&sW% zToau*ysVqd0kL=$PbSr>JcX#URLfLLiyTCY;wQ5IL>}bQu@0D8=f?SH^rkDuRJ)ae zRk>r!;50D9pub!?)bDNQ#{TEqKr=-61ADRVI0hfwTLdvaAEJ$1u3`4ku}?jW&KjpS zQODQVG&zYSdi0q{O4HCsSc%};TrV9~8jD}J4Qei;@&EytSM*O`pmx)z7QEcsiqXaj zK^5g*cZoZH|D~M8^h69^5=qfknG0jjvDzU@+IHCZJT-4 z9qD0{>AwS2SV=_-79s5~MyR<4l&O5AErM|JiE()bChr`8;2gQY598$HJ6vFh5Wt7FS^7J+;QCDjfS%|>IHG-%vZnpa44fgnhiLSKzLh;{hVh<&+~l5 z&||-VC6<@qCfzP^W)*H?48dU~4w~3(j?>6#8}Q}U*tB$hGaHPpc6iav%15*UPJ208 z?Et)uKGY0KN5csEv@sr0y__dSk00Uc`B)Wj$NM$;ebavC8`>a?Cqbmf(J+W1F<>JhhX8(`OKO0#dx!WW(>Cl=$E&!+t<%y zpD#4SpWmIfh3Jl_F29DP%B16T$lf4VrvAyeqh^H7Ks6D#OwP4`7@@I$5qUn(c5ZXY zA-!8erMq~mAVCSqjg^cc6lkrpY9Wk4_fG}?wtT`fIpxI}xej`a@KhG^*r0aO8c}W>ReoJ0(XG76i(^y1 zo#T2zcHFTR0_@^|$4|dT@ku%QV4E3cP<5<*3;vXP>%lM$2AS=2;#sW3nX!0TTHEZU zM9p_rxn&D8XZ8al%#3}aAN`y<+Y&VV7`-%@yG3cEpULD7n7v4)&ZZd-bC_NqlkcSf zxB&)t1z1_$pCQOYgYYuux!FXgFZ5vPioxhoY6AxPI?q+8A>J;%RDf>(8osi;?HBG4 zi}{EW5#e1hSNd*`h5BL;fvaZWB_MKI8_Sz{_-3k2bnZhi($c%OOgeTGNbM>Yom)S~ z(pj8%=;8HhK#tD^3*Q)u5uV%RF;Pi?d_QN$;I4GVZ!P0JD1&ozdJ2a{M`^luE^hm^ z%9eo?tDZ8cYSYqp8$tZbM+B)HBYTYvP2~4tIH>RD3t==<+11qucDa2e-%YRPgSfWv zJjW3eY;o$p!S(5lKK%8XJ2y#9K{b?2)aIt%9%c!09(4L)1S>joKYsZ95w@ZF`#fGa zEX#u=!vc`tcux_b=k^upXypuRgel#4isONwa39hp*G&!oLIZW_o~uw1l%{bu`q5Pr zhi#QmkDyVi6-?%yzgT7hm@ZNkyXw`MWfu6XEDS;S9>^W#o)}frm^3$wH$Dw?7mZTMIuQ?Z z<~qiwfh^-U#LO~4>ElD(!W+{@H|3|OgbEb!gqNr08ZPBxI_VFw^Kr%FrKXFbQk8`& zmE)!f4-aV4}V>TcD-g|3fe%xCrau zd+w3Q+(|Guk7 z)3(n*lC%rX0Oq7Mg)J4#p8PkF|NlMY|4DoDtSJ_(91z?(W*9#fhGP6xCbtdWH^LffkY`R%X(gma z1Mbxt>VuB$DbTTU(S~T$40Q&LHh|7^E-)u)+z-JqwHPgV>QlwhaCEdwd!Hr}rG( zjeIiOg9riq4&+ts4Kkz(fcU|Vaw4~->d*{tGlg9Vt z#8q5+pd|N3nn82PdN`gI)dZg#?&2@vpS2kGlyY|z6DCc$l#|f-S4USP!t4KXzACD5 z#+S{&Z2_AlY!#~?`!*vn+4qPX%KZy|EwAD%; z?qqQYTku)i;p4IJB)M-WK2!GOjl*Zb$Htr(lakynx%{sXN!O4sK5mKI1srpIxSi5) zdOuu7+}*gbdUSkVlsQYE$}?!RrF%_HgK2wUKwgrOIb#JUsQ=wX$fS`=3^;8g+I@tQ z*EkL(jv2fR_3K3fE2B}mEq0`3B5UptuRkN(Ci9XQgFY9ndTtVx&6OOa zTim|_TT$u}%p=UXE0!N(vwO_Mx6VdxRfs7~X7ky6t6c!?5~Nt(`h7ZuF|+JNvt^9j zK4Vr8BM)y^I!fpjajWn^&5)-0>4WF69S;lM>1fv|Wc^zm?b>*-?(|4)chMKP z@%8Z+T|VY^cEUlx%X7kBeDtE+Xjq1|kJmqju?drJ?ZyqXPc+N$U&y>Z2lt5&n*r9U z*EoWhg=57nZb3~v$P<3aEq>scyUXg-C@V8&;ULAoZ!IPrZBu7D7yT+QxhAx+>k`~~ z?4|nGM_JfaiFS-?r8c{+$2uySnT~c>u$QXj@C$g(fT4XBIW+RhuXm1eYUP)GOW(%u zhWsh!xLK#M`xc?jsmaX;XVY{V|M~U%as7%)HkVFQ*tzW)+`r!ZYx(%>%Tp(~lP-Ol zAEVCNyqP)K3tBe)&NEVQ1}K*!*Ya_W)E|ewwC(s3CoSC1%V8ln_GjgS3EV%pdy-uvWj_&kS{BnsD>} z3WkyP{+^m3&XGf#q$Ra-+j;+70&7CxZ2cm{L~kS-b~!nfHS9Y6HDN9CVUbRMOC6$5 zmbet=Jk%R5aCprz&M@otI6+9kS#9&6n0jyI)l0#8SBx+)TlC7Yv%_8H<{@Ju3dm|r z@br`qaV;4HBp}3xio3cpH1gw|Y#!HpUqC!w_Va?w=Tm>z&+5?R~ zO=0bg%klF_l|WvE?HJP3=+}@)o)<(%Y<~$B)K#qQ$P1KwKC=sA<;eCt8Qlc*Dg{V7 zqw}%>tAtZNO>pMm0N<+<0+?;te}5Gi*yhB#oS5d6rNbVu?Rmf5WoOqH|H{E-PF)wk zdEt@Hz4&JD?7wp|SiiZ??nE^5>MJWc7HY}2U8WuaM~t4+I07;nnt4$$pqua5-fzgq zk)yYiCSQP_zOwXn24cg}YF(`u?%p|= z?$yopcBOgQxNqmFLTqW-YY>>J4nM&((!8~zAi-Go=b)44?9`%=h8(Eb;*L{80?IXT zBw$psAh{?$iCK-bO%)@&C2U4x~~9<<1nsqyyMvO3Mj z9{0;u`B-RURabz8FP<|-pvfl-{&Fn(zgn1j>h$hlS$Qv5GA3w>J>>vC$xbxE9x z`n^7W|ID$o^XzkZ-!HHC`gQmNGWVHvIDgOO0V4M%;~tHC^Iv&UN+Unl z@+s&wxp-s-8pw3=HtwA?=~!f@3mYeiaYlNYaNZ8I{XZdmkjuqgSC;~ zAy{juuQx*MJc&KXg+F+Gh-ur45p{VK20_W*w{ZsYqa?&CIRr$7I#m5~iIrMM@=o?u z)r}A?QX+Ftm1K>YJ%iWo!!BZ1a)z8ZbrKim|QwFpcau6u@zl5p`FpT$)chKD?HbVGX`01+VVU zcBzOm!!u*CZxUE=TWhVUk#|n+m*de9lWY9394pKF@GhPt4S1(4z?9eDu%I=Z7FL5` zBEMhb6@5y;Qx=CqKLwm|ZvOAvaFy9H9~LXjs%csgN5}RYxLE|XT(v+pMIRpzXowWK z2Aj?ErzJ+yDt-#lQCN6%JhV70#BZQtr03g1_>wIz@R}6z0(Y9ogi0UHE)f;PvsafR zO48dN(-;?jIxQ!HB-cVTm-FU>czt@Jtr$Y@;UHrU)@Y0rR#6?=t!h(g3XCz7xhGrE zwU$aab>E6n9W}o9xF1e(@v@{n-|f)9!uw40mGtT`WbF za3jueyYCizkn!pyR_SP$zc@sh{O5ZdqKr)7VMzJK4!i+JKJyFW4EvuDsvut`4K9K^ zQJqJ?wgM25W_i?;QWw0vCPc+1x&@ObIH7EpQ<| zdH|Q=ndiI;BQhV7U@Z}1XreH_U7Uu^e_r&|rjb(aS0_(e(il0*yVH~iVl#3GF5LPu zZwBten}89b5}KX!XlxXR9NwY8!1tp-2_fgfaB-EzyxMFP4_JqP6D1L8s}rgiRqBfF z+Vt;Bq6dvmJMirQ+DzA_SF2%LX-o{#Q0o|Hl$QDcf=W>p6>3I@1yvD^l3V8mlaBWN zNN@|7dU)1uMk7WG!2xBX8}%4b_0n%(A|*CT&;dPl`~oMRI43t^a`g*An9%EodSRBX zI8+Q1^(a6G5aycru|0`u!IqC<`NT~^DITn9^0>@ZY78IX2+H@cZ2eeh`N@@twDrU9Z6+9tz)p89ek!SPhO;XwKo0I7)IKU7s!LT1)&?x4)lAFNinHJ-%Hxj7-K%teh8BRBVA z{l3K<;!M#VHA$@V?#3k%(o>X8%vk*vPqUCNPnrT4#c|G*VDYbR1IbgPOma^|I3x57 zPWJGaZ@EmDHjOf+0D!ifj}Fdz6)rD%n-{dn?-qqHX8f2vOv#jz7$sYa!-#AAY%$ZW z`|v4CKuqV-A6GyeFY^~kH2lmoAF;w*qbtNv9(DNb5Usy0HKpM}OyNjQWZ*DJI4QlG zXH1)0>ny`oV|d%c6dl1NDved1U!!{mjo5<+u_73)xnmqCn!%z!5!TTp@!Zm9+S z=rl1>mriJeG?+QU%jr&TbB0jF`kkr@EeoPKAN^(Vc9eWzF;dBgi%L7xDXO1d2-1H~ zG{cvE6U=wq%%e%lV6~YBns6KzlHrJnpcjD&>wtQW z9`ImG(w5$k{Z{94m5%A#P6Biy&5kT`(9L>_m9jlxt@`u55Sv#^?2HkA4U0lg{DqU7 zIJ&$FEAzS`HP#$1fY);H-C`M0=r<~CEa8?o%vYS~0YuB>-A_aCM*FwmjiuQMuW`tL zXiQQ?8R@aOB7nXECztc3FLS84G!JdIn8sJ;xyEra;rGa)n2<1!ykAQkdtM;H8?4}6Ff8+Iv#|?6W)|cz(VFA$$ za>0bp-D_1MQU4x9XQp(v%fN1IYr%}8>0pYZCJRa;wmLKP`&KHLuGZGYRz~`Mgipzj zuB$P^eJ+n?4!c*Vqkmn26uH$LWOQT-Z%UK4^Vg~wIKsqWysYHoD<7W3u~j+B5y<_t z+)vwxUpi3lnAOrxG1$N$1#kU?vBI%7(1Ns=~?7FRL3enSLwmVL;x3xj_^HlKv@Ag&oJ*B6vR zmVfLuGuJB%f_Nqg;giuIBDMa{u&clpM73=1su9%bD2DZDSP_AHOh&vZW7v=_7dp^o zp|MUXiKTlzv`ftP<1N9bVO6Qt=+6UO)+Klo?fwFp82cXU;n!marimLNbHQAeo$7@w~}hQABWjM%Y?1LudAg%A7vE0Yi4vDO1165Aw51M>d^7G!XCrD%l5BPa10qLfQzj372J*9U*0c8av& zoEf)+O)|M9MtbwG9k!rjurEc@lV##*JWM&9%y5lU-o7EfCC zMUI)0l)>7Xy>LLv!6TOQ3i2;bV(tBSg#!8hs#-@MH8v592iOXjB`QBJqF-?T3@r!D za(%aoLqsYauL!!D8sq8_Z|Ar%s-tJn$NW883XwVhHP~Z!z`op}g4X#*Gi zBXR*p>oY#M0#}Y);WEXuqS%Lh@2}7SnbL{#ly`px16p42HRKWL_(f%k9&Qa%PZx@2 z3_H(<()r>kQx)^fyMc!*?eCUFnM=KuV_Qk}i&bb`X!e_6M9EBtOmTwET3*bdt^2)$ zwg`6rs~5F4K|}6tKO)%bG9|hSNA6m=7*CM;ALJHAy3RV4k4g7u2*!qtSc|ybu|$Xi z#c|1rVhHDEIe?2Lg(Xs{CYTV^m>GN2Q&q9i4Z3+l=*PK>Ch>4NXubJ)KsnKRT1$vd9dE+v%IJ^MKr(_Sg(7O{r}NbO2tqpnwXD z%{Xka(cL|W97%L8$Nl$waFkPGzbp0-hR=KeZR?tGoOj3iAI1d&v$$-vU~LREoPjt* z`6};5`zI=<@~CZlAy~18B}vth@(jg%ys9RotLT7J7Xiz-UIqm#zf`)Yr?e*gDxG0Em4G z7Zb&xG?^P-*6$x8(m$d7CmZ@? zS--a?z=3vOySWCUB>qodm^JN}Z4YSV_P=dLPn)L8+s~fTh8nVc*R#CE?QGA{$8{R{ zpC=tcwjTR()l^R4zem2)`s?dtZ--hJb6o65_mKjr#ay0aAW(l#etF4PzZXgyu*|qN z&|>i?7gfk;KkY3<_3YBvzKHr0GHsF9hx@tTyP+b-%GQ^T%V9d@O7q}#ZM+ft&HE1` zVY0f3q)jx^$wlwZxshW=RPkFO0m*SGH8?=bg<<+Vfi#m1-`f3@Of^XG_74eeT&B6Z zHlo(Z!oAN6+!}dT`*zx_UPD^{mFN@EkdNE#hmg2)w+&oy&62O5KcACkMIU}p;bMbE zBb3jw&y1}|vh;agD`S0dqb$aL>hz;2!i@5C6EcIF#AIWpt2J40%`|Dln(DzQ zduCR#R$rj;oY4&6|0@4khfm=2meGnr}j7 zl$rzZTO%_>!GV0hnW6k4{$it{R7)~qsRaXbMK{K5VGX8kVyV^||u+=4dIP($2#HM}nN&0hO>hfW@`_Ck3d7Yp|J zZMx)!rR$zRU@8qw|uS3NYe4@<>Ysl1zTXH-a zx#DJDz7?{aVYMVAz7aR9E|wP1 zB(o>MC8Q`sw_g=Y)inJ*zF4lg;%Qh`ttv%q^T9K`azq|r@!NImi`>0n&spCzFs0Zy zSLjEdMw&sRTGCuYdThIAinEjX6F3Oc=Gtc~5^Qk;tq?J?(&_g&)o%D?sF0}7^mk5a z111gmsP7ITj(+5i-Ytt@G}Px_#N^5Qj|X(ZYa26>wkR9lm%>rNwC#o zr8f`bI;Fd>fc$nG&%rOMMo(&+ARmEbtZVjg%+`pjBX}--(vGWa}~aji4yiqZt73u`5r{g~K%{)TAuQ;$xbs zz=r)@swfcfj;O=*_I_22#d@~K2hY`h1BdPS+zQL`+$y&{#;&}*Iwz`;-?ePj``blkCU3d#L|*~o%4+Hm z$`ukcNL{HHU5$Bk?@}QG)psevYh&(x1NrFh$|3#q17If|sD_urrz#1pQ%~(ic&*&e zJnJj_l(PT+D&R<}{~X@K2YkG@wXYCv%3A%dKrI!$l!mfAtph|tQ}*BKI2f+_`JHyq z>)tz$Bds&A_Vmhm_^6WD9E6GW_a7BWrnK1sLhy`!68n=|Cip956L%Eks#n=bfS>(OZBfAfbH zOHA0ep#Zw-*X7l;865gmU0Fd^LnbsiIv!#p>P&MXec|C&Z;UM)*aB*HX{imULTtwM z4acJz(zNLS!DnXSu5o^2ZLVBKHirB@3lT!KCi|!U^FBtlw-${k&dYiLFm*i)EI0HDRw} zJHB(+LGRn=U^)IN4PX%a26u)iA^uuIpf+33H_)dF^7^NM$;Gw~+s-Fbuekg&cT#mZ z!*JMx7If!$%S$)!!q=Z_H{6Si;2&2x;OEY!6IEfLH()GHb9Qw74qU)ohYnw3+_u^4 zXERmkJYXkUv;cwY$9||%n14)7Z;~~bQ5!DIXzx>Sub8FlVG|&?m}srfF8A+l3bP(H z^0@7Db@)zvd7G}NV}bA^9|aQ{sgW?Hz|Yd1zQu3k?W^&s(0Z^xvvq}p7QRBIkgP+E z>v$EtXJi4d#a?~ROPEylktvE{j@_{w&pRFQDo=kMuhFif`6I^Lc^9|Qi7B5tps%du z|C2uA#~9B3#y@=J7#Nk*m@Fh9Q*)odkt;KYA-^fFdf?3|#r5!tMD{>P0!Y6{r5$9w ztqSH~a^E()1Shd8CQ)}RiY!|Oq;KUzg=H<9p=7JBtH(Q#YD`ZS;#n&&J zB5a=x&0#EaW>T@AW#Th|ZgX zVd>SCycRIQBPmf2_p$cwDyyI@BF{OCGc0kvfsm=qZ2vV5hM8~lBfEpS z%byQI_^o^zvMTa9_nqjHod^q(FCnRvT+!T&l1hWC7J0?sYf8#N?b23Js!z$s_z^H; z5p+Gj_&Dv^W$Q`ZOr8-XKPHG>OKY_T54w;5i%l6hLom9DD zfj{;8v@j+i7@JaM8zL`<8*r$!Hfsz-AYIf|RCxmt0~sC5G=0a34#p?BLK3-#85bLucFvRs$sEFe?Fok(wA+0WDCM$WH8Q2 zYHkUDP8T4cr2s07Mf0gWgbGh*2tD_%0o1ci%t$nPqX-CSA3Omuk*?;90zjh(RJ>!i z+GWTLK$!J)9uF@Sje4r&ctO&sZxGJVkRuaqI5S(APfTnU=QwQA+0HPKpIT%`>~HT- zfi=OXl21-AvZhGqi9so)Ix`c!N1SaQJU^eN%gMtI$ zs1^S{F3TGDQjttw$CMsq*{d5o!>K{zbu;PUBW^v&O}ADgm~!&f3WX7J&FP`5UxML7 z)=h=vqa^^I)3L6TI;m1@_a~^qpq<|q19f?)HhTK?+$2AU?MC&5NENH#amYj8bdzb= z!o$|(Df%#m=+ow*MOK<#QyHMi;bOqd3p&gN0Gt)|z^(nEBn61(X%5nQ8UVW>B+{>0 zKxcRGWa)&{47^xGzDQp%z1$4BB%&<@-oxX%?+l!6=_rCmq!SzkPZBJ+YC{oj?W=MZ zHA)}>aCC4&1p~aB11T@Lrgwt!`K67?SJ3)(8}m)|hYxX|vTLgmLG-HMmsy*bMH^hWF3n z9gxbp`_RQwy-U0*OSyMW1%{B5MQ+;pWgJMdl_;rccvmHYpo_dICbPSc10>oBM83mW z0V}l#Dd?IkS+G{nw`Z9_f+XL(YJ?B?-NERRKS^_`x}->^vlJf1OWTGECLPyAzL(+ zi?xd5CI>QN2Spcpyd;sdfov#=fEFMil!X=#Q4GeXsQkOv%(BWQsEX{wI2XySZt!@B zGQQRjfNhAaWqPgbMp%V z%rpP{$Adj;Yj`<=mCWUis_}_UmKeRo=jLUjYx%@Se_8{Ip-IM3l8vIuFE)ra@8e4QK4paXfivwk*4NYzqcdo!0C&`OA4>GM+iHC;PikM2G zZ`82B4N>RfXGhXHFtN2s5m;n1PYtB&7vf^RI2g2|->WDDU~))Wva860iqKjLX%1e! zeFwGalSUP%O)4#Z z+WHW@z~wGJ`PlahuNhuh0akwXPuL=t>Wis56zG&`l+ipi#I2MSR?2k328)g+F;X^{ zM!yB-93{6*IM>s5ZY~qww~!qP|KxEL?= zgFww(+$|*Q0|&FvizFt4yw$SIzx_cq;nwfMc>p$43m!&0kb9md0tj)GM=)uq9GU^s z)KOWJEyrONJHwQ`AsSoKUk((TG4A^NATF+aVam`q2rqaayitc+TNo9&bJ-yK0pvw8g8Cz=zvHRj>S? z0AWBb|HOAAzy72cXViR1bl0QGHNo8+)9Idt$Xt0Er-TW)A<$I(KTM1{FDC0j>lBE| zT6Dz!xQPFYTQU*g+cElZpgKxDQy|)blbQm_tcG?`+Et=ZBv}$euS{i}%37e@02e>W zX!G8M4r&$b3UZE{c;?*K(kroO_*l7zTsMTCr_sSM4`@Spr1G^1>I6ObtmqKwu661x z-4F(;VE#Lw$}T6=V8L(z%}DZD=nEM62x`J+veu+lof>Og2>GKr4b|lC7KCf#S`VwG z=uTN26I*$Y?IbhEBL2`4qMNQ)lrlLn?J=hKj$y_4Pr+;<3`6xwd%=f*ZsHrBc}>31 z30fh3Zb_Mg`M+*hoMzUF(Zvo-lk8eYcujNe9+y5&wGtaf7#ZeX=ats!NG_8}MKwXn z4naW19pk;DU3lVJ9wwSW?L0CbA1HdXw9P(Vp^?TwE**`d0764`TSb?KhKGqhNP|+Z zk!3zRB-jd=*})Z;!{;gk%H`a5c}fEa{Xreeq+AtIrrR`D@Ha&J#TI;uxIX~MglHfw z=$s@7@2#1S`wo}Kgn-Cg105y@Q~FJTUXgpg$bWNf%@HBiUDMh7N9p)5d;cGvYuTUL zEmSpOIoIZD6Uaba*w|IbiY#)ik6^6NM$MnCbu@)J=jp|<|FiGmj>!Z=RW4cOgyuS5 z2#ex-aF`qvBusu*`U|lxOjq!JMTY6_y~Tr_(f#ANl`XBf$#YHenL>n*q;>ZM2V*|f z3?b1N5z;PLhH=yrKr!i&Xp;lFd#EZeMNNFH106dIxgicLoil)UgOy#w(Jy+%{V_#DXwC_cAqYQ$!-o?1u`1+ zeKDpe(j&lLM(((c6~c+E_ybZuofRZpn65uB_9MF?hve1}ORFt$YMqFo*I==Xh3Y23 z?2?Yc%Oo(S6GXJ9HS*^prxbXY{JY%(44-v^BM;R#hlLPgz;ioV(2G8+C`P}S2LdNO zStUg4FkU22=815rW%pSW*(qffBb7Rf9!Ok|6S-8JnwoY`2nht3@BM%+%QHs8btjIN zkU8xx;Ya!HPVi%{oifF6$I;Dd53w5pd1QBGDJ6|=*-);5@=3R@ClCTPqxBNN`E-flwxGcEC@3Hkim@nDH`FFUvWat z4V$JAemMT9Xl#p%dJPCHqsJiod8e?5Uv61;MRtRp`EX^ymk6~09o&il*(F(A^9 z??Q#V^$~df@H-U=J{{D`=yNx@r0eyy-3SUkGq{B!rNnq1(&28)DHRn&A)aBbu6fqnf$!ou4leW zM2OeaV8BeMAj6ciuS3We6>gT;`!fVacHvnrHgx-VC4n3RH-&*8fC6m}S&EwLBGC9lgHI$ku(7E6WY7#m z1vlSbdd^!xD`2H}+M^Hz)9o^Z^7$ek)$PKrNry??1d?kGwc`&yJ#Gha&wH9jKrnGq zR2Ut85GvHz9fBiuSq$XTBR_IfjKAK*gdjR^2+WZ!vp|{so>k$jbDxLHxcau;Nadu# z*p(U=*s-?!ao}?KZ9`}bjno4@tQyR({Ikmy$S1tn5C%d~e;8BxCP0aBywR%w*2T)& zqFzHfiKG>pWWH8aA(p$2m(Q(Pj}?boZh8z>TR6n-X71q}I?gfBX9}^@G{uX|XwOAF z+7*p-1u<1|H${5zzD1(8141dH#h=f^=M~2YP`5JhZ$w8mvTw=rIj|ky5EI>5>5)Om z%hR}7WCK`oqz%X6ldcPBe3qWK+C$9NwJikke8+q|W!8McIaNKzUdk>l;~i-aU*@@> z^>=k#5J*>Bb4>J)F7Fp2jNOlp#IOFI{H(yhFxHFwdNwQ%CNQyQr>YcK$anCR?Bdgq zb<+KDLaZ(|mWtta7)&2sltl(&r&pV9gk-}%qqKUXMxL>Hgf?2Bk-wX?Q|m`K_m6{a z-e~d5xU2l1rHww+#@cAejc>YYGX)x{q4S_tX@-%Ewg_@A^VJ>%^&5ZXKQ8cmPZfGy8YSFn zVUC$ufBpqpORv<>EbeZbKujk*X)YEUY zJZOAw+bmw(>-eD3gh2Abgn(M^$XnI0I^Dc;f~_ZOHKZec)3snNz9TkrDI6;Zx>rF~ z^3jZ4rsSNMnvT)a+j()WGB{jjg_e8K3lcATic5_qb-{`+IL`^0dhDEO6yHhy^VI~! z#Nu-onX>Fa53dU8mxY^!ltojt@y?+F#tv`nAViu2=^)LkOXOusgeWxmFUQMtD28wg z=57GofSRvQmKvndRM$fcwWc+H;<;hZG@A;RTGwX8^`5AqP!H%+fq5VNgl z>F>+wyFKbXBZCiZAI_p$uwI9{A{=Zy_eqsd}mmla6oVl^0e%uq~ZC zqE7!Fm$?zjjs|6g4(-Gmxd zq7fmImK-x+vJ?z4k}#_?^z*;rOEhiAM{}m%nW>iPqQPL8biSev(23PR%Gu|M;LC$+ z)fIxGhQ}LX%KEni1a5P0QX$ZceejA)$kt+`A5<4Y1+1Il&SRpU=9{Mt6zG)ffT2mP z)J|jQFP$w2vx|3Xjh9h$@YQ?46bm>039s1!jmv;#eDyvKA@l23&<&ZYBUrrW=chqJ zRZk@FK1r>0nrXOP@F4Wtuv;A6GLCy>o!!sab8*(9tx-C6js4kDv!|#^+X|%DS6gWE^ zMps%rFDPN`AumYvJlWpM;I@uYhw0Id_@3zabGW%|&4xjc_{|@KaPS5iQsAlg#e_g- zl~-Vo+Fg*WyLUs5cNJ|j*ivmdsv2Df(F|$*>x>C~Q~&S`#;VPG@$;`wWle7O!qt4d zGdU;;Is?-kYh;SC15a@sQDts#(zDQLng4A1yUf8Z_i_ZIY^m+ON@7=9Ch1+YKC%(NDtbs=Jp3 zKXN!2J)f%(kQhbV&lGeB-Upt9;j(iij=(sw2&DN-7}Go zqkCY1qZjkpGnXz~O6j>197thmHCP(P(()`_Uo6^cQDgeKMLRbPmNMzjD(p+% z{sxZ8vtlbQIT{!bYlrza)f8MP_Zj*MH|`T{N1Obt^nST1&Dvb<&MTFS&FX@Yr1QV2 ze9Z5C0na60$|l0Xx((25Qd={=&-&K|oMX5{84sVAt{dZxFkQ{Jv7PBzu&Coik01hn`lnca)rS<%?bZlAqd({`&NCOKfA- zKTa$CYmqulPaNebsoVu%W~Gtf0To{USFPg#UK#P80Zu;+j~0o6-gpgG($Z?1OevN> zts6)rj|K4RvW*#mm<6x5QZCwOyn;vk~?t(@7G2TyKzT-8cnD;DxHhzWN zGX_S9=^@Pc{9b;Acbjnxm%HnDaG5PA%u)x3rTy|YE>;!}2r|S#^)n)J7Rt#&0F-D8 z;gL<^&5KeldZ?cm*riVfk-Hlf9o;uc&^KgVln;bNTh`njMY}WA`^wQR^9!aQ*qHO? zWx+a_4cPlVn6CHJe+gkVn^C9uvAyw9tKKT`>Dw2I6Rdh04Hh=~=Nkx)3KrM_UZ$d7_wOEEJoZe#LC7}Soj z3Ce$7=%q=!pzGuzmmag;rHz2hq_2O@Lu%Sd4Fv}xJvy~2iE7YSD?;q*lIJR-ELmrI zPFh2Hoh$|B!SV}d4(7z!|9|y*AHVyQCCwVSpUi=B*croJlVKcJ>xiK|Ny!&@oO{J=5bo*`!%RNbLU|isKWp+B zUiGwZKQA1rR)4f9%-nVOu*9-^L&0Y@7Q)XS>54at*-`VbI_asG5!Ep6Mp900eOgGO znyps*$Gv`kXfZO9DSvn?8C}Scjt>!)8PeF2{$+vX0$X}Y-QQTkFYrZ+$;Foq;IYXah%*bSc7fcSd)td0Oks7!Fd&{MKl4n z#Exiz3RmkvEgOh0G>lKeBJu@%y=@`_8rvs%J;3|v2SZ@d!-Ve|M_*bo~R9_uhIOm#YrU7wx}I+_c{o5GFJ4ziUzsH@K>n3OAG;-W=1V9 z$fIvpj!IMb&Euzdk{GN?L&M6eXun75QtEo{mJZ1XH~2K%hC}m2s?m$x&(j`BM;B=PNXJ|lmF{MIm%a%Zdx+huJZp-v9_vQn43gtd3wkSH zm|EHWj8!bfl~q;sFUvA_H(sr4yPO1bXq=zp{Y%>Vc(z__!Mpia)!V@T&KCdD9%d11 zBfHF!cgmn;7GEAH`1`WnuU_-U*}mw+V4RJcH_KbfNVT~lsR`&iQ8v&M2l-Yne}t3L zHU`r$xz+C#3Fwwf5J#}KbcmLcW`>xN)G|a&WFqhLC8Q0X=S0W~*ku<#;VDrPeH^+% zkFiT6%M9T{x@ve~2p#SG>7CbNPA}`9Xznegxo^T!S^q!`i=@3F^9ud*6S1le&F1k= zPRj`s=+XRjIinlv@ji!i_;dyA-8brsrHuNvsNJ+-8@PbwKjSEr(~FSYXsknYX2qjQ zJ)Idx5+ZTbsc>^MVW!e+k0)-DsXP%tjK7Pndepj1G@7U~!|A4GCmcLUtA?rYA<8P@ zXY$fPDz!BD8<1Q9lZ_Rh!&}8jBR$vHProQ+Fsouq1a^bGrvYyil|vDe!jy%1L6Bnp z1{FkL?`lOE41JU5&`V{U*1khU6`Dxi?ghIzd8&FD^ru4ve@Kt+lo6J#mgZW?dcgz@ zfuy%se< zebg1aEI;?89R&R60UU@N-YF_|==N4lnO3hZM6jCK2f-%S2UNHjX;FfB;ET;wE+#7% zIG=wyzbH$F88E(r6d6+WP`^@&m9{s?jmXhyZr;6y!xckNknizpt1HU&seGfBnQXFS z4gT@!EG_@O3GnlsG7!ArzQe1}%yByCyT9W4m5qk9fm9c5 zXf6a+NGocH7V7CziwTRl*{2ZU3YpjR$kPbK99gd~OwyWbOA_R7LwY*(7a)F;{DtcY3Zzg`@_dc{avDvE{zg>p;fzo@R}8@!tU^>; z`on3XQHIdZ{Quz;BCX+LvD!GR(XA@5{a<)6Tl$EP0{qVDw9 zZ#97$@)&=>4#@%wM8LCPDso+nw8Uw00xQ6xzPAP6!C?TNiL+jF19sHT_CkANfcfqR|bat~Iq5VJo&5 zL5EWR@(>M-5|d47_y8ZqCfN*00RgxaliG)%la<4p%HU^T%rAG*p8$noY>L%Ho3vF(YplRi23jPIrFP`g@-#j3 z2MitA+B#@MfMrCvkA^=ggDQ9m!`-2R77H@uQu|Z(7`$bF(1^fo_;CXL&O0iF%Cp6! z9rfT5o;u6#YY%{axp|~i6bnAI@~#*qAZs8q(Kr;tDF4H4l358AT(fV+*%QpaYZI^j zRytSW7t#LLf-;L^9vrSf*>y-2LMi@1wM^grqZs7-V($uY^7y{o4Ir6!O04ws0iNp( zzXf~=XeV(@n3>dN4v*N&eF-GkBRkKrzA6$F4PG>)pP`yoAa41U2?)57e1qOi`@LOMMJG%s zQfR*?xlNPYC1!Hz+?sq?80p-fPmZZE(*hi0ZE+QDsj8%uDLb>M^HoMoOCuyIqdxCs z5hRelBu=HmA_u+Qv@FTU8jf@PzlUO=0nNV6TWIEgV~Nme7|Gg*4jBd-IPlBkp-Q9! zc1lkDDKNO>&F)l4$gg)VanoCWnq=5&7CU%(`A;B;^x2?Y24{SUYaz;O;A>?A1nUho zG&K3J1}|U;{|}}X`RN;+pxmoBj8S>xMgEk-CoL|z`cS103A24BMxiP_9m&CxC?(rU zBGlNpgwdifY%6)(L?j1}c7%MG`7V+N2ltCMOv+hi2~*7nmJof|PaTESOuR_h&cYN` zluAh1nIdaV!-pyrsvo2FQ>z()cHQtIJ>7dBN+aokFlbR5!=C6zqrebDezRohm3tuj ze%HA&Sac8%I`X@TF;edu?s!ey6kz1}naG|GTMgMVO#`}D#tuXwh|z2yL%7UTG&H&e zT1nY0Mxbr<_-y(!NZYD45RdU2|6fq@1Ml6CM&P8$-nJgHTFoUlkI&ct-0oqr6jeuo zVTyH}0#z~Thx)20PVHH|vHKl-rF>;GSBp=*V0U32?OkwLGc z>l>4(5y}evSJXPu( zdx_#SfRtKFi}0BG^|9Ui*KoN-?OM1{c0JPK|0L3^s=}Xka%&%7|j5Bb8bW){|UV zB63Y$<0Q3%;7Sih;m))o7d4J43c?Vmcfx+AHWHIau`W^jP@*OpYtg1W9ckp`Hp$iW-r)wov0HwHdv= zc+jBJMM;`@qfn+xKd~@6V^<-nk{SlFlVRvXsI4KITkT9qdf4E_SO0np5)dUenYtXE z7Zo>w5VA(@=NOJqIzA zN)Bg1+J0t<(f&g~977Dy%I0HSh8!q{`EYp-^!{~&Ri@ETak$c+LI>*q{HV{Sg+A&j zEHcx~aA>;d(SL@+~;+paZB_}yZ(t?;; zPd9$Y?fC2uY8O@NL0DLCSBA)agQErQU%k>zQy*1EsQXj=;g@J*Y=E@KZZFQ{ttG`) zCMCuRo_v-q$`@?iFtG3+!CIdg7sp@#lF2eKFk!@dierozTwXAdViHSHQBwpa{BuZ! zo{>#MEFMT12lljFjsG9~&>H|O1xJ^XMQ50jjl5I`t)p((iHAhimZocBbdVJJ4rRzv zJJF0vw>o_CuySXk-Oc3gjxxmCh8{x{DOoqGf+^EibdO-3uTFBybGTLr;d+MO5Im>= zQQCvgQ=-xt4i9v5lQTub?}$}e zVl(Kh)E6r(rRm8al&YRiAS35Ms3x}-8p*IP;aIi=zK74?E21>NFvLrNvlJ6hOS_Sq zyxzNxDGqS5)7}u1-<(|Hr^`anZjq}nN#w$}AsD65yvKkco%w_UsumKtOz)j4BpLyM zM=wMgqZ2zFL`lQtu7ZLvS^Wn*Q%aJ}dAKfmv8E7(Y#m*VH-wWL#n{^68u*gkUs-JQ z-L}};fn2D-rdBw|@*6zro9(%~X&)rG25ItZm=KUr^f?F@Xfeh3Pz|x$62B zupsW^%W^--6Qv&T7Ym@0`n4(2(e*uGW67tVQDq?ic0r-f#OTvpn)A9kLs3KEqq2jm zflW@7SZw*SlvI@9JcCY*7^o_7VX}&TB5gaWmV^AuXUAQb3t{BH>}2#vEnbhOYXR1 z`-2Ko`gVu;6a9X=5QkY6m;&)8Kk5n7FWS+}y91@?`c@>EG^;kpyp1*pK>U!NI(2|7 zFu2x2S71eVm#bjO{>eo2VO?s+i++9Q)DfE3f>$Q27zUDB_P=uEWeo0-G%AC^?+Rj#fY@glrZanKhVE z$1C{akW&r7t?$Y+L~mdVsjCcx8yN}VlPxWW*|?(6hg!#nL3msB@aZdE9)}MJhsvLI znXBgcYKdN{Zc4)Zm{sJVY;CPDEv{3B6S($6jtgyqo4h(yR{{aC0rR}L%?p-&u7xSW zjAe(Q7^|MeOP4Js59+QnUMq{NTW?h$x>bB%@HCD1pGdUU-V9_MjU9?Rs8zXfG@^9J{mv~@Kw_<%)6oFPgVty zLa|+eekSiM!@-d&hUi#2dI<0SPd-^0rTuLsIy$$un662+0xxbBb0LE zppbwsy7`J)V(|eTO@w*o)LSUtMy8kCB%c%(`}gX=_llzH-ogYBc?nJQJ+hic&{QDvAYY+P~VQ1@c$L6I3ww0&^q^a zIz#kIMzpGF6vh@r;leJD{f*@JVoXgIiKUz1OZ*lLGg7q1q+{!q%U&EzweN%gz9ae* zF4i-JD_)FyF2x7|E&Q*z4~7gmU~oT0p0>a{1Mo2d7(+y33*<(5GBe$&mXZ92t4;Fh zrRjhgQnrSuAm-GVgFBEr2Dh4;zJ-hAAI&?WiBUAd+v!>YwP!A8G>tI<0x;EWJ`GV; zd;_J9ly~Y$svl*Muse<>?kL`4%D_5(PcXN{TV@0WbYtdY1El4T6*?w&om1$c+5hmc zW49|6I{P|@J|e5jRp@$Lw+~0&CJxI$saz<;nz3lFZcs4FkAva1>W1Y(4e7m$gBYt* z^9Zk-V)x#`flDn=68jYU=k#$n^|$|+f2fa{tzWxENI%7{jA$yP+p^H!*T9ss-t^$p zMP1AA^M}=M2!0cb*nIU)!E@5!O@BZzQ`3l&1kC}t41&s;a#v>|)cr&EIdJE{5Oa0wU(3x19z6?5a)hl+S9D5XzwFRYY{%a$k zN~^y977BuZECM=8W;(NU=AM!$P2^X=g;3vtCEIQ|Pk<4fg3HLcI9_mfV&NWNYki$G z^7QwH6eKkAt(yaRe{;q3GCc6j?|_t!+vw3#n{BTlQ}lJU*5S|+a}0t9g&DUC$|Ov4 zuZw#jZ>_;2jbnQhSAoY)s{D}Duj3u%-nw9jWlx_hQ)ql2LNiRhf3pnT4L^P&B+w=E z!Cp_{rcazbf&nD(X5lR&XiBoEX?brv4rjO*D)aq2+zL>h#;_9v$VdJFqe1Sr z(knA#=PO=r2pt6(NnK*xr1;-wAPdNU zcBM~JqjY^}#6P6N*MKGK3=Hj`fZMK-76Z&o&o*e+pl_Vq7=Ht#qbNgqX_KA*kEH7k zY})w#3Y_UVD5()3T(cCw;4sZ>m=(j2uxdsjr3^C+4rRE^u*EPqOw&S1fr6o!I;`ME_vhTt?ft&m${77Q#k4><|U;l@1IPYEt-6K^R0)uL8kHRB-Wihn)@{buzwgFA6x=q!nNBR zmKM8f7t$5Ey`t_rppGtN6*b&xF@hsAtoNt%b$RK&UnaN${QO->2UARRP!Aye@J+sL z_*;UG4&A87B-Ogo5y!=CvwRS+^V$m5`qW?c6w5)<+nO0w8rLi^LI9tV?LG#24({z{m#Ol{EU-bdwg)X%;_Q_{X~4G7 zqGLH*Laq+k%Yuax`8(0n2~obeE;E&~Te=i#d%wnFW&q4y)M!M-V0A)=v3*GH0#>*( zq%Z(|VJ*uV}*x7fS{$7xq&?@HVa1?C0nOB6tofo_fDOohs=*4>@xfGfX48<-~dNDmKn;2Oe z5w*=f@MLkD`wOy;7WIAsZPoK&8>`%}QhS;)jouo|vI7qP#env@@A}r_p$@VoKaD=3^qQ0q<}-(N>2nZlehS)B0_{+Cs2|1D9 z770-^wb{cgW^D5f1_i~YEHL_k#BvfEm92Ik0r@Fv?LUl|j}t2x9RJ~|tZW;;JnZd@ zOEXx=7D>!ry8l#2Ljb94AgT%Yvch$*^w!H>(hLHpTy ze7GOBqPi=JGtuquFZIl-`^I0)4wuQxbU%n7Rp(dbpCM*1Xa-b(RqNoVr&Km!Ikkzgn`X=kW@VW3!!&EGByEXb4A7%^V@EJ`Kz| z?*gtzje+2+Eu{`N$6?SC0uwE5^mK{3FMmM>6rO0v_n|+OAyAr_X=?}!rh4fzH7lIA9|7}ops{h3~?`c_y-miF=B!qbG z_%GY=Agfagp6_Dt;4^p1%mRAm4GV=BmeaITi0J`AdyRPrto7rV-@uB+*dxQ={tq(j z-Cq?7BlI*1@|6bs=J~sJwvW?W%dZ!P>GD2DaJSr#as)F>nf1Fs5ArXMHJQ}=-(`eR zV=tcIYq{xtjK0d3W1+3-i!wnuQ45DNWZG?kYe;LY`9P3*)4?-#X%xC)kBo29mQMl8 z9D9!f=9h9UjH5r&J9PA6xsV13Lo3GMbHzKeaO;GAOtdxr=_0%%L>((y;R(4 zv^=tR4QO~d>J$Ify|v|+!|I4Uz(FAZs9RaZ8xq8a0I z(kj(=IjqCqJqBrQTkeaX=^KlJHZ|z`5FKzpbO^4O zWQ5#pBp@owov6f8rnqxG3erhMjc6@T&OSyiJC$_zj7VW=T9`>W5){=cBy~9}u1+h@ z;5uyfR0lc{+|U5Mjlyi??&M)QO6g#(!kE-?G=(|B*G$Xo~--}H;1enf+Z27rw{ zPX-i%1^(-V*N--wRvaaJ>Im8Jo9!HlGqxv3U3zM6S(ovwb4VGS;@&Z8GSBZ>i0z_E z6)cMU+W^+tBwECRK~8^ndo~T!UZX+UnF=r+N=;>|LphK#&j`-u)O!dSd61f;rn7DX zt=Efc5;>cRT2ykn3tW0V7eEG#TqBxmbMp-5+T?t?;E~`li5Y@gE-X4eBGC|DFc*or zm5H-GY$ndJ*oc7r{|u2nz_dnQVsyQzuT34_Bn{0)SzuZCGq@vyRF%q`o)&uG729X` zAPDNucfyHfEOwL44TLySRLU%5C|9cfHgg-v{)*6QxPsN%D0j{f$tC^6+A!JOmZ{?T z3*pgwSXPWuLbu@KpJN3FoCbs1TVn74&lb$cpW`-LiqPSpwrCchIRu7K`D2POw9O=9 zw~I~38?>q<7F8peSRCXZ_1%QF3Dnv1Eqvs*FLTm}zP)IwPV~+U2g4n9kcB_Ox(2E+ zz=gR^?o^3b_h_A@{{%6&A}PN><3)FwzV=M2tQo*MvF(2&Dk-F9b+%geUrWjYO}}M1 ziSZ@2j)z%BA(yA!kE~`nMFXpT$ZAY@bO^wHGVi%dM^7wg7{B!XI~>zL+K-=biq7D! zLq59(zz#r-z$IlyZ*T-K;K<{EbJCbJYliX)STXhXfP#lr)rQE&ZxAFSYmS3?P}Y}S zlPq?L)@0J8qBf1p10Dyd-2>V4M297VM^&B#fy2ENJ$=Z@>ltvBF!cPcJ#xSag#oR} zkm(|7^&BU${U)X*!2=}5YLV_`8E}}i=Oh-zHtA0^A%oLDE@Yxq=iW>q^CK#gj|3B< z@WKDYSUIkh!M~o%Hl#Hmv5Y(@dWTusYpr&8SlGz`K}cm5ZL88nD=}CexZd?pWz?GY zwKlS@HTFsA+x~?dyhVes4|0K~V$eX;_XbA;ZipDFNe<>_A;GC>A%I`PV!9obLp#~* z@8ZBE@)uhmqLc=oKowIOnpoiDMCDYKs4hdOB6latPfm`2L-5Wo*iDpApW7AWGxJ$` z;eLbbv{O zWZ}GZGSUg46ge!6bATu}WOWlDPdUJ_jck4~DxrhC=&3}aoxu@uB@yMrT;_KcG)3QD zjG#piAr9kqZChyj^+w>Wl|I$9QF3WzR-AnK1?0r@d{&snCGSHRtbLBC>dES{@XP() zH7`say}~WmlxEa>`V_3x%mW~Br~4%GVGVfXbVu2RH&$W#m4^c`Bg!hRpH!KV6(K`P zIsk}K|bAWuz0BK91PSij`O==LscOulMACP4wSuxN%BK_u?#Ox4t!0hVG%3-8$F?#up zU82h1*^tJzAS>Ngjte?Cz`6TIFdd41BTb3&PEc#p=x+(kgQ40#HR`Euf`-(jGv27*WLwHaKJSP_=6wUQjJ}5~Sz- zwXqR}P~SH8MW}Us2n=ScI~ME8Sr-6s6yhvxE>Nf#?n$_T&x~-}4;h)nu>xck`k)YO zyZW33T-~G!3oj}^{b`9KvEV6;IBrm>JWBSmU>G+jzgS1Mf66vVC7kORjR6lWsXs%4wd@R7*=AAZ^l?zEu zxLkQ^^X$pfaXUnFbL_rIz=g}_|ugU zfZwbDjPsNYQ3vlknRFt@N{Ui3tDM(hEz9jU#B1OX{E4jp3*@V-Ec)x9Uo5NDPunSS zHHiERi*Mu_BDK&+DoZA6MxG5hjTtiaXK+LDy56O|%-{Lc5E-)x%c55HL5WkQRdvMyi{L83*lRW$=7&6ZzYju6 zU?~K5f68-`hA}9B%H>ZAA@AFjF@jL{8)A)!V#{(Mk8BxQX#4Fta{uv;E?1vLZ9NcD|QqDo{Nu@*`7B%8Zx6*8_G?uiakL9%`bvma#301%y={Dm)*s)v$U<&?Tb zW;x2rl-HIt)aA4g^l&R3UaOI4v{-8o!3WXX7ek)FJDlMnFqvp{R%a;g-q~#|aETlm zQXC?V!8q;d(ZimO7D3N^X*5!%jW3;=)3dOjg{q-liA2NO#^=YVc}Ev8qw}|jpaTYI z*a;Vi^5VR`2$k*=aS!fY&;?p=%4%%fwaW>rfj;}GvtUBSW2Fs(1U3dy`5_0rf*!Jy z+rqRL082wynOEkSN&;Cxh-L~b*F6IYW&=Y&;x6W!XmnUtY<1Fy;}{*GtOzEkywt)l zIFyGqnRnW`0Yp)0JL~7BcK_5>goLQ~_cF4%Z=w0wJa4RRU&eUAvq zhIBCf0Oe1v+@o3;3QilEu`L1j#?USjp z;FS<#k&Mq|FKH0fi6m(TP@2vnpkE>~o{G=7Ib0Wx2N`XD5_HfSgyD}eiJ ze2IHdVwF%)g=Hui}EBcO+-A3 zJCX|`I!LjvKUu25BIK84Wn;Dxze1G{xY6i}i;K|#P$GVW*GxI~ z14vWe(-d}3*pvfwyZtP-Xc&+W?_$cA zhI2SF)4+iDIDQ~FyUkh?D?f^zY0ai_Vp!yK#PkUK$N6_!a4X$PR!a(4PH?QU$7ED_ zZe#!E?E^gL?Q(x^Ivm;4px~n9yEeL|a2-V(^4!LMlqHi>UF~p5Jdy;!a~aoC@`zl_=%yV30xmQ{80# zYbIw@XM|al(;_6hd|CT=mwMMUdRyJkdIT%L|Uwcc<)nEF+57tH6h$e=61+!q|HPw$L01| zGVf644G%ZX3ZZZ()k6mQbI%z#b39>R<1pAQ~oZB=tN}8+}BXzku24_PU@zIJz{uNkTM0spTKY=Ro zz)-kISgQn1*&uMpA>&$W-9&onLoP!Nrw;L^km1oF~tdb#-`k>nS-wU!RlPR=$F`xb(s1L?M>S zcYD|)e+_=DY=jr zBUyY|xj8Q(Mb9hk=rI;Iw_Uaf&T2I6S7LP2YE4cEGFlKcY%iquq-Q=KA$aTai;hk^ zln|zU$pofAWM6wKL{0Qkz0v4$qR0~m!W`b0R$ai%cn$SnpttxnTL{&m!h$9V9zbXh zxPgoaUg_HRKf&Xrp`$A;G5T=FE9NS(mK`l9)#$U0BZX`<18aN^x{cQjtBrJ8C5AJ} z3xk-QLcguDhK0RGEIPx0n>UyLMKD*V*0+qt|GoX0#Y)@!HA@qrJ02VqY=h|MH%}Nd zsq*V)pNXM!_<$R?DP+pj+JUSp#cn&htPR6dAX|X20~Lxy4L}mH!^Bd9vAe_%_hcgprb$+Drj^_?lY<*)H?bjit0nEHz+I)aus zvD{H1T#K%FG)tg0sf%BLuWHnsjlR>$M$K%tNu7-!bXoa~qH%{okdF>e#+-5T?800c zo=uI}^hEfL5UoR_&eejqES*{J1x6VAtV^;Jgxa$34f<%uq7cwtVKx#dG0niSL=@w<$2U9`h`$K1ewyYR`U5exOmd!iW(>N zR``tpTkxMO(s-yR&^zBugZE89rXhds5xsqBWad?-+pPVwP^Ai~&I$}KAdr_tV~5`` zfNZ)v3%MkG(V$avQ(&rn8)O4l#}+2rl6YnPtYve}ysVFXxXHvTDQ}XQbZK@bor#=V zO%EsMx^!x(lnvLD1IzfUH$I(g8Ddu_JQ z)$@|h)H6BWNN0O8;*$p{VOsW+a>;r#d_%L#f&;h{Agi*ZRJDur_MJXd>)wJ)u=)rKu5ffX^OjjzDg%oV$r;1=Y7ywHh(B- z;&jM|rHwlJOUHZo!Tdp4mTZ2~Kc?LY0jf;0GSg_%AUu?W&!Fgq5AXeaDMVr?QxjvH za{n1DcwPyVinGJNB}Le^%Zh3uF&$%BcU+KVC3L#ZKIdw1cY5U*er8)=%i^X%_j4Cw zqmD5aKMnu6t-YI%{@Y`D`v@<`ON}Ws)8D7Jv_wcWS@h0D>jeaAVM*yqdJe_5e<`FR z5b#?&=wrP1QgBv6kV;+NS!~o+UW;@oF1+fsE1NhzW$?J)A^VOeM_Q)_$efYP-GL_Y zh#YaP`XY27pNIE~N_Q$}_{rNcJ~zO!H~6d&4-es#H90rg5%B(I2Mhm7<-dW(oL!rB zQcy=&SpZ9EMeW!Tx<)ltYR$hcm}*kRdlgbG+~B?@M8n$6njlp#ehZ}?IIE!@)M1^7 z`P$Kbhh2f}5-rfq>OKTn#ESpW0N-=yS-6P;{adCYQ}~%hqP|tNER?pN&5nt0t_lbt z72az!6x!uINsKq9bw1}A)uzYp2#x{NdY}v*YF*zOtIL)74oA0;fn#Lhh`DS}`DVLI zqBRbV^Lc1LTT{HMdwiop7@gG&g-Fc1rNgCa;z(xOa?V7t2#Wq<0K8K7>S`$=lpfv^ z^l;+I9x+ml^gYaanR1J-fVP$o54y5x3*Q=+T2%iNF?S>tt?BSHx2(G<3W%?td9d=p zYRt2Cq+&ixzcf9I+cRl}Ma_*?divI0$eB>zB26ZpGW1-bO6z~f5)<}+d;4BpdvGU!*Cxms|SN9&E_Fg|qcD+o>nn}L_7K>VTJhS`h*8|O%>#n^wVl|K5e~BZvUdZtR4ZKi~y!H1kD6T$3 zW;N1js5X~Wf6lPGl`HED!4rue6szR(eGKI0*KhC&+}=k%u-NJj44tuM98Xf}z0Qe| zAO8dKDE$lBPhaOhX6}SB35Syd&3R?=&qy&%q@}MTvxX+lQj>Gb^77?i|4m+<;yA9k zxG6xp4r#!8x&(BGn91B`CaN2#w@xX+i{)8%oz;Rz5B0Ky=`iCg2+WZD#Hi3JKfg3$ zfV~>KRMa8%gVa>tnuRn(fWK(Pq6^+DoiMuS6*k5;dmCbSxi7my-%v|^eLLBYA*?8_ znH<>7%WFFAO%CDzZ4bN6b@NjH$rFM?rQ-2beD?D{1J)R3V+x znfFtf!}G~M^NhK)bCwq`R&8Hd(8uY6Lzv%o^OgQAwJqRW!z$m;PF;ZIt=aZBjJ*my z&)#6jV4S&_@)pPDiS2!1n)p#^*2Ri5R<&Sy)#0pBB3HYen2A{ZM+F`t|HB%4J~_TJ znKio)b>GCGel{i_!`PIXRqwJ*?{wuE$r9dU``{N$t!j^kv7xfi&`8PDe)Pr?B@m(8#o5z?uB`7!?fAo*&eh>7@n3n9`Wge34P2Z#Laak$7d{!B$K{Xm@nQkUIQSE7_aI z%jWL-_L;mgrps20>1VUV3dz*c!$sYPWaBtor`G=sTbtTIW9Rs2?|YNx#@V1Wps6kA zm`_P5`#ZLvKhtq(^r99=@1(7Q6Kr$(Fvc&9ew3e!4yr7VEKquQema}H|Gz7P!?Shx ziv8lJaS(yd<~_l9Vfh@^TxlGE;8f?#$4<(H7qcI9VE|rAKFpzAPYamuC zc+1mv?OIu))VhMr`@u-W4$Nau1$z;_e6tw0f3PTXue9GXswK%_bf*u_ej2zDz#4)=*deh>lA5EfIKAsj?z-}QS8R>XIr%s^?K66BYF||yDa9Wpa-JJ!O>GrEUHXS3=nm2 z7;hAHRk-5@DUZ<0@XYEyWl1{95O{g0Z9);c9n(&~R!E4WG{KPDi*%S;g36tP@@AIY zP=O@A$cH~+sv)qGG^<*iNhZ$~GAp67eGVRA zbd%_F(QBr*3p#t0I)~N-$(dsmGpLU4E)=EEaHona`L%O9doJbn{A~pNMgC%N$&n6D zSC|&v-eSz9fm=)n1XKS3i-q-vK<0AwbzstH-3$gXwbU|!39s($2V0QZQ*kAN6lb4^ z)JE&Sc*Q)b53hVxQhh1aVBKT_JRFlG{FCT~!xEqZ$PCe`C9PZzi{VD0V{NFXKRiM&J)xtTLfy@TUAWtRU z2cjGFUP?68C-SLO6LC%|G=U|KqEzO~geIC0sn!9`T+S}aNx+AbMUvh|ls_WQzRWE( z8%`(3bkS3TM162^Stklk5pm-YP!6QN9r7L2dv>)C5z!qyRz>-%iKd814a8jV-0!L{ z9m%?nSyYwFe#^d|evEYr&9yo-dlF^@Ps&&*3!%m=RG?@6QH(FD%c@sURyv5TUV}FBqIz%*9nt{K8TN!?|s zW)8r@IZ*A+fk?B*&SJ)v`YQxs5>0Q*L}zC6J(^rznR5!d>V`Yl7j5V7Cq z377y*|9Od*%eJuu56hIEr6*F6C|4oDPGg;1pNvd0;7XQ>%;jL(a%pF>tmwC%VPYJ* zn|NEW?1T6+tqmn;Fm0Thv)ts)R(K1~{)6@_K#PwYN5}8n-^sQgU{{wKqji!me#PFX zem5DqeB^G1iKNa?#a6IBOCpD=TC7x!EJna+*EL^eNje=RTmysd4!Qm^OGh@mhsfq~ z3bh_mzo-Gn)xfz#UhfdMW5N8a2RO%_-^?&`mEYokd(jl-}y4_+j|sf zw0`;zLQJL$Zd1WliS|wD$UOd;9jYXIwXke=U&{*4D5xpPB9h%ry>bej5}DtsPkuSfLme+e@Y_z zE!Y;OP%&7MyCN2K0~@|#NLKEyi0vF+mMW1pHL)ORBk}39v)E0_H$!mRq~>6wv!$k! zD(^8b)@-egaQ~)g9VE?&8LNLiLq~ch zVMZ&?vWEbYaVsAj)78eDFUtKzu3X+Wr-OZy6S&2@OCp?QD?vq*=ikjoq-jw}LE6^_ z(=Q}z1^9BzX%_uZ23>JQQ22*rE#xKt%{*obZ@}*7U(wPMqv4rRhNopM%ey3`z9nOZ z&C8E6sP2HV1OZvSvy%bC1rGTOVr2G){33dI-V#vN!{sdK?)e~JumL&pbX(S1GuVSE zl#ZL#SfsIgM1zWeHd$iGK%I$yY8=EmP;`Dmb(b&TA+}dZF38=PI-FOZGOgt8CNb8Y zcuR}=v5?{$!F|fj*)9dh!5&QFzuSZ~BY5c-WcMQ=)yRmH>nXD_d*)6}F(%Ho4a$q- z$J989wSs5^eo0FdEYcN7Ji2bjZkdfCJBq77&dyxd(v?o#X+YGiO#Q20gLG`cJ+4fe z-cD19%#7Ca3c-DobBtE1y!&5)lYDfj0R0BOM@A`E$6&rqmhNXRPWj-+7HDD1E?J;? zTz&4N)O6qxe#1>;23q~igJC#_XT4{AC(QgKSaac-F{46P4Oxn4cTvruIK%1NgDGT$ zI+BRGPc)^HXTPU%B-S|tXUm8IEs-2zE}BXIBsidHH&~56;pnz(hnb>|WZ4S-UhRyT z)cMm^*2&YFb(t~h?cecsfq(We2Q#PFf%H^PbOIE3adDhHt16=C<7_if@6y9|kYe1W z0duVP7ARb2L$DcnP}2xy@`AlMmsDPZdviY!?49Hz8MCA;`WpF>g!3EpzmsTEo|^=Q zGc?N`d3mj5#xnoNlgZ0{+H6wcQ87nO=b^P9S-S|FzHJ~LEpPdN zbs19b5nl|sVsq@!toMlKzQ}FpW)Gl%%V7P491B4xsbwnVQ!4fN1O|~6BR7kpL~?usFNJBKC9a9r;UB#-sNW)zIEjA7-^vO=^jDohT5GnKEq2>wQt zvlMHJs5)&s)D-VGjqDCS+P00|r;yn%m`Wm>nWKRVED?hhh__sZncR9%93b(s87AVG z1J!D1(Bh}=ZB+!lNEK6CqXUQ)^{|1osvt!0#6Gu-UOaG|4?^iXCVsiAE5WPErg=gP zKp{%A5Gr}YcQMY`mtc$!vLLN=U9$WP%Rx`fd4eDEX5#~pId}V4%(zr@3+9X~`w)Yc zKOT+sai&!i(qRKQz63#W-%T%Rb=mg|mV_3b37u@mmkbwISFzYj0$>pSJm0!EuX!+DOKS=!#87^>q0fCTm zuFPkX8~#QcLLQav3dt&f^pR(56vK^4k{5zS{{1!H|IRCh&!{Z%f^xa4JB%@;zek~x zxT7Bmo+L{Dcg^Rf4$mH_=AFJ4ZC&WhyZ3}BY+Sz!L-cyKv1!lD04eAEX~*10JS>Tl zMwl(3xEqLOByhIP$F4Bs;|wcl`W7q0Nf%gXv%yzr_XmFIoq=Lt5}hOJW>dAi1_GaWvqb%eyu9&*-42tlW(G$> z`B~Y-JOs?(9F^rEdurzCN!r02>}DB=ViK;7n0W(Z=*2{pyez{;vX2UZ@{~LKrRYf| z<}--irvC=s3S?lpxS*`b=Dh=_W+k|(b@(clB_57B8P`dn>QIZEFUCWna?1x|c!8sL zwG#PpDl5FRcKpNWrg6HkP)~EWaQUciLT#(J5)Cgs;$~X%K;sY93AoQ zkWZ#uj~HZvl6DUCq&&|trV(zqDAlLd=5OE|P}UfvEo62xOPF$VE3izK=ubs14t|w! z*k`zJdidb1`lkfijkhusmr&0mcDP`E8xAHnSD9>=Y1(Su?x0uB)`cmd_RwimYTdTU zXC`i>@J*%a#O=(FN;)F@T}#795>i#dErO{^lu;r@BoT6*IF^W9IpWOBfUfeNs1u3% zLaLPnD~h2c@;?h}ZlLW0R^}4KqP|qU{FdQK%U|p+;K=(WID9)sFjH(@36O5wyqksD z$cpZkk2Af0gjT0K-<}UTue%2-Xz5=xX;l4praesMy%#kyhBw2gl4woQ+nYw;u=0}d zu=;ic8D?xWA}!k}I?D6z==^y@p~$MDdH_4hd@=A5v1W=M^k%%1k&Eu0LJVXUI{<-a zJIS#1%?`YiZ8T_G1&%fFlyWc5Fam3R_FW^;h(DTW^zao1z5Xu2No^m83n8$}m-2Bm zu2XESf4#3Uu)$WAoOX6LD@a!ouR?&??qcZ8 z9&1p*B_D(;MSj)5*Y)tZ=-Eqi>)eLZVb#NLEeRaJPQ0&ot4Lcx@q<+tp25(4qKEQy zgtmi8ul!e_kf0sHBt9lJMyxL}Nts`y`hh{@C8poCCbDBuahxng19A8@y4}xG$lIPq z>~}+$d&Rq?NvelP5A5kw`MwM*-;mCoFEqoYmBY5I7hZ60I)R#HLS}0P5}OaWFd(pQ zOUAA){{Y7T_EA5c5lhTdNzn_?$;(zqH$^4AWi$*rv=1B0ktWqGNPuY53x0Fm+K#M$ zi8-^PT~8h5H$YpA{bG>%0bHE9e7*Zm3r?iKEqP_J!hc|f{%$SXB_F^0S#rTv{QQb9 zo2GqR1B)FP|J)a)@jHVH-Lz;%XP2IM9tvhXuWHJFmCV)P(bRlkvb#3V{pD(tEZ2vg zhF&|87JtX>N{B(WPZISLfEU9&cWM_g$P;%d5a_i}v0|PMtfj70T1;z44%dSZM41m< zIXbRZeT$z231&Ft#|jNM+TnMVz5vXYY>2-gW%__guk~P7nwk@arsSQvl-cIWTwOjW z?Cxmh0DJTWWREniE=x<6KKsmQCbkKptqm$l*Jfba#i*OwM%BRN+vcYTUeqW}8Oj<5 za@mVhIWl1|_5sdRDhqf5V;NMLXFaTY&$ML$t^r0BUB$Gm%&z#l-wSN@l1&VniTUpW zczRZ7&BU6UrDsW&SeRfZhNN^@v7jh2zf?Yy&~9#QE0HDZSnZdisE^M{{a>B6*kDcU zgw+->mDNBZEb&|P=xy8JGIeeywsX1MJWw_LUt3mID7{=E zq*ta={HY~QCpAM6KR_Syp5cPb+8d!Qd6Bz`LabAN=eudPW4+NtqtexU4^>h_8ZgMG zM%Ys7W|p)i?<{ngsOp+p2>W&Mb&Z3LTbwL-Ytb^K4!%D7>XC->qd)9$I3Y~eh1Mm@ zHF<7R9ve!niPZ$9Caqs}3bGXxwezE7sR6IdUVjna?cRzqqXu+Czm|eCg*MsWAlZrZ ztK_Oy7CA~Y??tqhk?~QU+d3Opaj4 z743JD{+?)U@@~*c9jM8kK3*0~3hTYpXjUj%>84a=9MIY`dbWk;|#34MPL9$w&SGGRM zHD=S#XN_Q?#jT?{z|#3?L`}TnR|C+$*GT(iFGx{&W%O4^pr3D?CFn1~;F-|~tp{pWZ-?tD3HcM=8FD3ho9i?&)RnLKyTXebHg?Ai}_>mw!( zr}lRXZ$`4?h*eQ9?kVl>viBY?|6%+(Tybz}jL~P#Y)4@N;uR^aAK?;pVL$b00yQ<< zKjbg`8y)m!NP~@93hCklfwMOHvww;Hu5y{_VuzTyOj7Y%hS%1}-cvWm;2hx(a z{0Il8OgVS;&wTvqYK!tG@vB8?Ut^XzONu#!xBp7}>1mvN^XM#_z!N*p;#_X2ho=x> z{bqNQ{rKvaGM^ar{DO-of5zCW29XNIfAfnF#C4}u=Bc>vXFV<+!k>1i>O4}P>7?fA7B^MLc`ROD9yw+(R)tGF*B6gfZhYFEy>j-_UKn@HUpr$A z*yfB8z$(tvm|!xFHA=j0_NukmGvdZSa&fWq>5%X6=d7vn_qh7y@HQGR9n=VH z<=wb<*EYdDxFEOktA+Rz|0J*gf25tQ-T32}+HXr{;kK9M(d7?KyEk6QcUl&oEE!Xm~Ct z+OlF18{5%4$g-ttZ&_ev^exAMNacWCfwbhJsaQgHhsO30b)0Tv$)sD(EWp>@JN~J0qJ_*k7us$O zX=wEFwVsySkbrf2v7lt>+a|CVw9bfGoT!w7RbZNWKojG2J^q*tJ~R0*XrjOvXNZ-{ z7r_M<`R6mtzjkAmJlHi-hfLi^a^3_+iO<3}nQds(83*v(@FHA+)s* z&{auupuU*)DU2e&(soOLF5_#KiatmgR!q`gt}k#WZrMzq!bg*L4aMxKzg5Anqd(mC z$^5kJNdeq;CW95>Lt8KJ#P>y|cVVwFH~7lpp}jYC$Fv%esY>aB>dKx_&z5zA zUO00?euye3^q^TKHPd3{l|plu1nhDZ58`(8l=&C5 z5whSBR$A_#IS^;$Eel}mj52A8_^CT{f5n-uy{2JA&oe3?!HB~DteqRzDHZnjIl3v0 z#-07})rSB6JBF`@wlFhMB2BrpG{MZrCjFFyXU4b2@#^~E6ijKPXq$rj#qw)nNL)jm zB}Dh`Y32&@wvTU*1*O^sym#U!N|${ssZAGTo2RmI7mm>ZlEuS&;i-#DZzU$&Vzy0M8yjUD*e3mD!}%R6HsbTK`}^T4=Ify(abw*4Vi}Vs()2iNd5oq9dUx1ocXBk7hV)&&4OY65yNySyO zZ6@}_m$U5wsxPe?qg1^+AM`NgU}K*Lg%1+0xn{iqo%)O3*YH-l+xu{4pl}onlfA}e zgmzN#f5uE+%KdVDf{my@AsPq^;a^)<>c>?|D+ucSp zNd12xU)#Fhp}VL%vT!?T*I+ROEXujKgpAMx(KobJKDc2{9_DG%`(px?(DnLU_T+tQw3G4tC!AfnNYC?Xre2pt()w|+b z>&YV+Ip$;;NY->_ln<#`N3d7XG}6{y#OFF@FM;q;#;o_{^5MC)v7G1&`5NnJ8`;_( zq)KrC%+^w}C4fE$yYVw!pEnjW4gYJp>;1MO$A!xMtK;Hi2ZqYLQej9% zHtjE(zG;t>&*%)8F><%{IPMOc@tasmEByZRYp)Nu_?zawPJ)3_w=|p?O1;}G9Z9J@2{nDh%ojw+x2reBV7II;%*WSz zJ}g9BVMgha?qd263T-^+q^~t@dSt;T37IgBOF*6fPAg2~xyn^~;1TP_Xfmm?Wvs>l zAL_V5HyXlM>pGo8_c;`$|8g>3qOxg@26M`DC0H~Ja9 zG{!x}W*X=r;+p7+YQ7L3K6zw17{qgI1~dq6>8+U{2|1$&_Geu(YE86MnlTqYbk-VV z4AP<$8J~mMz3sWwF~5;LKy@cgg@_(BeKH?6(OJ8Kp7ozz#>C0vnCHY@Pz7@zStD!U zsQu$O$T$1vhWOU>e!Rv^bpk8ncyPewpwU0Zy3$ZKeFF2ZD>&{#`1D1(CP39nrz{GM zwtR)#aA(`NJP4yX7%)vB9bPj1dn7KA?3V^z61N>rPn!9@d_oYutWm`=YWDsQUe&oH zjV5Z|R1?Q&R&VABXz|*ZNzK>F8?ETHw-xr4n#Br6l*;8ZD4EfV1)h}5FD&@BQ8kc{ z((gGVnIoe#63^8*(p967PHl`4o=ZDq!C+fdYl5$Z?ajefBP$g`?-3w6nzQJmcEK2ndDB4zavjveJWq*D)wXOXW9IrOKX~{&k*S{8Q@&~T6D?RHm zm0Z;a_As*KtCdAzhqju<2{mJ2CR?EeW55W?!B=)2<&utSLTK3@)<)>@S?w6NxhJ>5 zaPDI1I01I|Ah37F-Y9xl`B0v!ezH%sNDl3yBDo+#X%Qy+0^(+P~pXS z{faTDa^SWxjVhboKu1z?6EzWFIaJhysruP*wsNA~W?f&ke>iIpz3=8aK)9f##P;!G8KY#Rd&I8B$E%o8cht(K%>Evn)p; z%}|7uNOko`;|(LO#dc6|#{u?qnpwFj*gkh+OOS%8{X6iBbpDDZO8uYA!h~_w{^(oF zh4Zn*+`nf)SN~nc!FU$~P_|shky{qTi3)3RXb3SxY>+ESXe(cUNNme2jz;%9#hk>4 zK-G-rQn7B;EoVPc6{^6NIU1bCSPZP(d3Oa3q1(zWPu1g-#&u?lFMAh zawxu#s|YB=-(Li`$^+ivNfqkCRfm)??6O4Zor)C7@3rs%qgAqw+S>hr_wn{A!gcc2 z0zJy!ui}neqy0FsRYo8t?HqfBKf*$U=at`wwomY*P1+82ZqHL}LE-*T-x4SahOe$qE*aA$Mm!~InELcTr%S8}eYGsysEZ;C` z12nkX2&0oTS9)Qz67}nhDD{5(3iB03i$dxw^%5VYFYyYxkv+_08pCkoss-@>*u8M< z-v<>bMx7NTG~YpPZzlb#}MN``k~H6`k%hV~$lnq*x$Fp!d@)XgnN~k;~?T= z1c~O=)-X>u!aZIAnM4oFc!(XGb0yq^*>P@6MXa1$b$qZ za}7rbQdw$Fn+aJMz1a#_(7KONw@l?0_l=NEYX;(1pA5-|dG@Z;XDJd5L?(mtmEkI6 zlRTBF#etvaU}bftjjk9CXSi@wM|3Q7P}>5Q(jW&mX)uHVVQ`A>e^q@U=!}&hFQg4D zg;y%qLF1>Mmh+kVa`-Wv?uYtAs2}_uOfA1$;tHY{kBV6-s>L|u>Fbdl@2_F{-JKVV!>U1 zngZdWTJF2_G+O!xi;9?10(3xSZ9R~c_q%iXA)b>D-b7^b(r8FMrKl{9vDGEM+3t5S zsk*rnF{J38vQWUIH50M9asNlsl?S$X|Nkd^VxMRl@w6UMSBj9L#2xojgwz=u7UyDQ zOI?d&Q^$B5p`{4JGBXQPQpaR-l{p@xmQrLGb*Jc-j!pJuWX|8~49FykU$BtdP3qo+5&4ebmyBy*>LWZk?BxSBrCjOm* zjB>sSDeTsbtFVK}23rgkP*bO!Ivy3~Ba-~{6N8^>|LCUl0la0NA&!O|aYKlDch)pu zU@ObSZP*lPhf@ju(Ud}1>pNt#4XVycL&A5j;%14EXSW=>Yd zX)tjY-MgG^^gSq~)wL(WWRKXFW9}dn9`e97R z|AcsnFRi7>LE8EKTrW8?I@3XpU1Afw5JFeVOG+=53vOWvxSr41!6Yj>c)XNzj{=oT zbTPx13NI)EGaX(~1Uq8bpB_8)FJo|9(!_r-R=G94jP9Mr2cSzWZpLJ(?IF{2x<=N z#d78^?njzG{djd-1EsA$?SOR*=L!Kthx-VoWFls>_>%rdER6qGmZKw2#n5a8_be`C zWidQv{iM}E?Zj@+#p>&SEoK8~`fF~G%(8;KMSXWm2sQ5(9_F3#f7LM>_ZSVDUaO_= z<}6ltsZTi&|IoKPgC!HU=i>J67>Yk=&gT>G3HRn1uhY?}e+)x#6CdeWA6dCQ{6Kc*rpYQq|SCw2CY{&)r2798=Rnv!&pP=73`SD`OA<9 zTp8Ai$RB3~$(a*b$V4kh15Qc;rZeS45vG2)rc+C~J!_dR#g(pOlQ`R$ch`j9!nzI$ z9oHhwgtnZ&V=d%0x7i@<%W*;RTCSDES_(1P9Ulo+6=^gtD~AlBOxnHtM6f52ocvgYvb-O2=-(QHx4kO*sy(ePazG)!pob`MC>G*+UCg55sNzdAmFi4B1kPhD+;#tI)**TdFKcow2mUbpYBuU}Y;CjMOoxD%K;ou^h(axu2NA zclJ9-7`e&^`H&eex>}LQ>iCu=DIR&s2M}CMewAyYCRHWqae=pE;GQ;RUsn=YS0uT- zA{$`W7=mMJOG^YLSFb$q^!1o;a1*(!5CL11rZtURB_U{C^=b(@;KZLme!+}1Fsyq%e2xNJWE#^#TSEF=?yor9lGg}W5287q}QQLKe;Qz(>F?D zRfb&uexR_`lc2%3m+|=!yXb4hn*t~Kt z(p0@zZE4*|>>#HdUY>&pYz~Ty`NQ+W9EqbZj5=r4~WUF!= zvE=&nf*c|)W65;#kGWPFEz>Bhl=HP0^hv}w3QCIfLlv9~^Pp(~_Mi$c!gw3~(CNat z&@od_mh%N(j-q!PEQ96cSoLFnBPH80I|bQN>p18F!B(9>jJ68qL^JK4j$<}{VIB@) zvF#2I2SN2IEPaLXp4bUZxtvX-;aeZ}>d8)bS7nT^|#tw*K;xdfd1qCjmX~$lg zFR>hemDFIST$^Wn6nL<)YmmgzHj|ZL%o@)uNX_|7u-2fVGucW6keBtqewf;!oeXvF z=u?g`*1&JeZPe6Y7+A)8?E%Kk4gE?PrQu{V)IBK-1C`oiBb6>{Zmz*KZJBrQ$kqB2 z$IB-!WW8T)h?DiN>5Tr36QR{wV{I*zj_Zr)0-5tpT7+CWnrkMvExBQ`wK_@)X!5w` z3J8jnDNYLXiBf#YuThyu=r{;5^2?w2vl#o!6F>|S4qaqq7UqWmAlcR6qozho$BT6A zlZFIjFCz!XhJ0K^TEj6Xrq?4mSBHH%@# z^Tssdy{Yv1;UFKa3;TH5tBg`)I6m=&kzJgivXggG@JF$)ik0M@8D3CGoRjl$2+r*2 zi6Z+eB}apf#eXv9xH|}6&P{-s`S%QvqjcpSR?_joJLNGdUi_H{FGzJOVejQJJ79wa zo9}1zJExtYlsfb#rU__AjWmRSl&XYiK65AEM)i3gu+sGpHsNwmj2VEBUnh8Lz{T}(T5SJg2+2CB|@Y)lI)e`?% z6}BV9;N#_p3RDvL;y9?p{p2ys2`6K_h-x{8trZ*NR<;lOFxq;!iZy$VsBv7+m|kHb z>uFXY*^&LWk94=mP>i^9k3kh&t0abxAfDNi<|BP)8(h>M*bfOIJ!pedG4l0bEFuT5 zH1v$l%Hl9Fy@frSHWW6y>7(LoQex&~aAYLzR$}N={=gaMpW8`=IuwR7?6`Ll!cv_0 z%;|#K^cVP5JNT*x5~`=#AW_F2Ynq-+k}zF;v^JJa-*_ArL*K-Q;6LO>Y=wm*{*S?f z2gaykWVnabaYkpcMl4djK)DFmS1<3yN+ym5CnVqDwZMRN8#7HL{d?Yv{uYgLK^a%4 zu;$wlQQ&y8<1s`7SGov*U~pj_hnGwLZdQo2{_t(|3q%Z1Iiqsd=Tok0(r?l^2mYf+k(ykw0=(P2vq6U_!yh|CA3EmML8cM{sqt8C~@i0=m`S9po}kBT6v zb>E4(1*QquM#uUr2iaPSz1(^VxAcw_^i>&Na0qt7($QESF1!VknmjbkOXL+5DD@I^ zO{Ai;5Y>^{v+({D3S`x!>Re}13MEyZ#h1d=)4vpK$mRSO3>BIG*1??}$>M;Ojf^`kIJuOI zCBiJfSP&tn&IvgxqE!hd6j{{zMdc^oU%Tq1=i&19&AY053uKl7J=I@Yr#sKV+vN?dVm-801o^rD~Dx0>&cMh^f*_a ziB9>XV6RDZ=hEWnY|4_^K0c!il8OHbUKJt#WFi5yF?Q*Hc3j0Q159)=O z)uYIV?lbqw!_>cNTYeb5HhwC?>*uWPy8|M}OGLRiPW}J2gQl&W(m6k@4mQo1IyOwj z9vhW5>a8;Ct=3TWXJs4*>>(^y-+rv!$|!4kDfc}@P_OwO$Tt)w<kNI;Ma?xyoRRpW>qY6v0Six0Oz6uMpJWR12lZPk7n zuWv*{D+cne#&q7}%Wn&d*M2L|B(kBg7z#Jb>8D(9V6l(LcLY~W zBF@M~UU4^r6(au7DVT_4HIz4L*j=p8g=AKmI3HW-fwWs{`OzK zU0uSp{URe#;4a#2KA;$l zl$&&(MT)rieO?bllWGfC;K$LKS!>+>V@~Mk10OiEsUH9J!;A5{5zfExv>@i;S1_2)=#kVqCtcYpKqP94mQ8PFiY4M!;9ADf}zVN!}8*mzrYbbG8|aKv&OKhERG z*q^bnFCH0;$fH>e$`j}A;{zxZo>Ud*N$}etKoK6 zRz;zhL&~*2i6vf{Y5@`6JZynT;eG>Klq9$Bf4O=1;K@k<94@GHG0bm)zC^0!^R~>*(M-n=y}J zB`khcU?l47v{FLe!}TA^P(>C_X4R7OTMO9Ax}8Ob2uyOAvU3w%(X@;Bq$M_GDKy1Gt*7(uufEBj?UtT3oHAy0*h)bD+rL^ z`a7*O@?S5U58S+dZ*%x>XIos*$j^dhB03Ge&AuPGLqoI z0zYvi2|hUV;sT6@AHNl1NZnUtS)qhi23K+Jwh%CAfD*?V&;=gU``&VTV9r$J3ZjM_ zNdn<<-w0!)fKJ&bl_PVi*(f}^jCU$fkR=3~Q|V%#avKdqrt^LS)t}t$(Nh22<}93I z73}ETym}Gu(@@g}H}h+AmIbV=?ccaZrs9{~p~_0HhhW>XH(^_(l2QfJT3bbvz{Zb4?)m0=Kf`k7&+od$)GVE>rE2vczfSK%lK4_|`Mxq4p+ zx(394y%_MrG0@DS|VAem;G94lpyj>J{q<{{RnNj0{1CYj>e22j?Ft!t&g!|F$J>Y(fDg z^=D(Twf9*`oRpnwB;p_;h$b%Mb6tdsR>(v~?HQ!=2xzk7nWFEgBxDOj9>Tj(1RZi> z$xxdeN+2V;7Pv|CPA~vUocSPP*DHvGDN`zRWbGam4*9-`Iq0?$s7hi7SSKYe*jf;q zK&0m)??6%rK7dv`&m%~}4NP%W%TpvDA=zF29>%-89Cp7R2(2rGNEmJ*hau6Kll~uny6(s<&{1tE+xr7 zsKP|-1#KP<4jDZx#9e8A^g^{nzzVIIw$A0Hm>Y5<)A8HAN{kRiO2}6TV=RZkP$cr4 zm85WInScuRDsVx=<_v`UEz?ZJMpxM%$^;`^amjwvHuhsZmc@-KFVL~!yx{2KG}s+a zp@>Nzrv*r)Po|ZIi&bMe9800eL9Qm4*Z)vJ^=73_X<9N~!Te*WB811(-ZK}`k#Eov zhs#qzfm&FRLu3nUjw10Yh@kcb$^enxXOUpe)=J23K;)}13j1$F>j@I*gjO>6Uj_$#*3EW(!OvHZ}bROr(W1Z0@OD1&wpKd9w zgljn<#Qm5K%i&90)BF{d#QSNMNTuy(+4_$-iVyT2l@*GXkC8=fl@}=38(A1FmK9?C zR{}6e-~SmTB04f7L}JPgnpk5t8XUeczbb@Ut_T+Li{qA3%E=$4JIJ?xDM0>};;a?5 zc%Um-NSfXiTGbfl66JP3Rhof@aF4aY7OTgLT;P{-r;c)B2mL z#z)~nC=J7slDO+de$+5dabf}`SIhCAl5Pcv!Vgs$N#YA7)-@8qMu}O)BI*Niq-xVa zE)A*)vw>R|AAQSR6+f1LM8F@?JBnG*OFgoAd!*neycqA=-n^pF3 zvPBQC!$7Df+^Gu;dzss?FU?CY`|2&g7QLQ@g)OK!* z63ER1tavw`#OL78;?n^xG|7%86Zvksoht%&N(L1qo00VfLJI&aNR?bakr_lu-uuN? z60K2eBGFrdErsaYfCS}JnJ%KW6c~whR7wD;Zp?0%wqZx4zl&W2xLJNO{}V{WxsA$Y z_;h+P&vWI`6%nFs4ASfH64%gdWWEab>@+L!&%uiNpCrm$U67-EI}P&dL&y*=pbBwv zmID-71r*_K0ZzW%zt|3>niNMecUmZ|L3WO;2$G6_A@WLULYR$D&oYr34-0(6wXwiN z`mcq+gMy20M-Pu-nND24+%woIi8O7I870}OG#^R0 zgWnCgfB}9$m^?FYVNt@)M=Ahm)EEDzWvtJ~NI&*LITcGJt24nvS0Tc0)eyoU#v|!2 zZd?JlGPMZYF3*4&B5AYCWY1tojjHNQJ27nqqwBuQGLhstShiplNV?c~)}D1MP)txX z*&-_l2sqG4VSD_XWAF}S=niZwm(F-&hQeXr=NIZ6)Sbvj($tD9;AdNNquq++mfMNSENM`2}W}<7OI~uCTIc z31w!r$wpwJsYw50nO-slT>?@_;ZU8VBxF>B#j%SmvlF*Gm#CX5^Yb` z?MyS1_2t-;$iqZ0$7TA6V`Hv}{J>0^bh*K@+e~HWqTI)6SPW4JXbJZ&W-e7=3H6Ei zji|u|xcy+jnzcYB+`lQYM)a(w4?HSlPAwJ?iPv2NtX+auK)Tk@#uoEYU~)Ky7KG6y z4a?xY4LcNPBarbT?I5DXfw`cbQ)$`g?H2C(E!VA{H+j8BndMzqyOJkLOz0@dkZp6n75WOe~WavQ;3jf}X?v|;o3TuNv;Q#`ajm5DgoXSv9{F5s`m6IIxv z?Kn}S6`6i=n=*Do<4$Nh+p#P1Yb?st8x;tiCt--U&=;mA$!Ww43EstUE{~Nno0^+- zoR^V%R^nibt{Q?-;-8TJl6H3v*}5eoit@K)K0ArphNkm{$<&e1 zop-_Y@mog*+T%C0;qAOSsvfZ{!-yn<`B1+KEq!^rNUsFTcwG(ZIPr*=tn^sBeSEYR z4NPhe+5d3G4&GFcdT;w+OFb3-VQ(6=>c<-g&~R6Yk0sHVY6OmZ_oqkjXmhOen5jOd z;loL9o99CQa+{ep&|w<%5~)*9yyiN^H90Dv{eAzLCTh_-iXZ+O(co;4?(L_E4^VS- zolz6RbIx!-a_Jr2c5m0{dN-GM{inE(G8ISjPqawql{$YEMK5e^@T>L1|EJLoRR68{ z>aoT;u(@^P<~V+4YqPlFe@M*V+^5M?jlH*e&Kvc=sXDbrIq(TCI=#)npWx)ZRU?Cs zW~e7yZxy5H5$o{a ze)91{82*vT(G?0wD+(ps-Y9YcyZpUh;LF(K8qG9l`=G6JVa98`&lB!EtcCZnbxU@p z;Ca`JFA^16+oV^YcCClEy*GY-MUUs4)wlOGP*CglS9%-pw%b7a;8Z+w>N;VK*hkCN zAJgZC!mpOQDM}S#^}<_CZovywiX?fxTL19suc)DUZ~f5An2y0gSw5qA&nlR=t=%1Q z*1vo@)k5igyBCkUw*F#>t9Na&?o$BKx9TL`s;9o5yKxy?T9<{2s9FxizfwfhrfywF zp>Wa^|GVKU%p$nzy{}P2%m*Cd3T~bYIt~dH@JLtyeK#xwNV~(v= zqJPA^vrvnlr?uw2J!z*V1NcBsq*Y~swAODprHR&T9;@`ThqcGBRn}LeM%5C%SqIA> zcC_!D>d<;Et^cZ|(D(nNW=2)~#$P98vkK1R5+koRKd8>2*f)_5ux5aD%KD? z*e4CH4sDfY7WfQyBc~NWWT~f&Nn#sIPRNchyCsuEqwq zP|kcVxODXAqvH@CLsmL7-^5*nV*+$PqO>e48HLP{!yXD@u+5hW+m}p7y2{FDyLQn|_ti1VjAov6gq}1D7{_ zxd-%8Qqfsg0~;vTopU!C&)(OwE+*mmN!g29Iy}E@Z9O^GuYUO~**DhTTsN*kc5Qr` z{o7n6t}m}UePe-1Elqnf1Mj&1;tv6YuO6Q~^x6VRZ5^Pxs)*8w-)4^Wsbz9TKh~?2 z7VcVe5tblFpD3e1C_KSy2hmb5dW;RAI^C?XZgioVv!AyQpc~!GSSyj?>W>vxEoa-E zeo3Qyk6v5#1L}sPEx-2ym&^5UPe2Kd_+jbae=N|cM{XW>8x)Z8*PP9`OgL6-vD1Yb zJ^VDbOF&T`Ko7S&!UqS^(~%y^Y})P9ZE%~XKkNX?6q`)cm|CmF&x>E8FfG#UX3x!j zHTUa;wGdZgo9{$?C@w=bLYyA&QWqZ8;hk4q!OZr*x5|K=h4hI+PAzh?m(ziwn0}yO z{kC&_v_5rhe23T7qQNvTA4#X-g@+7L>aKZUY*6igz2nAa31|s-ZEO+059;uwcYIQ| zIjVLf*xZ}rYQ5OSw%Mol>)-iBq1Q_Kk9z%m!bImSx`JOy=gNBEHguN0$fgd=e;i9S z(zQz;z@~0{Ybeswy|3ELz{tHjcYLj|!NL1o3B2aw%MS%nOTK~!GX+T%BL!p#7lFVk_KH1+uCp;}wUg2;EA zy9#dFceh!-i(Yl)dGyqF=NEe}>u1oyKQC4vH1ePh-cXUDD}kPT)&zbX0me9Jb9DG|$LUbM1et??JlQs~-7Q zC^4r}K;IAeaI*T7<8O{)B#xd}K_pUfb~lffZdCrK@eNT+=Qp>*{%|wDUapYU+;KO}~{q|~OXMk>^zOkih`PW*zGGeHP)f~g|AU__EqcE!_Wln8A zK15yO8+2YF(wpV~gU`&{wXze+n}NBwZ_j?IET#4uUGph5I-f!$Y+Yl|kJ9LYcKKS$ zWwb7GqgdhzAFPjjU0uFJBZvQEEqvtpU-CJ1sD7!=;H9=xzhcMym9Kzm{r7EnEq}I< zFGLfvVL!hOh|f!7ahVHk0nMwZdrm)G_Vtwg1~ZkKoKO~` zRG}|J@jg^r&0PNOASCbSAa`;8ALQ2);gK8}N7N&>v$g=fCCXz8T! zYg0w7*yf)`zbXo8-mgHOP;)=s&xepo9M=~o*UTwHGlFVq#}x|VmHs&X9T;TmqWexA z5MsuFYS#|%^5PKc8vCXQU7RMLH#lhj^FF6U=ia_s?xJ0i27`7Z58m9@h*i~Mm4bbm zAetatDr=S>rg@WQr536q-M1cm+wtMOAzw1)>CiPDx6Y-Omc{q zF2MT`wJ(6I4k%5aF=@{U-q!$;pb3^j^qJ^piO@)H3U9~hHM~CWst;Ycp2ZJGZ(r6K zk?Xa4K|rm4!*y9;gDy0u+KHGpvZ45LbU`+47JRw6RPFuc+W~m;KS=*wV;-UQmtX0U zAE#IEzGmxk?1wKiun4u?59b7Qq={K=LYr;(OEMZCW;VE&~tjy%_-?`A3RtQ&D|I`l1bJ$E-H-rA#` z{?kOOHh)?6+j1@5J0eF*G}-FruBZ3!Cg8o~KR79ss%;#q_05hllUnTDY$e_~hMuHl5F*~5YjIc$D-uBH?eiBdfSgz~Ah6k}7Qa5e z+v1~-FE856sYTDW>5S)A@B2t;ruKt*hB!@5&Bh+m<@@j}$0cB#HKdn63bQWB?mmOZ z8r8C~?spk>?91*PJo!_;dW(>9I&;Zp98Ke@ugH*^%Y9pP{S(@O$+>AXM43OM@&*Vt zY4y7_qsqLaEn?b@2SClDyYH4z{ zwrpYUpS=fCNw$Rh>Qr2Kd$Dv@*ow5SLUTgRK9jXQ;LvUaCi+RG8A6dR*W+IdQhtZ$qe#`ivR4^I&%|UbwpgyamQBzmXd1qmro`CqcK&do$LIfaVMxFNtfNweIsYP)gBvGhkJ}Z38sKlxD1RYB0Wnn z>bNO_2*>P*6j%K^wF^ZUa5JJxC~Zx-nwo5_I+FW!85ZcT(^e)R(&Ur{(dO=F&5peU zH)_Z2jculC?V!Z^no=#ykcM@5X3n%yBCImNAt3j41@?6td57g}D zn=B~#`JgGwY?a%+TaH^CM~?$IMRen#eQ_%jogqY{?1mibzRr>`Og%0`pt(nk;I%br z?7{>CvRF?K$Ehn-OM=-btq{af)V`z$`tA2gto?y;k4Gs{zb-u=f7>_($}Am;k4bns zu4e4F0_Tg_u#)#7NV($?j?cC&bNEOCI#Tp87*PwiE5DSAstsV0*s1Fv<HU?UIp+jwIO8Zp6@m_c+FoW2yCNTal}5?qNmxlS^+Z;LyqXUB&`%3H!A){k zWti%leUEJyH@~f;*t8#qJr{6$u+3sd3RjE!K?n#Wq8H3{i98Jxb^Iy>(hy4&M0ocW z;REq5Yr&nJI~d#K7(LCx(Za%>$`G~vOATRaPedvTwQBkq+|-zvWeB35@?2*Q-Pp9) zfEv_2eOV-<#g5xpz1iFEGNi9*1{F;47w(O$iq&XHVr%)=iAry~T$qf4wISCaC0v)x z7%E6Q(&4obPa#SD;gB4Ra;>ht^0WMsocixFUO=kCavs7nLTmCLwukqZ9BAlvBJZwacoiDj!( zwKUKC3`AcF6mzXg^a zoHK)`8Y-NeuYl6;nsfxa%OQY@=mkJ-1IR+i`^^&}k&{9YL6Rndwl?**dxan~5?uA9 z5pZ454QU6<@Q-gq$fUsER3=m zWkA(itC5$((p>b(`5I6SIaf86OcoPn6VMrgs|m^JjIcN{=D-MX!>NqK{nsh(#>lX= zrxIJ9KpP-yK#*$_+Z;ikN_=YtUp(H1EJ#+qq5^8ObFGmUI~H@B2*Y0TO(hy^1&Hg%*lbB4l1V?94B z*HKedhSe?q9xH+puUCQFOnb(9kn)@?_(#&xnh%OZ8q7a}Ete;=9NL^|1B>)@?KlO_ zam8z`Cx*q|#gop*6vwCncXlpZ)#odHGuUVU-BZIC05cr<>Mr?PO^(kry{{ zr5^SaUf+uD9KD;JPG*NO--gyTUJ#M=M|PS-Zi|_EA~qGY)yZESA@#T;!&!D~^SXkg z5yH;7al&;HvYR9J3NwP^?f?XttUN6Q>yjt;GhEcrl%l-6zwNJ2O z+4sJIrXBm3;l|(mvy~?TWvB{c)=p@etb-0;Z9N}IpbJAYv0K_YAyoW1j6z`synsJ4 zd{F&?R}dYtryls^cU?f8A1+iDXao=#lzc$~qm~>@Aq<6Ki3Xmn`0bhO1;q zLzNL2vLHiwn&8qC>5(8eKx9bZV87is;sFC~1zXD#1-M^K3mAA+pF{`%N2^?pR6UAF zN1(7mOP;sJXMqj~{M}^f5_v+PJM}(ppGJwoRvty7;{lch?Y8V^$g8HFanPc;f2+VH zk~l+C*WL>kVUPSH1!F34Xaorv1wSJMqrY5$?106YW>Rx1DF656X{gPr%jcM=zNLy6 zYtUHBClF%#x*MUEhKJu&xk%3U=mUb|&fb%{Uv~x>1xKd5Mdvu#1V)i87b~sQ@kR}4 zr{B3c-$kWYi#&c*;9X*=r{ayJ1v%Ui!8?Yw9dt!w)2ihiOJjT}iOwAuFVkry+m?gp z!1B)Vhv3JQ9^KypF{tInpWSg>p(F3^5`rJn@5gLpo|}#J>$CWal+|66T^)YCFAhW8 z%hTGgVQ;w|A5)DVo0k~UX(C#+*wAqnLw&gXno~;y*Z(Y!KuHk6diMMOl|wkSp6|5L z{+st%;(+YvfdB(%bWQbG>CVZeP;NcW$K_i3!H6E7QrfqqH(#ix>o;D5A7IAGeHv>L za6}(5Wm>cGg&=n(vD$*E5qUX-k3#3(XF}BQegw=JN)r4q8HzwZ{z_<7#Q6lHkv4gC zHdTaOkyyrHj>g@dSYAk*^*_fVRo-(MQ$4H_m&a;+9|v-frMWRy3w%sda;Du(y5-JAPx4;gE#?X z2*%Fo4+$|Nx&JH+!RNiK=d&3=;!Q~JPeD7jjrEn;)cfmsC4ghx@4_(Ar~IAeBTorv z+S_y$1a$B_!TTO@#|530KCS;ROE~WKA#aG&9VzeezPhyT(WSgqr0a*7Qe`OE^U4ij za$ua`>p*o*wIP5i^<}t)sR|OYC>2^EEI!Lp9;D{YN1<|R(IqTE{C$zr7U?|?@^eSh zqM}l&Tl~Oa1ejAtkh*zISKgX{3Xcr<>q0-JiPT&)(*UnSW+6Q6aA=KYx!&@N-IUvs zB5SynLJV)y-zF$+DZrdX!IefF(C5-n9^D%>XZs`FVrDGI%hic{yMU}LZL=ba3k5-f zs|(GRHX2H)dlU*U)m+NVRshhc^M?>_kq)bAe8vk>wXH zZtCyt$L{-WXFZ^>6MK1IH5emWq@*0V0b%RABU%cH^mB?hlC+pE)kTskE5uGJTLH++K!T7oiSRcmMXfek+2X3$Y?OjSW| zBxQGbnn0!TQv|z;=+2b;scb^&N^M}cG088t7-`T_eJcm#cd*+YXwGszLy4c{o#c#D z*Zm@f!MktGZuT_eaZ0|8YNOxgJ7{xf8U8)$K?jhfZob81qjUclhasq2zsLu$-nH|V zLh9du77Zv4RsNtvL-yXc@P}}>OptxJ|4D<3x)s9>UK-|}GNs6|{5?a6hASR|*hD1W z_M!Tbla$cx^Ez3AG<^Ii{%ostyxdD;hsQV_H2nBEvI|DCuH3O@M{u~uo*z&`z34OF z2?_l70j#ZegMd5++ZkX3P`TE22n<)95z3%CdgtoW4EPcMvE*9;42JS5y0PZ5A|F~R zZRaBz`ttjlP#mO7#q8R*-@|wv!~VdeY^4vu52i0FE8SH4%7Dp=|29_!(42wg`f{5( z3*Ktvc`-Blq;(G71@pC8ZC=J1w{#lrAuUMdZ3u<5oXFci1ld|#OiVI@RP0Tbuw1@h zn_|9!Q{Bo%TF19QSxQ|s7UL$q6MbOwNqtXaIFA0$STUo1NfoeTuxuhgnDWLm>01xXbHYvPX$jsAXIe36<4gx6dAy|y+VR8edrmv8)b(n4fG&A@ zjJ0;Pe_|=p)8@UuwAiQ=VC5XMA-D3gp2*#yPfj%j`#Aon1Bvhq1h-K7Z9cU#Wpv#ZgU+1W)Adg?n?6wJ-Yz@wu{cT0q3@2Z4#)DOGIn|R{CDd-1K z$Kytrqrc>AetR8JaRi$fH=6VXx)-XbAJ351ZMpHCa&k|mWAEP zzVn9x(dsUV><>;Wrt5Duz~Z0-KU!j-v`_)BS`y8B%3xJ>w_1Up?b9pp#gu~?MJ9Ut z%zQqYK)vl}0jP;`WBUn_mgIj61-Ux+bBeJA*Ix*KNV$Q335BUdXn=F8-h%=kX!gEbY)dHCNrgNu$$=r&fTmYRMP;X{PQ@ktgb1x zGKFi-Z4h#r5=VC=&B{zK=RF$S>m@;xhXEr zrS#1=0W0ey%bNS;BR<>##lGc&Swouq$sQwpcpnO3V@Fs6yy!r|TA$covEbdI3B0=j zl@2xKOB=(C?_<#c6|Nm0!H+NBL?YE|mcT3iZdXG0bBKI4&@C2m5FS_B4>7puhJhz= za~oI6)a@#dW?4$<-(x%Bi}QalJ0Y^ za)rtYD7Dj(FEpvHz@?LTcfntsSd~H$k?_faE1fug;AIMkvq>yB*t=|GF-OuqgFtcg zzXv)Dra1DkPk+9b??c*G~CVYS@9@&tvKI?5^U1xiQCMOI_Q zUA+uB7|A(?J?#8Fw(WYI)rJ6_(Ei7=fSOYe_{{^C)uC}XKsLrk8Ym4EUT~Ju^^VhE z3acyCfd0L67eUnZAEV&KnpAzEF&6ychB^@DIT<|utSw<>{%eM{b_VDp?HS%zl^(vR zRl4cGO+z6@s~pn6XwX*`yff*rX~Q5*W=t6k<_o%i#m1IgK4alPpeRj4u2$Q%P8$O= zg7Kn1D&(}HTquTSKLZ7AGNNO=5wTQmaiWn}A2U0o6a+Ky6W*7Aihv$0yZ&V!tL9OU zW)0c(h%-1f5Vpoud-}+7;D2Kb` zU~kZLIN>u3Ho5#TvO%XbhIF9WxAQqDRjHO78r~kV_^H3v0qlBY(66|$LuiR)uqB^E zOiBYEDIpB9+P-6mzWX2D%iz2`D;&3~a@+Ut5e4g4IbH6GsbA=SH}O zDSA7(`jVBZzYIf70{@<4t(zrf+!IDBJ&?jl;Ur63E!RFVcC4O?uP9&G6Dbf7P*BRf zqj|FlMOQk#U~^Qd$}zxLPA;KSj*s_NBNpiEmdbKIRI9Y=BYy&Kf7{JA(Z=sU6P&d**2a zmc18oTz%W=YFtgGQ|L2W@^-jiet8bc6`9Ky9bU7AsFiZ=b{0F0G;kH=&?;4WKtv?} z_ZSP3{N!zxcdPYS7SoWAu?S22si4rgIkYI7auE*_I~NP?j>P`8P*{_7$15eGUXap= zH%YK-QPKt92#S3LzlwNQ=jw>-kf0wyee+vG*hc+bJ$7R2B3MUI(+8Z#NVN&?Lr$;v z?k*3~{?#rRWVJTs@~(_R;_4&>k@KM1$1;f04^IMPOrI)2Jb6F=MG5D7qlElIG)udW z_0pRUzv)eMvU*P;e z_PUyFFOMT-y(&J*Ia(dEJy2l4Mg87VWr!AfHYj6M%BW-k32j*DgfG0C5-a1qQw%cm zU&`}9?btYycf-dYuAO3P%UMz!b-5cw__9&J5Ty}uI%Hs^=xb1m|KL(w*rAz($8bq` zJ}koMOHjjmUX28YYxoykK17YC7W9P3zBc(rs&BxR7gFx8w#po;7YfS#G~xW=A}u}f zGb>kJx_=JHWcBW;9zC7eTjX^ZL!hn4LEYg*X2YEEw#1yGNyD(WA4C}->VI1XL9*!X zj@S6KYH4sm3NO{B(fDSTeQ6pzpRwteBdRMQSn5<`QR&F??FKV7-QS0mF#fLs`mxRi z6#%GXi3S@jef5D8La|TV6F#-HtkxmqAxUSZiW+@gwbaW!hKbyp-Lo||I2G2-Oys2+ z^vob%8Tg}Yc(@E%L(aUL=QL7VT9<}3!A5F_s@*0{)Sz}W4~@lt_1|85fG0WnsJbTF zKrLz(zS4xyKWE(n2I8%s=k3hXhSbzL$0Jjdayk>akv)R3C;9C$LvE0FGK)9ju!+C#L;%^8NHe zeVZXjH(zKDdGdg+#3H%}^kh&^+@{S8>}=~Vf~_XeXYj6uREm7bI!tE`V?j!;SMl3A zpgy|=YaMbozbH;$el{e{M!w3!+U>11A=Rdq(jFUGlvMgtd>Qo$-g*PNs{cryh3sXa<7m9DYgX4B!2C6a@oHC)SOX(fjGX%3<*6msg2!nuOC z7J2eHv;R*04<*WUOH#`P66K74<4^XDb|#PXMWuAec^x0F24F)|afqDP7NNSgJ_@O;(!9Vb*48Do?>nsLkxE$$f?Da* zMJKOoBCTk8tBnjJp}jpByD!?l_*&y@qUPRd^i5HicDVUH`>^AcUF<`t_<9cBas!w4 zWwpSXYpwEabl|GFOm8E)))q6JFw1K((gR<0#$%P&JRZOP(XTWUZ&M*U1@yAh1A@4; zCJo3F&zX)dPCn>yQ?8-W>7}Nt8fSpos*Uhu)7YTlo*0dM>lo`-b4Ob4fJm74=6ab| z%^3>sz*6Ck_hQu$w#I@Z9V(6mOzv1(!I3WiLU3~HO}syaMmh)bvuXUa=yanWzzRIZ z%4>n6BLf{yghDM@@C_{M$Cn~O`r9v^F6tQBNok{EoqbA11YBDbemM59obuVzEq26F zFO@5Fbn>rDd0R4_w{yvY5ONdG8Ww*3y5-ZGr>QQatEGd#mTUTd{_%G z(or6ty7c(G?-errZ2A^lw(WthV7)$Xth@ThQ2J%rg?VOOed

117KQ*M>nRHgI$eUpKv7|sk2B%Jt>9a^*DPlQiDtJLeqL~{ zA9SD(OfA-ujOOs-5%&Q>98Zt+uL;*d=!M{2L~r-&4^#*u9TW5}IOi%1QFudJj#Lz? z#Vs4{3S2R8!w@6>?ga>`j&fv{lHvItxIOm{!==R|3ce81p!5fW5yan~r@e@TG+vm5 z#wslDzvOwYjp$cGj{6T%CG5b%*8oCH<03ywqii0GfmU0_hO>V~!KD;&JK%_;*dKM{dS)`OAkX&GaR|n{_ohQtyn%O#S?+ z@(`6furiZ*eVBU0Rr)>yR_36&IIGl4j`4+XvRDww(b9cAgGzWO{>ulY1;0GP;B<$~ zF5#`!s9kvs!{Frq;UMEsd>AHCq>c+LOs+3@1|5mJ-&ks;%+0QHx)ETf!X9Yr{zfJH5F)HW47CV%YU(S<-a z6@PdXjbZ53{XsW#cexvsS;qY)M8OlnpCv99oM?iMzyEF{ z!GV2gY=t1#L<2@cAVfcn2vQz8vDXtw7gU^xtP7Jr_@96bwvrGd*dw|HgAVWstiy89 z$eEsmRqS6}ppuv?6=HFm~M;i?_!r&2@C}}5r zN!~#lq#VAstZw6Zb~KZbc>L#i#f44z;^)n9p(Sws=z|6>r=W9IJzqEExx_iv68c>hHa zl}FM9M6gKKpc_l&`=VnI@fZ@w_~=oX82Sc^c^^39sL)vSw4}+#V$6h*9&sguDBqW& z5kBQ{{A67_F=L>+Y>2RoY%iotNG4q}S>ah+F7YGY)fqY>@?TeuFZ6Y~X(G%xc?XxN z4#P_jqaX4*&hQ0attp+_1U<6szRAbr!0SBjl0kMX3CFZxIz*Vv98<`su_K0w$WOsa z)Ljr6=m2($F@##pi&b$dd%0H&V5=CjQ+*RIh{+$mz#_2T%wmy}WOJ-1BHNMNKU9X7 zCw5i2=vs_V4I1TzkqwrhFj8N^hw;XnNC~^9@X}0uALOE!PZASg;oK+a0JFF?8+^=6 z{<8r}>{?u@3e&+eK*Gl~m-{xs@~IdA$iSKB#gv9F0LDpV#_%7!IjGVzKPchR2J=KZ zd2$!l=`HTkxnrC$Iz0o~vFkd~EYd_rbU(p;f(k)P&DWfMDxwme(Yjx$Gbp8pEgkw* zbTy^(-x8BG=_Rwen7$bSGcI|{z?^jdS3u>FLt=Ot3OY_h&V0HjGny*_(}U|LR5#H)G3Ax)cvHTn0$~IqW!)S%?;@MD;RQl(m^#!0-x2Q z#}A4%=ODe^aWJYFK@x|_&vYxa(V1Sghk3TDn_#4k>nuj9+i$@+uYU!~${X7(VLEi8 zCCz#b5D@cMzbv|*q6=GdD6hPmFHti3syaaH#c`F=M`EZJWmg5ja?m-)J&h%1b}oss zxs}gX+R(4@5W2K8T@#-W6IpSs*+CCDkzdB5Of=*z<>cCjILnOZ+ypefVDihGEm^uY zUo5Ug?~PD{2(dl10{K1<8d^T|x!uDuRa>FT!s|t>Rpnue@;Gj2E&5KdRK=G9(K0ey zz?(*%`I;*y!;~4l%VVfCdCOv>4={TGy2MRpx~x{AnU3R@%!^+-ZFE~RG2RAMpq?Og zH7$%#!do!828hNy+UO`puQj#5wJHk6 z_=#e&78xx@=fGYbhm}MAT%`8U^~XhH4Z0`fMKG9YDvPPoNc7BOlBJvAZ-71+mB@!+ zLO(*!3p#y@Xnu;udfOdH94$5BHSaGz)#0dOE5Y`>{M?8BUg3 zc}XDH+NG@EgEWu03d&;Ye_13QnWOo8!4&g(vXv=jd*|Ou1_u4BcBsc6mhes3QExTw zPPZr_M6poTKTriAa*63pu#NRyq)IaK+(sb-(y;%A*xiUt8ND*%Dqnyh;Xz3mW4@J* zyW4p1sUkrY6m~bD^4~a}a^NMX7vsT}sstqm3^6NvwSHj^?ER_tDxrLi{NpuK`5Upc z6U%gLj&Ln5=~@W%H6e31VXegCMP{1VQwZ9WlBaSU&})}13QhlScbL2-I$F`(GVG0V zaR+QLa-|G98H<(vxZaS)fi*2e6VQk#jE*W04R5(VG6O zA*(0T#B_gZgErAKx!2bqO5FCGAVCKIegtp|8Cqneu5#!~dHYW$Klns9mtz(?e1iD* z=w@X`nz>czqiz9f5%hf+AtHC+ceUiWQ%Cn8C6&*Vg;jQ_(t@Qt@ayPXrlSK_sW5!S z+u`dcmjk6@Z6gMn(8C8xGH}T@0g_TCpz2({srG~Sf+yk-c`w03HY|paD1%PpffG~j z+7U54JWeRhMV#v$!B>;HzT3%v+u9X^^o$ZL!jKr>PL~8}lDFt0<6Ch|qs!DRR)Y4V{pt zQIDW@t8Q@8)TN~*I-U=TcR=6s-%H|{vx9K|-rc}4+eCgr%rv9Q1?U?RH3MV;sDcgE z<-3F^pu_H&m;ix>4$LvfP1?rHcD%a+9GYMkcqr$xo8{oV!7p)&`{!*q2;&sQYO!Hnd;u zL`S_`9@CmWvm!)J7@{5N`4_5S^NcIYP}e$akKt}X#4}Ew$CC5+zKWg1_`^G#%P%#c zCB{Mb7IPD+z9zD7B~!BnQTZGkf_%29CSdfKX6|p zb=?c$@B*r?1+r1_CYiC=Uk(@P%XNi>K77FOy^$Uz0&C7ZvmXj6=%~hj@HLZ=3wU7S z@Q1GnZVZYqSXfG5tXr0(>#pHZJQmTFPtTQ$>85nW=bU@@+7}i=muwVVkX(6zQ=*ZV z;Xuk=O*-6{#aW8Psu;>6K0|S5>gg$3HT2it0P)lXDu8)e<_yy(zTq6h50;tm)OTl8 z>T#I2%tf1T6Lbcah;jU4ai?RPx}beMm=9!og^v!IAtaFK-`bu-@THaGoeuiPCLwKR zw!d~El$XsHmA1?;jK)$$8Juk<~bgVVjY};$)Hf&fE zc?SE@_Hu~jx_7X}rFuN@`dGA#6{cx^8>|3pz73WG2~C9^v~?Bl5>2XWEou7dJ}$~1 z1uDSV(4a6tLz^KT@2EM8zZ~soN`f!FF7F{g-k)6*rbAMd2qirC(RV( zS|AVkMF`Yk#VfW5VFO$E-*8OVEypSFd1|iRoK}jmD5DT7$zf~{PKhV^a8YkTsm&gA z*e*y-St~T&V(e^?himSJzTk1n1>P1s6@B>jU$`Kx{T;rSfAyMV1P51p@syTBu(5wU z4AXYlV!r6VTx5>{rCJ|%9ocZ6m!rtzPualPP!z zjpxo+`?XewMpw8uUmNbBG4}k}s#SVuT%Uc~fmiQMeW$;W%xCZY@;G-^SG$ul0SrtO zKm;D%dPiWjHNJhD4>qx}ZJEu2u{PVVY6HH?6yAqWy7cAV2tWZVyW+SmDke?3-;h-~SSw54E=e-OZwM~dMR^c9OQI6~UP!RkW}fdp=Jf)*$~JJ~*bH3@ znH`#L3n|j&BJBt)^PES5%n(dk0W-xIs!Eaf#Y7{795X@|vHn?q3NA#ezvcewo~w4j zU6;LJSK;tPveX3RRl<)iRIdR)-hfs7rf9>RHFDSVdOW~9`wLp55iNsqR3#4PI`<>w zLwo7VDnFXWq! zWfHyELImDz?l?$Ua!-XqJuL--Ahe9aAry*xW{A<&pbo5vQu%+PtraB`ggBxW>0Xry zcJ3uj1&9VkkA>+!{Sjx}b#;I$%IM24RHBk~@B4N=y~Oj&N}Ek>1!iC$bVmbdjhy(h z9^OdMeMPVu*!_dwY7+xB(kRuJyuje~Nj7cBfkS3U+Azjhp>;T^Z}@gNSc*;_pK~7_ zXDESO-0 z`CqC;qGkOG-XO;6c$ZtL)+0j&PkZ*DVMn`O zTPM8|i}d;lI+#S>6ZOa%X2nb{jS9T2(iuP6rP0vqd?zEmP(_*~4T)m9V0k4J;J&)$ zZVZ_WQ`couK_Bbp+~)8~+sNr0!x4S$Ejzx?OcabYHEt`~>W0xOb(kv2uAM)Ni)M@7 zwuhKcd!l{tmU{oWt!*$al`=0q(?W|>m10Kvh2d7N5~c^L(ju% zULBL$?u12_yj$A@=7L2(2)YIUU%UcIeX!*#NKV1Lr6$Hso$z=Qtlz;)_5kZu^|?L5 z=FgZRIC5EfEEGo_c4^9LjJ~pRR7sYl8fx%hgd7kuCbnaPBWPpSCLS=k*#2GLt9&eW z=c>ua^mjg1Nz9L|f}cJ30sJS85Y}sNml^ASpd`RXeDo^Lp_F%i455(C|v zb=He`Wv^TZSQUuMJ4f(r{w>uZPp*3$co*N`v*X0iX3KTVze9y+yZoV;XvnlH*W%(s z50rW%?3q8Z_+`ic6wI;a6kD~syNC6<#j#P5AAiF4y(*4E#S!VaSX`IB&Z+Evf5;mj zB?@@{U4CmmytYF+F;SatT*tW%B>y;$l{1d{6sD8sc!3wId0n(T&6MtkvCSsF;sJfn z&1Pzae*Yt`qD;zQ{gL2!F^k8FEdmZ&S%v2y0XNTEw?92jrLY~=T&Rd{P5&xSuyvJ( z_+}$5`vg`+gBf2#01w+wV|{Mecp9$mR*O1Hwu-vW;JPTscO>^$9?D6#;++6s=m*em z>N97Wns-!1sN*wHSCi_CiU>{7$7HfbsY*vPCj}Y!t_XrVdYV2c2EYV=SBTYR1-1H> zIM@&M{wR^@8y*zEvEuLdVv1Y`c4<>XG|JJ+f3%sGH1djmAXzZ88S$1^F#8=(LD1Re zisKNAZ@R&ek=r~ zdv}amxY;VNo+Y*|grhgMjVRmLrS<>gI`>RH!QDcWxijsAmYG?T=M2~g#(etOsT>{q z^Jo`stcgZ>{)5l70kux5IiSP&93(9lAJFP*APYP5#c~&`A{=Nqv#JAb=)vW!c%7%F z&{vs{&vRb*=*4FIZN&ED`0cS#uYf)ymJ6UDTQaMTJ>5b1Stt_(ePGN?+iy<3I4%egp?t&Kq9nX(A4f*F0bVvB;ryO~; z@bITt4&$@eD|Kv8V!A5CdgYH2bkDJls+RUrHYLx81(N#dC4R$SR0fUAw|aFs#%b!m zSe%LC`J7qMPEGqnUiOpH&OThI@8i^$ZEi;U{f zQ=WDrTy`0Y~^!SPjUm6&f8$b1@3v zyyOg)2l2eEf}54+pnvX!rX>dtsH1e@w<<^z3Bh?4*6{Wa*?h;Lgy4DhHMy7kq*76(nN_Tr}gcB&HSfg3fY5wd|X zP@6_-h(Lga3!YTLt^Yub<C2(g~Oh<-I`b?DGMx>{!;0OEu)VftN9mKPpl2;$} zfr4R!#YMYJ3c^yFe_m~*pYP)~q4ebGLX6BPiyQX97*&K0d4ugzI`wqLTv5@`;T?obU1q$sm*2VP6B8ycyt^a{F6P;S zgvjZNpa7|twvEBUSB`rjI*+b$k?i-1Xhjd83JaJlXLIOF%vR{2FE+zOdU_V7Sm?_q zFd&(E+_jVM6k-$gTzg(f)MueulY|6FIkfeKP)*k0!6M$Vb9$m)Il@Yh=3-+>%spF) zdnC&Ywie{J=++X-Z7{8)5E>ECfqJxe-yi{`#>#gudE1p>41vOGg0+rD{!Z+Rw2PxV z?n^ zxj2Bdco`OtynmWthItsQ2?eE?hgaIrhT{;Till0&DZx@3Kf}S2JyLF?P*bUHw9jg< zo5>?bR)y%+4o*gME1e9hGdgxcdy@lA%< zr+8&5*EFQp)A?IDvJUCV5Xd_!$ui_vGgl4DHRuXdZP{;V{rPgZ`Sv_wrFD#;=@7dhNW)#!``=u^C7$MU@)? z(XJ*xCjYjW0(bXcylR_-4FMwp$C0OLZW!_SGxrdroi)o_3R3fF6@I$;7<>SdXoe_0 zoo!*%WfMyKGx@+lFS0{RL|-c~VEaumUXt!#3mvhwLI(ojB1U_>USX#0A1fg~H$M+T zM9e+CM(C~=v4-kb<3#i^eT9Qg>ZfLObE7Ifz0tsng}u!YEM_uEaNJGDPk6T+V#|Y~ zlZVzVDy7X^l=i&^#sES(x?3-hetMpEwItdKysczFhzK>j_>TgB*OQ-n|rs>?M1 z`awGHeKi1-dZ7hSi}kp=&hD$KLA4qhXTYvC9oUFAluxxN@{ zKm!SpwWOJqNJN8WbX8t3PE#AI5No)Mtfzch)Qw}xZ%s@xQ;IJjY}jR1Fa|=IOBimY z>!(n#%ilGVbcSQc`aD9EVd zH@N1IsDZ4dH7_C?O+o#Dameq=#OzKcD?Q3HsO4Q1%!2WxHa4fk zZ4(40k;k=W`X)4mt2d&g^1lc)Mq&_Eq7_SM?r#}@0gL56iLz2_H!;?jnvIqWiz&G(J(Xt(ZXIIsQ$$+> znl@KRRQgpY?gS)7^};x{9#uPNWLaJ*c~%{!Uo7ON)}UP8p+3@<&+0Q0MpPWk;qS(+ zcZw7$9Sph{h^=(LitQd2(e-n&jV!V!)lBCV$jtgdC+$9Xm3%Jrq;vi z@N_Se&^033lo@Ab(cUZkXV%tlcdimBg9y0PYZ|#*>YIj@(HM(;sb})rK4J%0b@)E29xl}|Di_G1M zo0h)A=HgfL4tMDaC!wWcp^uInS02(3n%4xQ9)Gq_qPnUw9VIUGOkh&IUr+^Yyj6(- zmA|%N29Jr!nXo5ehDmRV#ZDSQ$G)aic@Oz{QY7koP%_vMm`Q$ABX!*f=ZQ4rHn?$D z31RX;PEQvZc)X&NHQPEmCjxH86LJO8ch3ejbV1@>l`Kj&9yD z9Df>sV4^5GjWhDDsVqTVA0u69jo^{#WbVBfr&yoSvojqWb*TIEXmaO&sY%3b=os5Qt>~&9p30u zsW9U^6*$VcrYD4LW;4Dhwizm2On2cr{8;795R9Kl^^UxAAgSQZzN33G+@g{CKB+2Y zt^y|q_D4Sc{&9uQQW@i)>eK@f=u76BXlkjE&fZv=lVIeI9yayBB^ERFwG<yL0asu zAoScCwL&jg&~XOYN{5viO)wuqPSJ?u+`}S5kG&7|mbg`2j!yn6&6@sY_dq#9}hyo@8LDZ^4DTu1PVwXHsnE; z2aX9gXrGz547gYeZqCU+-sd)_qc`$%1e6u4;RMg%)D2`^+-_u2+gZGysFWkhxpY+- zo-DjvNNXv%XMpK=?-NsmlHUyaxm316Pm-Z?v16bwMua9#h&BU_K2apoh#ihcbV!+x zW|tLVMZGT)-0>^06s3nk4AN~hgw|713@?L#x-Bw}Y!QuZC^;u)mcka@VKUMcdz}tS zri-biH1ZASi+{bF1xSX0LO72_rn-Z8g4c!%3@OT8|Fgpa`01yz2>o`qNa~=Q1tfd! zm!;lf#9hi!hahQ0vWsPEH-pt;-Pz6y30l*z&`K{|DZxH)cvTq|r`@8bo6*~307n)cFe9y)9P;-NDcBkr!PxBv0gwE2sB8-hWfy} zMkobtw4On#OJ$en$)(CsC%Q`1g>La2$BQEW?jctU3Zz<$^n}UF@~D2B7#qtH|Bm7@ zi-c{IL`=O6EE3Zh_?-}=j8xJyZx<$*eElfKQri1-4tCkvUvW^4(r%AEOBICfSA!7O$*cWI zKd(im?bgGJ->5B&As1YPT|C6qU1<|%oGM`b0JNry6Z3x=FaAN?EU*rOkKoZ3>cE4S z%)tlpUoiaSc_sdKfnI=m8ehr5l`VJJ-MniF?01s6Vh=O9mAc4A&8M8D zsEfzJ=Jz27=@Fu<5&i965L@{mF}aM9p0}`zl30DdnhkxStjQ(`s*&tk%40U^K>)Te zNpsl*W%@xWhAFbML?~{h@ti(4t2@#*6;D-~(YbtoNrw3zrg^V}%s=hQ@#DQ01xFp4 z^o!DAX70Si8)dGE5_Wj=(5BEm(aUELz|CHbt;hlG_Wi$vbOV;!USCLo%Y5D)p%^xV z^s=beP|sTyKmC5b(@KB(o-cQ0OOV4=<$=4)9Q6Ef%pSSjz>ZDiza6S9^4FbC&mSHJ;oW zL~+yn4+VDv_#Y!pAm*q&hi6?$WEA{G^NY}ru7O2_?05Q@JT4EP{Wr1#^0XGuIQ*Sp z8eM!gVe$3d&Pk7@x95AYtsJ{1BydNDHJp;pZ3^N!QX@-BS;V-AdvgDEQoHGgHwwdK zkQl8G0Y6kF)7T8r*O8_k@iH_rLQqyQ8Qgl9<;*kXxZP?E#ZoQ3H4k9{`C=NT_VRzY zAil9%ZKa=HGsVHSdB__=6;2`4%!8hyQiG2DU5G*$x~%5qtwh=aTUOp_$ev_RS57v0 zsIYIPOiy-0_^xDjp`QF}kUG=Tjrr|AXu{E3e;)%Nj%+r_gQ&HAVVXwr;FIh#SD;39 zWL}!oD$LT%%Rx8%!0({Qh~^npk|}-9a4^1fp7%Z(HQ(-G(mBMUG^FIn_#7l#4n4`G zfhc}4+Z@hml|oS(WvxlwRMZ2MYtTpNsRF)qrvIRhkdPs@8!c#H;)J(4W!m|HI!1rH zj+cJxix9(EV~NuTZ@>y_W3#|QKjTc&{cDOMblKl_iIH1J#4xJOL^2i%DpgiWU-`i4 zqo2>MvN1=a?%Xig+y$~qPE~~HwrQ3u{pm8smfSq8mZ5tTmRWh~b20uoqwAbSe1m+qp1hH?_NpQy3WN)tC=ZRy@MSs{GY zu)9cqlENh2>otX$G@%!4EKjqol@S&hKQYK?vW4h6$&~ruU`EgTVGZ+YkZ0&n$(f-4 zOi(45^w-hHg4uhkJ;~(6e07%YKE>C*vPr}kVUuw_U+o|k#xH(k^ls5yxv{66nBI z7Cl*Dh%e>!OmYnjts_V?dNqQ=%lH+@0q1(|!d-AZ|D>CN;F%r)4Q> z%ZhPEo4yUR{E7cz$6`N125+B6YGDwbF<`93sykg&<)hA%CD1J&@g_W89EYf1mt>sLue@7*cl_dKMz9Rc|uV!jXFf5mJovsNt*;%0-i9?iKeog z4_&qwF`mKjVBa|)#*wY=DrWMi{AnIDkWw0u#RyC=zd_2U@*5_kKL&D5XYR0_M|K+gxd_*VVbL`bL;2L&l1Bg|lCv0ujr&zT>Y0S~ z{mWU=2DNm;5}_~gLc9iV6iT?$%qn`gj9Vh3{t#1Y+Nuy=$rBAqKKWA2G^M&;ykC9j zrUiPg5)y?4ihZ60cnC?!7xlTAD(;m^7BPuP;1^gl{s9;{zmR7mkK1j9|Av}L-L`lz zjcWjkmM2;~l;mL+sjj>tMP?cF1L(Es>NL&WqAn)a4QYYK5|$WIL{Qk11b&0Nz%j~k zjI!%foIJH#aOG*pwv`3th}r&UVRYtQXEB|gfK0Iu%~q8W7-;bLHE+TjP+M24t&DX2 zNEM@=bCzP7d|)uvBX@a&P(XPVk*03poRO)bt`4;w1$Lf9#K>MK-@%2TJ>4k!deYMI z7(o3;un!Xj7Kw(Z<1}X!sLJp`$WCf^1+1P$tzBfa(*~?V74EQ?B|w!DNFW(*kY&}&4IJ-FHnDh z4LI=)4C0GI7+Q4Z%t{?2SDzBHFm#vIt#HsOYQbFtTt!njq*bn7huZ*=$NlNjVW2CB z&8eqk^Wzp^Jq*U?x)AP=JZ5AWI)Gc@%*odF@KmJ_ zMV|w1I*OIhk!jR=A&#o<^GGSN{fM(#n<2e(trGrU2K@~+EHOb4daS5g6rU1M4O97RO>OKc9XZm$eIduep6N40Yn!8y3s*PQrUq-I z-{)=A78d|8Rre>JP*A>|f^8Q0$#Tf;+Q$Z*ysw3jLQH6A4Fe`T-vbaSQ8cc-Q1+oA)u8ovE9BVEa6%@5RWPGsSj- zVJYCjBzap`JEpz=1DL+4&>p!e&QVcWWeEz`XX%V$x4tm8ASt6*FnEeg}$-!Wm0=wGQYQ`Q+n)x93PMYLHJ zu{GamUKpkKm>9-ZW5e1mn8po1{T;y!tvb#ie+=djoI3(qGvr#QR$y&{P{@Eh)o`5#lUqhb#;0Xw! zJUnlm)@lRUP}0KQPHY_k^IthP1UnZ0H-jsd?xhHzH-^qCsgzRf~A^K{{-*QR6pa*w6gCavq!D z1%KJ0>?VqA3=4;39A!PYij#YsOAZ#yEm_(RNEYJB%YRm9&{Yyf7}+xsCaNsu_sJ;* ziI>Cf2HyBh%)()tW*`weWUB_j8etLZ|s%v zA_{zGKh0~Cr1fJ3E2j02pG&a1Ge06;LB<=>z3HAm5UP|_ZP~@`Qvs$r`70N#)C~1q@3dx2R-IM_L?>+6U->!$^L@y zfU@Wheso(=*A0&SWRxo_27^0FzcUMQKq<8?5Y9jiwDlD8431$0Qr~y0%rgDBXW(17 zegmo!aNu@t!;mF6iz}l{?%1y~4(v2%Zn_VaN)7Ea#S{Q`b~27t_UIt;e=kv&l7ohj z4h-|jzI4#L&M0XjhMj%=&C_K)fAS}+3yIY813(0 zgb$P{L1u1W7r*o$4 z(8s(TXsiW{;BgO)-7&7o)4W%B><0|D<9Q*3<}q{9yo9>;Gpaa?|1%%wb-X3wp%w9_ zQ=$WwBS;q;xD@BL9pMce$jm($7ujKUA_Bdbx1t(*fRl#LoQ1$D5$f@%(2%|AV!D5X zn9e2n2BiDkbIM^!9B;~XD|r+4%(e4He(L#NOyt3AfD&_XeB#i*0h(jXqjQu*nC-z9 zTyo^B1{@qrRz-NyBLDcm9J1NXmBO#P_Gt#%4OuHjR-nl7H=bQpP77Sh6=RS$cndEc zWS5y|Py@S_d5k@9NTlDBTtOGOouHvrNCE5r;2hJ({Tkv#ZM{2*OHILNDeTM~vIAd|& z|H`v~*&Xvn!8kX^6lU=r7deznU#{`$S;ldRcf|2L@jfr$^4*<*QS%IMBQRuC9!3&c7R^I{}I+APeHX760O;V zYsX3wZ1L;0OfpNmj^OgyZ=00sS+DuyOR}28W%cgvD2u#10>iN#1ndYjhJ!T_44-sT zjLM9@@~aSOz!v|}4MW!vDSQN1;*}*K-T~V`o%u_6$iUV7hjN&-)5PdZ_8_~jGQrvh z=3&3@I0R@7)}v^l9i&l@ID>ii>;(?!O!Zq?se{Q|2Or5B+Tt~}mdD3EvzL0!xJ(6J zZR=mc;<6su=ykENwH-n5Wk~TBbvI8 z;{TU|Q=q1$?}lSdkVQSp6{OlnsGvOM8ZbIYrXGCyZd33>*|<&!3)Gkvi+ciB%8Q2N zsc071kh#9NE_m{2bhl`p0IGs_OX4g&XazzD&sRJS?j{VOX4F&2yDm$Ab4}lGTOVkv z0&i1OoZZ?JHYGvp8OA4n=l3vWnQv-$J8V(oEzDiP)=tRCIQ(nzN`vW6=Ch==O+{<(4^n^f~nJMMVe`N#77c5_%Z#svcqXR;>u;ivnx z-(rkoH9mrooguTKA0lHrK;cS%)e!Uur~V=;=x%mO#!8V_>@tBTq3n1iVUZi>&8{`KW~uy>m_VcnwETz<;5IWrguN|>YtYDKF$D*G7<9ap z0LB;jUe3O0{DgB(Dsy-vViFd8aCuLNQf=Dd6R}uN+qgvd5ynN2_bt~Y?n6CN!_B+Q z^Y$06aqpwt9kVvC8+A{` zRzx!W5cMXP4dx`dWXNb~zo=-&DaTj&;5~&zI_YIGT!%(aBi2Vo;DjjCOV*=1W}^iJ z{jHYht4&=MWmy{kRPCpizQ$HFatSw(G{55to-!eZ_^8}T4VIWC_&_?FmnD695t?$E zw<>fAmKcrd`A^rv?RPybV#y>8@@^`fv?Ry`L-ajF5glKWKSlR;CVLPC$fNU%5m)ei zjQG#8yG|X=ZN?)u*F2b`Gq0;I<|#AwJ~F;Iv28-+wN7q_C!f_Zs0htr8|zKsPVFL;9!BuKeE%iMIq zcE0|}HQw~##b(FXjaRGXEwgrqt z2LB#0t-(4-^t2@SlV)k?6yS>1>yK0cIL#Ok<1G9}A$dl!3IFDEF(Gpdz-LC6 zzz~vwIj=&6`j*kySXYrzPhgvVzPU$vCVQ<2Ozpm7`(`j`dBb zVd;%vmZh#PDhaS~QL@CtjMX{ku;-iYB_Zbc=8FfmaN}Zrzepj#yXp>O!uXV^hf3(7hB?>| zzqL&-#6x{67K16cOQDWB9u^`{)EROZ5eiX$oR4eBYm3q}^G6Y6(_Z02o!DO{NdIRQ zR{HECI8KXNm!;|N-JMD5?TK-EW*4lqZr5?yRkI5fy4i+_h!k=zk;XQxT!BFM8((-! zKv6EK7PXk^N6kgKHr@QQ+D(sMfQESRj76fMG$eKTm~xrPpZf}BI%Eot?cG6;8!-7G z>YZ!Shia8kBTuP0sN6#@tSu_0k;A`BXep(Rr!jx_vOi zn%(Y%i8bmh7>+EVunu~!$*d!WP1?Vfksgv|x4-DRo zKSeW`>UJPleJCHdl9~s(06-{JkLvc~LwEb46rDcVsizG*Jkad$K$*$C)FB#ut;|SE zuaw29RIDzgq5e*ZB!5SII#!sZiDxj)k=s}p*2T#9uQ&ydEMUWsycV*Qk|hR5OB(pG z$VE@B!(h%=QI~4 z9dM&vt_fV*CxrpJZxa{Q4j+rzRy6emPx_DDhauk4%MxOj_8Yo~km?#?!D^qOHdARp zCDBA*clmSRkGaIsA5bjxA(CU(0z-NjsVCarWXh18c>L}UxTOCIuJm@4L=4JdYHnje z&}4=aDqxsXM|GTAL$2{eQHa*7VTsd^`r*S>NvPbnKY-dvjK-Re-?CU~wRejEUw$MO zGjdrh^<$&c@>S^;N;@(l)u=26IJLKE7O1 zXay#9;+Nfjt;j_eKeR~1VSrD&zXkN%-=9>3 zu?t3*)3j(Y(uWrd)AV9@jEUo2tgds{)ec0}6T@lWJ!&J(G{^W4X@Q}=_LId$&uy&4 zc06OH;LtIt?gv7#nME>3@fVF;;Z1Usf%6`h#ngx+#0Z2CpY4c+`>NzkOh0>IiBj_* z0KjPUyfZ~}OE8Ed?qHQp$l}G_*p8=}EI-bP&;1d5BRc}WT^YSqh}U9~&j)a(Q*vyG z+D6g_@+`e}3fd?$0Xvc2Z7HUIpTMS(3E{=Ju`o_|{8;3mQeBk?YzGFpGrjabNLoz7 z`Z%Z9Arj_?IM8Z>@oTK7_9hTxx*SAwvhf?xt*KvUa^H~rHPG(SDE2jPEx?2PG#r5g z`NLn3%zioL$}l#ZKZf{p9Iws*e#vP#vga*vYV=#u^ua=Blx7YE@n9=gt0Ks8UFD#SrI&d+I>ibj z^w@R&-x)`X7&WYg*132UIcnOAZ$RgG%DLTP$jTB@)psr?#wPLU=?j`NpYckECc--+x7OSF!`Xo)Q6Sm}%P z#k5FQ{J;@y%DYaLpGiOe0u=*hs?c1NUiB4>YNlx1fUE*xVo*>u^AQe~K40i9Wy*ur zcFaS|`*!3$%wMW7W;Ma&plp92Aa)d4@qyp~3vrj;f?SUgk4vzk&P*$DyW?}P=+I*a zOJc}q|DZyxMb#y!P;$4EJ&NG;-$D`rbASh;0RBfzM$lY^i1&d<1nQALrax^Sma=UwuxPGP(vHQ~v&% zMWVy5o6LaTUsNZ^X#;kx6VFxw_qGHZVmDbW#c{KX08FLbr>b$^t;+6xSvRLo!Xrj>OU+ z(fpa9GMjt`ctM2?IcwS(qhTjrwO<6Vue*HQuH@_;*gBronNb}3d z;X4-~6_xr7I#KR))ec>GdnJAwF+Rc>!wNc0Qgq`9OhI`=Ga-W}F|BWCLk%<$`!DYa zk)bU6#bs@5mL}EtbS-W1tZ>AY+VERqyiV5J4H;-y3=tWKbSD$amNwOW+U&LJ}Y{f!C&m7-*g^0+;BDuoqu}j~2wbuSt z|HK)kf8rK0U0h%Oqc#7-&M$0-Lk8s+=lC_czR&r!?%kTyuMbyfeY-W`Fu1IA{Z{vD z@h=WB-@QIX-Gh+mvHwamIm~z6P`3vDOuxB#Xf3=iu8qnRyeIm8c^x-s{&mM3t!qdaaY-sK?foj}v??*p7)UO)0jf z=YK-BJ`;i9(6I*Pd5EX=7Tkiq0Xx*@l8}KZ{LfYFYiob5g)q(X)v)~Qv)W?toB3)Ti~;CeT5BYj_^U*ur5bs38#e@P=E@-zItn8>9oo`d^gdjZyH;p86GjAime`YaBak_9x%q&8?Cua*S-u&aL=LmdC$_lh-_39oqTh z%%z-UKY#aK1_C*amA>>1?<1a?GyGu=>*xNa&8rN5l7(+vdJ^x^CXbfnAhlEd$X<#+ z*{=zM3c1*~?`;1JD`mDO@CEL(Ahe{3O(#W$ExdrapWLHsId0(Gfvs`;vP!Oh9CzUP zFnEGLM8_NT@Lk4r@eRDC*1j_fZ$|O*e7qHJoV);UWKwU)4BIk#uqva;)J=bi!+xuN zYbU-sGW+O$eAWD=yE#lJAA7dixA^Yx{ecR;n^tr;#*eOftPkF#IgMY&o08t-!khfm z*@6784cB>VaWcGFPYgz<3nOtZxyX&&fRgy$6lP?|7N|MTRD7B8RNqV2jv zg{-S_l%GmY3Tel{y>o1joe{^Xs z6DPkvDE~KXprY0bfpF}-d3HQ*r}R<05S-qudz(QmO+MQlSDE|PyIAv$==BxsXCl|T z=Be=^e&4KU(Os2=#us1{wH$ZllUxX1W!O|xf|on`-o*#*_%{d}N!@aj$O+D7*ff=o zSP}7QmxguvtQ@lM&=%xaCT7MJ>_^>=@-c{A9z1e>rh%6mzxOqJ8y&x&Y3DiGOrI0x zxm)Z1wJEgMv)4=nEco4gGRHwTZ_U6Ka@>D+TC3nW^$&-|7j83G#&iOYPJV`w>T;(q z#hY}n{&-b3{jghXWVV(Yb?UuCnE37Ya`s`>M>g1KO43snC%}y5J^$Q=q1ZjGtJ+0Z zUhbuKq3*w=uF8nR@3;91T~Zs6$Yk^Pwj}&9ubf6+?suy@vnCrQvchziwlyXk8=75Wfq?jBy1H~%<(U4MVAk=TGX{nncb=zshO zTQ+@|(2NZ5lD+5*1}aCF44)1So_|P+u(Bri`{(wb4jmHJOcMtOP6DIv$Im23}Pm(jcN^M%`P zVhLK@(lK5c^$u!#__gniW~lWIKXGir-Q5*`-iW(%=4ZJ&s@s@}QDpahuMq!{+C_)6 z|GX%|8RzVCYbg~XZ>whQh&J_NcxBj2nRqOo$qYS z$>X_mz2C`!y4yN+#MTJUb(-bQ$-)OSI9+n}AOS0*(X9(&L=>6XhaXQ&`v^zW)t@C}9 zKDu|n=HcCKCQb#BNZ*^VP}&xCreQ##Ha?iejlJ_&Bhcl4AIc19xk}yRXEGyn)fGYS zrQKfkvnA;3mZMc}UY@$JA)}~8JL`-zfXIy*&qfx2N9GEuJYJczbu3m%Uf$Rg1!MCE zRXSeQZ|aHN;HKSTaVyTek$o^;(twTX^jAwbXrhG_Q)!;T@`X-($Q14684t*T_?u++J~FhVxkrPE7Av01~bT(N5gNuHYt3= zjiIf0eD!XQ^;o{}+2sWo*<~xsqkrjaZ{z6Njb#jl?W}Q>8ey298-WO}_Z#el*X?0x zWy}2FUl$sxAp>u&%)i_J-rLMPTVPevq9vgR* zlR?~&-oMP(^78z5*BtZm@;u3^K|D>~IIB5^dxLKe^}=a?-0On6i2kR6GN9&69~N*r z0EBq??}Q!v6RJ73SO{Z((+s>yooMyBy{`P09%;mmof%6u0u|7=`tveJ6H%W|x|TXWcTvNlI7iz4;NIyE1WNj!x@cd|_a8q=B}otkVbS zkW4_I@tYpb_)X=f(=WW08N@zy_!*e@yz%tRDPSyXpnq|gSDIIyf#vgDU|sC#K`pD> zbay@okHDIGdL3An#I%UV?sNL7G+}UzQl+fAK8?C(`~^QSFP}G!0WnGSA~6fqrK)W3 z1{4>l9lS1N`v?qZ-L!Q)qY(E8A4A<#tOAzzS~xWV>SJFDW*qwqLu}pNn}@LmJ05dl z-AJc{HZ$+=e)>6vRlQHw80Gyp4|?%Ip0%~eOn!_DejL$V1DV@^`%Y(a^Oha6KEVz< zzOREPTkBn&j*Gn)O4P7EMqEe076=h;99kkD8j6EJB&o-$Dmv8+Vi%0P`kF$(M=d8f zQs}7iBLqt&`pY$QW`gH>tt!aT@rqShl%w!UwO(Jt(~(*Q2EVXl7)tU3bvUBeBoge3QzqE>D=HB1u80ROnx^^e4Cbk-A(`NHEQf003c*YG*^4*=-Cx+7w~8-nF~QKZ7$K{&1$VxGY9tAwbVl@i&kE_@%e)siN1ZN#W85u zSLcq7Oz?8o>D5eTz*|R|U!(46y_vV#r%qDY(NFgtn84p;5Mpn9-l9)dVz(`ocE=2S zwCuzvERN*JF+uS+mRRl+*QlM|LK082>{Qu&8IFR$(#s|H?&wW+T3*>s$^&neb!#0!VLT({wcmt=lJR)c*}$Z$g%6(RPyygXt54((W)r z&{5*`z~c|Cvh=`h4DHMZNa7|Bx5adPB<1>2+@!79Z1VF3wXWcxL5&aI232`eX9@92 zypsE3Fy^mRS*r&j^cxJpz;(N+m#Fl-SO@_r!p)l;RQEijj-q_}f!f9EIuDotv6J{u zr_Q71l~Z6NxyPE+5gK^(QOrvxyw@rgr_m>kVxXUf<)Q30eSOG}9|Vs*&XIWTWW8Z{ z`q9gG)j=wcTLUT_nvr3%(-wy|6-TJ_@mVarVR{e*Y3US(`QUGqiofZ_qYOPP+A+Wq zWKRb+`RshB4kbHP4*HquOLZQf_x7iIApzut8l>TnA3wB(&gD@o(U49#r5{s z1LfLh1Z&%?m zYgM2OQS-e@*xg#b4j8W-8LF4Tsf((EAh_YBdL$`t-DwK&+CkNE?xFTG-E9#xWb~Iv zd1YE1Rsnpw`8Fm+-g&)Hl=x#+!bwrX^kXJhr3xcT-Y zH}Sfo3J0NB`sY*-q2udOV82g)-GcAWRwOV}dPf-`bm$an+i}YH%W0vGA=91E9*eH2 z(S2m*HSC(BW*f-+;DxJtFFiWuH>`l6*p2Z><>os%8qMs1YoZS-I|J0^{M%-vYma(t zE-Dob#3DD`pM!67sxqgSR$2EhYwK;1|A)uC_#EBlQ|aG-W+7inHSCPuK(F3BjA!!I z+G4zkeAYNQ@W~&bXk)#1@J#Q#W4>%^c~Q&crg_Da)P73y%<2gBIGBHzx0Fh=GF>Qx zYZ`-`D5)S?tCElHAg*=6n1$!GU-!VAXZJN?=M-_L7_3UZ0f;hOlT8@~Ze{L|ohLYb zf=a0tTzNB)2T>k*dF4%-m$1*7K)z2;y_TNs!Qr9GwXUK&h1mM2Lo`4g@`w&`7 zNpFnl=nl^lz;Nb{XfH%O1JUf(ux^71ML{=z!ha<`=}S`G!T^irC~eL{T$!6xg_hu= zRS_;K(6O=vdwJ&0LeV3H&Gjm(1m!~Ifx}EBD=d|1Sye$`I+X&ad&|3mRYL%EnBQl z(tD1!CWS^Pe+wZ#A(`exuaZr_gXQ))=ImBQ>GD~RaqlKAx7(~V`>$MVq4w0JH(B|0 z-e-_#mSGtxBf{f9uwE!!*rX|7P(Mx93m(KxeyL*0=DERF>O;t!g3&?!ul_N?AZvKs zhrIT)>xy9?^t!>44h=@137OpE^3kkiWfbD^7mI(ORrsG$|?yJmBNa|~uf@n1G z)FjdDbP-}%5ucjSbL>G4JIo{3`rrtmR&oB5wi&@LVllnO7Ggx%U zK6e<*@dIDX2df-VH&9#X&64jStU|x~p&+@Te*8*Sidk}d=Q%8gsrl_J19g4ZG83wl z^EkmGhd%{n=r*6i`taO}qNXaS$blrqNM~JSp7)bCnt@g1Ul$ZxQ4G9E2%*-o>UhCh z6V0@ylqG0kp;=`>Zv72J`0oG@80eG+R=D@!7{sTCcf)eaEpH-pRP%lr5-p!s#z5t^ zzr;A=JuEtEk!VpF(qNto9JX7!US=lrPD&IeZC@1zp8g2yCTDF%CK^5r#VX0aK2C9v z3)3Loxjj|E0{$bZxRTqIQbCR zM?@1y;rYufBY8L;H|289K_$xz=d*sk^0ZH30MI&`K2WsbjEKod&1nf+5>12GV0Pwx ze6gSIdXidPKpidS_$YN8UW?l~MrN9yo#x$rCKr`tmuT5|k;$3TQ!FofEjEZ5BW< zonDW` z0#^h?o1IFxXW2Y7_`nNOq;JhBOzRzW7OV4Urzz+39vaEhvAUgLpPN`Zzq|s%h|J;j zAL_5GAjggTnPkT7fo$yBYlD@>vmw(rL-YfPMv8OqI>5T z3N9>m(>jod@{#u-6}WXJY>dh30lkCzQ}-aHmAWRpD%R0DOAh$*XsH~>2Ha6PU}Nrd z%hLz=jwMI7L92Mbf9%weAO5F@^3s`Js=%@3-enIx+LAS|lBJpqBSATH4njxn|J>%H z$}J0vb}8jp%L+*-#uR1ONx_@S%NzC$LJi>IA!_jQ`R#}dM$WMu{-JLp^qO7=>|`z9 z0;@N4P&=$hlZMCy$ZC;QK>zu^4b~uh4|nob&|vT6Xb$vLP#a+_KOE2RLaT($hw+tl z>p8|m(!F$$9(Qw(+6~e0xX@4S+jt~gCf12oq(i@}g>5zJI~#}c$=wX0cwpl)GwoDM z)L_--b*})BJwEkR*F!2JJyPQ{OsUHAh3vM&oxfnA&m5nk;i~amS%WK1EC2S01wY|B z*;^UWrPw7WcK!E=GeTuQOMjCuTmntlD?HansP$qt*xc|Dk4J?2Po12scKQ(9#?InW$r|Y{E>usj&p;XvII7NvNd`_=l4IKP-p)_t#h{ z`Oz=goL2PLMN8ZV(8ve&E3q&w5IQrUn#YR6gvMMuy0EG(O;4XDkcORXXkeD{QAl3yyNTR+ON*z|Z*(a>BvtTDU$YWZC?Yjp*z4t8cz2$GrWLek5b>(B^Z3zX~1w zYBDRPE>%5NCn&i;-Gs?q+zpAbX9)-@+GCkXOYO6p3XqJ_p?SGs5?kTKBR`wNc5Be@ z;8uB3Eg>5*>PaZyHLZOKK3eUke3gX;?!FZK zC|Df^Fd)l^9|<~vdSCCr;4Qu1EurKRvxdTvk51#5fV-mHteixZ2#o0EAI-=K$C7O0%9H`$hrV7lV2{{?q!|1lHET5)ULmNit z`8or1Zhv?oCQ}rU;NSKUai10$AJb97L;bJIt0FuX{oqkf9?XUA#aN}O-yo5Qv_%ab zKo$GkeFGW4qh)S3vEE{7e9`VG1Sadhff2$Lq}k$B8npnMB^Q-4K%*JyN-CMIf-oigExDNF%hP?SxE zj7SNQW*H!^g~PJUfx=ey?^K6qb~{q+q4rGv1mFUPimc=$6MrGcWN;7n zpGB=ud0?fi1bODbJvlQ2EaDuy)P7jd4`cXyK*AZO3D-Rz^o+Nn6NEEOh|(AtRD{bCvyoRl4=FA3`&fh0bkS0U_y@4H|D(P$4Hm_=EIawVpfFB` zFHVV)(u1t}*xMF4<~+A=z9BOYSrdIq{G>*e6eB5Fz$kC!0(K~j?)Z#l!&q}V7v1jgnvWK_mmFC#sXQFB!#$=YgKAD91v=q!_G17IndZ z5FZZmG>+USY<|Bk`DQZr)EhV4TS8WZ-o4ZWF~0R2n8&)Gq58-tA2{KH)_*SqFzNMw zqqf`#s2t>g>kFMAoDOXmoD_Fwx>^D+?UnFaGl`S)so*D=f{DXnor5g z`w-8@j&B;4&Rz+1cDBBV92WZq(UF3FN1~P|Gwy=0Ia3H10-?=Xg-%d4%(PSQ@M5qK z*X*gr1E(Q(s+VYJNX<7ml@2^Ps@MWmd;uw}ArY#?SRzspz}!S-;N{8(hp9jsz?Fy1 zD{ooiO8~>>YdyNMRQXa5LHNaw#R{EPe}N50gx9U~IFJ9)m;ouv^V)#_w0&sn z#EGML^W{Z4GGQqQY1;YIFjJc~>#|l=K!#=kf&yCV2XN=(@thu7=Yv5pcwz$gSw3{Q zEvo@k8lb@iNv;EK7EPR*XA9B1;OBS^gv-FZ%H$fLcioj8n4|T{5WSaLjqftFI3?Cw zkIm2iF$Tk=-DY;9ougvlEn{k#ml!sP;VQ^c19>H$>$7<-8C0tj82gbD~acc zX~-x2lpz7%UCKZe2exJv1t%xRu#cmYSS{~$M7Hez7IB1*V|dJY-{GuHdgKD|?QLW$ zdQ(JXm>>t*NGf&5XK9KEL|;jB(}oP;TSZ=YL!V-1(N_6hA|Dac8nH|#gde4`EO#)l z=EGu~`R;9Tn(2d2f%;R4uAEU7bW-l=A?6gRGvhKV;oq>KvnCAdtyA3;LCe#D>lS0} z@6_UBL0YthxnWx0XXuCnH`l}8Ubg}w=hsbu#?|#|Yl9x?{Hw`9t!KOp8z!)!3#+E4 zACK@^=<~G$d>lP`eU^}i;Ojd}!3FZNXR!hr9F%FwquO8YGlYRnpMDJjE)75Qg{dL- zDCPk?+LwYB1Qs}G!gjX0t_B5~y5fP>_bV}jVsSC6#qh2(2(D`Ms|))Ce`9(y^|T2Q zpW01LVWhTxXfwiP`4NM2p#ywzdO-WinMWJ-T&?G*Hn~Y{=j9HYigL24K|E(l(6-t_ z=3|q0p8#pfUjQtL*xyEurSkU`OxgM*fiF6z78Q`2dvJSh{7Mv>^42yTMyc|s?%52` zWE9o>lyHe69aVChFhd}Fd2?1oCR-*5$!c`bX$u2=u?VwM z`jmsH@*2B3IqIEr8Q&ylwsz{MrPd9`Yn~4nN?GMz3|6%Iw)TL34JR3Jn=0%NUYCbl>JTFixl3(7j)_6%z2c z7{(T3w+_Ti81GeJELR2G#7=dDmkT-%Q90m@w-j5c96!v)?>~eElrwfi1coH9kXMzu z_I6V%RQugNo0%%_JjF$QqjjMp4*ZY{g6ui*8RpV#^&@=$G*XFmz3qIUf`F=oWdrQ& zQ_m5s{K4IT^aw>*@ z$eD39G-3-l&Pdy3P{Hj2?DL18XZm?1dEz6D9Z6c=ipbT{daswi@P{TXi_WalP2+8- zm1aMfbQKEiqdJE)apbkFnmtit&gA85bxJiBJ@V7m{-%lRcyGMtw=C{<@1wme{NjE{ zG+ZNIUOVmyi*q*q;3xJrf7@w|KT|6m{8n=ZzJN@JC#Z>PX@`|{HHwz!?rokbxN6fW zPuL=VZ%xJf(7dK@mKJF7^Kpdzxb%H~P=AZsk|tn){9OM#?$3R+ z)FgN`)Y%reAvMSkH3dU;+N}LL?7p@&OG{KHboQmusL&OR%l-E@b}#zyXC~{Trp>W5 zRHRq8IjB7MUC4_t-*T&im(6NfBiHAnxfiFg6}^7HyvA-oPW4aK^&$Spb_ajWOyj%M z{Ni#ZTvyl5Xwn*JmHQiaAUAHjT8nZ;G6Jqn(^ua@Z{;~JkrbuUGmiyB9C z5wH+}%~PR}9hagpGxdC1SugRHE-6bgVJsaz4>r-xY5);$zuQX4L!I;U&sew5yhW>o z5Mnyz%^0)NXN^_Zxn;-`#R#U?!TY3bsIvP#;2f{L( zTm4N}oOeIfyXn32=QVkV#r5esP!np+M^|m?BE(x8mThXtvS8EteTSNR^KYxym%}Hi zck$Q?c(-P3{~W21=2hWrmP{yrKIDbQq1VclG7YyhZau$U`t!H>1$57}Pe+0}+sx^& z$!o^Tk9Xo741etdJh2hajbCwDlLju4=JsF`d;-VBxp&G8Y%O=Mb1|aAzgB_>O4~Zf z6rhnUX~hwG^DmvrLxuhiZ3$}E4}*X|u;&BD0jYO^*pfnf9&YS3(}G7nh9Ycfd4ahM zXb%Mo_IO$-lfu&bqq6V6 zJ!TbFM^@Cthr5d_*ktH#{A^yC zal9Q^NV@XtHjSe(ADvKsx+d9#mkQ;)%mB|_^&bH!4zGJ&nt_P6H23PC$RbeA31CWO z3(?66F>o zPFShq?3D}>G+T!jAvAuz8VejItf<0f7_2Us@h_s87M!CjwjdpvGT4+&51-Fvhsk;? zroo76e`7if110k>XPh3LJXP+;%^@cvc9!Oc+ST{HB z#3Fo9x`$w;E71+}ZIn*Zew1m@D&;!PxTx|{Un*tZrR6^~7LrZrhsWx~JoI71i#b7F z4wa6D71K$5)fc37vi|bfsms302@iJdg*Nc$`BS)a($t9sF2eP%qL@2-ADbK3tYxkl z&3J`0X3o^e$|l<5qOlfm1pdne4&^Nqs3o{8tps7wE8t@{eW*s*rE7uOMJIK)tGqn- z^Gj9CP0uyhiiHl89D}S`I4h{nMi8-+5UxotS2_#z5ZDp}g&M2Ig(Upe*7q?O|MD|1 zxTN{7ga{Cge&4~;Cae{A3A%J%cYpCmnMU-9aj?V*x#~>@aem{z5P>PeH-jjUw)6t2 z%M((;2ujxmx3QCsU+sbebNFn%#*5>SqV1FEK~BnNag0~_rlnwjg&zIN=YmhCt{#L@ zIG*LA$a6R9qc}he1WW3U|0Y;KP)iq?;8Vz*QkF)Y?(c1|7^%4O07D)Z9D$8DK}xb|}rZ_-=6^_f^cLt7&CphEIjY+ zS?{FA-kg`7Rj$GgcjFyA%jS_rcT*J`=y{`gK4_qRl}b#!uWk^cJnerfq%l|K4e6iU($G%4e^lfa%NeOq z`6A@GeEtX^h+5LQe_qjtsb{RT&otjS~708Q>NVK zW_CrRpX}lULrpFk&T7lhosAC*oH}5HY{v8hIc*q;6tolK=qtA1h4w4IB$1GH*UL}~T zQ(fH2qGP(42H`Jijsx?j5?f|loF?b9T=PhLFci5`1b{B;wVh{mnQ2zmh)!F(3r@ql zp>?ZO^ATah!IQFsr;{T`$D#cdI+5Je=TUdZm05YD`#B$^?A$rU9vUz027+@8>Wh2p zz8s4mWsg+*C=Eqz_&crBO1ygarDL0=2`iy{yz0s7Jjm$}+5S$Lj{in$zru-@=wwkw z2dJZS5so1LekIx|5nuW|@I$uGm&vjTf~6LfZ~Y^f!O!i%)`%%TPH0t8q&Td}3G>p@ z(oiP!SZIWx%jUg(-+2P=!Nu-w1(58SzgL4Nl@E;gszIrQKiAEnD)@IH>NTj{}w z<@)2QVG&9VZE)$UtItuIBTqcs4sTq_=;pXMd%{Xq{OM6ohBo^D6$`#uF@wJcenPu0 zFhM1aAC8-xE;qraqkqqcFu=N2*2qW&g7xj;7|H2_D9@@%uU5RyFhJV&ni-4I8+H1; zL98qIQ#A8rUw1*qn!0z2Ivr_zf<-R4cyY0X=d6ZW5W)W6c|1+&a#y2+&2X}6v6aeI zn&3bs-~O8clF9yXk&6r;f{VCr2{;QImWn`qAF!Mu-2B}w#ZJa9iNz^bu`8qi_o(Wd zUS_1WFG}VAeJSRNWci1_B$XSELibM?rI(JYT!28lnPR2wKX0k>Qu*~yf(13Osd)@t zNZwgl?M1j@wvd+r=gUjh2ZKBHy8ydK>Zi|B0fV$Q%JZr85>1h*yrUn30OywPO9>G3 z2)uCriFQOS8@y1<#Qj_h)FOUgdO*X?Zf@X4!WsaAwyPm=$AmZ(M*n8Wr)agho2md& zf+m6yCRQLWO6f$tk*}li&r=|-2S%ExDE(^je=N&IyJE6FLO)(xrccsF#dR5V(4X2A z7f{QNBCyHjz)Y-?cW*~in8;_vXj4?uf6w|(N~f||?l;FJeXRL}l47t0(PaHQ2oSmY z*eo;I{g%k3k>sh70bGPIO?F+R)*ga;n%hoMCA;HVAxEroK9>3IR8&R$dEqo_wjS5IK| zS3AmbDvZ;LZFU?7V`5$-a`^`q6q>d~jMpWlZbY_ppJic3yv$!+HQ!9~a>R&^{5D8$ zK$IU4ikMtD*G;y!Ly^7ZBhgrgT&~G#2%~LF*umW0Vm2%Ri#Qrr2Cnw>xsVe}eF>`M zO%sCEXtb#j{2d)IHU@${u)v13Y8KaUSY_JyPZQXyVx|+W{$13hr3VV;gIA1IeqoIW zbpg594V=;cd|`|rGbK)R)$@a7dt)42I`3mR2V3h2uBt%)_#EF%Wl6dmUzTM6SPliw znJHawhs^%Sgy%+KR4fVXuoAH1=~WoxT^E7{i>bC#S5CniHhoxqOO+z6Jl*&_JdC5-; zv$6pa7(@3P|3uN8LCm)qm6-R6R0ELD{0Q-Mgi}Udo3A4cx0*P#A)A?tERMa^Y!V5e z3rGfe*;BMOBBOOF1}e3?1KU=&5j)%Oe_4LAtB2DFq?c~k?sC0z?c`PtEKFC=BCr8b zLy`<10TId7EMl;tJM%DI`P6f#AI5w6{5-NHO-yEx=f8*rI>Oh(WR(Kewb47;8RfZ6 zMUB-#a$#yAoJ5OrQ8wxp9rdYIN#ff|X^=*9eL@_E+&XRGG*_Gp8s(0yapR=;c{@FO^PT#DYiByd*@)g}aa}*7hCQ zfw-Zl!^A#+4-e`#7~v4}8QkK()etm;d*w$-t;>Z063Ye&?V$+2bo?*HLxvv%sW~Da zvxB;>{dU~fz4irOb?z6MY)BYom>BAW&QCuJ_NoZ1h=Qjo4L{Gbd5|x$4?O%60g%Ao zA3-w9^S?1gAPZYyg{M@`jgZ;v#6V5b-~<%);5p5ikLYF-KqIG8amNML0p+9Z_F{>* zZu@#$rWwehJ6TT7?AW)q0(yGYX=Eo*uFW1q@s`cNcK`koQMz&EixOl=Tr6me7D#Ya zIjW21YUJEokPcjFK61zZo9N))H5E`!{uaDTmA*Gj2=I+b36jq{#*$Roo6lnToOj-v zO$gLvGWqE}lb=cr4Yn|C_`hM!5OwT)2Jy9SoM5j^^U@8zI2r(NMT~*WT;wyOx_v8z zOJLr6&~WBw0`(Mzgv#|1dX}b_Ys`#2-=)5yci1;>dGX8 zG)-i#7Rw2EW{_$%$c@$Vel~~E?bb8-0kVOI;~?$)2$O~K-P;S^+O+z;dqSuVJ@-S7 z;H^pZ)EC%<5x7bT%-!fAk z8ibC9%#~-a!{E4eE8t0b+L^I>$&Gjyb9?pmUcm0@1}sH`Jr! zRpV2!0QLNL{7s|Ehc{wDgqGF_@pP(KW`aAEI-Puw=B*kqnLh3odsd4@f)=*e>0tklzeiQIewirK=81+_`qe9==E z-4$#BdZ*1DA(2W8+U#W&etcx9k#&3ys&rEdljQkp z$N@)bFUSzxv(s2-W%_!SUfe-|)GNv%Z_1KNJ*QJp6=#>tk9d7OO zpc&fTVgssImf>(KHTB~b-ru|$S{_(NKk)__Z)W3@ZyUaQ{<1Sm?SCZ%LI)YC#8tSLvq73}4$)H8OBsR)W6% zhK2FCbAOrA;B^~hG9bO^nJtNP#8L*nl(ia0vbE(KQ?_*pYrV;h{m5sf))7Y`$z^*= ziiLFRrM4iwS!2T;MkTP<+#l6!+0;9MrHCqXeWp0<fR~K1qFua%dV?KswcemMuNX z+G*wWgpii^-eA(~aWKVCUR(DXJ|UzypjkB{01xTKsMyrmmRRN^32|tryPGSC`i$1)4^1Nsm2 z+S*>S(wRpe-~0n-hGpej+bnc;zpbExv*tUhG=LgQ6p5jeqw)A54Ot!^LgKa662 zVAes;d>5H;1tt;=)@TSvuD}2H>JYV0?29LR94vi4dbS~0PBFFzm*>wG6cC&;#A&Cx zHh+T6Umwr4l14+JI^|C~u(`-*^0j2geb5ez`xyGKmj zeKq<|bhIJcQ^j~6x~f4JHO^iKTjMxNr)*m&Xlv8F&T+Mo_SoBuUH#zKFKk!|^=_My zaCu?^QtP`hgDR3u|l%8qLu`aaw;rVTb{ zzdc_Uxk&YDBCSRoU*^JExqxfa?RX?Nc#UZ7NUV;SgK|xWfDkS((1%I(ld>ocIiZHN z)c?V18$84DgBY#Lms{v3r82V?J>T_{3c33U1hOEOH>m@`UAKi+oA+hRrJmg;YP7YanwgK%~hTWAz~t_(Tk% zJI*wHZjzWgVRxpLXM*XkRZz|5EKI-S)Itw=xf@AR#=1fPplX@MVmx=K9oWN7Ta2xCRXlr!eRDy9h?AQiKVqiZ1=Y!57E|OzN^PgAbO2kF@|NMvx3B0 ztvE?PJWwP!>d?7;!Yr{kdA1S56m0qX&n!rk@xgK%${i<8$7^76TyLQZ7yPa_!nHiR zS56eUU}u=-sZF;s&%W;g>>{;`G61q`e;_*vWXkA!3u+N@hk!KkBw z^DArtx@Aw;X{BM?GAGjbwhY&E^kkEd@!IHh7Py2n*JE7}<%k%sO1$+E+hASmpjbT@ zi!DS!J3z?N+ zq>j6gTteipMHi@~Pmf}m%FV4#=)cN!@V9hI17>qygAV(CDT4=GEh=4bm^Z@acyRem zu3u*dP7GYD6(tsOuMbv>^J)P@!JTwh&A}bFN5!x}3c8j=NPH$}s^M$ar^C^Kb)AVk z$O;jAa~wvJnvyWleVFAU1(p;X5Xxm~No0?htWTo1d0$nn794UZAxhE>c+68KIU|_k3EK_~lO_ zErohK_ndC(3JqsxLY;NL5U&q+0x)viR4%@cZ5qTVQ`dnaC+xH{U$YZ+L9Q5XWU5`A zEjlWZJL3W9=tX0~D%AhOag&Us-?e}or}3*>eKJiuJV|Xu;)B2(7=io(m>KC6GFbGW z<9M{aqO|+&B|=(9SU)Ym+Q;L91#5Wuq6t>xe}`Cstb9|1|7hj`h`hv2mc7w=f0>62 ztqzIKDcka8BD-@rbfRKisk}D}VSDX{f1q2g9c?ICkT@^{l%gd&Cb_!Ydc9EGl9~MPO*F$ew8EiIj)Ek~`gN#mejzNADe#4SKyhCcM4QOC_F$Q`? zH7uO-00mD0gl#p^J`}*QB?Z8+%=MDt_r*vGu{45MT{bu0K+*tPt0zVwH%$I)Q)ndC zNjQ6-+*cGQS_W0TQ}lEOJ^aIjKsHN{R^dw>x)OC#AR1?DS_i(Hk<^e(gpsU?;19 zR1BTFu>Epz{ndHYF-fDgQ)8V67;}8D9nH*W^^-s1;RlZ1!~{Zrb&gqSaBN(SR;Ta2 z0tFZga#;FKy!~JkJO=&MOr>*DAgZ}coB95SCs$?dcGECXTJymqW;%aLVb(HiLuuWGdn~ROK(nJ#T(%uy= z>Self=wSio+*bz_y@yU{nTkQT?Y{th$`(!*rEau#y8wEn_4!*w52xwn@5T~zLeG2z zJBB>7*j)6}vQJ@i{qh0Is%Wi7ErdW#SWH_`n#B#>hAnBmAB?r)Aq*IFm<6une@$6i zBDAK4E7N-Q;hSP}9qL6u*6A0;1SLCvgP>m6>OH*!zKtU0HJm=N0?6*{l_m_GMAqJd z^m^PgzT`eb68Av z_{PIOs_f7Yld_CNYAR~0vu^J)PCA8koLF#ru@JW#aVW(|%xkd(18)_gWpO4BG0T2~ z5IA{Jlz~k@SoAg|YnH|!V_!RpBoetQN<2-y+BVaSN{y#tT4f@S77)3xz9*vDm-l8D z=n@CIgYZQ6KhfWVa+XoBEy7cnJ3EXZ1BO?9JvujdzQlzKcNY1H^*c6IDU1`ziaP+( z!}xQdVMo6bEtF6+^FZ`rcwf;YkVQ3MNlY1>i|#?afDsD=^9B>F9mG5>Nh_bl0ae$J z_G&kd!YlP-R~#fK7)lKAp|I*--K~DGK$>jBVkGrq6ba`8ag^kms3kO|8NgEQL!aU- zXnl?Ka5ch9>AaLU<)SXNgXGl*({XvjAv-yAv?1Z2O;#kYg#;bCC#-s(bwlII8P#!= zT)5$r9a0Hde6WYpA-yIQmsyDCCtni#@zoCOhphQKCR1<6yX+99D=ddFy|=Mw&!xKk z%)!6sA726WzEvZJ8_;yA0r}xe!GSZ0+*-5%eSWt(fgQCJ<`Lbdz zZ8&Zug51RW)P~)1?-KJWktBApG6{@h=M8Qx`#!IHu9x$thY{>)nww25V^R!c(_*I= zr4hH;F9JKk846$N<30pA`|Hc_0qox%G06lv`AAwJ@57toX z^1>#=_KWJVG9};XjUe7~dKdgZD5}9uovYJ4!2OXPtW0iP!a{MoQNm4XJhK@Q%sM2b zrP1v7KS4Fv{54;WlxUufrSqp>`xR`Iacw`=>*$V5#@z8MhnNdDzjga!Emd|fr$YF0 zeXQ8PUr^*$g+@xF5J%Q;v+-5--L`7T{q$JOO9~o@Tt6C~la29m(HCVL$=2r<5NT7s zoAiIrWTw)XH{K#cX_l9hfUJ+au%{->;bm!20Xf&%gsmOCLY)ok=avxFLs?FS&jb1h zT?3nK5VRm_`+gjo4GuAYvVpGp1TR&oJU9~>`LoP1nV@Y#SVaFYF<6`Atrnw|(YBi@ zRH^8d-b%P9`UsJJ5G6ctrY|K(jK4t7xV9H^L^%r;7nqHgqXPie4@{Cr47kI3Hy>XG z=VWQon&cXMo@wc2I&#F76({@pvRW|d*ygYo_AXN~AaWDhR{ZEE7h;vdiC^RHA z;I#DmTU(IIrG67)=FaG| zJ@f5EyGv9kakpk2C=(u0mr0bRqCJDiDj|gYYU!&YuvW_u1hl*aE-G@!i5}+&53Rx8 za&Z|OrL4Px@3G(>4Uu-g6XD(#T~*L`4MLIYmP(0dwc1GJJ1H)r)J!R$^7RX-L=Aj} zKqOb|5c6$JE=v-5Cxj5v{?FmuwssS&v;Ny*0`C%CRf+UBi2LTNce1%pu$J!iV!R5; z?&;((DO-w_+*~QTcp`s^|HgNWe_qI4+>6KRY(2#BltkRMza zLPP!_B}9}Ylj7F5S&atAtr0`1L}pPjZc$Mhxp*SiNR$eY65RXa@4HBg;*C3QwxT;)B?lj2D9^~ys&wgn}(T(yQRB%K%|FrSj%qo zh|slXf?0u`PsUuuER3&#xT0LY4g)H*0m~`Toh#C$Q96Zp!ugjU7Hu2XJZNQx!DRjEb-?Ib}tvg=@eL57sUK@k z6h_EjR+gC~pIivJDZd|s6(+wpE#yH_MTRiymKUZLaE}pIn+G~@H^ieaTe1?|vh+xG z(&&unP9fvI6BYQxxZWxktQ0Zk!jCHDW8*FBRB4neMQjxS#v#N+xJN;@)Vp&104ty9 z<{k(Zh#M}M?;<^pu(B}Mr#Kib8(k=o2Te;*sXa5RfLQ;{N<;WH-;7gL3Sw2JVo0!o zCUpV{l6&j>;v|Z)-gN5yF~aH#)85-9a8+oiDhgW#1ZCz5x|%f5eI`q2*Z!~yocef4 zl^CYl*dl0aA@;XQ(5BMBhv#Dor8v_HQ#;R^7mQU070t`Py!l zWzOl^V#r**T+n&FB9P3)eVIC5Zh5`GDu6{CQVeoybBrYtC+dg>1F7+@7(#W`JIwza zEoB|o23O7UkiOpw3IhK5f8=r`?>QrF?l$~vaygpSgIbpw@X3R);tW3w5N< z*P+OZj=XPlZzSDai8}#$FjN4s-MTGAt5V&}5{4qc@j9nN@IpPEIWD+b(fBQ< zP!H@!p;0Q;F0Rbr@1d{7D8y6EH-!wHp)>W=;0c+SLdp9wS>9FMHkwB9&D@lHzg@VIX zMPXtL<9OCLJz*g0e_*>J)%d8efSm1Ul7NRl1TrkJjA8L)Ut);#`X*4yJ6E$#3XVn- zJ=}Ph+SXLok5cD?TnaQ4&1g-j#=W`PgYXqAA4%69=wkiEyq8`o$H#_UnqCV1)=Nw~n0`s9)XJ2-Z3G`sA71T_ zSX#YXFZ5$*0Q89Zd^&qHXs_Z2So(%C(F{F&4B|oeBRK0z%!{Okd}kOTcJp&|)GyH( zc|IRHCs3t)EU@%?C#mpU1acy+A~hI`LK|(xHPc5WRVTPo4;!cF)0O1Ihd- zy0tVrH6YPV6`T+U8dHtQm#`9({C>zc+$~s`13Qz~qe)E82tiX$C=Iy42#cZaD`px= zK3VFN>9Bj81}0l!q$nPvtfh_iK`)X6Mpr(Kpp%;>EeOnE$ThE`3%?LG)9`y7+e2wl z(=z{!#ZAdW*jkc;*Z0u;Xqp)nbMqKD^?r>GmloB;R~rOm8Y$!mLXrQXaXPGl(?yGw zK!lRFt~tnu+%8j}5fk8tTUA(%pQ_!Bru;>r+TJ z=}T~uD+Vbdw`rfGDfsl)Zp`Zb8XsK)Nl9;1!zBV?V?RX`3KOX`pawmZ8TE9548 zKpSbCAE7&=SesQ_u>h*q0xqoWG*fvJ+MDV0vqDJ|Sg2yCAG2n6m8y)aS$T;t*56^z zqFv@~LEjwZLFBauNEbfOB4VM_6Sh9t zeN9MX+`_4KCI?HMQhC_%aQy?kp2hwCH6d5X43`gU(rn1}FM#yIN}8R7ui^jnnR5Je zdkUc&)jM8H=TrBhO1Caa=lriq*Hc2IzA5p zh?8RkUp=OOR4W)7F!^$KyN#u1Z4}JSn6B5WSeML#y+%!6vM1^|nipFHQQv(XvfkqH(drzC7q8{jozHWS_)hA=iwp z+tS>G(aVqg3~yXMbrmNj$bBU7l;m@G22vNO61lN4SBrEp=JZ4~%C*SCsyJnjVSBFh z;w>D+_P&s7jTw|iq!k7(=OIF}q_+@5!OV*{y=J<+79NAl+wVa@W330A?0U(7V`}i} zQU`UIMZKAo)w^kzm^JsBDa7>Zag!gHKV$^K2ImA+Vii<)^-HHBo*TZ~!<0nhbKm8SHOkHtLK@Fn+bB9PfMWWn zer1fD-mHOr{Hg<*xT1B@hl;sC&-nTDv|_PT21MPU@?t*8(~OXD5Z|KOg{d%HcO{ky($g8 zgUFBkh{pt>@HGZg)`n9U?uJIzeWo&<+TAiDub3&LJ71ES(qbo8C!DFoipy`UgjSVm zFD;L;*w!{e8Z8w1b9mB4O*?{h}w#2%T_c9vB zVGpk2p0(T#6wQw>d(!OU^sRVJhTP^u&FL@8DibWy`(xak z#HQd@$fqe!2~(zd@Jy<+y9sLL_0@I*bDdh?0nOB2&s*ro*7^82EF2JuTd|wV-v@og z7Po}GV7`WlqeiClj1pO0nycWsR^>uVKJvNqIstS{x>z~0{j0$-ed42X!X(ExxO2tH zoA#{77MqZ^xvn>rFe&|@9pAsX0sEk=J&0n`@Y4dDi^%s=3r!N>#WIy~<~}nGUZoy| z?vpUeWHE?Xp1B6nK>c7oP8x3Y6||>3S+osD6Q0$C%T%o5eQR?6!T4D9bN~&jP1|CH z)ZQ(@_@v=9EUUbb-_V~caCzU4yhta!s|m=M%>4pnPTV{AIHVZi<7b0g@b$-L@%VlA zh3W{5=1UHgXV2l1NIvww3F7DS&Ps_%hW|`fX0CnO1ft8-LbxO?h-wQKYw728lUVwsh3QPE_B?zDaLfP{ZJ2K za`OYAmgL-nnjlk#obiA{*1e&LFy(A*kBYmQ6qTs+6-Z$DrI$)oX8m*>&x89XbjDKY z@AB}cfBkorIcEK?$0g)A3%@HbW5GoqUP`cRzlB)k;%^)#8;yJ>N($T9R4c@4vDY3f zz|X!d1&UxTHX-qyryL3;QT@sM#f!5I=w4pMQI?nJkc(R_T*V9%zdF=%aiH2Hq zU8jJLlF_2CAp)PgeOK+wgLijYdcu&ceJio<*?N{T+Vw5SCRxy`R2m{$8&U~COa>~Q zgHooSSE3u2l2RVNlFFkgTHI8$BAefcui||jcu^fZ){Zmno$QU!k`drCRS4p#N&kzG z6Y`oDJZ>0Qp+I$;c;jT6+m`!c;6=1q9j8L~2#~L&@<{IMZQO2jd#Wz{n z;DIzAJDwXStEX^wn_>br_P@goC*{knm(nOM_yO2=bmQj`zZFrQU5#zySuFLD1vTC4 zrFG$uJTGbiEVJAKnb-F^xGcSjQ??usleKC1K|K4$Ww1V_m}ssK>%&q)!%O+FUZny2 zC^c0L%X~FXK!%CgCX|FM2B?uwG$jS6=Mhq{4`Y$f;IUf1QYoWt5WxtTQ0Fgjn(n?? z$hL-4<_lz~X;NhxJ+q6BV*o9}vZOv$h8QCf>i7*N@`EThBx-wwCOu-JF(n2bP9^OS zj>5_r)@mH|!*PIKflQhrC}#NLCn1N(-3FH+{G^NJE~c#c3$Y3^W(U+49TL~Z;9zdR z&%zgKO!|8P2UR+Hk*r$OK1VJhCdpceN&{Lfc>yPzE<`zgR_9Dp{V5K5qP*s1DA{dq zLl;XNL7+bHwwD>L26EFSIY`%OFizBWK7trf2lU`EEkZhDVNqaF4wqPcz$sBVrHxbD zOYknjC8D8_607KFOydnXUcYhOXI<(?nQ7(Xw;&`6USuOYwYP_}0 zlBAuyu(I;bA%?>CV8wo#!c8n?aVw6YqU@VdisSbx4{a#F?S@=cW)1d4SoqCvYf1yi z5YDk`p8(>ER?*dn#^wir+52i;P+yV<30$LbQ1tMQr^@!nBMo2HXaz>NM-uK_nKnT(fbrs64G z9qojXMG)MDy;E9#zx0IR@ z@tGZn&|71o4*J#%XN0zxtW{|3m$fByeji?#*xd`ZZd4DZHL2GYAGI%ZoKzs=sJf7bNpa!fx_2DnLL9ecC&zqCOGo4&&-Rgy9 z9ekOqf%(O}fnA-vi_4!?Mb#3WV&+n>)ico7>decqK-7vD)Xs^jO6bJwObt}q<8z_Z zNbrDHqJQ?Zh`av$L7EGEQFPW&S{bj&((3W~X@@`DkTB|p?u2w#5>MK1EK&jbbcG0)F~4rNAt zXBt}L1)}X|vo%b~waVc0fJpy|j&2|YAWVsCgD%{B=j<(t8ds$Hw# zynYAOq%5v-V1^ECU-`*xKC(GrrvH_DV>H}}qtfb+^YAw?!x8tC-#LOZsU6T7#9agL z#H=8j)Z##n_TEwoik{xzqR?kgLO$RA2Zzg-ooP~6^p8P2baXVs7B*~HnxG4zq!`^) z4>a@sT3FNr^YA10S7^ecQ_mQKBAFD;P~|i1ENK@YlsI|WfASe`h6fiED7<=@`HnJ6 zxdn9;TdXWHTHu{~{l$=uZd`}wyZ)vL_tJZ>7o(Q_RXN(Gg*HM5Hp6b2*W$_BJ!J=N zJ^osiji$n4ycR7xjcNAeYhz?6wLR-}(?RF47NmVuoFZxDhRW!}OR|+dfizXub5zt{ zpA%gIwVn|D&A1rOwu0gj%?O45E~XmNb;qK98vB(e)jAYeT(n@W76ofLFBot?PMnzx z0rg3ii?!`FWgV_ZARtaPb4t|q1wK*>EQFrg8i>;-KX~2r@pnzwC$EUkALT?uP?2iS zI$mV7mU6oy_&2BO z%nsfK7N6p@()6FAL89NDsY=rOkJ=-syliH{1ev!U?dL*_{?$N+UX7JYD7!lXmLuE# z1NkI}<_R%S6&aOZMl4k+O5PRYJ)riSjQYGdC+W^hsSFQ5U074Dlazr}oPfi&nGfwPFD-qRy@>gORoLJE@w(>KZ;s0|*2QykdqO|m<+ zdNs%0_IVamLcTMm8jyE{n1RW)ezw2`bwLW*(jbHP4~V2TO^0z`>$-`tR#YDYN0hx8 zMQv_a3`?|ZS1Hchvt4xt@WLPSXxJ)I7HReh&kRCG6xX5BOIisNkgbiN3B*VtvuT@Z zVvtKOgO|&`6WvHs7m8&qsrI0qp(FM^F)Pq!gW*<{Y+lOyC6(>Hc%@8n^}9k2JpbUR zDw!T<+7K;n5=~Gt9narTTTIDZ9{wTwywEPSqa{@7>cyk|Pz7bwr%Iu=OQH*RUdv%&IgIbOY+mT>V6sH1@s49Y#(>6>$=JMCE_!5NfRdh;Xku%;bYrJZl1ttf? zg51e#BXKb@m!Y54N$9$((GVTmOY5McoZ#HfZv|9JfPhwrQdMt`-rNDrbD$z>qq=8c z7{%Kg=$?))dMtRccDf$CPGT~MJ`qL}0Hb^aKbS-?* z7%H65^?a`yiLF6_Bu(7_uZ=m(&AzYyv*^)O8I|a&p0L}~Z$=e*@n87AaR+N#haNbfMW@$U(AG+8Rgku7SFXU(=r1Y^Oc4OZ_grd4 z$3qe*lJ7!dW`42+Awsas-Z)GsCH1oyV|2)EY~a~A;!?^jFW0)4Ulbw@p>VsI{8T+> zboHibXLT99`GGe>r8d=J8h%8KXzB3x18(}TCz_+Bhd}e54O%n3HA09;5DiW2Igsit zt)9L$o)^LOXs0!kZblWsX)!*Ek4<0j6R1yl+lHW>8p(OUZiX8iLqs{ymB+A^hP&)owuf|{99!|-Il*P47e5js z&+7ELKHKsfY{9ZS@EN9;eu=3x?DN}sf`Wc)_A*3iMW`0y?kx7X8UJKI{SFK?!aE+v z_*jkzv3B@nSTM6Yp1{5RG?I5v@88)DkOoj4J9sB}+qK+Ydgo1EJ9g-fH$(&XK;d$` z3SMADUhtts(G6gn?o2akwUDr}k^_QZlh`V6E1ZfpIv|u4v(2^l7r4jjl^Z|L-k+CX zvxna=@Q>9gL#u3pekAL=^>%?gPN#UM{3JL=vbk?OP~i4p+L+D9kvyIab}NXF1j-vA zoTlic;XUpYBs@B4&li6bSVzGJD@vGPiL^IHM$y8KV8-xse9WgR?iAvv>YUb1h=?rN z{Z~F(DgD}iKudxL^F) zT!$SqsU3GUlu7^au|aaJy6D)J9}qJwnfza`K#Hy|f!`-Dzk{#O)Cmp-`|lsHZ#z^B zLenLx5aL=W#sMMK_x^l6k0YC(qW(=B4qPFc${-^@_t2zS_ytMuBc{CKZ4Lz%-oX7L zsW;qjd5_WUp}k)fN*>Y8xi@BSzZ9DytOIMrp7=vZxlxB)$e}vUta+;-JyE9~Ip47$ zHBKjIzsU)<$*fZNrXV#zM~+W?Tu2yL|MMsq=IF!00j&PWkFXHNF`eN~ImUk@1bee} zMhL;~taq-wAA^J5btx1-c6Lx6*0{qGE=Z4k0*aFL#c+P44##T72HY6NYbE8Ag%%qP zY=r}%{t2%9p)|=>H;dx+q>Z1Jh5&ZhgnyiVcZ(2f%xoPV z!5$iJ#jzmq2E%x*vK0Cp|4hB=5p0jKqV)=YZ{4WIc#o{xEXJW0>WVH4d|Yjg${V~X z)RsZtAt=7 zjn5M^Wh_c@ASe4hjTF5L0`@ zMkI1~F;|CvzZRCku!cNhooEY%!{SQq@!%SLg~r8_KmPxW26d}3eC{P*!c;Ze!56PFT97Vp}zMu(1B7=2@}2UmWq zVJVpC^exbXm&0y2NA!xg4=vI+u@>0pGurp9fleX=u; zBAaDCS+DH9CH5rKPwa|sNh5jlqcZ2V-N53j>Y5bBUO9|274IHfnMCyccZ@iMa$?m^?-2p;Khi_JZ7MSMlr71!RIAUyT(9q@0Q?ZWrdtv-Nl zqh9{n9!EB3Z*`J{hZ358T+laQQ~&4#W7YWk97xo;9c6s`tM7Y*Plnas1C%Rr@!<27 z1~zxbFd@~3ZS8VRh#>H~5t!Q$g)QgRpxR$?nQX8FzQlGt*{{^klvQB_0hKzU-^<8I zy9Sj!*V~krFvHlNH4zr;Qy zzk)AqiM)v8*6J^Cl)Kl(gRkm;jUyWg4|0gA8>{bVQXJ|Bt+w)t=H>X(M+fZ^RqvxK zLwT^HT|#NfI^0D1Z!gX%eKw1?sH)5Rnu092*Jw&J*Y`)UYSO(&aU>tN)})zUcN1qO zFQ@D=^i@A+FG0`V6a1YG%RLHH+;5xAjJ)(IzOVMO!j&M+wWxDBv9D5Pmk-(m1n|b8 zQ(!7fzSIRw7;ntc*ox{d<&FO4KlpPDs?!h0_=X4hTg898V*;fnvS{^#&2{H0&%gQt~_y=GIH$)T9Z#TXLujJL2Dzi*6?Bncz z`Z$jg-+c|P?~@ncYW(-Lpg!hpAR5{NLJ#l}T2Xov?jtGugY>RgtzvhN(IGz-q-JgET{~4NKg>soOYU{M3RwX z?O~==x5Wps>tYhYkez(|207v9Hk|(|@BSbc#Y`t8IYiPBKDQVGX5MQzAb6E4)iPD< z@^-@TJ3>&8Mcyas(QVSs5~A`)yqfK&8N54y%v~nrkOnnA=W#IdOAZf45{k+PR3G+^@}N=j(@rb!NDcRD@N^BF8W6wMs}0f-+?H3&t8gU27vQSxd9M`I zwd7+SP*DtGvIp7=xj##miROkNg6a$<6(ZA7$7r5=3CD3(^($?XCXQ)Uk}#(5gDIj_ zhXN}xHQXT%^t1#;sqp<;#JO%xHx8pmKpuG4r3uo8FL4PuKqn+%>KNiRFLWd^TLJo`&TgG{bt{29LO$Q!5;Zq3EYVe*N&QL>~q{x zuyY_tuN|riQ4+&_Cym%$`5Y>%sBc$|mr;A0o3x3>;8u!CTg0B0nS5xVfoMvaMW&_U zbNEahp@m_;T>~+q_%wLtqjzfxxHeQ+d{mu>W|)Pd8=k&S%+;eyM4l55JH%oJH#M51 zSuf9IlYd2PORCZ;?Ce}2RtV;8jCh87X%vR)YDDAZTi^zLW3b4XVF4e#*fQXz|BHHM zTIZ<60Hv00kLS7x8ZT(?MCkair;I6$e!Ya1TOH;|fJ%j8Pc!9*t<^5N_%v2jImSu} zQ?9+|fhhcU>m{raq!wV7)TUy15G7oZx>xX=rSuvwHUX{kU|TM9Wa(*q^1TLPCVgoo z@0%dsjOQcWZporEP^*BOE@<;4n+aLQGuThsRm0`G_NY5>`gI< zx|7dfKL`8n=Hqc(#&w!9G-t2IDXgPE!aPpu%M;}#Onq(*h&h-yUr-8k*{NU686Sfg z_KP-!@Udv=RG7vMgJg`ho3;}p|@;!RU` z9J)xlD9AAP<(8nOvUwn_VcnfB>NeODkS{a5@M4PpDYc?NHsGRaJIFZ0u2LTg6Oc|v z(0Ay+a6+l_KOSIFzWss^Jxfc)*cyy@;9(h8_h*E3LnbAG|A&^n)0Z-cay;)_O=d^{9 zrmlNW;Ejj_tFR9fDxi*`lT|wV8=Ul_4$N@JsP9DoeiEzSIw$0?>%QgC(PgmK;e_87 zGc%a`)hU7%?(^HVg>+9HS#;>d<{1`T@Hleq>90#T`Rci5^}U}IRfyIh_f5FSa1-pU z>yX)Ges~HZH!Q&rxFaP3g&Kq zUYo{_DH=FjW}~4CYM7EJ*)J5WMReM3ZqkQe=mJAkwr)3tm|Fg#CXQ&$EpC#2@w>>H z(80YuVWu?UI9E3pI}K!q(KQYI!FGaJ%`;F8M@4f_?0yE3X2e}a!$Cx>KWe4!OH~Su zh@#&@leIV&Yv`k@Al0K9P)qg0MHTkQk~PqEVMOn##6yoiHmbDZOnt>1YB@Tfqy;{a zZys;fOQPd|48}UklP+@M+;W&Hjv|7`g)}IsO}>dBTudPK$v1AeXKGv7|e24>cq*FZWb)7Tdo4IB8GReO}4BHMKJ+1i zR9blLuw(tR?PW~TzXTpr46~Ij?P3wVrNf;DP7Kau=4S(&}EodjTNu;6}Zs!ArzQ$cMhK(seBKF1R%dI z7Gsa05Uv7D^lxuXmXQ}b^Xj=WK3GQ5IpAfI!>?l{<>!v`ZRm}OWk8Y?3}x7LQxGR5 zK}`@Mc#H|Wo;iZmRvsLL*W^fsw@Ii=^`#Cbjd>duW=U146>X^hlp=iFPjn1p=^k}T zWlExA%tqaxb99?5h06vH)VBK(Ajy^6nD6cybnvt6-sj5^ z{m>EKpPs&c5?da;ze;0c;T}jz0jgBPiJ)*-^H_nOB*FP@DSQ)`;zgO+$YKL#Wf>^U>?bIYq%;6dsYjL!Q)_?9HO-~T~T-` z!g8ID385w|^@a)ZL>V@()XmCv+~?3#di`uum>rlmzyyIdRt#@qy*Kp~f(==C(4)>_cPXD#ZtVW@$4tv=n@+F5|^A=YNi$L6jM@{4{l$oT}j_`MS zwIIWQ(>LU+bnG;5io9HxAJ_0v@ z&wvWiTexS%HD3b}8{KWsp~QK8)Q6^ZZUNG& zNXRy$yCHE^8K`yv=lBbUMK{p&EEZTkd#Zq<@;5*bAaC4r>8}}))uM0Z@x9lHVYI6I zElGNonsCt-Px4;(t{HH4=g}M&MfnRhBv^s$;vt0*mVlnBYeaN9UG2o>#0(*f@`ON& zLn&!9Vvf-d20&bs=u03fN}({w&mKNFS&`l;1@GR}24F8g!riL2e|Zu#9sw!?#3p`D zs(EW`aI-gz48EAkr`DBTz|Qif->H+tTtgZ=fGb{j63$ijFt2h@8qWb-8-PQNIJP?i zMXH`Wj^w60^c{4N^i9uF1#a0}76X-k6XVaa?7~|blmpzt9h|iwP#V70!Jc7ikKH(? zozo#&LeCvWG1Q*-An%owcnOcaY#^3qvXTWLau#HTbFG?&G_Pn4pkO2sd#=Rs@&RF zp{o4RL6wkU2fl~GPcM0&XZ_SQOA+Tz4ql1)fsWK2*{fd;At|Hd723PGQ=(V6L{z4& z7xcJIQ%_#%_ryUEv+`33Y#*}O=<7ghhxxu7c$;@AeYXTVGJB;HEASiW!ODYivZnbZ zwAMU!4>B`7^VM=FUC)P{xlfDAM@%Y|AeyZ$j+n}rQurfh+kd-X^0DNu?@Rqmk%K0z z-kIYX7gHAW2Hi>@E`s=Qi|>K{^vgGthLN$1!5cDk;O)Hr3)nr!A{Zw6T6krC2X<;^ zGVhG8ewaHe!2sTU6Eao!}Ips#^y{`I-2m7Y23jZk+xc#L<_0B)ogp5Q}8GtY?TCe*mh zjvIX7BTJed_}LkR#N=pnH}_W+({wS!X#MU-Wby<22ubkz>A0R8yPUj-S>$L9=JuA_ zeKK~;z2jex0o`2pA>hKZ&f=Z)wnp|K<}S2@mQ8ziBc9XcLFk(D!j3@u=$rb6^ zXRt8;`&=8RQ%?&BwkfxbiJr7juK^M4A66a*2!ty7KiqL}ChvK(=`7`W zp)OP!FNOi9^qClJ4Dea}mfVd>R6WY89dEwN1?rl7Q9?<-eN2(BnnJCB(f8Qhz`JJ%*}<)HBaL8OtCIJA{*z8Raaw9D-V_<(rWNI@q?$u zSRYz@I*jh(cG@7(4-L|;4~ywq)bM72(B2&PD!3Cu?~^ikvOPI?)}zB*)SWeFpf7r>0E^K~`AQO8!R z^tS*nq*BibA=Ft9Yv2hpcW=zJLXO+^vyg&=)bwDLN`Gn(k~s4YOe3iyI?lAT$NK`@ z2jVmOpC+#Mko}u#Hgbxn7qLdz46<2d18MlY5MxNR9>&AGb|dPik>QZ&x5k2j3kg(r z86Vj~dg~!6S8w&i7)iIb=;0p4-=XSRuK^JZXBl0+35<7nRlrBzEec39`U@8RNV-ljMp8~~=WJReERcjm(KE1*Nx!k3qrXL_tUr?d@t`Fn*fka=+1o=Gc zgcygtc12L?F{$S!ZX!CnTFg|@AQ+ea65>=kagd{(xb=CEHhHz3W-6QVgX9>#L@pT9 z?MYXxqpgKkqH|mEOxBtLP&LFnI%hwa4S~yL_@)429(^#g4@jc zmQ1cHuLpAh%|B z?hnPPbp1i}0a<=hAVUo`gT@WpLPmEd8u^r$78uq>Q}pX16D0qoZ!9sI`$mW%{QLSM z?o=#z4ob1^R>6%d+R>@F77_j*sMD}h3>xX{0pw!n>+1ukTX>ZV^1pw92|(&TqqWlE z=QUUhcM)!y1XooP>Ue7@s+g;Su(1MYIQzwm-li_wByu!>B5MsuN?i(Zd7^RD06Wnz zlB#cm(ORtG2vJ)n*OcW3r*j;MGwmxAy7SXpeA+z5J|2D8j#TjMH=)!*=Xt$G)4T_T zY$w)qaaahw$9{gQjSwHfw*PREJ3*t3sBvHNmpzHHwDUD-k=-XO4*J1P*mRGf1c^2P zbdr|7=BP=7B`dg4Qlbk50&nn%AS9cD23=6-QiqU%TXAR~A5RgUGZ)5(yz4$ZOCmoF z6F~X7rb!w6Xoc;!o99|=Ra)4D+1M1`yC+{W+OgVKhG~!p+TqMFGQ$PUba5LtsIj8) zGlTRl9RCC2cpTGD;CX6szYk&)yHNZXRU0v!B(Z4g7n+oT?7Y>23|# zd}bu*001;RqeJ}B1Pwj{wkAKKq6mEg7BKT2h-LDRQQrc+L=lmOMpT)hNSqRlkA%$X zJ0o`&s-mU zfZv6aQ%rFLbbIHAi3_?k(x5s>FYc(aQTi|hr{i$7Lg)Qt%%P?WBx`-g>*5G|X}~YF z7RwOpyXS=&vrKUH21>)fLe>WWq1Eu*i2Ifn(S&}YyE#>QbD)|?KA24TU<(h*8}hhm z>g$9C3w9xEYmWUqIR}c{&@AAfTdwmF^Z#5f_3QL+9`WZv&b}>%-^M(?z2yOe3o1Y_CV$e zOcu2M#RjspuALy`7G9o-9a5V7!yn7p>XMns)BfTeNlLGNz@4BzOgf)~NZWlZxPIwp z*g)6PF0gbd?&I!Mqtq+UXH)MwdL- zP)K#f_^jhQl5s+{S-gB*S0(bKWu6hp}S0#pr_;SS7JGH zoj~6tez6qVqPm__h4_hP=!M51%anJQW9!vQ(Kbm(UcEUy55JG~x1*NBRaxU+p94oD z0-=RMyz!aVNB)F&@E3CA>JeVnC;ijHj@3K65L7BpeAe5xr3u!x#n^Hyi+O-j2u(P(HlKG$ zIy8Yz`S*jOzdrT;1P6}{ziGlw&vL^3>;1ZDUXKvMml}x7>BB%dhDSG6qQb5JZhNsV z@yDH&c?zu$L6>AF{+wh7>d4~L@Of5kzHi5VztagEB3ln)+Xk|?gp8K?H$Ea5o@JZX zcdJaYB2y!c4;=jzw?|OWijsvq(T{aFDY}rj?|Zfs{>Nc4tf%3WP=;JUYL_Pne1J*L z7#*AjSt(2BmSfcqN!-JpVMN@h+ux;GrX<$#4nX%#2u-UFJFWaz;~JB5)ebl%q5@Cg zXcXo>VCHmGwuniImfej;=!CsIvcXy!OSI$_OPpS84@Kl(1TlMMiPuHi7{PMx>)K+N zo1(RXDlckNlw23H&8YmVn9@;YO%+OqJ~cWF$QhJC*V>{$SejZh{ESx(pcq4itMjX9 zgBOynPEh3`9#ldnK&%6jkhqxpA1#z`M~*9^5{{(thsa>40<@tWB~O|NQ@R}y;)ptI zm>ba3)u&*ccWe!-_4_-56-^q(*S#q2uIo)x+jb!Z4_RJsNuZAS5I`=`ODzuqcrKzg zgT*xZbXw-CWF3TKpNwd&PnQIoNqX#m0od6SF_n)JG|)T=RJ0W!z(?nU+{voRpfQ3{ za)8dre~4Km?gsD~B$WhtTI?_o?@TemL*m>y{AKL|qwEolWb z^N2P<$xA?Yqw&*ic_a3c6-E*U8b_R?a8D|XEr@2TJQzrU3 zt#q~N8X-SJY~7lSI76-xXJ()-l8eTalclHYJ#MP=aLecF73fT&$QB>{dSs670 zGQnx4QeV)E@(XyNi~|V-?^nU$Tnb5qL^=Qt&|epVTR0aRgefjAH1Pz7P-!wAZ+agP zx*LcR0?jcP={Lt!A>0euMh6bj#;B6Q1BS(+NixytfFCNzHb%%pqG1SCdVm5i3={aomYnZ=jgaaBNG`T7eq>{x6P2j+t zD=Uo9Z$6a1xQ#g*ZzYu>M4DjV)QbV|qHSr6yp0V3Hi90MpfiTFWZShExv|ZLx^mW! zk|knp6q!8@yJ>_JkU9@_k&e*Kzd2zj^ucABzVA(>zTAhgVemZ|qsg);EcPcYdTOhN zcrHofcSWZHGAObt%!oV+SPZ16R;B3@FMjwPhZrQ1*J7a7gIIh0Q7ECv7hc>{0f^>( zT~tp)l-Gd;pS6SmnjHmT;^C?cec+-PWVG2e(Z^`*u{BYSf1ExLdKF0LAc9ct(PA7z zWQOQyLFJX$LQ>b_pz6Q**x>i`pe!z2tjT4jM@55F9#s?K{%#ca#Wq)IB^u#n{7U{h zAp|8f)QcS?>R(IE?bFnKTbrY@JrJkzFWwj@q16AVGTsaSvJ`jAc7vqd&2TNf103vo z0(+{qsAh=#fy$(YmJp4983>{T&#{iGEWeB-L>Hsk8TmG{ds>X_!}pcthr?tt14&L(sID!(bMX&^uHw8jBJ&6+Y3q30J-L8aGH+H7{|RINk z`c)x1@TbZW8h${G?4#zLBwT`Ne(Cj#;pM;j8 zUu9l2P34Zzr<8ToMyPxY`(geWoShtQabZ6}e%YKhP7in0%7Cqc&F9|~2y?q6)PP!1 zl?BZ=%Il*3$Bow76-pL<#!t2Uek;u{O4elrGJZ)42WETCf+Kjj~aQ zjEnJkP!8Nq?9YS8T4=GEcAg;6lWp0sCy5-l0ME&55=ftfXvBMdh@-Z zX);TY!GL6mH$~k?LHhCt?348ozFA*b($snlzgC+eDMq&EN66zAD^;GxLXuXH8LDiF zQF*6DPs{vTEYoQV81je~!v3C$?tf)c0NSkLtRl{5;%%vsm zL{#Hj3GVsk|11c(Yqb!jyPYn2J&n7MeG;`%^TH}KH53KRG?~P8V~4TB%5rRzVT?CI zL;a&+>iD-Bpw$&{5zI#Udz!1mi8HpEZ{-VED#P~y7kmQ?*zE!q(%m#M26}{`s=hgX zx21zNMhkaaA~Z41nWN(h#4zFmEwwp{ya%NCj~u5)b#t_)^zTp*>RD|Gv$nfq_ahiI z)J?t)g1ze&6*!#R^?S* zvzHCqFgBAagT&xkrg!ayaFK` zbstq4_Sa!3tQf0Jah!AR^vtAkVULGE5Wf%O% zvgTreG-5XcD+>}0bjsc)FBcd-K@+jJc0u?v9of>jEqaQ>WB%0?WVW|cKWO^x)qaFX z;~)G|ATiw&>zh{R1c2?V0~$>rKF#IHUg2nPdWQ zUv09DR zR@~ZPMbTD`R&DCm`y0Rezt6qjbM<*LWVXD^+1~S>^E<|PVt6$br~p94jud;6gUJhM z_|V=hllEeqzwbA~8i*-WU~^!{bjb;AepxH6X!q)?;+ceUO)+*wmi!F4aC4zl>5Oxo z^8phE-%Vzy3tsmip0RbZ*AeH@pS0#+#wW8EqYTM@I4QX4_bY0NxYef+QH=GlG!vKi zYlIkL-ndj_i6f?ltGSTe9f-sW>&8{NnV+4K5BGVLhC_I3?^!i4jn~y;rgVF|+Rcn- zm)3EV@EbJXZ2m8*JatWAlq;b*%*Dvuu1ASs|6_%c6{+0oN6yAk*MW)qg%vFTnm z&wBcFJgO?atLE!o-uOjjK1k}W-o}vbn&+<)K4OJ#qFYsbkTv%__y_oj|MZ)l*@Bv~ z-dZih*0K-3$=iu3D>%9o%vx;A!n?OE*r`%y0tNpK^6p0vbC-CHvp+f9dXv#hxMgWl z=_YDQcdgirX|)#o2WXRBg0YAm0EHSWO|@vp>tPZ5NR% zl0G@87(9wh{wJ)=3BBvBsAI)P?oZ3yEEU%WAf5+EWwSq3-Xko3YPgx%IP^TB!iqvN zKZ3ublvCjwtUVHlJ}mz=poWkZi-3?zPLW%f^zlR6)O>^zz+_F=Mzm$zi}e&R51QwC3IC*r#vBI}uagqM zf;hldQpXHUsYxP}#;IVsMmY5vE{xRD=^Cmz>0I&?Xv@?zG8YM`9nR)bWPH~;jkguK zdL{@QD9}IJbtKDsxxSdCdK_t~Xap?B$3_=w^$iCe0WW|+;8#Hm- zYmtt(rNYGWJ#zcUVgj@S@BlxrUyYYgp0`?oWtgrBZl--6Y_(T*tuC5LyoN#7-^*t@?xUb|@#3Nq&vx-s#Vnyk7@T*#Ku@ll=>;0S9zM%C!BK)`v zWBS|bv-qiXGp!gkzuU?BTJo;1O5=!Ur&+I_qg|wTuOsNxrhb`5AKCKTR!!1yQdzkY zyFPK(TfsRT@xTrvfa1b6bx6fXZKdU7C{bIyo2WA@A*@m^9ncq(N_`T1=Sf9fF_UL* zHPfUcg>=vlMyzIMX^U@>@&VH!S!V~Gh9t_=lxs2*h`Wj2=)t0Uyo6Gq+aeWa3p>e3 zKtEL6Q9B1*>-G%>;6j$$;SEo<=Hh&Z&+Q^n|0xxvjh}*2zA?nqGFQ`x3HkCmUYs5r z0)Mmh@n?1)wy<;TmBeNkiFtIW&59&qk#9Lapu$b8EMjZ$ZusjmPK+H%99th+#vz zR92(7ZLF~l0PvB;@u+2`C2)eCl`=uZW)kk5_Xn*H*h6~B=mkV3$5N%yb@`M`+OW*B zjn>4EAUjb4(njnP%8i7y>KdHi$Wr>`p(X7KX7d<7CVf;IyW8Rmb)?K{OrG^1U+s=jfCx`yW0|sgo;-Q>6Cw@_X8kFA@zt^ zcO=0CL?##12-^!{g6f~CEpEc}Ov>Z1%uu;LWx4Ecff;m+bbdI!zLKS$>El(l2`qoo z_ovDg$nuUI&&qr(|DP_l-pz_{W>l+y>>(!CPpDV!{he{jm_)o&E2IIae}>6n5ATANAZE-zOxLQZ z#);otQ8@_t{B94JRaEFkuPOrl=(Qt7V?IGze0NG!8NhPG{`j13RP(F*{d9+JBt1<* z;OkLqZh=ADx8H~7_=WdKwVUNf{`L*T{+SWG^j_lIz7_h%m)^{tMCu%`CF^Ee_AK9 z4(+h652$G*?_y43{A!-|1P3T{f)u4>^4~IrNG3d;t%xA1wNk)9K<`*Ib7!oWU2dHo`z(iOl<)Sr>lOyOPnysb{}mq zO%yd=mVCsu0gtcw^&lE7p6QMLbGch{A(7omoS}A02_RytuN4t2Z%ilv`#a5R{aq)^jF&ykWQ0JMuVDHwmynpu!@^k90-Xd9ZY@$+m7dx3Qz-6mBst4)0-ODggmb zeb%}k-a|!im0$;as}1<9GWW$JY`0eHr6(`GZU>$@8KMM1o@X%-UoJ_+O~o-NkI8sG z!%i&qED+uxbu#`Ou{8pBYz^(IAZlte;yPoSGDZL5_MFdJqtsKMTBV7YG%>iRvqq28 z&z{HQEsCL!*54`3aN)6NkZ|#di3sA(-a!?xu;_e?iMYcDLC*WsTnwM zJ@DGEcm?kkDeucv)+ETW+}={GB^Jt{0iqf zKNi129daP<^XeBGjA2oU68Sc*LNE^050My$bO}?^nUhdQwik9rf83}YfJYklf&8e2 zdvJ%r1A5c7^w;ZHs$20W{KStVaSQ+JS1@0>Z42NAYW*cztBV<`Y-BF?&|6v5teXIN z&b!u4l7=Ir^Eey?<7XBeJSQ6`qfvryKAd&&Z}m2i(|`ktV#0lP7gJJmPkMLAC436Q zA={YJ{Yu2u$I_iLsG8#Sxms*(EorI8c$B}x?og!<z86$h^|f$AQ2lg6{l6ZneQ7-^bj_zj?S z$ot=fFGBS&GcI@PIUc>I9yMg4_uOxl_?grJdY+h3&U&p4Caixqkw>GIVZZKPf#?R}3ZGf)zO<~1+%7P4(>0w%ilFg&r% zek^g2$h=rIG4d2_BmPti4BENY_C`cZgzBvz^*@aq@q9NDvP&G8VzdzM+dX;_e#+U` zG3)%I8oYL3wi+w!uKn6#xPBg&*GOjn-Vz=9aCCQEy!thS1+%by6?`vq^DyWG&nTeP zNBxCsNei{0mbkqDZx*{f2XTozqtTR(>y)*`uviJ2pEl83gUKmuM7y~K()vNyayQz= z9ghQ9{qQ4HwpjE+Zvjhv$kQC5;$7I#3;O^bw_cJu67;ib3`jbd*c?B^{D~aBpjlne zHuuUGs8U9zqYjh%sZ3(iVc+1>G5kL?%cFUWQP}T8yT#5`PEazWFQc|e8Gci5;!kfS zrkr1=G%$1LmNXLW^j->N{$8%(VgGIiG4W5vL6z~ZE*TrawGK!LQTDZ>k)>7$Mrq0p z4}*bjHYUQ0w;{k@O!!qR;M=`xmyE z-00I&!MmlCLklIQ={PG7^rG7(uK@W*vX~UADC?Yq>B>H^Ad(F-i@%oZB;v_%ql2X) ztl`oqoq1j3X4B>OP+f`q(q|c7Kt72B(YS{kS|q)DzPSYFlEMs#R9Uz7;yRpLJboaS zh~UM!WeJ%~Gk-i8H>3$hi^@2JIZJm|l``=xs@|IBF-jeC{teJT-GK>>j1ZGhit6SG zUc#UD;^e|n-~!&B5zk!MjT;-KP`08ySoCR_JSP+JJN)Lp!_v;skxqC!KgZFKi9E3B z2@xdlN(V(TlmG3xQf7Awlq_}YWd?E|m6#0bveL|~Ps5BXeGQ+!x=a$&SEpeCcDbj- z48>goK%(5;E3`<&Hf?h~EM@NTH@Zbp*Dhn8HM=vs%))MY#Y_hqmd(VMr9!}9&_7B< zvL`A9Qt+%jI!V%%4kmIuyu$5ofWit2jHU2JWM&ZTQAsg9)RFywWlP+X=OIFQM{M|2 zHlng7kS#znZ>GU{KE7p1I&uA=z`J(bEip5_R1d6#V!o0L3)L>P!@Vv60q9dpDw)Q* zbLq@Sy(A{vo>u|NGjGcEv6SvjFhI_~{8Bpq>1~Yc*i@K>)Vr_p;+d;=DsXlPs;FUB z#0JURz8glIFw2~0Vf?;GAWT0-1GAZOIbd8-VV5xSHHSfTNpIm3*xy2d-e|t8Xe6GN zPZjB`5YhZox|Eogd+nt}_+ym4jyQJx1N~-=J~fNhv7Svo&jyvKGY3ihGc6Df?KgHk z2l=y7QH%mW|I~ZTwAOUYUlEoOrHbdSy}Osx6z%57k9PBjN?>Z!?5@Prqo zJaK^bnLyC#9Wa?fjlxOzlP@bA(4)SpIzqL1f@0XzLn*RKc=}Kw5@Gxq1;((j73SBI zG9Hs%nY3UPZ6hwMJL<3#-t}FD6B$A&lGruJHUQ{8CpOQ@#NVmn86g_N-SQx>j$v;b zVGh^Ou;8d^pJ)uw<;P~(p)}95noe7Y?(x5v`s?Q#tVA4?DZy#07p#N86#g5GQR5z6 zmIhQrAP{zzva!7;KEmy~<=|FPF9rRTcFQv`5ANg;By;LJOF&equER{Z+g6N>uxfC|UjDqk@{iW!_ z(g*04u496Ub^Q0SU9zTEjarPkX*Bs&WU|7JUl&STy=%qi(tPcoXN(~6?cDle_!55s zX{>mpv@x~q^4y63$nzmE>>wsXy^Tncf@@ZV&AB5A7warNw*qv#cUldmc+IypW>S3X zd)TI8^XHfVb;=eDy}?uS8GcIu;hA9_G55L|kZpC-s%+S~#Ae!vm+&VOw;h97$5lC) ztVD<>y z#5r^(F)U^5KGxais|8?waiv{Ri%dR^T_6!-uSzK&t~dh-Tr|87WgooGjwXh8&9K34 zdkWAL?m~&cc>cy#+O1zDbc$`e(9D2U4`4rR{RN^)=@lp+ex8OZQdt{Rrx zc?>sy5Y7CeCnj`M$hk)5!iO0;=FSXl9bt^0=*T=uD7?jNzhIB&dcQ=|lwyrO0?XC^1v3>d*~-;m>FY zbww&#!7am>2%i}%+0r(iHL(`r_^_{0N4Vdwqny0D`_h>-%%9cedcX)hlveScJI`v8 z01Wc@eKnD;3mQxan4Br4{vGZl0kCd6ZMS0gXArnH_ZtaF`OfE()IzN_$pFcH2J$J- zD)BHECg$>hWYt1I@h65sAsXZm)ZQadMDFE)f@Uf=fTsE#cpr}<{swBG_MJ>{FdxKX zfB8&?ly=)mmEdGf|7WC#P#mv-dYDsUOb0&k0=tQb@}DKYhd4bUHutvXGlJvrZ?$t$0crC7HVGWHi ziMvVyen~6TIVDFfbxQVND|MH)F_8I_&#ffXKbhJ(HM6%=S{B`k`4ASqckq$r;7YOM z%M65i{s}waOjs`D+ZQ7xU%vY09gUfwXlAuVk!V9_JQ-wuBG~!2OBHW8KuOAJb=c-Y;4GX`-w7Ihug=+RJZ3N%Y>w~41|Gf}ruD6r1i!__#kOE^eb%lsG% z8*|`|yi%s$=LrB4mSGfbm1MY>ZExR4kRs*G$y~gOm4o>2y9Q85(HYR6=j{7@gqLRIzx3w*-q2HuZ;p@&D2&B$x1~BZwOK^oOY0bp;K-= zAXyvi6tvHBZ6<(2@*!FHIIT&^yxT8@%2FqBQJ7e3k0-)0Q;CJy;;;7+YQMK4op^?h z$4g9J#FdiFr|*nTV)`!9Q&rq%=FBbU;_9t3+)DYNDt|2 zC49FCpn;rtGYBEB(j(cOj0UU{nwOZEW6FdGX4TzuP9|jRd&lEQ30uv%NvkGI#G;Z2 zCUJIylTcZIB*Zg`R;8M$+bCh#xdZY%Oq?0AojQ43kGAwe9JUm_YC@pu*+&BN_7P;B z6LHiKs5>Lm!S-Rf?#fA~TpMiBG!?=>h;p;ICctts((SLc=z z%Vj;1>Daw_<(t47x?Mx05_ICxAc^@6MSJuvxB|vVS&7b$8*=Md!~R=KXqdp&4H>wy z=N;`P;_%(M0+N|ugL-vY`!udVB5XehrW0wE-9h*ZlO@60`K^?~&7E8-xjRKofRr^d zYpCSh`Tn0w+9DJww()5mKmxA;R$7g!WN<)Hw{}7)h&?-+`)YwB$uF z+ah4Yv^t-Gh?y-9IBG_uHH;ZwtkfYHB?+lI_Cpy?2_)AL$kZt%{wnpA=$QWRG;T!k zEgmX`*W}y;e~Aw?QcwR()L4KssyMB;KtM{X**CLFe9X0CiTIyiz!KUqUW!sdL}+>_ zc0nwW%*UIRPUb>&hM75bpv1|1{3n!UkJy@8B(IEtxk&9BD$U>gCJE`xgFsC>f(<6L z&^v%cS|AxJr>>l{Fl=;&h%_{#fDnI|y_Qf5?78UgiscOyHq-vr>oDx31h4|HAwey3 zlon=UsG=CI-L-mfTzRW16AHUkS(&4w!1s=ec}dK`Q<7~tw?%@9(IS=_#&;Jm?%qe* zQkHRyC?TX=q1OAD87;KMO2+V=#E=8u2dW-<2L;Y_eFW8aX0Rp#z*$+r5(!x=r`E(1 z+lx!NRv@cM4omLMQM-@$=1IN`kD)r(npoaiQx3l=e|7oSB5h-9*DO3FEySn2D#M}O z#%;AYxZZrf9fupmJEcW)ix#I(;Lyw7v?AUr7S>V=61;T}Bs z)AYT#VQ{!u#r zw&aO)o#MS+|Hlvh^yi%S-)G;p(2Xcz+*FDXa5Szp#uI*lR|?ZM+jAPc#1wdg)(zyx zUVkFP?_13WkNk({$ealSX>}qW3uh%xd)}UM(Zpmpc1E0a|#vv?|uciupgR zj`gWU*@?*CV(ZxdE?m78%af{MLabNKx1Ifk2TyODvL%*Ri%D(9+^0Eq^2YD(fI_mq z9=Tc~tb2<$;$@|)j~fZGjgW$S<5$0^5!l5;ChehhB>imf8W-UUx4@R`Rd^tmB1Jcb z7(Il$wH0F!y|WabKc1Tp{r7pz9MtstwN5xnr?c9avhVPAippGGQ3sW>7Qex@F0CoX zDcurK7A0;&%om_RQ73_AsPXWrMU94AoMc_p<(9ICp4{F_o7l8D1DtsB%Gh4H7Sg=M zdT5{5&FAOVk*`)g!VgnaptKxuqeK%>$hoB$J$_Ty8a1lQwTI2eimP)!qD_#iCJliF zxNNVKV>5il`<$vDfv!o}BYiQg0c3|5EL*uZU(#vR^4OY146F& zR)Y;sstH$v_kDFwVI|W}#KRytQDxE~6QB8V6Eu;lbu)V@;nod@46Q6G##kmE-+?uV zZ@~&$Z8F^Gqh&GQ@trrHBskWtZTKiKn~Qg6&kn{{)2UzAXIm5RKKi=9M8mUhSG~pv z*6H_N0n74f@s=O*t?U7l|G8L-J$17CPq?^eK*m|{e9+(5-5Aojr-I6KEI;uZY|p5v z-)mN%!Q4A0y}+RHQ4b{?I6*PWo(>G1_vL}9iXJs4Ru{Z{AC~8q{Y6z08QffD^s#NG z=LpjKY)|PrRvaC+Ki|vp?w@{9*vKjU=d^%1jCi5V3}q%N;GAjE_Z(u5+dfEQxF`ud zZv3CpPW2i9Apq5?zMf-+PJwax4pu1k_-CUhHfBHDz#Zo!>8c8Av*N*?0 zUrQ#W{eo_JR{i`s+YE=YCbhu_tfOBZG$JVtqiMb00t*OM9QjusT}zyQY(a0_lh;EP z2*ukqE|xu@sd!SB6#x0)Dlgd29qPDAlY#2iJKw&+iyVgfL*Bm+S zrbu_nF&o2Aok%|ki`n*1pq(Nsgy#~Ha4ZkdCDR zH>OELDg3(qkY!4kpdf{VWLauOznMDI#KiAjb3#=StRnmMkhPf{J*--YGOII)sjs=(*oI5d>DQ` zuIP|0*}{r_$>4ei%e{zbi2v<1R_w1Svd?J9WEbB2>TAeE!$(JJC{jEAq25U%CXa+T(m8_l2EsiI zsqhlW~5TE?TK8*!Vf}NeP=JIA2VxIW#=izVm$JSDm zt?B0mqnhx;@@fR~7axJiE={h7{HUwGg0bt!gen@zy&)50Bh>tiVZoOn?wa`OFg?_z z|E^#Q?W=~re@r%zU;MV~b!5`desm*C{p%fGlSwXGKh-;kZ+Its{1(jfZheK zyo=YrEIpyGCEU+%8#t1F%7`B^m!DOX5_j=`b^|fLN;Y!Dx@M5kK%C7s;3>Yx~eeV*d; zFEk`E)iX5da3pNHrFX$NuEUbodRy}}zm!$KyYovv2xLIB*ZCr=+q`aHzQBrGhW~_< zI{B?W`Hn=va=Ys*FtcD~6_aF0f+=mc0aD3X8NTmCoEcVuwk(<|X7{=Fn;bE4Du0E1P3^v;EI%D|X!u zE>M*Qvf>Y;z6L3AWc@Z3kI-(JEnQ==wpC_<=H8zrRkx|s?K zv1R>dL@#@mROnczYv1NrE3wASRlzY#*{&C4sLA8uOCaby@1ENM!VoM$`bAWk!SL~m zB8?zTs|40tKH<2=6ipmqtsi7EWTzBBPhFiQ<;LHbnQw*_@zWP7D;o9l#)~R-04szV zdsT~SPvx7LcdP5jf|JM5M1JgDyGn5sU&`@~n-&XwWR;7tnA)#?njULo zxe%MQ1wEl}%Q6>BJ$c(4Y|aPpLtr5Bd2P<&Qu(ye2oI;ksXHgq7DAQ$qH(Fozz|D~ zk8s1km;96yUr0MlZ|7o3Oyy|ek@K~*B~1PkeQlabcrPv_s~RCfrvF!64SD$SvYPjk zNMhbd5@=lJhcLmpBXz&f5cJQsOt?@D=QPy^yvbiz)<{B!pLfX!SBj9Wr%(kU1Zy3` z=@Ppn03<9-M`L`lNzHYQjJlECNW!-*pfg!+rMCr^QRfEzmkf%YvoA`TgTH^jn2)!8 zO%H=A5#^s@3&Yd;?kaTDyv}XJ9m4a1jj=AZVUnxpDde~OgX_{F=4s{;L`Si@FW+@W zV?2sN6_h><-6;|#cKx>Z0ZQj@B2DK?5MlH!?Ji0P0+p|x2T{S@`2{W1O$@=OaCbUB zxj#EUp@+=ayiO5MYCq|PGlrdS zK$zxz?<*F$u1Du45nu2aTo8X6m1`pEKHc&x%<>JnNIZ`^sxXnHth0(F!aa@E2#7E` zo(h3UmD>~ovapP3ncz1^QA~<1K9I~iVa$OV3kj?Jt)>_#l!K&Qt+0EDrwt@$CVkVO zCgo*eMju(-lZo}Q{JF|!l8d2FrUTFXcmHV(Px7}_K$@I)ua{^?xSu6Ob#@Ld!89Yd zaLt~7REmCvi=O(JHT!1TO!KR;xYT$7Q`U zqF(71yAK)Mz)1=Oyg8z72$gBl^0CZ9yM%%D!)=WkS?-?qRY}KdAs~b$VRyi>1GE3k zZbU@M{ZCYeK-S@%5>i&jnkqYgQ|4t2mjhbU0_!euEiH4i=8{Q)5|8l}{!&co{)yVm zAm(ajt_MM*4K*C$cU4zFkj?Hc`HFrxdQ*b^ZPj#&q`Gf?4LF-1GGcs01w|q~Be8b> zq0`s7uw*ZstZ5`!3v+YRS)NWGNc)KC=r~AYPQO)33*iqPg?YiJEvUh%mA}CT;nqtT z8hmvxMI{j%fRP!_Fj<%i-koQU2N3vgdX5PEHB2gX?3l(1*g*GMDIJF*lHY+#S7|VG zeCX~P9qj83875|58>vVRb)mPCV^pCE9ibXlf*7b#%ari0KFs%leiy6&w;s3QwDa=M z5>P(bKSyIhIOLKL3Ez>sr)&_2dB8kPEl@PK4pL+i!SycJjKK(nN``Upsf2shH z*GEe{&(&^Lz)CR>R~U$R`HsdCL9Ao-`8-RB69?g(;pJqBBNUw*;56NSNkR;E@+)&W zhI{it1XK1*69I4qK1zdP75q+ZT|9Bh7f1tjp$$Bbj2bwcfuwHncuhR$b^T1qCO5U7 z(vU=S(OY4`A#f5ZFrZEQ{5qCzK6X@vhpaksxD5Q>evw!WArN-!tSTae<(q!EzuL=+ zO?{cwE|w3y;w}R>dxcsf;6=mQ*^`K4>wPKMS#9=LSctCw6onhO;_u-eUXIe%MljWd z5(1V@z$ON>Vz!oqGwKyut{L;ZUKfkQnFzoVNlM#G~RkpJIkhWXe!jRC&p4N_n_pMAgH%u;pf?g|iT_-Z@$#Zu4V zaq8SkjTf{rF;R*G7S?{Pj9|>0@iCUp^#JGOjr8#Pn|ZZNie7rCXCgYye>fLgdFk`= zT+CDa?xA|>6D@=iu@OuOC?LE?^dg5Kv1N11KOU9=;s4E!M)K(5kvIdwn zB$Ak>m+29H(Glg`F#b8`j3P{LEu^T>=9%6?(pSVvby|cOpQ73P;*Ofy7()HhQOXPA zuRXDgM4TOIw-EDe(Wpb^$R8>kglhXlZ-voRROMi%g-W%E`$m=&Gb?_RJZ99 zVS^s#>hwaSGB;0dplY<|#&uAvXv~0|>=sk*IY-)Mnx_{h{Yb z@y{*wZX#S+u81e* zSRNzc1Z9Y0la?HQZ2fV!i_~H%u=2p57dfbKgAF+X&xl3#OI2G7#;)6&WDe z!u&Nip5)SID?~!6a_tY1S(Ul^@K5zoYtqq#-!aPWrE_z>Bn&K?ntzISnlGS zk7@MtaCB}Z@x1-Zh#9%iTB^0B3tLj7BaZor`UsM^sZP}x205selEAhUd}GWcXYZ|& z00y4i9ic(+yS5oDW%halb%X}2ch8oRf=&B#nRLgBMgMAe?4aK|(14NlRcdOR6W)-k zz;xISq0k?5{bfQX^KCjl4v&XqHm9kQAVn&5EA0`aZt4omo@?mw8W*wNd7{w;5L?#} zD6HB!{Ul($tZT{&NaNqSf(IyWR|BSLz7xI*-2^E_Pq=p=*GtkT1!z24QZ${zj0&nI z=p*&K3L=ABzXM{z(|(81M#O8?xtN0?-&JscIL|avL^%CZ4Z#pj$m5vnE<8%L$bi&K z3wvKLqFXv{p)7gO7<}bCg1yv%WA%gIZ4KKTa58Uy<;Dwh9^yr*Kx1gf=?=sL4XKDPvts^*spyBn()Ek1R#XPokNCPoK$S6m#U`To2)UuT7vRW26pc*IP(? z`RaQb5sU9nr)fzG1}O^>Ff?kz6`4eQI!q6Zbf!5Zrg-mTBgo-F38=*qa!(^@u{$>r z6PziBrxHVUas=2qb8nS2SQfDX@?=_3LlQ#Ac2$%Tt|(gXBHXi3h-R)O(AdL>b)&yj zxvk$hT1ADkRN4Fs@akXU@~)~fgUQ;5=QLo^gx1@DyF*^J>aW5#zOoMASkL_6Ln`dF zdb$LZsnj8?`RcdLRa^)wo`3yBRT_-dzN3>WJ~+`c=R|!n36_6GGo)5CS$zltTnnFp; z`8btR$?|g_&Q?hq^_RA4)73Kg|256GP$>q>0O=A?1k3NhmFMn4kN)d^W1cl+=RSChuyH$1*(XEuK?ot=- zX)@ao-X+(U65ThS;#O+#bNnrAnWeF)Nupt_RA=sP+f?*HT|5|{*1P{nCOeg0AsyU< zPgW!mgJyk&iCDw;)j-hSD#WmJVSm&>@ATc33qvUMoDofMd;r12e~_h#2q5N?iV8E) zz3!iD0qFF9crBkPS+u6qrwRl$^pWbT^GswsVe+O(GKZ^5hhXHJ>d+%wRbtv{h#Mp|fJMcnRE0pOvyB-MOs9V;T*#61z0ai}6Dlf+ zIots0%v&02DiIE|4>Q?o{vk-S%v%q&qzN-oDg?S=!ZBkyky#~$>YCbIQyET*ny2Z_ z?DFGPWff-Tn=rc%F{{h)BC(9us@2T0?vPG==moGcb+RpHuAGr<8;)!-q91Mkkn*RK zdVZyM68GJXQd*5~e=L}P_Axhb*vY^VYo#=+I{zzDq~Wcnqrv4=Y1jh`vnNO4g<9#P zEmbjhjZ&sLPazNjB|Up)85@Z&exAmFq|qtkq=+?P)jUm704eq}RB$MEtyJ*D%%1>b zs0Vm7HrRSc3N=7-aGrfoQA}*+pavV^{NiyJzj3(qGsp;YGPXX5UU%qaxtYY-Qk839 zbc?i}&PYbf0##BqaxmL?o5Ddn$}%I|&g=iE@F3z~7S!gZKa4OJ0$YORxSSiH2CC{l z06<1-orHL<-H?EIgzL|-&r!ZbTO7bdak-fWev9g32oXwXcX4uZI2C^5M<)Ek>E*K?n^N$X^v|=1(^B#OKW9TiaP{j7+4H??82p7-(7{V69{PDwAEL6T_EZFi+YNGozDiA_x=~S_it~5MJ@j*GA=Q`C!5>91ezGun z1@$2n2OlMNtj)5{^cD(xca%cFi(F`1M`{Qa&*9w$oEkyzr9Pq(Ijq&33Xg0yeSjLz z!}Rg9%V9IzY{WfAn}P>(Ie5GZ3NO%_M5rTTMv5$ghx$w4zWQ-itI zLa;~alP{D#rv%=_wdBGK0XoGx*+6<1HG*ryg*yYxibJw2`Wq^fL#qveg5s)d8hwBQ#G13|&`sK(E(Ko3XTsN_qH;9w*@>BF3{!^;E5M@>+`3v$Z^h16Q)l+EhQQ7=O z`5pQhKcDI?M4N+M{vP==`W24>5Mn&RK7WddqG>u`JgWnGN3jYH?Nf#<8Y~To~gP`CV|F>$#(&uHb%ZL{~9$-*Hzc7G|25YLw1!j)Rdu5xRMr`GP2a zUS3Vtiy7u5E-GHNj#(i;i*d&=dx0fxQaI%2=wtj$b9XVy0$SQ8Z$&q9v$-C+=B27S zMWy@~`cFQ~+|JsZQTwDEsQd^ zb%lEZW-7id7)O62eB^2C19ucCP8DR+`-Mz%Vv<%DxJL0~K`wnz80`UsE*H2%ait)S zJ}itef8YYV`2od^g6Z^8VXWr^9~K;^6n6?frH=_9mZT;^;1$Kgf;seYVVtL(t%(?T zNAav+KK-2lR&q7*1U^%|Dp*8+FHG>X_d(mp{A7jsbhThM8uCxtH}?!InEyD=7&^S{@=*! zlK)HEelIt&KY&RBBIs7 z%l&^S{DXd`1HWfR8-h3aUo5;&Ki4hL^)8Jz1@HF%weU~+r4H<07i|rW@LwrEoBR(o z)6?4*Jy2E57-cQ1S5p~|IFlw(Df-vTpH_p>OnnS7TOh?B$X`@LNxA!2V@^O;JeB`j z{f1v`>g$ZT73}r@SN^v89lylg*BkQ&vVvylf?_kzaq+qcwTh4;ra+brxom-~h$iYH zQov*vaLJXr|A&#p0&B9U%TaeG%@|dRe{~@u6Jm?hX{05iNl{i8SyQ;!a`gz(meHmJ zR@=QPeC!!@4(Y^1rUWGqGb9LMBLWf?8)O6XgX)*^skO0<>bay>QFK9Y{W2+i% zNm>!aPCZm-dW-mwFUi27Rt2H;C6uwaMS93rWJD39Q2lb=Slhx9a)e|RwJT^+|2fr< zv@8z!f#eiHDAljv`#Hid1XvV@Wn+^glUF(+qYj1KBA+lxr@p2>a&>|c1%@UWSiB>v_(hK6U*Kiq?ahaNS%F?2N1+B6n?i%B4 znm$UQ=>Ns-Dasv1LuCnN>&*R=^nzxXa(B^4S=+Mpp8hrn!yAgn1@n>@mA>3yMfOYuVssqAu62%Jo@LFh05<4bBZCk)G$!jDlBw`@+^~+0?Fwd zXl~Uxbc^y5V@c_pyvZ;~Xf+~qukso*?bI25qN#&3A`42lseEN}*W}Gk$ko}QCzQW4 z)>CJx9Cb%^(-myGpI*K;IVpLIVX&_Cy3h;C`^@Z=9?4sskh+ILZz-2NVQeYAlD8R# z2(7P%{-ykfS(wr%dAk!*_<86X<$nyH!X*m^7$sq0Y=FO_C?zGi%n6~~IV>t5SW%pk zmb}9-REQrDmKe}Pu_C2k@=hmY^z5)+0Wk_kN_uj+VVEvqUD&{Y){1p0Q0LCh=E%-L zTl|K|EAxwWkl>jK&ag27?d%|}*spZMOB38-Qv$l$H_HZ>LD{>Y><{>jDg2tgrh|O1 zOYnv*2PAGgQHL)N=x5(48&*Bd+Ldco9(2`js{BauO&z3vW*bBJrhvir zU9u6eyLBT=+nB<42aK}sk&TLlGN@}~4gWS^y!{(lX6#WxaxgY*j0DKPX$c0?@!4p+iM<`)K&<8 z9`KpsWD2O%3lpBvGJ%jm)#iMsDbtV`g*~_uMa`*+`TO0O*2G>=GpiNnPJv2Iqn(La zu$(t4eoFD04~nB3p>_HM3U+saCHoLJCjNs`?cl&l`_+Oe$qUp2GCy!?#{}-PUxS&w z!3mqAJp5|FRC`^@*yJOIv3y&%c1qw8`%T%5Sg5GF54_qd{tpX(EBK@yHaTfWnk)@G zV~577ckx;2?c$q!8F;~duV7aFF=||KyYwbs1zxp7fz^M@kE?BGX>ug+mK`Krf1Dam z+7~zZA@Hsp`m7$NVS0PBx+8gLe^o1gPsgiMNQx^3De59?R<_d9&jvg64w+fhUDmv8mH9(gOHYWFWtaAb_WQ!~p|2&SiDHBO zNNQ2?DMPkk7!jdSE-x|`*vnRX(rqw(S}4~PWythpYs?w0IJ2gsa#PWuQ}(j808@n} zl%kAS$`&roJ}qW9LSgq|bxYNS#o1^6M;1&}?os@jGPU}!d4R5iN7J8ewRGGmsB_0e zAMB(8Wt*khr8HNqC8m_`mA|SZHLB)x$Ke~ zOmylO)n`3}e69G<#Voh<(-cS97W3ew)}3U;vVRgkwsg{k-(o-U zOG@36e9+L*(A>>|Iur?=B?wME^TjU+*Kztqz(SR58p z=R_&8s z_^uJn-mz!>a#9Z@Uw2M3ckK*A>5`u%^-%H+!*qvgMPzi)BEKnx75SG;)16(tP4@+T z>DNbor0go6=f#^31XcP?FWjAdQ+$8(x41e$zFTUuxy$TkBZ6-GeRBFx{be1#_KNI* z9u1aPx z{!3F&SJ!*3d{SCeoGR3Rc`A%K>!)H;PE==AGyheoXRH7C-*3k1y(lV8)zW`WDoj1= zOs;!5Y`eDpU#6a~Zt%|JyPt{5QFZd)l=@Ry{r~EM_y7B>d6o-?;7nDIWlQ8@tVd^! zNK!`ysQi{~m0v2m@0sQ6PBs5ADA~X4v^&4i1iLV*xkHuVUvc_M{sZ@HYmZ*d1=Udh zs?%5VADUn$W;J)JM*Dw#`q%tF-E+J>7B&}E+5V-eus98~gzi_PB2^QY?U!FK`^!8x z2}a}<)s$t2r5gDkWludeTQ4rU zMev$s8&2QNe`cER?3D!zbff=Ir|;$e?Vj)LmDIdXu*u(@+L-*@0E2X0^uXX<{+Hzs z%dQzB)8Pmi5xmF$*VI3&Uw9Yrz0XAF1RwOjQP^1a()^hVnqy|L;CK7<a*m39SgWV@iAWp zUs!gp@bBd3-i4WcxR@QmSC+X88?#?=iz@qM#;ggx=Kojf%jDNWUfug;@r`AVQlG`X zFf8!&vBZ2UtvCx`R==hemG)j3lNRh*)|mPt_KkI6Qtx84YPbK>)4u#Srp1Q7TVmY7 z50+g|eUbc@`z*7sDMo6>OZkiXf5pYceTt&fg0K2tPJNyK%CngCE|2*QM)dvEH`#Bk zSdL$aP7HeHf3NTj#%fU`8o33}K9oOCe(qVs_X&%s48G+5GS!#-vwA^#pYmuS_;3GL zsW8B;OT@l+W1a`U_J5c9U-f_9B^1Z#7`2?piguMz*?bbG(`nQJ#R^8ggRbXo9H(oc zhI5}$?0|Xh!czVf+mr;I@hgyD&i8T);TVi1A!lH%4=sr2N_B(P@x@_90TUI~1(sx& zZoJx198rV?TykM$a-D95I;l9SNHr10dt-8@ZlSs_(WODvb|{Khs$-X{`xUo56D0G` zFG^2|kNr|Tu((xG=p8r-ic`{KzfzAVh7P_HkZ%`La$^5iBM+&^l6GlLP6a-NTd)X* z|0L2et?4QD)1_Q$dF)m7RMIuA*{Puai?O$lXF~t~|6L_yGnbhpY&L{kUnguXhM0>A zm0Ye(5>laZP1vx_)#jQ_p-xdwM@~n~TvkFVIvqz+;dF$YqB`|`_WAtr`@G+O{r=o- zYq8DtdOq&=$8)Q2@E2;$qfSfN5_bxa@t1lC^IGdrz;z(*63DH>93Y`BA)h7XOwn)KLE>(K@@j#uV~=(?eD((k4Kh`H>1{4A zwBzLONF5czNa35l07rq(a`&V{iN?;VCJaqiB@9D;P%4sW>Wpq@gu0qzs^uR^QHkcx zY9^3^1YoYoKa+|fS~~A&hl4^Q=B|9&pHgu|YiD(nB2Bka%mewiQi()c=bi0vaOl9i zkbf^#lYT{1L%x{l_5iaW|Buvp;a;&_tl}}ZcQA4ME0rePC#EUSM7hgir4+VEX9=Ce zv{+0L7hS9h;D=lyL7=tDOm`<@u?mXP1w8waQ2`^( z7Qz7fGGCXpj`mW(OCuya#B^9}UB?dX0EOMs} z9ofO*hP~xf&rY2gg}D6A>?7eY+BlMqXtkjN^SUHd1d1=qL|mqHmKBon?-F-6;xcl^ zJm2YTC|s1jCp-qBd%2Wno=&iQhIFqmG}G7@<{)((N-;mbEjzIBQ9Y;A*#LJ96)HVI zjA>$w~5Z#Az$C^M@s(8coBvoiHVtDpuw{lsMjK_L95dRju<`wmyF>n;H&7lkR>F z&Relo$}`I&6Pr=#zP}mQEq+z{De;8BVzu(e%Z{wjmOqsp6K)w#uirn3i&6YV`UR2F zgJo5X?SF?mqHs5VCi~Q!m1wn;w-i2CQJ6oM?a_!0tsasM)GAUO%Ae0p2)F62rost~ zsrX2mOcWKf^-b56CgS;ukEM4@oDsrxgE|{v2gUxSZxsT&DJF55jp@EZ-AE-f88w$efonXk$9EoPL^~M`mtuk2Do?~uLN8m1AfxTV61d0n9sRH{ zGJ4A3TuKC_Reri3QID_WFQe~LCh&-d3_Mb=L+P-LkxPZZbG1ptKU+_zlolal>cSOx z#b0*x=j%->osh9~sS@m8y`1hZ)SFj2Eo19aBk+#D(&Im`x2|+v#=)gd;Ij(kLPB3c zIZMXbr9nWBZ*~m8>MJSJWn5i&0^gSn8)SQZO=Xr0sh^+e=iAa2a0DhwuFU@a%bEV; zEh_;RfO<5@`1Utv2KcrbAE<@_vqk1WKctQ0t#JqL!s)eLCaC{f=0V@9Z3kY!ym?3F zX#e%hL;v+}$FHs&_^O|-+$$5--<1X4Sj9XO&lFlKbywhWOrSJM;pOz^2T_{_f0U<1nj!-7TUbx-Fx>Co|Ny z%{b707g9xvo}D8I59@8C23i|vsG#V1Il}O8r}pN+Km#KcRXQVQAUvYCeIYQ(z(GZm z4$wS2(&?sd5XZnCs^Un8IX9f@)S(-!YFMP=PUq)LgwuLEsKM5TwJKyfjJ@H}PCqvX2ZF8_NWYfz zG#o~%h2SK^Zk14aTh3H?jMHu1!yLm=6)L?W=Xv%&yz{^og9sxx|bv_oK~5 z2e)6NKh61T4kF+@n4l@!JLu1I{+>IV@$1mh1*5au@6u;--p`#Ay(9?GNa0az4yKUYrN>_2uo8beON_QZjxU3Zd?~z5NA!Ip@>ddC_jEV|jZ9 zw$IboayI8+pmsmjyyxlmcl3`rU*;fO&O0`==gszYIt%BL0Y<RDvn9}|L*F0j(9}IYEOFTI|#KmxBc7yT{}~&7ruPnSVFbs zlBlF;R;F)nTj&v>M`>tT#DHX0)_Ctq=mld(RV`Ua0kg7w1+$@F)x1>kvP!Npgq(Ik zXxP-AU{wRzFD~2qvQ~RV!m^EzsP16|_eu9bK>p*t!c|Qf=-dw(IZl1eVb;51R1FwA z1`t^}@qM8XpC_p5$nMOQ7SDMp7z(8t8>!mKYPibvU0Us12o*8ORCQ)3NXkXzISF;c zj~Fvl-Qb>4;`zS9W{V&HFM)w|mFGQ0^^wCL7+1?VGIS&rdD-J|t*S}2st#O>c$NS1 zLTH$yNu%mLNxcCjLP4(}DV$?WRt;d_2Bdj#u|9moI2GY1yW3SU>r#AwPk5wBhw5Qj zc)|41SAl?Ln+R1SWKI9);)OVeK(!H73d2lN4O7@K5C|#2bJbXem83eRNNbQ2F=n!) zdX`})sevhO7@Ue&G5M^T%Gf8ViD7CDsY2=}gU)3@2!LTV3U%sL?4yiBe|Pb<{Oh2 z(P4ZgzKYfRA`}U;Z1g!s zn4}4h6ZXKGqG`rPhcb+FRS4Yn2MggzCLHub+2aFd5hbDz^C<3Sm(i1q=v<3el^H`l zlt{A_^mE2ZNh@BJ@9TI_y3fu6>FQl07SF&8yKGjXQqVY!=8jRjW1JLzy&thyEmc!4*D(+aKvV zu9#ubY=*Vu)iBQZqm|?Ckgj}Zgbd)s>w9U;$SG4XHL=2s0fWA0J<;`1D03OLyRumW zPU4)5F(y3hKmKjDq#>c9eJqq}ZVne^Nx4`8`{h_@lsy2?0Y-!?@zt}oVJ6kf{H`in zw!qbez}6ZbiqbX3p$lc{Kc2z(ab{!;pdU6PL((;(gf*TQ@#CJWWD9e#5xm~<1!@x9 z^DEhe+#4BBR>nnW+2(Vq<+7{+_aAq~jAWX-q76iU+_=Pd!kEUvdaJ#c)s^tT6tO1A zGzs0fA3v4rZr)VeL?}&3(-J)*g2K_95zB$%JN;$^W{j8Lec&P;*1@UHu3x?USL= z<`&gzK8R-5079z?97zH!LJ$WFA$-AHZFn*j9cR&{7E*XaG7xjE_wfR4!#q{Zv9Lau z9MP=xRP_YYVnmHncuO)E^Hamqz!NLxDQXUdb&_OEv(}_)beqLyVbh(E0h#WoEPN<=oOkQxG%9A@!eK`}qHiFK zaLweY=7~~^2WrO=9j=fNnLO7#S!(IE;|gNZHJb2q`}5F~x;s!i@(Z8lo_GbgJMZL> z<-FSI!fDBqyxU>Fcb=TJOxV#?2$2x)mzTe9KgGU#tIiC&+~qJIg*BA@q40w4xL)C`ncn3VF)2jy!+*!8<2U4sf!hfZoPo%*7}nJ#8OIq3sQU# zk{Q-4InKaZRsCI|}vN2cZCsfc@$@`HIz1)yKM%IAutG4(TKuT?pI|qxh2FG8m#DBF;S9d~c z4KlNaeCLf5)NPpRX(Xi1AUkV#9MUy=P-T3PdV{4|BfhWO5{}rksRtnq2g|eWk3-mY z0py1;q{$#B>wzz%T-7#X>NKRqU}e_B@i%d&??SppE3&>+9WgrorvCJ#&0Y0JTkQrR zU1Pl+JN?dPL;WIh-yl#|`2|#>tZl72xk&d?X~c-r>*j<&8>yW+NWx%)_&5u)Hv?PM zorOrZL7w=8{30{a%T{-18PapGN&GPjqPQ4a>zy@7pFyA{@=K^Q3|se|O-TR27T&Y; zr40+dZNSc}$b)WI`<|?V?IW~}+<6Nb>;^$y{9iq1=55t>78UttU5|Ly``5ym4clnM zJtTaq7G^4bX~6=vZ12368@9EbHx>5I`mClMd*?_|=%qHy!*+=A%rh3*R^w|=+xFu%nPk$)pNQw++JNnPA<<)NSHH$KycnxUqhvszI6Zt3E)&xoV~4v zMse}hAYjo!akKc=52?w!*}D894x56nO0PjIB#yR4B^4B2AD``%9r z=Qs9#(?~DwxilNG;cw(H zgH@O{txXPabNyZA#rFq4h<;#gj$Mdxu-?Te8g=`r_roeEH`x$L@rt)eE@nL&|7+!p zv8~6h%W`k~?ht;DgCO#&n%}M~x!ZD=B7nJ5FLpYF>}o5Xx-?1nX!520;-o{&u3zL{ zxGfVtg+)(YTyaR*)m{AO))mZ#)>qZkYPDK9VX;2}f=FLr0qXmhyN2an53Xfxj(?3y zwFk#+TyAl2J?nGWz2?-web;wQ6~DXmG2%<_zYD1W_WYeQ#qYOnV7_X7Q%z&;^V->m z40mhq+a!N8POIKGwkvJ1X#LXXh<{fhhHcyTeAjaEr>$Qx-?YASfc-}!{*n7K_^nW*kUB6Ey_yqa{Te9;x>3AL(EU~4jiEkG`BN@#Ye@(GvUun!p>Av4c3fp<%34I znV#NAz4KpdMBO9tm4T+@^Zp(bB4T>MVPtYdDBgkxbJ(^t^1QBnk4- zr<%V>TDk+}Sd+|v#BE;lGz#85gvbPlOXr=|HP53Q+;<7(*0zdfOE^ntWuYJy6#{#7 z%Eme?Y0*)x?ifB0!sILn4Yi6AC*UuGvd+iTUK$a%M& zCN-m_AX|;pG-LWo=?Nth#PxDG&fZ!dw*|QC6P0huELyfX2Wwqt9+EP^s%UTH=8QQ< zYu#o-)Qa8SxNRC7ixjPH<}oQ_tg5ywIu}JK&>CPu@`^<_$_C{c6DqYvna8Efv1-}~ zZZ4V7s`Zo!K`eGhBVsx?j?kqwgK`_Pl2BJb%3op-u4z3(CAb4JNkBSX;u9vd{z4s* zvf~4dNQRhpPHT;s3^BMyxZIsfvyiucW?q!q$5)t>TD-JD_@*VoO3!nQ)SQ#j%2OiB zYHyW?44J5P69vN-QB51kx+DczuC}}=kT6F?ZEn7l3;!8ezCG^(?q*ai(BT(xn)S;o>eBE#* zn*vQ2wzh}-$v(eqy$MK*?Op1%edSxEe#&^%mcc1#Q)|{fAb)k}fW&UL@_0cEfa9a` zH--*L7$~U7(;48SM9JS83KBjBenIEEOlqHyznyox!EjC`+59dzbMf*p?PnYLZQlfH z_*wS1-0-ZU*vE0(7b&wYDTuTHR%_mYdHqb~3};!bHSHAEZ&Ft?_B2MfnYXEZ)=p(X z5REm~Rz)*Vt}>WhR-aTj7G}jDhOw&}oV+2I#+qtJGZ|j4x|lL~n2sc1{uyVCsTpBf zb010_=bH&mfQ;qpfZ@tN%)9c^bV4PbZm%{2iT9X$Al6)44PBV0=8kESe>_B!uwbkC z7G84=#QY@xZ0H7{PPJ9@9#;)SyZrP}Otz&TMBFc2<1lyR{}_tRwwlBm zgfc%IW6(wGKoR=oUkx?Aw2M=BD#AkkUB!AhbS~7!Pl0S<>{ftzDF1fow1lm~PF9f@ z7&lMk{~9{Of7T}1TNLR=(SFW)J#Rg0~zkYjhpxO(}bLoTPKC=!JCweSG|0lA3-;*G* z&op|dc)<-mU0GzQmau(-UG2_Fnx8SJ5r0dZ3bmQr1%KXZA(-#-p5p1mC!w?-QK}d= zR%+OtOV{lUrZ!h>_=NDW$c|)lq3dT^Nd?cW$a&C_ zNK9RK6|5{IcOX=kv6KoZOp)JTOw*8~vG=G_yqb_yD#Vxij_MwBf9V1b~Z zO@f;xV4c`lQYqF`0Y@qklGd;p@R;$j{tEh}GNDI;PA@x>)PX&$U_`1Adamh+mW0B% zsm4Y~!~4se)+RF>utS7`DTyoeN&qL6PnyJ@P_QIb3HPtzGT;v9v8NSmNi{<61blDF zJZT+!UcrG>C-hmviKW%V9@I<4#j!-%W{6Z-LGcY$EE zD+CQ+%RcD0yS?lMsHt}pjt*bXJ~Xj=wd|`$x=vcJLf9~n1wR9ma&=Fp&agt%@XhR? z34{1@dyuup6==giH2e(P%a3@r=}aq}9KM}>c*1bC{DNnX&P#>(VE`O{MkW>2o?|+T z3TKA9vX4#}#aG+~m1|WYdH8O2h~J*}iWeZkZYo?H?#@0ov1hg7tEUJ~R54??Cp*;7 z*o33*g~CZI<_rt6!zPU5IriXv$t&g$3$w%hOxig|yo_;Z#lrk6^ZqwYUUCw>>~Xsk znWQ0Nq^YSEx75oEhgU2mjS!=50{-amI)dAy$RRx-QcTSnxEDO4ah4@j(xX_QA=BIy zuN0g^NuBf;vC-NV+{z@6X50bAtHV#S z{rvQLDc##QT(aVC!+=gEtX8YO?iaylDE1D|X2@~pF6OU;ybEWWekMgDT+Ie}d=&@OEqHk(9xFFdzq zCt54vla23FoFlCYlM=vs!}^rs?<>9`0ZCc2x2dT2tjCWlE)K8HXNCzo!^l3Z_@^a* zNq@wiZ`?aw8|TxA^<($C17}$SQ8^nvnO-Tbkv4^%;SM(7El=Q=O8$}l!oN7@kPO&m z4!>5iDg7@$HGJP45N_7+pG*Fg{?1RE+qVf6Mof1>8X6oq>3)tT_3C7luC&sY5zuia zfWp{=Z6~iJJtC2l>F3m5ukK-_t6C~sAQ=TvX0bkr?4YYziYkzb0vAuOfkXDz)h$&j zkZ}pP=^WP3K|Z3}&E75}s}ra|U^P4-Q*|wrc8nmlTw)W(z1P(eb?uZiJmmT>tr0{U zC4k@%l;D%IKQ941KCEx4uBQ^tL$N=9jhF$r&`ZIuR8K~^sUY0tPGhL=q)w2M;fP8O zeFA{a1t=zjDVdC@<}mzRO?cJ5W4bgYNMmveCxGwV1qU!*$!0`7r^wH(o%h0bMK@V# z?}$cD@dV(Wuf8IB8A?tgnmJ5AcX__7pOjv1sq@Ir*UU^12C;rhdUPdM4@^_xoNF?m zqB-5PqEa^*tPWe7#O0Iy^nbvi5uGh1Y|=PC2K=MEQttx%>k=^!>83nCS3Q2IUxD81 z(oA^&X!bj(cdhhb!S2^!C*?QY1$1;vDcHl%rQFoBy{X!dtk3O!d{u3S|;9c@w^?%@?4U zqovFmanIrV`I)p-2axskl*>jua+)Um;#=;5A8(?}9r4P!?B}n?p9+Z8w=SzL@Q%77 z@Lz1%2uRhhQmXd=>a^yc(IjyoTc4oZ=mE5A&Bq3GO18d7S(A)^Q_EaHa;xKkMt#3B zfL~3m;Ro)th90=7A6)j6%%P^Ma|bqC(+>#r!^?n$HC+ooXmhn5-lwC>ewI1h^wZqI zgBy#Ll382{N| z5Ac*HJOG>}1Uvo2KNzt4s`68h6a7E01!w#uJQ%tAmhy8C;Ajbldw-fgn7I2_0)Q!EQKF z!-4bJ7%kMI*=2P1LfQHVk@(xqkgyvaKXDlB zr2bfj$h$)u@I@!zJkp}XU(!}?d_81<5Gfa-r$_ZThw8Pd1|kil$|dNTQN4mtTAOvC zhCw4}xY;@a?JzWxx+4XlSS~tzIYYpPUtwyGJwluv(swq}PC%>AUk5$zqNG&M*(Sln z(e^ef-pBxwWqNK@pCD}2JTcJTU|0FLBb+xy!lm2u0$mN#uqsm?F-<@UZJUh;ZaEGqw|d(dTrfO36$*=uNN3w ze+^0-*`S9+sF-?k`yV6#bmRw38k|tE^sMTC2w#$IF&j8z5La&PdE@1?u@h1`N$?vc zl-q2pX#ym9=aw!!958QW-TrZH8~nnbWi6zA2#1N2B4N@+vq5VH;tG53*XBH$IF2q# zQu}I!yA)ThhN;WK3By!>G8s)j)`N=FT^tSn7d&F<>((!Uu89%;Yv94Ba*eIzhab5J; zN{k7~Js4*=@?%tcX&`!X(TsT58ez_Yi@g)GRm|I7hno$bsGPX}^OoP)C&zEc0HFOt z<<$LOw!Bb?Z9kR-XZ7-2hpa2`$8cf;?pX#ko8K#y$x#4p8xovlKX0%Une;GTxWcacC{I+hLKO0X?|I&Q;so}fwv-DqI{~>lN|Cg2j zz36$b|IZ&6zaADb65XD0zb9wbFV3V>{m8uG2bC1h-(3E<85{OX$Ke+cLnL_$TwdOc z3+psLqHZL&J!_lrKd-&pKa+5(_m}y@>xN&-^XS5;Ip_G6&cGu^MylJB@88XtVaH1Y zRF*VSt0<)R=DeDSU+ugAWk{{Vk+Ato=aCR2;|dP_ zLDU=P(=B(Vj>H;SR{&#sqM1G!wd8!Jr7Q60b)&!vAka~N3C=8bB^~WH3ax0PPer|RKCAaD=jf;rwE}>2 z)Zc=$v|l@q&KRY|Rdmu{L@hg?Yx#BR=(15#1pw-(_kweaziu4;W|UshL!XUWaZb{^ zs~UpblUD(}I%-vrM7wJpqOpfrF+`t_T60crxf>W_w1-mx_&Vx?AbIg_Qi#Kz`ie37 zLe#o*ir#OW5br(B6+pA2{t=|me(MYg+0#}rMSmCd(fNGKZ&M+$dpausZby9*oL~HH zBP4ZCPsJ>KC2GU@f?l`kv7$Xg6~MZqHU$@G-PXry_l#96(AT3rJ6~++4m@^!&r}7V z@2D?=i;LY!$GZ2-R;H+#5-Lp^uBs}V0K`QND=dqbRD;0pgqrN$(wcMLJ zw!CMf;w$}I)OSJJ;=PSy-}Z=bL>M9z5kk6Nk7_8=Sc)UT5Tl6prPF$>Lp6+194Uqb zMU0Tq(i0eJWUR`OWk^!Q`!W`LlAt)J$w4usC}64U^>RYJjdeLn3>nInzD!zgXK0AA zF-MglOOYgiYdjSiYi!L?XCNtC`?3~$H$qd5!2)EUDBz*%2~@+1jNLg{h5|*pFPkQ? z4y!dLb95O>6yV}5g21rr#(^9Ih6-g{U(TW+DXiN#lmh^pB1_2C>*Iut8dEvu3^fX( zFPGNW88%}a$FXLpQ;>v9EqzmA%f?9@dxi!DK=@+cM%XvwbdDoKlY%1T=?PWCktTT@ zB14-Z--BTO zy-k`q0StYLa$fTeamZCzSxAaei$C`9AT z4X8#GnGA6v8KxBQ-)RHZ5w#{`94f<{qDCle0T6!OWQr5Ru%zthD_k5%is&{0y27xg zs1u6xfQyfsEN~JTwv?THMYO@rh#8X=P7(t`a6)klVDe>?4bBCI17%lV@#5e{#5WTW zZaTw}qDf%t0X0XON^!Fp&J?XaCT++%Qo|I*&0`QLVA8h$L^m>3BE3y@xupybicTM!HryE*VrtCgFuW)@LP-k%=~z>1ZZ*T3g6}I? z1c;t$>c|C%PSGWl>W!#I6`8to`3ygbUSBC~#5$_hl+0~r1W@z|Wi2CtQP)iaxz`v6 zDZBg17Dtkzx=lm5z|<)QgmS(6oTyRLG%B})5lk`cE2rJ>jG8fx<90HRP>cu_E%&FQ zmQ9nmcNrlRVC;+cH=@3orgM83p%h~RNAH0u1!I}s#y~rl5OSaKAEADbN*Ie6(@=o0&+ZNMSm~kx;KUrbTE`>S<%vu+$b+DOH$FaV9jhjKx6f1;yh=fMHaSqknT({DJu?y$IYYZB1qXwHBRc=QxaIP30cYKT*ZEjh) z15t!?ciE7Q<#_-vk92>>1kARIl3ik7j+tt22CalX9fph@FsHH)H30Pr|J zObd6C9IbCrUg?RrjPvKUOi#u|+gj9C0*}W9U|P{nn9&{0&x=;#Jd*s z)c8cD#b_n4Z5+^g?o;xKR*R>VClI%Bhj~9uKaD%lWieBE3ekxJT91Clgi-2EG5u`i#Al0dl>qN?p_n%G6e>o> zQnD%wA;5+4+JdHxW7I5>RhJM#TsWqkJ4KGsw^XU3BL;90y!Pp-xENbYjjCeA5H1pP z6Ftq0@vy{Il^{lNKMdd&mxB3?J3~IzYW1}0FT_V25cp~6m2_FnRJ})R-~g(lfxwSgy{Y8;A>kj&} z?bLIt<*HAJueemqJ?@`lr@=O+yLgv(>k%?+6imI;ICbi;9!6maG;> zis3VOJwda^acb7c>a9o#JTP`H@Ogb}mFjIsNqiQscX~E1&emF^S`I0N&&CMQFPU*3 z*0^d#qzpcXCkT4k78h)7RJ|Q3i_gXMabJ$bMO#}|??58)mw0{C&}T`pcBtNkMBzcL zN6(?+3#?tMF-Qe`K2I1lXB=N??OhGH9$$dz=gyJiTdfaP??$TN>Ae1FD8F=Bhg9!D zs^S@#0rV?o{D?KB+6<|NFXRmb0lj~29b0XMRL2)#2Dz`s;+L$?R@)&p@Ws5rX@L2k zty8P_AvN(#%n*7Wl^|o2TTMV}<5|3+AYl7yHbvELNGzU>8RpKD6ZCD$t38o8dMOgQWsx}89~2hCV1FfuJ%XjK>+@PZLU`zLK@)9G55Kz#}cA#ZdV^h z8sRH=_ou-FNU`azK87^Lb1)CkZ&0TTYzC?$kfwMp??Dh~0hKnR)yI+M_)5$}?i=#y zR-32QCypnqs6oo{yP8gHqsOi>oO?df=OQ6G4k@ ziNUr;H5EuN{AJ8zE*J*Uww5(jNN@ZV-s9=TmBbWVhnhMh8Q+YVM1ycpVC!1LL;B%c zc#}a(#%C&R)4Xf0AOrBNm?vDQ2DREAtN{T5f0g%SdMWNqmu*PR4P+qx8s;hbFXovM zTT0C>WHA0G-qWDJ+Ri+;jjj0wc?5qQ^Nb5Uq9xn2HNPT5@HcqRrh!O*woR=8Jptc_ znL@uqot3f6tpOB_2R$L^o$*;UyP_JPx%iuyY3@7nS$(_mn)^r!{uXa~`d!>vTf5pC zuodtfnCIxfnP)xhF4sIpM&p0xJrDZ3?QF2!^_pkM7(B=e+`q@pM%&%4`5hUH|AqJa z^xrFIQ|!8H{zS&%!DT=%qs|rB4b;3sCgAVzUIZ;0pR2SRt$B+~#CKu-;4YKTwc0(c z`3rd#|10m0>E*a{U3N1y?~%Y_Ff-`)Ovta^)O}INb{}iLAXD-8cz;g6Upe>L?pqCr5BMI;EP4f%Bx5gGD=wFb@8!(~tr)}bjjY`& zmyH)-UUFB+N&5CGwcF%!@qN6P(<^aFw)Psephe(?m^t(+Gs(jqSF0#jfbZwc1+BIv z1=}0dZkJ==!II#vjwMCgTh{K7E5Z-*UQMsAB&FCp)b5gF;z61~uc49)>|JXya%}uC zZ$4wtIQR#cH|P({)#4xV-cEm5N&ak~TDwoK9uI~E zdL5M_vp2VvAlHZ==Pd+5KTBcb%M~zqh>BQ|>bUF>i5tJuby|Z*8rQ zTr++WvxEl!!ej5{T7S7#{1e_%&_8V{!F#XQ9+JC;e~S5w`_EWP^xoUGhvly0pYi^h zhHh8N-tO9Ca&7o2%sVvL83lU>Y9r)s;-`7)xle zC**G9f9L%@{W0!**WQ`hQ*xd77no)ACnf}vZ)#7=b>aWuEeCySJO6y|a_u>}yZ9N* zd+w*P^Gka_)}EK^#{bECKmBRt{O7&jYSZL;@Uxf|^akpJjDuudmYe|plD87HVSGW& z0acH&4zv8VPqBB@UMAm zL7QzCf*p+ND&!vE-(Ws)LG*}ru&k?+8^yoneV7KdCB?y^u1;M;EmocBXU&byjIh?KgRc;3Vp7&|`%gV*i z4ykqbJ-F{$-P7W~-u@&0CI8Py!{Csd-FLSR9Fn)6#J@^^lS<3oC#;(*UVXcf^_BEZH?4f%gSt1x zAKq??|C|5KJ?-+o$-1TDf8Ku1`giynHSPAk7jrmgM!TnE0%mG7^*(kZLaX`-Hn0xlhi=#mV}y6N=1{v^t(8M?lo!I2R- z&DF=FV4q4P(spY@)`Zhi{TY;9^Uir>3MeykPHXkaC@{Yw<+`@M%vy8$Tz?U@uX)$J z+-ERo#GJ(%GElHzBobvSrIoGVEYpyKA~ZucFa?AfZD)mse3VPGcBFilR9LpDvsyzT z3RHo4`Oi`rK&`YJSSVPq5vgD+-H`3)oTlGUhVpFInO8`GMI_W&jmzoK~5joa@ek4cC|lsk?>BOESqh-Oiy6ZOlNb0Z~OClgwzUg-|UTaR+kKwuUKY3>6BOt%&K|SVCvR3uY`89NHzsW^O8>r(u>E zM}?NPJ`#PYh%nSJ&rG0#_7jb?xl~ISYgk|=QlXvMiVV7RoiNq#j(L`9C)~LN7Em{Q z*~JPoiE2;O(3j(08YL_=tTR)ndxaX&a(6Dx5LOyCm=~zv&9%x+Us@(?G<;>IQuhgW zEy-af9lI~^Sp_=jY_Nns*6xNTK-O62+_DvmBpaC5;3jv(|NH( z>qd1}5!FqIS(4w(OC>rsf>1;S;Xz*konJ(BZ^W|LR1goM6>RcriR4BQil|UwY*h%# zzfKHnG+>oeJ%u_;3d#B1#Lz}#7KaLck-j1~f0RgVG-p*(!7qwdypumejBB)JL1~YO zZ&jSmUnV9s+Ouk@0CkrXH}k&{Vf7lTo(csxeI;}O(j~8v$ZDiQi7gs*BMld3qdSXF zgeFG)3Iqsytl~>(beHgms;INVt1Rd9xtZrKd5J1yw7efxZfwUgR>=7|8;zAvB0q zv7y(xj5ShOP>3QLwyFftue(e&#;~B{Bs5%7Nv3zZ%r?fcI;ls9M*7>i^ih|E#za;Z z^{CJ&dix#vjLS-666-ECgt(`5`!s#oWux%|tDAaE2#ugk`ZpI5UOKCX3YA%XFqM$5 zQoL-IfEp$=j#jl{Xt<(yc`P9{oM_St;*ybTnktXM8lXl9p^K8taB$V+FD;*2f)2h^sM=!+Joa5Y1ZA(~MYGYhE>LlzLofwuIhfq`Ert>RDq{ zXyfXG$W-L&&f~Kts5GH@w3~;<1 zwXvqCP~Fwv!7UthrSdvhPcmeD)z6wbKD@j6-HffKD-cT5*9yC(7OvSz5KgjP#C zHVePGrt^AOvs9@0>Vx%!bj#xjS#wlStfSR!iZtAqydl;+HGyc;svcBi+j?idAl|9CRs~V@R6gzu?=x+<4v*NQO^?XT6azt#kzI! zUa*#_=Y)1kJ2#6`-FkSltQBe!(OzEzU0mcg#G7ZWQIm!C(Hb_zwQgg)1=cz>g}Ap> zBdGYg+Z68|>mwEF#Y-B=#ocbRycO04^#T#pS8nmB+X4?nChA3@L-ejY#WQXzybTr{ zE{OYDcTE>ByKV5kvfwjcxNm9KX7M*S5xxi;K6{Cd`kH7aeBTmZf-Oda&%kI+8>WUk ziZ8{MpuuNRt7Z_>$X%5WG7=3m$|cQYrh~gCAH|lUWfPtCwYW@gcU?ZXNwgdx=!|!m zA@0U}D6G(+*4(N!&5U)o=Bu-jG*Fe6z!6GycjRlbQM5cFQC}O)Dsp${W7#1835n6# zHmq8AGGCXiM1u}=t9B6Ux_cnsfUQCUk!eXgnbqwc$~R`K(ilWneGHd1>Q3dGv(;$e zHAQ3Yux8xj_||OD(ur=Zm}%CsdlKKCtw96LX$iB*`sSX_cVuhQm_&DdXxku3d3+*U zn+DcXG}eZ#L1OaV*;pF*POaD=wh@WL_hRE{;4Cd+li3cWdOn%0O9Kr_Ux&-~CN=W| z*!nbZqM~)~utP{~{6Mw=4Z7E@I@9b}QYZfi+lU5=)RN97JC)SK4`oBShUle_Lzfhh zhWL?eQyM5z(KwruTGAMw$~LD#QM(lvRC1j(#gAcI(!iKn!X=kb3)X}ONRBGg*+QeYH(m=Ob(oHUP@X%~x zvfXKXBDfXYQg094rc$;C4eYCEy*s5L9>z@^wigWws(=jAWTO0t-eT!l z5BsKCw$I`fi2xaW>9Sl8ViUMoi_O^q9{PG^_+wc!s7$sg@6 z)Pl19_L2C4^tx1vm6x`m@T94wUw-Z@l z^H5VP_a4{j@CzpW)NwF;_s?Z7JWlC!`W+!%HwSM2r0ku?Ii0(HAtZq9bG!cmMJ!FH z$1jxBW)7Wq<#JiiOFBZoa8i3mV7P$=2xG-MLwM#%1HY_Xm^1Px0XqNPI2NdLg2A%AN&Xiva2>@!N;gj+h&tG(2_{EX{ zH_jRU19sUx9e|M}z>V5Q$`uUHK^P(3Q)zCl7xA)o2@sa-NDosz zZn>A&Wn2kBlk5%BS4XbOK3|;P>k%hKPo*wVfHty z3%H2e_ZS2@C8~lsqEc#q4vz4+L3+HD>Su0Psk*-q=k^$UIVBp~d_OD`D8qR^Zjydn zN}Di0S!un$2Iun_^f{$y1&c!1Ezoq?Usiu$GBMiOqNy@q|5e;Uf3WG+qcbh~!KS-~ z3oiM3{2SqW%lE0Y<$W7rKW|x+)irEn88RZ`OD@dY0&_qWwdcBTH`5riGA5+f>!=AG=H~>7YF)LdYCcb$$QT z<(QJ&wBLmg8z)zF@1MOKSJFv)L4+ijTQ$1hR5Q`Pi}XiFY`E3WAnLuxCHdba&6uBR zw0ctYZvQ9T1^;f+pB=FB;2-ezzT?vUdq}h9aoX0()w14O@!9?Y(#wvxaBBYwfocQq?RbX&0O?gn{G9a}u=;l4nf^nhdGiEqo3d&zZ#=%#e}we91J)({ z43gg-{N6E*JXq7RCjKup1v2Wd$Oho_F=gBla#SnyNu9DV{(M)3}uIBzRT%O`2Y!ST(wSops(9!Z>W1;DmnoP1& zOMM?hpQa0J)g#Bj1ZA(x(NOiKlQe84idn<&5 zac2%#gorpVj<3cqB6wn#*@N(N)wqShL`**}!DN0z;yLzBD)6+xZOs*T;WIzb`#EVfS~`gt*jEnrXf;phBUhc^;o-=I!isn31< z8~+c(o9h=cVKoEa=P`cC|DWN{i5CS9QFR?YzvGwvKMj9bhwWuK@QL>dzvd4?N@A+> zzNWfKpTF=Q{UIA!PtDxdUpMdb0sq+_;*LaEc=5V!-RBGboB#LW@9Sw|j$7&_$l|)N zS$jm}3@kR(saGOz)0GT>VBw$iOh=b`ELl+(wkMB>oyib5M%9~>cjzJmwvLGZ18dT9 z;G-3z3$M5li8GnbPEGXzEl5YiV)7Dw5flc;k)=^Sym42O_0vi<@$>0wv!IT=6(*+jiO>%Iv zp%M(9uX8>-XTWL-6>XDA)dJZAxu%4ghA}ct*J4tw0P!R@f$&?yEID2mmQocU4_vxQ z_@iNkoUFTdQlmib2{@krHi-CU=t5Pc0CgbGl(@4I<(sby4Tl2xC!l=pZPfH->Ha^q z-aDS^|BwGxB90M-LZYF}L}WBR$$9T~$W8-saO^@TJ0dOHFd^?E%Y_xl54+c7K6E|<`4!Q_~ta^TqwA+qf9Te@$~ zt|OT$hfP&TDZQ8t$gQ0HNA9bbnyQh~4cM*QkB)p$@i8?b70TmJVdW4e{i1T-6yP_# zt2tQz?WrTbR4$nAAr;H7zQtxBTl!DsqUl~zNiSgoE)Chz<*I=2kn776PT_iY)*fA< z8f{7^H|SlA3n4W#tlD@QTa zJEliT)$*ICNIgiJ9#YLUg(Z>RtsK(qZo$#xss*OzB&#>yJ~DMAx0k29-S2yE z*Rf31C#GjfT|LOK-nzH{*nQP!rZDg=Pd#;@{GQFRLe&9Nn1|}6+)AfN2}45bL5U(%Oy=iHs`OBj!}c~tksd? zTr1P9`KzU`sG-WYQ;+oKx|r_BmzR!L!|vW5f-G%->7IN==>#=g`HtLC$-Ed-G=H}D z8V#Cg2t-3_taYie+9#vC=vD>1bNCryeP zeAJj@{dwO_gCM1wtp>j^#?&ld$1EfNuvwm(S$}>E{O@H}3!&X&HOu~j7;`griPk{z8VgQSD@ZQH+IIfsVNXJHhOsnnQm{4EzQ!^W6~X?NxK`FN?7< zTu`??yIsOVr|)WWU6z+6H7YJWTJjC9FL%Q#2}E34n= z2d&PnlB1TK0t<6Z^`!nTnxk~-b<1uzk+hyH-70-*`MKb{`EK>h{>QYl(q${H z#5mFBi2Ch*knY@qeS{__+5CX|{r*0hi*)&Qs{@=|b2D{ze?N_JtNf{z8>iCTR=u$Q z1I#>zoId3J$P#U zne*E`NWH%Q4b4Nka;1$JSLk?zdUHSMd~U&pMU%Vcc$|8B|2vvjx!onrs|kJCml~WA>rbdxp2vHiAn(ep~&i*{4n)U+~o4<(eL6t3NlJ?DU-h6;Lbp z%<)q7A+yh&e!kUBwqsnM;PH>zg3d{qy*O`l8vt&XAerPq$^^kDHO~~XDqgB$eD|EMfyT$d929CVyDJB^A%lD zGtEm+2^5E0m}qP;m+Xr6ZP|B9x%j39rLoz3RoCU2me5m3@g0j}8fxa!T`|6(?R9{y zptT10eY#?2T9=-VC~mPhtpV%Rt}DK6`%d32erCbY*kLZ;6*tosdb+jvy@j`ik-0)w zyl;CG^q}eB4rt?ftqjZx;6uOXQX74 z#U0J?Q_MKIRth9(`q`65~_6#VFk+Mxzt2ATGk**xy-lnq-u#1-0j5o)+ZqM{C zb&e>bTW!?5Zcea=?VlPsXTy!C#!?!*G?`C_oEU97s~LAB+vpgQYywx`{I?Fd^=oG}@1 zHgD`@fV=U79P6i?PcpvjDu-89kasSz9^!nKImd>q^t}6}2Tj&*Ip1Xb*)GFOWJJwFwo=?ih`TH)l+oBa;^JXgxz0v{E0h$@fS`50hh^nf zn>Ad~q)0|{>*$1sf8`zoMDv)RU7lXQjA zhP=!79ISM=G2pIEif6R9zMJrzs|>c;%T-EBV00kw)x2bR@isVjQ_^+D!`AmMUWPoD z&0(%e(oIGuGM4XU$>Z8sa5a(=8C|Vo6JGwjIvaZ~#IPBUka0Ed6kdesekxex|tyhgs{pBt>6w*Ae$kW|Nb z)B0uN++6jdEngvI!x{Ok6d$SQ=yI^!oY zuNIV2cko1R;j^R(#!TzHOAxQl?nF@`1lSp~$U=V5V4eGk%EFgP(~MuO3ll+eb-^bZ z3L($V_>KHg3zn^qKhaV6KIuDSuJw;guwgyx#FIjZw=?FEzxlzI_1qH!g;PnhjD^;} z6T$xVbtgs&A??oigDk3rq}2DE_*nQeX`b=7bUD$u@}F3l%L(2H|`gALF87!#aD3BFM(OE=8BH zFIqNiwO>;tnk?wb-?n7(qJP64d!-_X%DXN@m#SY%X*g)FQY4j3a}{V?%DBX9u(RJ* z1j%_tH1^n^Ez(Vv za|PcVBaGMh8r;f|x_1>vm$SnL8>j8h7wt-3=enY8`DEB!q#$s1fH+k_b5hE3~ECKN#?-*qJ_%nr9~+Ilj%Xn*o%*Hvx8li~hNdroE*K}6qG z3Zq%<8onOkI^XL_$g)W8v}%>a^lKkmpMQRXlf@7 zP@ zosQ539zs+*am}$Sn!q5$X#*}Gsv`rUyaR12r*COPm|k>yqHNz4H^{kUXhYUqR98lB zRa{&fe)_I<-+;5IUZUKwI1UgB9PJka4AC7j@;BnTVLV!{Jv`ths-Gy|7xx)}g<9=5 z158l^nYF9p#oD7!w`#u|@Dv4?(6M+;;1{~JKMZ(_8p$Z!h(FMtd%9nHa==$~XQD!1 zyjy$a=~voc2F{7@l3BOvYFvBA=`rme1OB4B6W1NP%7MRb$YuTkQew9b3?fCrY_RIO*u&^Ehz`u@M2W;r$F6Gv zIB`G+##o}HjPi}^2Oj30G1E~Wyd_E{D)(J?1CGL0M{6)ibiWMD6XHNd=%52EyXb+$ z&BtzV0IP7*(H~3`Jt(u~#*OZWAJ6#e>>SJxJ(Rem@5X1KEP{0Y8_X0vETgjOrdX$t zLxhgWV7BOyM3rMVH37Pa)4>Lbw?_n3V*#Px>~OP$Oo2m{NLWTYckXaVFFBY32(F-- z$gRtrsKcF-qbYe)rjcqCAQ|Qk1tsPw>?t!r_1IevI~^U$N~}^iQ|6Jd=Kj>_=TK8( zmr^)&Tu?(KQMfD8p{3+hO7Rp(5GepQ5*;3uIHr_NSqf^#CK6ru9G;c9q?AutMZyBz zxvRqAWr=&rgDGplts+U6yV@Mymw2V{rfebsX3Xn)?l4v2mr^}tE2tHl^ssB(;b%!e zO6`P+f>F@k#hvVAP_>}gk(}Fr8DVHCij+;uar#zfG6A9F0-Xn8Ijnc%F zt|?Xf8jA2~YemZqk3PdP@yKH<|NKgV6Atdz%7PJ+53slwfnj`Y%;l-{Yck-8Lc zB8iUsOYf!hO*sqd#ikP7_Z&@2^Hch#K-|~`*hqz=O({3!#S}wuhe+Dx?l#9Wr6nnY zQ?8MKXXbT3cXTbSNEx02tz&H3!|rj%azTiuKXUg2sAR1Br(@uDNQ^&X&VuDppl6v= z*mekVKl1Pc#zYxrJh9s$U;W5))*vh$0SUs5?GSr@+VcgeFPAICVgmA;exuHk=gmo-cKajH{K=?B@L8Ze1W zV;y;%@ASNMQg&7&@ZRoWmgnOtr;yjBUu1u4T-dxvKJ(h+PN(tGAF}frLHG7pXBIym za+)svCHqGsc=La0nZ1uEoMuZGWEV9c%{QF+?eUc3-|hbf|A|6lmAodwZnBBUHR;Nay z1nD917*IB|k?;0_m#Sn|OAA+2+($pD)icJmUBE=A1oRrYa}RiE%`#b58b_ zoV6;`lv~Y-9Y+>&F2UaJRGGG%Ea!?Ny7P8+@6)p`WqNY*oVal`5ImM|&w7;^$|-Q- z9kJ@$qrKnH29)iVQ{-G7#};lcdAig&w9Hs;Jtx5t-+5>K)0NIKWr*BH&b4to@QyJM zw%5xDIc3guN22=9$)`HbsbvS`ws3BY6AO1PJ>BP=Q+7m7m2=aP+<7hD*vU%D{4pwAp~o-R8l2g8`nhtlr%_Dwj? zmIcb~(agMeX!!m&*vl@Kg~;vI1hz*$SMnLnMX)?fZl7lMy~Ebv+LUtwV_pvZFjr?x5!Vd&h?JzQHbePkE-?VNKwI5HcQJt(x2~QUe1;?*JR%_8_xHHEwx>Fp`3+g!De%LP;Yj+IF^?J zoXojrZp|+4@7(C7_h1MhBAMei*xmgfU3~Sbhit_P6OX5Xdi1ADpkAHTiSEMLGpKPLi=@3-}yS~+)@`B|B8?mjnVu=So>F}llVt-?61ForGF8?tiiuJE&NhMm0+ zqgwB^6|?)ntTjJZ;6*qiq*?E+m1lRQAN0N`zqrZh(i^w(?&i(fgmIA|yPbvEFP<_c%4g&PIkn?2Y!S0N@J#c3WtxlnXzV4v%T3Q2ibi8-FyS)2{Y z1GNfic~~Hgp9+N9zEiF`6|(ZMZgD(aT|5fdw^41PcIZN84PvZSFv6mUhN1ROW1OyIw)a-{m}YbgnKtIi%y3T5&-B zKBup3`;W4qp}lU|JK#c(duHyky*vYmtGpd>{l)b^ckwQ-9kO>T-eEah5ck}iQCj{A z_$%HH+hK0pi|33V<$s~HuyM!9;i9+!bJy(^3V>rh+~F`>5;yqV)w^Q%aF$!|4(H*r zxFK`5(h6Ikvj%s#4OhesKX?045d_^lqdPo@E8||8yKjGx0kGDm9lpaLVtwxJ{h)Su z#O>P-|KXar*XGR92d{wLn%faHTo?D|IrGPZzr%d)OY|=dH^hyYdu*>%0F+BuKVlfH ztW2-FihWCj41(tCHOx5u_F*8(Wc+W`9C)q5 zyrthYJSO%d(Z8?8?X>|jL;vwG0A?})t7_w3Nv)%vfkzjXha4dkyAcoWWS)_-gLt^2p%1rsm^ z++=p?k6Zufo}0Z8R)@T~!|cQ35ukM9e(8Wf)X<@$8|870k z{l^a~lJ35F#+=ljwO;7{I~yDZ$6oK5KlJCV|8_6>g*4ZXz4^&p&|kFv*Zpr6x`_lv zmU-|SKuK~B-?@t>4ay@@9wG*UHvBzHeq9WMBeG2%s|;v10zFI5U21M{fY61!0TfpD z@c+8R-xx7M_t7~!Bhn-AD>Mww)6RHoH-L`L9>H^A&5dIt zJ{~&_*4eD+S^g`Gze!*;+{46RgNMrF#|Ol z=^om-h~_2-NOxEpY_(b4Bl0VPzd2&G#pASrj*V=O=($Lf=DVZMJQxN$Y~*{yenp1C zN!@!7Zv!J6g&y&9QO(U`qdz?Y4ffb5_N@37#ozMj)l$#UO5?Tbxe`v%J6qPjUFjK9 ziLBkomHZGL*kb&4gXi^1Vy!ZFrPJl=mXmLFJX0$Vtlh$0_2KeD%O%h$ojm1b+zxzZnE0-;^%lxIn$*!lA&#Fq>wOZWOA7U3;KfSu> z*=TU`<+k`W$FFQ}Qvm$#p@G9oop{+7SG?PHzsvIMHE@2Z8!vY}uC&b-XuLrKx0gHO zfCBzF)-{%fmUPg!E`*mIiS4XdX zraZ9$&i4-6=5IAmVpH_3lR3WEIy`MRdr9$P(vj&6Q6PwLe!s(OEht;DX(-4Nd3gCf z>a~e?J)M}|6m^|?mdu45SOE`s!)d+cX|df8#~r=P zcth!K(>tQly1GA&`+3*!06(18U!E?~Bm5!KyM^~Q-E$h8#Z-^#heYp3JfIP$4VP!c z_7ETLc|YS#r29@AMP+nB)~CYzB@f`l>7C12B9AYBX!Cy0`=0JUy(@}EJ>p2pps;qm zk>soBc>3|2?Y$YmIjR~-zlw=RUgUW9)_%12(KeEObtN7>e!H~y6=08sMhdS$;`-wD zkKVr@FZvi8t$&pej~~CY{iy;_kc5%)tLyQ^i#y&=cYn(AIbzfT!A{Q|cTcAufum>h zDs_d#t;Lx zirg)*0(D?9<9$1-&L}h!mJbR}Ki8W~_kC=1*0$`Rl|G=EW|IZJFN|DmD-K#e;Jkb8 zJ6YrV#>m4KrVIK&YTlZBjCX4IY060C zc*^n~!JdA5acS3KIHs4Wj#X&edis9x@POx(k>9%Ns|p=k0s535yf&4-F*@aX#>43| zQ6?(+E=ejtRR}Y>1T;gX{%~5#4 zWqc@K7`g;Hm{Zlo3WHo%r;44!*`J^Kxm1@c40GK+R0Iw;etzrcRn1d?^?=iZ>fzDP z-~B=Ys%sVAaG4(-EDSH1UV1LHx=~@2>)}+n^X2;KmFHrrTNU1MJwH?izBHcRaPE5b zLxnM}mlLo0<;iKCbE(zc3Lm)MA9xEO(%yG2r@B|+6W7NHuCMIrqv!Ig`xPd+z8|Ur zUn!4EdB+;I*?{EZ7Z}PLr%#VVNVwI3RElZ`6txitWC`8*h4nJwp;y^Yxc7?GjFs%oP6*9eUE=u&0&@b^Cs4*4(#ng z|J)i=mKyU`JIsH0-|hU1YAje9%tWkbCi%_qm^z6bj^)Y!AOF_W=J z>Okhk`*+lwVd*ea+8;5-4S%rwpVXXX=`vHXZZ?3rT>pU@SJn<@T6_28xc`qj|B)IG zmH{&z>rn@8x5xiu4aCfu8SOAx;{AB-|Fz~kYZsG+J!S*OJMI6w22$tD%=X8VALf26 z`t#LZWbI{UVNcY7>J<+Vs)Z0bGrJweP=-I(1xVCJv*^qmtd|Xt@791dwU9|?-fr)m z{OJF4Pk>Tw0t;u}!JeuE^LsErr4}OU%)9L{v*P`<3)ohh%-YYqhxM@m0d@~Cs7+@b zWZrM@oBTBQGdN&xZ5Hb=GZ%ZN4n%N#0A72Cb(ERc4g)U38CJmI+FX_?Gau_`10c)| zu&6CynKQxHJ~`n(Qx{-gTg0+p7GTfSffw!x2sv9@#VOlA2S(Snuud_H+hKNQIJ+(|p|*o{ zhFO9QvVkt%8kk)Bh~>xx75wCs|LmT?tlB56v&=GVNF89~gMqoV&sZ+Z@^%=s@n-D; zi)sg0uFMK-nEiPW?!L;}mn?VYgZAOc&vUcEfep1IEDvTS_EH^CgdL8(+_BZPSvkrU125xye@OSMWRxq=^{mtZ;xnGNce06-87nu#%h&o`* z;unPKmSu)Ap=_7&)$sSa3leognc>VPY?KXD^VSP%>O?amna%B^lVAOR@4282n9fpIv-*y+a)vd|A!feCdv4MGZzhF=YTqCo+{oUlZx!=JT z_SPw7CNMj&_v(N^$6vtfHf3ICK5U0cqTw9t!r?lV%$v+kY>W*=H1~orZT(RVeH78dws#9&LA_L*@Jyx11~*&;e6e$ zOcwKT`-jONb90LqF4pbM%wj&lKB@ygEglqIN6*Y*_O`=}(r|uVP(mG^d58HF`@{yA zdTUT}-Tusb%)a(dlRy3E_XK6t9nQ>UKEo!|fvr9mlv`(-na}KRhk+(<-Y%%9&LXpb z`5c>M&kVxzv$D=6lgoV3J~=rvHy<3-P-mZ6#2mn;)PcN?59+8plUc$XY@cGx8ZNMc zp46SqEMpE~pV(h54Yxx)8+%EugmLe@p(M1q;@P zDK=@1-v4U-Tl)rit!@oWM7zMAZzpB`w1x&a6 z+%<46Zmz$f*r_#kA9jMpf2@MH)+Z@G(i-3LBMpiGT!MGhrz!SmeYpQ)c<$SufZ#p# znTk)eK5qFbKQH+=CK#>1t@u>y)BT^;^V)w?gAdl5v1KN0{s;_k&Fk5U&$TA+ z&kWCd{;diQv8yjs9MGEDGAqAu4T4jS^`(kKTA%O3p0oJxP_TRb1I3qG(_4O}E%d^; z*RQ@>@wL{M`@e=4zWtpK4z90P9MSr^<+uDF$wgX7WPP*ZTdi;Re_Q|2UX%-ouWwg; zul0S)T-u)_FdI&+?@}Ds`f-15_>bqJQ3$L4vEoOqpIheT|6T*D?q! zUbG6~*1u4k(wg0}koLD12FVrm!-~^dzwR##|NXWY5K>qFM)9lG?=64i7bXA2gtXPa zQ~a(4sJZo`_P^ASp85}pKegt!{7qXt0#oPb^^=OTT0ou;FM9r~3VB`sMe(=RpDl~> z&~(rlGG6~fab62RbnAb`|As=Q>whW!(OTT{FYRA1OsHq;7Zew@fJ-0#_wC<&$YT9J zMZRr(Dtv397D42qU<1Dr^h@UQ+3@M`$zK$208D+`Qk5m?d`DrNEz=;PB)E+~cgagW zFTR}@*EOtA656&*W$D@_*ZHW6n;TXs(Y6WX!gjrc&-&ulhSf@<+XPkk)0aGj+4qhH zc_r~}%X9f(F8R(EcyUjIqLRcmA(drom#$nAdl7BesI+pMaPBgjr8-N}E*@;yq9nDA zrXr9Ig$wM9<_+pfQ1hNE@N%iwlIn|g4O&WTwu!0;uI0ZD(KpA2?Mianp!nH_zhueq zMfV1MrM26{RhFmoKZU8fU&Br%X#UMz{*wRul7)-G4gV=AfsamEa+x^r@DY1WM%GJ6 zCJUJ^+qzWtQr!RX8STYJHcG5qBYbn&L7?St?L8Ex{1y6XA1!lPs(&fH;b7L5ud9S; zq5#ihm+mwi%~Jg;6;0bO00JR-I7o{0e#gs(q$CWg;$*72=3p|BsenkVI z_1jkGio6u~zBKSsUBd|_=y+2RT`RbfKlV~v1CaLHWOGGr1a*%~L z_`ka9{=JM5Jqh__v1bm>{0}a@{9l96S9u|E(d98vx%0lkE6ecf+Gz3p%k%kPT$*a| z%YqhVp%qskm;d3?&xU}k-Cuzsc?A8vzb^f02+sQNtD=yEs1R-0^3Y|Cp;^XXfg;&2 zq_%8zsAywkmdRIWqqrhOf-Fd?F(wQ7x*=Nfk&w$W{m`|I@mbi{jY2C$g=3asp_>}7 zXAxh4G1)JizwCIZMq^?Y7`=s7T>${VDO9&HH46;a(W@Q_Prz}^u0~eYp|4wnq(o^n zfvC_BdSgx&IFF;H_R~t_Zib3VooIlfivd9V_XuQ%9x;ZHZ-SbIbQ#S~pg7dhm@{IY zpgth|lNKz{7<$sUcmx0y3mIJzmOyW)vvK(dv|=LvFR{s=P6j%~=$+&UEK4F{18eP$Kf|6mEjax^cLStZ!kLVuI16(tHIC3UI z$3nJD)J{-4EXBBc#4%y}fb37vV6X*b8~2W!P0+QF(-mV09tq1c?jLbU&>N8R5vvnC z8CGmOIO3YH!$Q7H?6sh07|;0Chw{Jgl}tFlYPYlIzkF0hhULz(6lx? z-UI8{I0Z_Bknp`tK;U>lWr)T~IpM3}c+;lr>mEc0#6*mQGs6!zsbt^uAaUh_l~%%q z;TBCA*@+%hhw>Eo4(h}0o3>>qdqBU4#;R1|$Khw2bhA@E4s<}Kq)PZrxJQ#gcDlzw z9J*tNgujHJZ`zd&BJz$cQ=mWi7k;s6Z+4c)VO&K+N{+T7BD#s5o#Sz&0|F>UG{uO7 zCOrF&$5C9hK+1}y6_MPuKl`2sn5d_u0%-q5WHo^t!2_yFG^A5$haz&DOtT^L-2rKp zD%y#Nq9$-9c$nkr1=2&X3#n|f$p%$zhx(NCJS`-mp$XIp9u~NUhK!uZ)rgL!Gub5` zmK_?dGDaeq5l@=Hq~KwNYZk~@i4;Z*G`VJ1ctG>!luUp~eZ)u;h!s4bOjBcZs>tJr zk4-+=RUWn-kb|ibc@y!q2|NoPPCn6 zpUF;xvthSM=ICRIvukvvyt($ExN6ibldjP*3GZZpf!x6ckzw+9^n--Y8Y3x%cyS`?u1VkMCkfwV=+NSV z9D-x=Vsui%Z_Un|aB}M$Rc->?d5Lq$JD({`gDaxe0V#zi^w?;uPn9?ntNH`~%6!>989^P`fI@U!14m;UrfUk2ZU53xid1=udokQo+uL>5@i|EDl5_&1U zj9yN!pg*8j(s}eMdNsXv%7>7Dd0y8iMufm-JWk*Yr2^5&9_oE&Uz+J$;NmPX9pv zNdH8ipik1L=%4A+^e^bwPY(Z2IRYVO@M>G&kWGkYDY(umW9b`MAi|8Rc5Pie|F+_}zoyaa^ zH?jx$57~f

A3IvKK>08|(%o9X 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�jX_Van&TSP2@QKx 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∈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

lAuQb z{82Vaj+b^TlkSupluO-^gCg%QrO%#x&;+v# zipak}P{UM(#nREDZ3Vp&-hKY34OR*QPJtoO!;#|q@rXNRU?uJOw(WAqY`S-S#KW@1{Ll96$hxAQWAA-E;#nCOO?!5>UCEon z^nMuey6j8-pgp^?t~%#y}v?b*Y*;xlEYs3IfEH}Lgwd*#=yrm_@$ zq#|%rbGl!3#dSk&ZHh6nN8q+*@aqMG{ne6UitH2kZSyF<{S`Ot5Efk?Ik0?J$(ToA zj-k1zPf282`Rig`AoKSwSWa6WPmRqj5raq@4 zGs};ZOnwB$8k%SA(;PXg{CLTfN41t;^z&-^{1Q38{8Y)*M_{{I=ehbkiCkL#W688f zM=ZBp^SpiDMXm}o4+B%~)opA(-WQK546GlP)!|Q}QA+2wG z)TY3nhUGLIUku*HS$$KYz74!G3=F+jzhVoD`ldzg3A{cmx8daCJDLT1`%Z{D6!^<9 zu=`%!p%*mvjgLHD{_8MZ;i<8A9SiRDHAkH;ca+YErs{8GVa+iBcmd*q}X3aulzavqt<V}=f?4b-$$ou3AJ#&nwG2chv$#@H z{rZg-(P8;o?81kSCJv_c_1{{&8BEi15|!r=uz>M%Yw>1Szm~t~aSmaN%)Y@e2v?W2 zB1LsM#4TVN-C8;j&ZwOzYQljyY*Rkuv#b>^sZA8cX2EbOO;w$e3?{?mE_;-04zubO za2iu>ny4d(oCT$CBy6QS++Vv*)PqCG0!G)Zl>-rp+Wn$_9BLK?eWPKkh7mOF8PRhb znihBZ#gb4- zWSx3SWSHUJ;EKwCF<2oBXJKkW_1P#5D$?0!sLFz=*bf5Ypr{TVZ?UE<*OWTH7e~YrV!%fn!q&^E?=F*iB8Q}1 zs&b`BcS3BPBkC#4*OOmEuXO1yh;4DiJnc$&=kQO{l{dP%qPtlzZu`CO`Dg9QuI^tk zYsjfeKT<;Jndolkh5tYt)PbxX1|@B(zo>C;FijHQ$3_OFDJobpl>m3 zt2^3XPhDJuGt1&>-;(Ob-RLghqs>RNErv{%RktN$$a*&7vYa{0Bho8n+paN9djI#< zFu5HX(*=A~m9yaKXu_()x2Bjk5QuAY7C(hSe)8L9%x?h1Mx13&Clb~ic2r_T^|QsT zI4hpQTtB%J8mp&YD(=8p{d6W_!{K{VEKRpT-1Rn$`F@{zzOThb>pvDh1G#XE;b+w! zl2^(4qvB^dQHSTHzm)xOz1pNdFMjd%{S-UD=LdhLLI|)b9(g;}{B7UYu%F#mm-P|C zv9})`eqRom!0y!p28Sf#Z}%MjAWi-7D*C*kCYwa^?P2DC@|Lh&!)r(bK8f_(YKND~ zw?6z6dQHzjQX+?Q_~~-Ow!>c2HBU(G3pmG~LVz&2mwF-Ez(C?G=Y++Y$&Tv2um;}5{;a%EIyn3Q2kYUea7It#C^^;7GKN1m;HKmebXRT;_>bG zhc~5nrGD?mutVA~z{#7kwFKPJ@&@{3uEf~UkAna}xFKCqIaw&7&*_pv?AzOdEW-38 zO=6mJ!{U42e%PPx8~!KTBwllVwfNchYwOQ}xWtqF5=)%h77$H@{WXlEot%;Q#QDSG zSKps4U(5E&lEMckAB+H{ng@BpJ94Ssv^^5Dviw z(vVN`2p6*@L;t~T01u{yNJ(BUHcO`dL*bBP_#3KAig0mQ9`0w@K6vm}qM@mzG#7Bl ze#UT!HE4!TlJZ;vmPh)Twt-Ug8~RHg=YpuNpE(>-j%CA0NnI{+OV0ko+YATe8I2Mp zO}Jpv?`H{z&;w~imbB)Axv-yg8<2*n5lu4AkxR~!zn?7}LJ)tWHc1aICCg*|N4A*` zCL|j5OZsuCSpupGhfIWKG$VPAOVbhv(l!8)exqf{2rjs&`#HiPB3U-tk-W+U$xlD$ z_ThtxjK+*o30%gOQvIN^8YLo)`J~dh%q^w+xwnCqm>MIcNL*M;R6kER1StN->QZ;O z>?~n$+-5zPlxS=!RnCR8gh)Lc@)Vk}lT;RVIiTv?Q!O05RxuVar&$6f^ zg%L*!0L#=!y~sYt0#7mO(YfSMlLu1ovLTB>iXu3KQnF1(q*k*dSagtLR1UY4CX;!o zuh|gIAjJ`!1t}9I8&W^Aud)~*C8(TpDVrwyQh&4KSl};-;1WvZGG#+B=OnPe&q?KS zOI0xyMsVb$u$Uqd2<`$1ZsZUGIq59sNNFnfTxzJP4njQVHj5<^iQo}};0BA3$sw^| zktiyUTUwK;J3=WZkHrQlgWxTI947>!nRAB)W^yX;T-v5-EW#k?E{i=9jo=f4SciZx z&nag)#egC5IS>@g@)5S&^dUz^IUY!PYyc(UxnaO#lqd2}63&}-AiTI6hg=vHcp&u2 zFdISyaJLS*F~Yp#kX~o@3UPt^{*VWw5)WiRqrjb_xE~IAF)9;}O{RY~+eKXGelm0# z-gyBcA$D^X=_KyHAs~gB*yHXeSm$_A(Dx#7p<)d|(NqY59t3XGvNRrAKm@Qxc>_TSU{+RV)gnpXYpJ ziA3rk#0ns6s*$$OhR6^0(J)oVyBak}zR3B+av2E^jJd2(iwDy0a{gh7M(QENg&>L= zkzURD#uAIvr;5A5EplG^YtBy=xRD_w3Lu%VD( zND4tv#fD@iGO)t+MwN5}&L)iHARcCgs{kQY0J)VMQh<1bH5q9_m72>AwbVh16FFH^ zk){ZQ5X4wmqzsXlm4Gy(BHRGVxg(W`$5=Cv<_PHmNVP(cahgOC)-0q2ReCOG(=rxm zK$Kw3Mp`0}LXdJ1kmf{bRwB}higW{nSBSJD%CeG?SOls7La!R6Gf|#37impJ%@ISb z9w5Dm%B=Z`8dJhynTb~YNIxDmtAc);aNvD3s~O}u9!)EV#J0hO=(k!%%4KP@7Srr} zWjjHQ*ha<@At9rkT9n-*9l#z!#S@KK%V_q#Xl=42mIp;3>JL*B9j4G>WIbSoIXqUw zv_u>Z(@gfns-OyZY=47Vh@ zO(}%s>RFefCV7H~+Y;Szip{y6)=j86o(seG5j@x%;wC3@qOoAcgSZ=&{it`9#>JUyknmG|5FfXqSOTf^On zU}LD}i`sC>u<|Ai_a^#Gsf6Y00pH~2O&jh{^u?(*=X=_y$O!Rf4i6^!O{s3>UjtD@ ziZ^F?DA6CMrdm*BV=sf@MW>DU2lT217j)Qo%czj@(? z_xO6juFVY@LsDtlgg>BCOrfA{mW(BdmNw-d+^Zg3sAXFsV^69|oAD1Z)~GIYwQZ1b zB|+rpf38N~G&zsf|Dy3*eHLm;?*XV> zbr~6s&@L#lx0932B|%(>jG$`I6@}XA$d-`CS=W$}2pyr~Y&)!MB?;0)WE54$t+>g~ zUABSrlJzt4GD5eYc)~73_8tksMC28!?p*PvU99Y5(tFlTWHdrg2=FdJc8~|Sn zdW4%PjcDpXRdC2h+w#ed@G=p2%yOtU4uc3MvMiQ=fDmrhLxoa1TH&?=K_DQ#*KC~{ z?eG|VhO9ym49GAx$CT$gJVytS)d|7@nZ4%0#0g^b z;>`)tD-fop(JXN?7%~}4K&=qt;f@f5)5H{!?Fh0fkgc*-q(YKFBjX5|6>>b*s-g<# zjHx3#6XaJQYE7#c!Uba5$nFHimE3si;fgifWlR^@o1nY`$t!Cmi(@jTpX^IeUCEEP zv8qHn=3++4frR5`ceiYARhl}|Fw=Y?SdD?gaNC|rf5$e=YrczE$Yr-}!zyn&mSR5e z>7-}{6dBuL==qM%F>B;Vf=)njuU#;`!|@$vlN?RZ3jmy7O@HP16|+meG;$&!+t@Pf z+Op#g<`>@$?8$+<+oujzF*-5IG4RJ@jaJeQnW5a zr;V5Bj!ov@mA|qK{!1*3I1%Xr5Q~PCsj>$vXPVJCu6Z@6)iZQ z>NbdY?Vw8;ldN-%qit; zI8-&&$*o2OUnsZFP9L#esXl~HtMOE)$vN`ZVDSNWw``4q*7SFTocYfZ43=u*;m#X` zzbEHOfp~bO_K-7cZ7P0H&Y#jka9gR1cebjn!oQF^Pq{v5#88%F_JLa+CyKevXNmO~ zsNaV0xF5eP7s3Ak>ow32?sAK^fZvvjr95IgT>)A0UhM(rK+G-vo{=+2O*mK8It3hu z{3u`lhz}~A=;~0X;4CPg$$yF9w*qoQ8YIm!@?^>gAz-Cx(LuY;6Bo)O(Pq5aH}f>$c^=`b1|_`Evd#Z16x^xVuq(HV!9WLz!heR{^nfOntYruRJ{e*Lf{5{HRwu`9yRCBj-KFIr1_};Q<`Q7jJh@lzceh9@qqFAsY1Mat+ za)?AaU6X&pzc2zn@Q2+Yda2G2Ob_J-AvB=F*i)#&-+>@MNLgY-Lf~(A3!Z6fqC@=N z*l@GX7EhlBb(bRfanM3*${_&Xt32;Wm7k)lvqe=r@b&6!IOEbHKTr9>cBKOH@I8>` zdgT`>TWm2EUB2GhjivC2`^El@AZ_-j#oMQ`&E<_e{Gtg4e&k*oqdKJ1JNZq@F55M; z$7-j`8fRQS%m3v6jfL>M<@ATf9hcwo|MDNOzG>F2c1Eg+&y`)_umIyTN9i8w8Mh`C zS78N?+`~r_2fD-07&V#xpU+w+n)Ryrlr=fIDkvNiV7G>(y~XE4Q>3e&f`kBA{3(pte(-5rf|V-(L+`Wig^My)|F<{Ex-yQ-Srgj3fNm$nayn5xZE$z`J(d-}3B+0hqX@s$bAQ=mM{)4>^&?Lz-Y;I-yMMs* zkkX+%Ko%7XzM)28qMlqz#gxQneI_4TLVY^afnabROSSGdTT}}x>u~Z^P&#%j!+Owc zsU_?~MLuQrzJ@a`NQLT6|=|H6-v3>tmJH(*x_< zpcI*U(UctX$jq}98@^GUfInK4-1F*>ysY@N7`6A{rdO|$Z(j4WzJ$*>pdm$G6H39y z+MmrQeL3_q=wXM~JEhRPj`TMH07t4HzViC26rIp-aJAP&xD1(`QQ+r3Yiux-7kAl*xG`*3&)P;W0g3{yiVNy?;Fb9c?;>A0lUW6Fo0dMl!x+`)3*b_iVA+Lb-F}( zB5y5yCt%*^keCNj_q3iHv6jXq~%!gqxl!imr+QZq$g(-#ae~wU+1Ex@INy<7 zPKLjnz}jEuyQ~l);A|sb$r%wEHX!KZt=g2YZ2`pU_+I|NgfE{`J8(3`%3-2e=YYRM zhD3*86jsvwFe!a<;InVE>LbC^qsq*J<#uTUjKH({1mVjM3Pxn?!Cx?2by(0O1(;7? zhC{c)nL^d)f@emLGYj)(V!AB-)KuaU@`FK{n{&u)9`y8UQk}~ur)$cvw*vjz^}MO{ zR`Am331(5=EbgZnem@kK^AoJK2Sp>YdU{G>j@rnNV%JUHoXTSD2kBh+mf)39U1o9K z+c{5N{R~vT3C7y!4~kEJ>v)>zv#Gi#D8|lFxfvch`Si2ju4+hL`;pg7UnehzJ?!#Y zP_hvewmBL2K0cJSf7kD?>Vblr8HRz9CfS%FL4OW4mV(3#m19DXb(l-H=J@o6`m+f$A5Ap37?l1Nq20md z&8B?#n3|2sU_oz6bynAD12xG4!SqrTQkp0PP9Q?nB#)S3wTet2S`AnEJF6)aZj^;kb%nprnmh22`p!71U(lSLG5Y!y`cf_tZQK8Zul~s|t9bcD~?VhR3QRLtYx>HLGfo1rIX3R+SR+hM%nk{7}1A@Hpf2sxm`9>nKYg z^YO%j-VC2rm4tk&QFNfd@r;7O48K)XhJv(F%RrgqT*)1|DxK0DiZsnQ&)#Y%TEe z@vee*8JAX1Fch&qXE~dEyuSc&-l|qYk=1kb+1%r!1*;hmtJ)03Y0oXsRvw=z0J^uT zlTbYTJm~Db<8KPSW?Wg-Whh}CPdz($e7OK%->P0hiPd=3*%!w@7yQV$x~k7`Hw^-* z)#Ez_!2VVZ67CL&#R}B+NttQYx0_yCA%$W(R za4t-nundw>=PLviM8CV z7&Q`vjcv;Y?IWs;W{@F#8gc2u=CKb>1?QH3T zj^6-DCWe@5lndi*s|TGTpr$|zanh(2cDAh@#D4=q*&pJs(JJh2TR-R=QQI@S91^MV zP}tkHanR*k?ZFp}=MpvggnezB2VEoTj9wtmku{zP2imp{x_twFX$raEv~Y-R`=EP7 zeGg zE7{wzvH9hj|M~FRe;<+>CtrR(x2y3-IBx6-^BLYI?pN&RSu~kM62^L%eMn6XuN2M; zY919y8S7*Azg@{w>4*O^n8$}hRB^U5M)WMlXIWXM{DYf+#MTd4&rU& zo@c+1s%a)tJ~qi5OlotOSGbU`X)8h>n`RE-ZO@svxlpBv7pWZso0il*Ie-2_ho+ZE zubD6M-p_eGdSOj7O61`fsJEp1 zldnGmbGG`pdg(#h zXcyGZnnmWuKCh~oJj4XeTs(i`zQ`NfujW@;AAWedbMe}VCn5{Bo95BSyQJRnUCKD| zRAkw9+dQVV%jcc?rJ@t#B5Srg=CQ{gmA!MiRCnT~$YNy$n^4{}w-6etqa|L%$-yFBo*<|Uy zf)5j+AzGoFBG17~CiP8z_zc)sUsQraeIspaPmc+-~3_}N77=bw_ zh#K2TJ}(VKRL7Ny50q}KQ%*>w(!CE6KVl(hou zR*w|b;S@`?Gkt3Ije2XcKgeI5r#Ownj865N>|8q&siq@boXKH9FJGG61LNCR2T`2E zVMPZLuDxCwiPMoQrf^u(E0(5W*1IEpb<~OrIBe;ae$$=n3z6YEI>p5tr|9&h={?ZH z<8_RS%Qzh9Rem$t8@?IU^;${vvI#6@%Po+^)Iw4|uwk77LTInCAcY=Sb#}&47c+l&YUc`Lrj#|_S zFYe^aQ~-lqeX59!7i_i*^ooBUpBf0n$=qf00T#7=Ks zdKCkR9idAs9_9$3xA@If5b!l!7oONSeYVjmTFul!hUi(YwWt?tJ z@hrzVdi&CR%$M%VzPc^Na~v1w_xxUWep$F2uKS?)EypGL{iWA?Ah^ft_7($=r+4_h z(f%rVg{V7HyuuMd?_7El^VJYS;HhH3^YjOPZ#%!9xzeILU;KsR3jN{I+dZ)1dvzC! zf!5Qz{N8E*Q+j1eccb__$5r~HrFSv^bYEH2-7enaxK0On-}%qNm2KVq;y)a5^e0R2 z_duOLq<5&~Am=T5x8H*Hrerja9$N{pe0tB)Ld>Qiq|H1ftei=72#h*6&qS-~36~t@ zOrZnX-viIySPxOc&6!5;_gmE7DvgHJu7sa6oj$O%7z3o=S5K`(h%=Ku=(p6lwGbVy zr&A)vd7J)pX=!ikKuo-zafuXX4t>aPSsTDVQ4d>!;v~_BmzHC;4I$Q!!iL#{2tXh8Th;zn8Z)IAQli0mhd#En8uP6?W>GJ^ z1iS$HbH9(B-xgxF^sVGteSpdi7h9cKE1TQ2ju``eQF6v1oRod4ejq$G4}e^;`s5J zl-cQxua^=%e+8waPr@l*5nH?g7mo#I~O4Jj|DKW%;g9eY#1N8D$;Ddm+TC?Qx+UIRd+?NaT%~mB#rl`e3;%0+ts@!X}~Q3-fhaF<5u&o=QR}rA&JcK z!IY)xt*zZ_*9;A$Byz@wQkEUJRriXZREUwFjE|(OOmBznbwQa~Ria=V>JEF@^Sjx*52=HHw}y=%El*B)*L}z5WNm>Z7NYQK9#aQy%V;tcfHiWL85vb zx)F}xGI(BZGH{cqAAgbZY5M!t{>_S{x0R8>7QG_eqTRu@|Hx;_(IC2{+$NH;&@Ft4az@u%|LRF|-_fdo$EfTT*O-BlYkM*cpFr-ZYFel9ZZ&)`=6N+99!9 z*@jk+b{;g6&2T9BXUn-juQ_CT*TTO;;l8O@osYhl&-nf3N+t5c+bpk3X zPRwcy#n3nnmeiOKPKCm5IK!h`3x;8m+7qIw98QN@7~bC6G>nndpAb*w+}T)X*t_-D z@MfuDHuU68S>zan;yH{`OHH$(wb9QK!l)fDZj@bWnGK}|Q`QM3&j#AHT zr690EHkkI}Zy0r#p2-Gf)|6e2StudPXsFabTP+AAkq~C>gc75P(s9l;*&XS9p+DI` zMJn$GWrNvhdbEbwEuq2aRq6R`%^*-nHke})9vdx`hGuI8L9JNsa6!UzqqWk=Y^X=| zbA%l3On7IsSsI-Ur6p6&n!|GmUyXK4uVq7*sGoD=@Ls}SqXT6(vkikJO}XS)gc3Q7 zS;`W#jf22931QJr6gTE7OU*V7LYQ*bu(%~E84H$WWJ5Q$pL>HPCegrHvMf8>G6;$M zD8))iv@w>If>wtmG+2FE+Y>#Fm8GC-VF{&FD(h_GdE*mOz%(tP9$p zN4Apojc=4a;W~p>K?(}9b0@QzB$xGZ`J%ydac5Ue7Bl)>WTxZJ@DT z64yFaB&$yocZaSM!tjgK&j}D}_#}v&V<~GU-=%&{TxU5+mYCxFlCo>^N9x}R@N4)a zVF`9BizyR=Ve%FW_)Iu1MJPrcMI4?4-G)z!$Yq;~HswdaZ;-`=EH%Y-Ayvy%48b`G z_6;9`hdVRX(lic*;GIlkF(V^z-1VuhriutKT3F2aq>0>PsX?Y12$9K577McU6!(|Z zXj6TJ#N=%jOFkqI&(XA0Q!|A0WKPh_1SFP+DV}UCPZ?CqPx>FUo^Qx?uQTsf%(t1sOsjA!sRW|<6`k1@*)i8*vo>LfP+b#$zM4i;^>RvrpfIz+yO;LY^d{9X2WYY>S`IuP4zpCMX%02Wp&uQ> zr%ezy%cff908KT;^fKT<`^iJtI8<5!bX(n(#8`XifwHLIjLa@U~o zG&!B`bp%(ldW6elEsHZBNI_$SAhULa$0Rht$nsPCUkK4=j}WIP8(CcWz!5r{o@zFL z@SALAaU(;aLNPtxYzzSeg~go@lp)*nDzjMxzzG%)vf`A$h4c=yw+QGpuz2!;L6n(3 zWVV8cnCxVMa2|K8KK+&17sQpxhb+)9ARZe_Uo-oTxH<_PGqUp3u`lVnW`7WIlTTP6 zLxzPz87$^Z(g~A2EIwovoSoWeXK_~=e|QZI)|0SUP8QapvV59* z106-vaTjaOa<^zGf64tB4c1ek*ko3S#l7;^++WdGXu9)aTUoIdkIUb4Z=ykh5{5n= z!D6s{iF+FzL(_8?SG`?m@x1&a_YNAIs6ugv+cg$1%0F@cKwqVSCmMG9fyKM>f4Fzi zphyWrd2hsGwfr0RKKeS%z+IyG_B;rhKe>OS!I&z9>uJN{NBJ-Azi7}X=Owmo?_2yW z|Cjp!1_Ua2o7`+ROJ*7a&mj!Rj_#7G*}|4_9JIqcj2IBA3MCz~Xkde>5{0e) z|8Ha2^8b7rw~>}Oq!p2DR)};U%2}mLv)n?h6BDgQkikSvt0EdWVCy7CEE_6~Xl_NL z;fR=Zav~OsswO&H)zLr+Tc_ozQSdzE*cnO>#zcXO@@_} zY}HTmC91CHC)!|T#GuNVCOyEtWLXfY?JlEADzth|JIe!B64JI%<~m!I)n;A@5xk>B z+Yy;yk}1<`E*L;Qw@z-dSzZ z#vJslO4LtLWoJpo7C&fLc?>Who6XB^k@l_r(&BgwF{Ma*VQ6QvVVNruc#JXNp1Gq{ z$--EUiWDAG3>E26h;|^$VM&M5r=Yt@1{LiBSqpnNK8t9vUe1VP!=#b*tfW!IDVcJb zKTZczMvgVdRG^92;EH}+2&R+lja8}0C)xyqJW_+1BVWX7RTL4y2kCd*!0eH4U=1ru ziT1%&rcQElLX<3Q*&!MZX9b#uubc*GY^P9FI47$bbv#uLPpQMYpz3g7Pqg6|<)Xl9 zJBo}ii1K5UHEa~>;S>}~$sh!L zq3mL>qn=FB7hu%}n*wVtv$Z2KoyVuT$<#niK@94qX{Z6>1Ha~e*ATE>#jUd|hKT;b zEv9ZY3U0Yd*7+5q#K7Rz9n6A46bN#6Q4_cztF|4CAaqj&EGkgbQ^Bn5WFXV^xyDR& z6)%YA*4r692#UkGf!1vm^TZ45pwErKDX%j(dh$#YGHv?sndQ-}r%@X?uc{@4A1Hsw+qT|El}_DAdopu+Tlr7k z0h@y|2d8hQbvvC=QxSv8ENkU7F+RAb|4fLAcD}d`S0xK6F}Rn{jH-gqSFoX19N|sI z^wE6gLDbW+5wGNQtUu7t=gXs-nQv)>lHr|BTX($ai&d@8ceYWe6d|4(A8j zs81MM+t~P{!R*-OJx$I4L9Pm~Azr?vGI8FYvc$m7aI_GITjo zw^wW>>n7H`Qks{D8K(IYY7`3cZER&^r%9|Md;vrV=c{b+GV;?<ZnT<^4Jn8&3MbJ zCzpd_VetyWmRM=UTTu-*;RAJ_LN(jMN?TrfHE@A_b+4Qdi_%K_X%5U4MkgMP%tA}s z3K_@gYSvkD2u`COT*G=9m+4y87knoP8pDNwwr!Q}r22Je8;`&(;IeI3B}DA&u+oK1 zll4xrZGWXNsd@cX;(08Xh`F|-m4T$z^*P211n^BOZD%S&NbT!TO&-w z{q@(37uimv0l8SN3@3H2zexmntNP9h+s~DkNe|cGGF~FU&1Kbgr!toGX#HIx=vnJ` ze%Su5yg_=h4!dL6v{;Ln?HK9tq@MMKL^B6^(Dq|Htn<`b2}uRNE%*WP7KGwZOhqCfew!2`U+zNL3_9;&`zCR zNPEZRA$aozy z5NaJ|YaC~XHzFa<3n*^0^N?+Dd^!ASC+d)H65J5|WLq5PhCfF_%2rW4V|PyWp5yD` zFFTjxp+vlF7a{w=@$K-}NXWugig)a;%06~{Km5Ek-c zm2CQHkSWsWQ>69voy1tIesziSsXEy~M{q57V&nA(O8if?%0hxO{38-t-YX@Mryj~e zC^P(X=jtH?rn`x!`eY$z8Q$Ho)i#j2OFT6~2lcXgZ~0oRfze&+sVVw8@Av9`|LYG7 zeD1cKnx}(_S^aDI`o6)fyS=9t>07*e)xZ63=$tIOJ9TP<{+;(%HHew9CwuNLp4z7G z@&2j)>mT<3`s3TD_UV6k|E&g3b07Bo9I`)Db&&61&4GZMI)+lE@a{WRFw%z{Y`^Ji zs8K3v&xwYa9eYUQ7S#}6s$hQ%4P!W#q5amPVN|J}y#$)ei3Q835sxsUl-k(KqG8<+ zmZ?47*QmYJ(_R@Z=){g?)<}4uJ6RfHuURF+2QzF%!o1N|X{^0Ll>{G*rKm(xKmE)`IoTLa_%W3^Xhgd@DPRRO(&3jw4RN?v<-w;UcdR0P-fW8+3*xEK zj53=be+G~F(ehM>0kq$YDw_}`181%X9_kqSET7tj5K|_>+^W3NVWujCtg#`S1de2I z`8|gW*)HA_H6kmS`{uXGdmR?544vddM9s3?btvVd4j<8xP6~2j6>!LHE}wV!T6Kj_ zkFb?^CB$r?{0!)p4@o*$@rvu=W@F`R4oi1p$@&}ONpMhIFaP0CgcjyIStGFmN6~|{ zL%2iLxA=@|Bm>}ZDMjPKZKFlV#vxJzaD3FJiQ~AcQ_0Z7Fw3d2HyOw^1O8;U~2S=G~Aaq$2B z??;$TlQV6nVR1^;Nlxeulv%=}>31p?SC7tjg2UEq`jo*+F{1-JhBRYCkinB$tlq*7 zsyJ;7+z|+HMB29cL%WGH!j#R}6VQ0F8dePU6j)&@X27MLC5L16D@t(=m}TTuf9k2 z*idB3BY=3jii@m%K=#^DN&=f{z2XP%TJ>YTcf-mWSsSK*Dh@c_!hnNAfXA(xjTkIM zD5>h70Xz76CeB8&QqVCI^K{0KfMP1xFg2@0I+8FWP5~oo1JS*@ndLeTc^G)kVUM>L zEZRg>>N(!UOgIH$)ivPZM5(lKq+@swhsbGE6uR3sSGqekU=pX#v1#((A=-{r206B4 zUeCa)11%jED7?SY~Y zJ8gQ2<3u$GzaeltuCa5YH#okk{_Lc^!CO&0Zx==%ba;#TLb|e{%T&U4Dvdtkuv8tx z7gM7bbp>ZpK!5JIR=q=x4bdM+^F4*3c{_Z;{N!7*`n6LMe`kA-SWo$s_;ogMt?ln1JMM`yN`CgIYBwKV0c3 zs<1;&71l|nhL@ipXI4RVhYP{oNvY=HbUK?ke>u@%tSZP!Lr!Eilg)xsKIQPGD%we3 zPGa^pnu?hLlN;cuIUIjN?dKMN>P~f<$Se@@=D+e#Y|1Pt5oLM!^ zNd`0MDF5Gw|GnIOaYw5$6nMy(R@C6!svDeKYw%9FHT)V`REyy1drld$O89rd@al)d zVb!Lsca1WCz8nb7!j3uBBTj)e$N3B8Y%AbT-CRBIbg||HKm7Gj^g_qU>J6vMHM;yI za;F9^O*ww4-gUYzcXAf=XZ|W4r=vA2_$0YOQrU)m68z|x8UcJpjXD425r^+p@lIwn zNIXdni?0~LMOF7Y1;7#gj+`ByKH~Tt7uVS1tL5;sH3axC z9RCRRvo*`P&DIf|@wF}Zw>6>oPC2hxaHVH!xAA{!ZsL37d}fLoP}z$@Iy7A zPKUS+)P*=}*OuVpSeb+HZCH1WdMbQ@I{Zty^Z0vMk9JtR5mnoTe=iq`@4$L$G$33k zwWIita*=pYsoNWT!G>j2{9JRH@^Hh8sgd9^T)T?jsR6Tk!#k;Q#AUtq2mW`>4a$>^ z(@afluB>&;&WyG3l%5R`t+B3{Iss?)+GI-Kh7VIS0j3TaXTDkjWncqVdW^UR*J(P7 z)@D(jZul{^uz`1N?u@J@QieDDlUlHD)pgF!3bpCx&uU61I|^z#>b#v*YV#?hA%SMC zHEwft7oD|gizv@S&JMJ0xb4;5a5k(hrA&kbnYGEe3)N>iTh`JjQz2kwhq!CkmpI$k zR`IKwg=n->-SPEx&MxwG_!ro7?I3AK)pt3cmT$tp!k*W-hwz}(k2;@~Z^O@HFSOtD zg+ww#BWo)=cC)E?*px}}xKZ;+)Mzn*J9o3-ca#wx=zlM#}c!2Pt zG}yS%R(+HP#U1(k}mc7L;uYjAUOLqFo-zzn}ew zEt zxxA_UO8L2QmFY3t=`@gEmTR{udu%b3E}VBUEbCjB|314c8T@S%o3K`$XfDUOlmU1#?KRzSHLR1&J*%MZENq?GKIrS$-u%Y(l7g1AsCAacQ>x!=^Jmv93VP1s*0TXe1xsh7HBn=j>W^A{{2nXcAOT4nqQ9w?fQZeEl(A?tg)==jnpdg=%dR7=P30H31y*dv8 zCHcIHXY&DDEwOHo>rM-($mgR*g#)=;32uXRegbOp1r?+2fvT;AZqMt^3aHB$qQ(jX z|L^OYP>3H>d+gfU;P$HSe6HrXJE(w#z^K+PxAzL6FVduoP|tm#{6t29uvjmPh;p}khs@qOoY_9&NlBDsGv+J!t+H5Re$W`~8NS%b(T* z?gtfby)aBK#ZRaOiM4ULvnnRNfCVH3aR6EffTMxQ>ZS~4b zY={wD@i;}1S*P?G{A^2zS9_DYn_~S7=k(gy+3k?)?cMG^ip?)v)8T%gcCNU+6cbe6 z>g;Y^-~PfEZVzwVFDZ67ds;VWz?Pj^u-~sJb~$@nH@3fAJoml*w|ksoxAPh6CXH8! z^ZX#grzrM2`&u`*zw(89iKxeI#UW>Z>lO`I$%6+sK2LGfIq=yR>fHSKuzOUMV#VF?n3=NSC4wdmoLs8xtFw)3dO-dkGA^x+zX%XCA}Vj zAmp+~SN*%(OP}sDy%5=;Vk^_3no^&7cS zpB^N=9l02M|DMO2`mfGWrUM_|_J&-$-|g{1aqC5NI^5FKE)~PZ%yq@@FJjXl&4P6w zrSr~Xvwk=C+PTL8JEfOq?|=6AsrcLZhV_$nknq3X|LyTM<6nWB^4+L~*eC2AES^kC z3@^dSr!3$?6*~kyk18F0nQ)|+{{u19wgc_SuXN<4>=82m$OBOH)jWk8jvh;??OXY< zA9@Q4Ekh{om#OLfl-roFf{uJqStULfg7rYaglkxHhr6dz0|@-`gQ%rK*hm!Oso5ZM zEGzvvd1)%_OGmV)zLLbt+ee1@mwCdEcBXooDM`P~IWkOH#)T_(=6l*I$-X2V8R1_c zf}U69iC2<;NjdV2vN9EZp|iu&OG)`9*#7*hJQ10l|LeXvvue^o@{!01jigjGr`3G8F z#Y(4M!rmnQ4W6jX2bNwHN{%n9kIYiwv=Y|f>{Zv`oLBp4mgy4#lC2_4tCG7*z4d_4 zrw36V9)x>6Xz)7LSo?D2(|**!hw)y$4L--3YhML?*10SNkCKswfMcz-b1R=?FB?6i zLg!SSQP_9h?2EC9)5AKimrCbd?peQX|FU>F3MA$CN}(h)16(&d5m z+xD-%S8N~7dwp%Va;!`K9qOMN-qD9^Uf-3jzI;?`ck`bSXej*f`rU9N@5!h4Oq*=c ztX<6BjE(VmJ)ahmHnC7x5b$PiOwQ~31ce1cv{jdkH(w(mZ{X8n($+|HaF?dHXk%91 z(@#rG+icKZF!x3_67z;XEhlYbW2)i$Q)tZ1d-iFC=^Fu}yFhRC#zL3+?$xMoy)i40 zJtBHz8!L`Y*RHSZ#6sDD3LV=!FK5y> z@ZVcvy&g4ryD8Vde3AZX_WO2h8tSq4nMUY7oP!-xa#sr;J@*cRE>yAMm-ZjNSKA-G z@xG+o;qu1%tHw|2)!9d%y{{;DxxBOfr~RkS<*i5i-ZvVb99xjzMC}S+3?-l#**Xti2;H_&+H~y4f&}|cX{n29(q7!FdZk+qh^oszWbw1tF z*mz9X_lMc9n(K3qFP`pbe3SR}+|Pku8`t+9-#Fdf2%U>_yJo-TZU{ZeIz805oVR`C zX!CF18yZiFPLC_Ex$Jz>bl6mj7VF~jW`&4!=iI*8FDg9!>rTH^{_OI@`d9m(#T!vi zx=z1W-gJS2h6XIrqC6Qr{ZV3gohWEv=IiLv}xA?o+&m2~Pw~eqlc<+GUO^t5RGn^{$t_n8)A9ZgT zSJk@qZ4=Uy?v$Q_fOHGejf5f~h{PnMVFD70(k4iZ$po`mpopWcZodVjzH4yG_!B@w9 z4B-y9o6(m-;_}Pc!ySUY&Ti7~FSZ|&;j(U#hIP6aM zCF>$#!})V@G$zDi;du}gsT96C&mRXDQr_Y1-8Zdkh0W##;^<6BFySlR9@fpmmh+Gs znIkz4|IvNVx=Yx4UO0}y1R)l|3OuqQVbr{69HYJAtq7T(eCx>?$4p@Js*^s37|B!X z`5Ko@K<4(7zK0k|hxO|kk4)*f6A3b|$h4kO>n&m6@aVEOkl98)gH*|Z@NH8-%Se)! zM84?Rwf-y|WC}2q20)vAf{@8C;d`c+blD{-xT0u#5jF%OVW!Hu91Rq3fRz#Kjf4m!$`QzPm|frNy=`+*q+tFs;v5|fbqpy$)6_&t=3#0h zoyIsuurJd_PXr>i2!6URF)>`mu%-aq@a9^lj7cH^qZDCxV-Ffw5h1(dkv&%wYLM z$ezA6cCGKoCZHDLD^D(L(tnS|?#HnWsqJF0ej;qoAQ#8cPh}fZ+s9!0M8r48Bkp29 zyKR!l(7auos0kw`&a$5uZw4`HYOgES!1yN4r(fRodhG;*qkuRs6LWl0zqV~z?F^vY zPSTi+6laE$NC*@pNTBZyCS60nP=kn0QA-_vO4dMkfwvE3+X_V zZJ)@Sc~1m@N{kZ(2QqEPM4)pOAxp=alAt$GVf#V^a7YNbbk>;!SHQrnh#buOA>`>G z`4T@cX!};=c-|jzF`do$LDj&#?ViZz`9OpM-PsiAOy9QsBm#UK1Q2j$9_$T#vHc

ZyQI>$_+ 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 Usl)%AJ@sEk-)k8e70j;x4|gmo^#A|> literal 0 HcmV?d00001 diff --git a/python/client-contract/src/dfo_client_contract/scenarios/resubmit-candidates-sibling.json b/python/client-contract/src/dfo_client_contract/scenarios/resubmit-candidates-sibling.json index 082f385..9977104 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/resubmit-candidates-sibling.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/resubmit-candidates-sibling.json @@ -4,9 +4,9 @@ "description": "Choosing candidate 0 on part 0 of an answer with two candidates parts posts part 1 as a candidates entry: its candidate set in the server's order, each with its identity, and its ordering and truncated echoed. Part 1 answers candidates again in the same order.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "7175fe98eec005479f1397936dc011ad120092d5", - "recorded_at": "2026-10-20T16:52:59Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:59:21Z" }, "call": [ { @@ -46,19 +46,19 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "7175fe98eec005479f1397936dc011ad120092d5", - "trace_id": "a9c733178a6c4e6bb95f8135bf5bcf34", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "163938bcd15346ee811708f11f341f1d", "warnings": [], "timing_ms": { - "total": 4445, + "total": 4002, "by_step": { "coverage": 0, - "extract": 1202 + "extract": 1025 } }, "llm_usage": { - "input_tokens": 11227, - "output_tokens": 408, + "input_tokens": 11842, + "output_tokens": 437, "cached_tokens": 862 }, "timed_out": false @@ -69,19 +69,19 @@ "variable_text": "GNI", "warnings": [], "timing_ms": { - "total": 1270, + "total": 1771, "by_step": { - "recall": 3, - "shape_arcs": 5, - "shape_probe_coverage": 9, - "shape_probe": 138, - "shape_groups": 63, - "shape_labels": 15, - "shape_admission": 7, - "shape": 243, - "bind": 1015, + "recall": 2, + "shape_arcs": 3, + "shape_probe_coverage": 3, + "shape_probe": 204, + "shape_groups": 17, + "shape_labels": 5, + "shape_admission": 1, + "shape": 890, + "bind": 874, "materialise": 1, - "answer": 8 + "answer": 4 } }, "rendered_sentence": "3 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022.", @@ -376,6 +376,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "candidates", "candidates": { "ordering": "intent_rank", @@ -905,7 +906,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -1456,7 +1457,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -2015,7 +2016,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -2055,6 +2056,11 @@ } ], "truncated": false + }, + "reading_assumptions": { + "spec_9ce16f72ff8416d06a56f9fe82b10ad3": [], + "spec_bef1fcb184525d3bbe7cd6a0316b4a35": [], + "spec_b77d2ebaaeb7e6d5f8499a8b0e3571a1": [] } }, { @@ -2067,19 +2073,19 @@ } ], "timing_ms": { - "total": 3008, + "total": 2810, "by_step": { - "recall": 373, - "shape_arcs": 3, - "shape_probe_coverage": 3, - "shape_probe": 99, - "shape_groups": 81, + "recall": 331, + "shape_arcs": 1, + "shape_probe_coverage": 1, + "shape_probe": 159, + "shape_groups": 27, "shape_labels": 1, - "shape_admission": 1, - "shape": 1173, - "bind": 922, - "materialise": 114, - "answer": 426 + "shape_admission": 0, + "shape": 950, + "bind": 802, + "materialise": 219, + "answer": 508 } }, "rendered_sentence": "2 readings. Total government revenue, in local currency in Germany and Kenya. SDG Global Database · 2015 to 2022. Total bugetary revenue of the central government as a proportion of GDP in Germany and Kenya. SDG Global Database · 2015 to 2022.", @@ -2248,6 +2254,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "candidates", "candidates": { "ordering": "intent_rank", @@ -2649,7 +2656,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3057,7 +3064,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3072,6 +3079,10 @@ } ], "truncated": false + }, + "reading_assumptions": { + "spec_121a500dac8691cd699ac577bfab47a0": [], + "spec_2de7abdab14ea1a63e82fd9eed8fd9e1": [] } } ], @@ -3628,6 +3639,7 @@ "end_year": 2022 } }, + "assumptions": [], "variable_text": "GNI" }, { @@ -3656,7 +3668,8 @@ "start_year": 2015, "end_year": 2022 } - } + }, + "assumptions": [] }, { "identity": { @@ -3679,7 +3692,8 @@ "start_year": 2015, "end_year": 2022 } - } + }, + "assumptions": [] } ], "variable_text": "tax revenue" @@ -3700,11 +3714,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "7175fe98eec005479f1397936dc011ad120092d5", - "trace_id": "94e12f13a65a4e7292b4bc64b2575f0f", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "8be99a7590a54b20958e42ed2490a09b", "warnings": [], "timing_ms": { - "total": 107, + "total": 218, "by_step": { "coverage": 0 } @@ -3717,10 +3731,10 @@ "variable_text": "GNI", "warnings": [], "timing_ms": { - "total": 3, + "total": 1, "by_step": { "validate": 0, - "walk": 1, + "walk": 0, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, @@ -3728,7 +3742,7 @@ "bind": 0, "where_places": 0, "materialise": 1, - "answer": 1, + "answer": 0, "options": 0 } }, @@ -3740,6 +3754,7 @@ "text": "You asked for Kenya. The data holds no values for it." } ], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_9ce16f72ff8416d06a56f9fe82b10ad3", @@ -4262,7 +4277,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761" + "capability_version": "cap_347a470e04c97eec" }, "confidence": "high", "available_at_place": true, @@ -4276,19 +4291,19 @@ "variable_text": "tax revenue", "warnings": [], "timing_ms": { - "total": 9, + "total": 4, "by_step": { "validate": 0, - "walk": 1, + "walk": 0, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, "shape": 0, - "bind": 1, + "bind": 0, "where_places": 0, - "materialise": 2, - "answer": 5, - "options": 0 + "materialise": 1, + "answer": 2, + "options": 1 } }, "rendered_sentence": "2 readings. Total government revenue, in local currency in Germany and Kenya. SDG Global Database · 2015 to 2022. Total bugetary revenue of the central government as a proportion of GDP in Germany and Kenya. SDG Global Database · 2015 to 2022.", @@ -4443,6 +4458,7 @@ ], "operations": [], "departures": [], + "assumptions": [], "status": "candidates", "candidates": { "ordering": "intent_rank", @@ -4844,7 +4860,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761" + "capability_version": "cap_347a470e04c97eec" }, "confidence": "high", "available_at_place": true, @@ -5249,7 +5265,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761" + "capability_version": "cap_347a470e04c97eec" }, "confidence": "high", "available_at_place": true, @@ -5260,11 +5276,29 @@ } ], "truncated": false + }, + "reading_assumptions": { + "spec_121a500dac8691cd699ac577bfab47a0": [], + "spec_2de7abdab14ea1a63e82fd9eed8fd9e1": [] } } ], - "rendered_sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 2015 to 2022. Current US dollars · OECD DAC1. You asked for Kenya. The data holds no values for it. Tax revenue has 2 readings. Total government revenue, in local currency in Germany and Kenya. SDG Global Database · 2015 to 2022. Total bugetary revenue of the central government as a proportion of GDP in Germany and Kenya. SDG Global Database · 2015 to 2022.", + "rendered_sentence": "Answered 1 of 2 parts. Primary income for gross of fixed capital consumption in Germany and Kenya, 2015 to 2022. Current US dollars · OECD DAC1. You asked for Kenya. The data holds no values for it. Tax revenue has 2 readings. Total government revenue, in local currency in Germany and Kenya. SDG Global Database · 2015 to 2022. Total bugetary revenue of the central government as a proportion of GDP in Germany and Kenya. SDG Global Database · 2015 to 2022.", "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, { "kind": "slot", "text": "Primary income", @@ -5623,7 +5657,7 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 2015 to 2022. Current US dollars · OECD DAC1. You asked for Kenya. The data holds no values for it. Tax revenue has 2 readings. Total government revenue, in local currency in Germany and Kenya. SDG Global Database · 2015 to 2022. Total bugetary revenue of the central government as a proportion of GDP in Germany and Kenya. SDG Global Database · 2015 to 2022.", + "sentence": "Answered 1 of 2 parts. Primary income for gross of fixed capital consumption in Germany and Kenya, 2015 to 2022. Current US dollars · OECD DAC1. You asked for Kenya. The data holds no values for it. Tax revenue has 2 readings. Total government revenue, in local currency in Germany and Kenya. SDG Global Database · 2015 to 2022. Total bugetary revenue of the central government as a proportion of GDP in Germany and Kenya. SDG Global Database · 2015 to 2022.", "complete": false, "specs": [ "spec_9ce16f72ff8416d06a56f9fe82b10ad3" diff --git a/python/client-contract/src/dfo_client_contract/scenarios/resubmit-placeholder-without-restatement.json b/python/client-contract/src/dfo_client_contract/scenarios/resubmit-placeholder-without-restatement.json index 165aeef..09d6ae4 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/resubmit-placeholder-without-restatement.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/resubmit-placeholder-without-restatement.json @@ -4,9 +4,9 @@ "description": "Choosing candidate 0 on part 0 posts part 1, a no_data part with no restatement, as a placeholder entry with its variable_text, status and reason.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "7175fe98eec005479f1397936dc011ad120092d5", - "recorded_at": "2026-10-20T16:53:04Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:59:30Z" }, "call": [ { @@ -46,20 +46,20 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "7175fe98eec005479f1397936dc011ad120092d5", - "trace_id": "37707c965ae94bb8bd120182f24077fb", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "2961e5bd14b94abeba99a744e68b1d02", "warnings": [], "timing_ms": { - "total": 4768, + "total": 3933, "by_step": { "coverage": 0, - "extract": 1393 + "extract": 1117 } }, "llm_usage": { - "input_tokens": 7108, - "output_tokens": 691, - "cached_tokens": 862 + "input_tokens": 12163, + "output_tokens": 848, + "cached_tokens": 2448 }, "timed_out": false }, @@ -69,19 +69,19 @@ "variable_text": "GNI", "warnings": [], "timing_ms": { - "total": 120, + "total": 1762, "by_step": { - "recall": 2, - "shape_arcs": 4, - "shape_probe_coverage": 9, - "shape_probe": 11, - "shape_groups": 61, - "shape_labels": 15, + "recall": 0, + "shape_arcs": 2, + "shape_probe_coverage": 4, + "shape_probe": 4, + "shape_groups": 24, + "shape_labels": 6, "shape_admission": 1, - "shape": 106, - "bind": 2, - "materialise": 2, - "answer": 8 + "shape": 840, + "bind": 919, + "materialise": 0, + "answer": 3 } }, "rendered_sentence": "3 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022.", @@ -376,6 +376,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "candidates", "candidates": { "ordering": "intent_rank", @@ -905,7 +906,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -1456,7 +1457,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -2015,7 +2016,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -2055,6 +2056,11 @@ } ], "truncated": false + }, + "reading_assumptions": { + "spec_9ce16f72ff8416d06a56f9fe82b10ad3": [], + "spec_bef1fcb184525d3bbe7cd6a0316b4a35": [], + "spec_b77d2ebaaeb7e6d5f8499a8b0e3571a1": [] } }, { @@ -2067,17 +2073,17 @@ } ], "timing_ms": { - "total": 3359, + "total": 2809, "by_step": { - "recall": 387, - "shape_arcs": 3, - "shape_probe_coverage": 18, - "shape_probe": 94, - "shape_groups": 10, + "recall": 290, + "shape_arcs": 1, + "shape_probe_coverage": 5, + "shape_probe": 207, + "shape_groups": 2, "shape_labels": 0, "shape_admission": 1, - "shape": 1165, - "bind": 1807 + "shape": 1017, + "bind": 1502 } }, "rendered_sentence": "Could not tell who is giving and who is receiving among \"Germany\" and \"Kenya\". Put \"from\" or \"to\" before a name.", @@ -2092,6 +2098,7 @@ ], "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "role_not_resolved", @@ -2104,7 +2111,65 @@ "ambiguous_entities": [], "source_terms": [], "ambiguous_sources": [], - "unbound_qualifiers": [] + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "Germany", + "Kenya" + ], + "label": "Germany to Kenya", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "debt", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "time_text": "2015 to 2022", + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Germany", + "Kenya" + ], + "label": "Kenya to Germany", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "debt", + "entities": [ + { + "text": "Germany", + "role_text": "to" + }, + { + "text": "Kenya", + "role_text": "from" + } + ], + "time_text": "2015 to 2022", + "sources": [], + "operations": [] + } + ] + } + } + ] } } ], @@ -2492,6 +2557,7 @@ "end_year": 2022 } }, + "assumptions": [], "variable_text": "GNI" }, { @@ -2516,11 +2582,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "7175fe98eec005479f1397936dc011ad120092d5", - "trace_id": "318a8737564e45d48f515461ffd9c3b0", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "769a9afba9da443b89962d16356a9141", "warnings": [], "timing_ms": { - "total": 2, + "total": 4, "by_step": { "coverage": 0 } @@ -2533,9 +2599,19 @@ "variable_text": "GNI", "warnings": [], "timing_ms": { - "total": 0, + "total": 1, "by_step": { - "response_cache_part_memo": 0 + "validate": 0, + "walk": 0, + "reread_arcs": 0, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 0, + "bind": 0, + "where_places": 0, + "materialise": 1, + "answer": 0, + "options": 0 } }, "operations": [], @@ -2546,6 +2622,7 @@ "text": "You asked for Kenya. The data holds no values for it." } ], + "assumptions": [], "status": "definite", "spec": { "spec_id": "spec_9ce16f72ff8416d06a56f9fe82b10ad3", @@ -3068,7 +3145,7 @@ "start_year": 2015, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761" + "capability_version": "cap_347a470e04c97eec" }, "confidence": "high", "available_at_place": true, @@ -3102,6 +3179,7 @@ ], "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "role_not_resolved", @@ -3111,12 +3189,27 @@ "ambiguous_entities": [], "source_terms": [], "ambiguous_sources": [], - "unbound_qualifiers": [] + "unbound_qualifiers": [], + "options": [] } } ], - "rendered_sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 2015 to 2022. Current US dollars · OECD DAC1. You asked for Kenya. The data holds no values for it. Could not tell who is giving and who is receiving in this query. Put \"from\" or \"to\" before a name.", + "rendered_sentence": "Answered 1 of 2 parts. Primary income for gross of fixed capital consumption in Germany and Kenya, 2015 to 2022. Current US dollars · OECD DAC1. You asked for Kenya. The data holds no values for it. Could not tell who is giving and who is receiving in this query. Put \"from\" or \"to\" before a name.", "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, { "kind": "slot", "text": "Primary income", @@ -3297,7 +3390,7 @@ { "part": 1, "kind": "choice", - "options": 0 + "options": 2 } ] } @@ -3306,7 +3399,7 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 2015 to 2022. Current US dollars · OECD DAC1. You asked for Kenya. The data holds no values for it. Could not tell who is giving and who is receiving in this query. Put \"from\" or \"to\" before a name.", + "sentence": "Answered 1 of 2 parts. Primary income for gross of fixed capital consumption in Germany and Kenya, 2015 to 2022. Current US dollars · OECD DAC1. You asked for Kenya. The data holds no values for it. Could not tell who is giving and who is receiving in this query. Put \"from\" or \"to\" before a name.", "complete": false, "specs": [ "spec_9ce16f72ff8416d06a56f9fe82b10ad3" diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json b/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json index ac21824..ca1d6e6 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json @@ -1,12 +1,12 @@ { "format_version": 1, "name": "search-place-ambiguous", - "description": "A question naming a place that matches two countries answers with one no_data part whose entity_ambiguous reason makes a choice gap. This build carries no options, so the gap offers none.", + "description": "A question naming a place that matches two countries answers with one no_data part whose entity_ambiguous reason makes a choice gap, with one option per country: each option's data_query pins that country on the ambiguous wording.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "recorded_at": "2026-10-20T16:04:09Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:58:54Z" }, "call": [ { @@ -38,23 +38,23 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements from Germany to Congo", "normalized_query": "ODA disbursements from Germany to Congo", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "cc29e19289f44bb6bb0a6e0f4c8524a7", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", "warnings": [], "timing_ms": { - "total": 1, + "total": 1788, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 1353 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 }, "timed_out": false }, @@ -64,9 +64,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 434, "by_step": { - "recall": 1 + "recall": 434 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -112,6 +112,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", @@ -140,27 +141,64 @@ "source_terms": [], "ambiguous_sources": [], "unbound_qualifiers": [], - "data_query": { - "kind": "parsed", - "parts": [ - { - "variable_text": "ODA disbursements", - "entities": [ + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Germany", - "role_text": "from", - "dcid": "country/DEU" - }, + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Congo", - "role_text": "to" + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] } - ], - "sources": [], - "operations": [] + ] } - ] - } + } + ] } } ], @@ -210,7 +248,7 @@ { "part": 0, "kind": "choice", - "options": 0 + "options": 2 } ] } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json index cac5983..5f17161 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json @@ -62,23 +62,23 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements from Germany to Congo", "normalized_query": "ODA disbursements from Germany to Congo", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "cc29e19289f44bb6bb0a6e0f4c8524a7", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", "warnings": [], "timing_ms": { - "total": 1, + "total": 1788, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 1353 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 }, "timed_out": false }, @@ -88,9 +88,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 434, "by_step": { - "recall": 1 + "recall": 434 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -136,6 +136,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", @@ -164,27 +165,64 @@ "source_terms": [], "ambiguous_sources": [], "unbound_qualifiers": [], - "data_query": { - "kind": "parsed", - "parts": [ - { - "variable_text": "ODA disbursements", - "entities": [ + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Germany", - "role_text": "from", - "dcid": "country/DEU" - }, + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Congo", - "role_text": "to" + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] } - ], - "sources": [], - "operations": [] + ] } - ] - } + } + ] } } ], @@ -234,7 +272,7 @@ { "part": 0, "kind": "choice", - "options": 0 + "options": 2 } ] } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json b/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json index d3de644..3255290 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json @@ -67,23 +67,23 @@ "entry_path": "raw_text", "raw_query": "ODA disbursements from Germany to Congo", "normalized_query": "ODA disbursements from Germany to Congo", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "cc29e19289f44bb6bb0a6e0f4c8524a7", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", "warnings": [], "timing_ms": { - "total": 1, + "total": 1788, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 1353 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 }, "timed_out": false }, @@ -93,9 +93,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 434, "by_step": { - "recall": 1 + "recall": 434 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -141,6 +141,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", @@ -169,27 +170,64 @@ "source_terms": [], "ambiguous_sources": [], "unbound_qualifiers": [], - "data_query": { - "kind": "parsed", - "parts": [ - { - "variable_text": "ODA disbursements", - "entities": [ + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Germany", - "role_text": "from", - "dcid": "country/DEU" - }, + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Congo", - "role_text": "to" + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] } - ], - "sources": [], - "operations": [] + ] } - ] - } + } + ] } } ], @@ -239,7 +277,7 @@ { "part": 0, "kind": "choice", - "options": 0 + "options": 2 } ] } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json b/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json index f29b30a..f8fe217 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json @@ -1,12 +1,12 @@ { "format_version": 1, "name": "search-two-parts-place-ambiguous", - "description": "A two-part question naming a place that matches two countries answers no_data on both parts, each an entity_ambiguous choice gap. This build carries no options, so the gaps offer none.", + "description": "A two-part question naming a place that matches two countries answers no_data on both parts, each an entity_ambiguous choice gap with one option per country.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "recorded_at": "2026-10-20T16:04:09Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:58:56Z" }, "call": [ { @@ -38,23 +38,23 @@ "entry_path": "raw_text", "raw_query": "Kenya's GDP, and ODA disbursements from Germany to Congo", "normalized_query": "Kenya's GDP, and ODA disbursements from Germany to Congo", - "extract_skipped": true + "extract_skipped": false }, "diagnostics": { - "engine_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", - "trace_id": "1fdae229dbd2489c8551682aa2bb6880", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "670f1650b70c4616805aa3dd54c4dae8", "warnings": [], "timing_ms": { - "total": 2, + "total": 1333, "by_step": { "coverage": 0, - "response_cache_layer1": 1 + "extract": 1329 } }, "llm_usage": { - "input_tokens": 0, - "output_tokens": 0, - "cached_tokens": 0 + "input_tokens": 2256, + "output_tokens": 207, + "cached_tokens": 861 }, "timed_out": false }, @@ -116,6 +116,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", @@ -144,41 +145,83 @@ "source_terms": [], "ambiguous_sources": [], "unbound_qualifiers": [], - "data_query": { - "kind": "parsed", - "parts": [ - { - "variable_text": "GDP", - "entities": [ - { - "text": "Kenya", - "role_text": "to", - "dcid": "country/KEN" - }, + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Germany", - "role_text": "from", - "dcid": "country/DEU" - }, + "variable_text": "GDP", + "entities": [ + { + "text": "Kenya", + "role_text": "to", + "dcid": "country/KEN" + }, + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Congo", - "role_text": "to" + "variable_text": "GDP", + "entities": [ + { + "text": "Kenya", + "role_text": "to", + "dcid": "country/KEN" + }, + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] } - ], - "sources": [], - "operations": [] + ] } - ] - } + } + ] } }, { "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 0, + "total": 2, "by_step": { - "recall": 0 + "recall": 2 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -228,6 +271,7 @@ }, "operations": [], "departures": [], + "assumptions": [], "status": "no_data", "no_data": { "reason": "entity_ambiguous", @@ -256,32 +300,74 @@ "source_terms": [], "ambiguous_sources": [], "unbound_qualifiers": [], - "data_query": { - "kind": "parsed", - "parts": [ - { - "variable_text": "ODA disbursements", - "entities": [ - { - "text": "Kenya", - "role_text": "to", - "dcid": "country/KEN" - }, + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Germany", - "role_text": "from", - "dcid": "country/DEU" - }, + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Kenya", + "role_text": "to", + "dcid": "country/KEN" + }, + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ { - "text": "Congo", - "role_text": "to" + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Kenya", + "role_text": "to", + "dcid": "country/KEN" + }, + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] } - ], - "sources": [], - "operations": [] + ] } - ] - } + } + ] } } ], @@ -328,12 +414,12 @@ { "part": 0, "kind": "choice", - "options": 0 + "options": 2 }, { "part": 1, "kind": "choice", - "options": 0 + "options": 2 } ] } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json b/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json index a8ccf49..641b614 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json @@ -4,9 +4,9 @@ "description": "A question asking for a ranking answers one definite part that does not run the rank, with a departure and two warn-severity warnings. A strict fetch raises SearchWarning before any build; a fetch that is not strict builds the dataset and issues one SearchWarning for all of them.", "origin": { "kind": "recorded", - "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "7175fe98eec005479f1397936dc011ad120092d5", - "recorded_at": "2026-10-20T16:52:35Z" + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:59:08Z" }, "call": [ { @@ -48,20 +48,20 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "7175fe98eec005479f1397936dc011ad120092d5", - "trace_id": "05ba0d7c03b3468c98629e82ffeeb157", + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "b87a5f3d6ed54104885bb9ca8e8e4a73", "warnings": [], "timing_ms": { - "total": 4392, + "total": 3381, "by_step": { "coverage": 0, - "extract": 1310 + "extract": 1159 } }, "llm_usage": { "input_tokens": 6103, - "output_tokens": 370, - "cached_tokens": 0 + "output_tokens": 381, + "cached_tokens": 860 }, "timed_out": false }, @@ -82,20 +82,20 @@ } ], "timing_ms": { - "total": 2885, + "total": 2178, "by_step": { - "recall": 391, - "shape_arcs": 3, - "shape_probe_coverage": 18, - "shape_probe": 157, - "shape_groups": 5, - "shape_labels": 0, + "recall": 383, + "shape_arcs": 2, + "shape_probe_coverage": 3, + "shape_probe": 253, + "shape_groups": 4, + "shape_labels": 1, "shape_admission": 1, - "shape": 1098, - "bind": 1154, - "materialise": 42, - "answer": 187, - "options": 13 + "shape": 846, + "bind": 918, + "materialise": 19, + "answer": 9, + "options": 3 } }, "restatement": { @@ -130,6 +130,16 @@ "text": "You asked for a ranking. This shows the amounts behind it, because Search does not compute rankings." } ], + "assumptions": [ + { + "kind": "declared_default", + "binding_ref": "how:dac2aAidType", + "text": "official development assistance", + "refs": [ + "DAC2aAidType206" + ] + } + ], "status": "definite", "spec": { "spec_id": "spec_7778beed72f8433bb7fde4293acfd175", @@ -490,7 +500,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5", + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "facets": { "provenance": { "basis": "fallback", @@ -939,7 +949,7 @@ "start_year": 2022, "end_year": 2022 }, - "capability_version": "cap_3f35867df5a65761", + "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3048,7 +3058,7 @@ } } ], - "rendered_sentence": "Gross disbursements to Ethiopia from 137 providers for official development assistance in 2022. Current US dollars · OECD DAC2a. You asked for a ranking. This shows the amounts behind it, because Search does not compute rankings.", + "rendered_sentence": "Gross disbursements to Ethiopia from 137 providers for official development assistance in 2022. Current US dollars · OECD DAC2a. You asked for a ranking. This shows the amounts behind it, because Search does not compute rankings. Assumed: official development assistance.", "sentence_plan": [ { "kind": "slot", @@ -3244,6 +3254,38 @@ "entity_refs": [], "states": [], "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Assumed: ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "official development assistance", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 } ], "status": "definite" @@ -3386,7 +3428,7 @@ } }, "content_version": "cv_534dd4c2bf9bdafc837d51a3ba4bcf3e", - "prepared_at": "2026-10-20T16:52:43Z", + "prepared_at": "2026-10-21T08:59:13Z", "coverage": { "rows": 110, "dimensions": [ @@ -3509,13 +3551,13 @@ "end_year": 2022, "origin": "query" }, - "graph_revision": "dfo-dev-dc-datacommons-service-00259-rpx", + "graph_revision": null, "code_index_stamp": { "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", - "exported_at": "2026-10-20T13:18:18Z", + "exported_at": "2026-10-20T19:50:14Z", "graph_endpoint": "graph_release" }, - "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDDAC2A", @@ -3565,10 +3607,10 @@ ], "normalisations": [], "frame_grammar_version": "1.1.0", - "materialiser_build": "7175fe98eec005479f1397936dc011ad120092d5", - "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-20T16:52:44.191752+00:00" + "confirmed_at": "2026-10-21T08:59:13.197667+00:00" }, "warnings": [], "diagnostics": [ @@ -3588,7 +3630,7 @@ }, "bytes": 10828, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T16:52:44.112078+00:00", + "created_at": "2026-10-21T08:59:13.158978+00:00", "tier": "working", "url": "/api/datasets/spec_7778beed72f8433bb7fde4293acfd175/cv_534dd4c2bf9bdafc837d51a3ba4bcf3e/files/sha256:7ca72626eed07dafebc7eaa78713c1c5a36ef05a19d8da96b723dec80d50317f" }, @@ -3599,14 +3641,14 @@ }, "bytes": 10167, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-20T16:52:44.112078+00:00", + "created_at": "2026-10-21T08:59:13.158978+00:00", "tier": "working", "url": "/api/datasets/spec_7778beed72f8433bb7fde4293acfd175/cv_534dd4c2bf9bdafc837d51a3ba4bcf3e/files/sha256:5b508be6b46ce8e01315f9c89a1837e17ed7b49d7d2554011cfdba9f32203084" } ], "series_count": 110, "output_options": { - "capability_version": "dset_1e6cd9546fac19e9", + "capability_version": "dset_88fecfec3c5b89d1", "columns": [ { "name": "stat_var", @@ -3912,7 +3954,11 @@ ] } }, - "series_coverage_stamp": "62e7b1eb49fad49a576aaaa4599270e0561fdb04580337cddd04d38b555864c5" + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:59:13.158787Z" + } } } }, @@ -3924,15 +3970,14 @@ "response": { "status": 302, "headers": { - "content-type": "text/html", - "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A7ca72626eed07dafebc7eaa78713c1c5a36ef05a19d8da96b723dec80d50317f?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A7ca72626eed07dafebc7eaa78713c1c5a36ef05a19d8da96b723dec80d50317f?X-Goog-Signature=redacted" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A7ca72626eed07dafebc7eaa78713c1c5a36ef05a19d8da96b723dec80d50317f?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/e2e-working/sha256%3A7ca72626eed07dafebc7eaa78713c1c5a36ef05a19d8da96b723dec80d50317f?X-Goog-Signature=redacted" }, "response": { "status": 200, @@ -3948,7 +3993,7 @@ "answer": { "kind": "resolution", "status": "definite", - "sentence": "Gross disbursements to Ethiopia from 137 providers for official development assistance in 2022. Current US dollars · OECD DAC2a. You asked for a ranking. This shows the amounts behind it, because Search does not compute rankings.", + "sentence": "Gross disbursements to Ethiopia from 137 providers for official development assistance in 2022. Current US dollars · OECD DAC2a. You asked for a ranking. This shows the amounts behind it, because Search does not compute rankings. Assumed: official development assistance.", "complete": true, "specs": [ "spec_7778beed72f8433bb7fde4293acfd175" diff --git a/python/client-contract/src/dfo_client_contract/served/SOURCE.json b/python/client-contract/src/dfo_client_contract/served/SOURCE.json index cfcdd98..d9f2516 100644 --- a/python/client-contract/src/dfo_client_contract/served/SOURCE.json +++ b/python/client-contract/src/dfo_client_contract/served/SOURCE.json @@ -1,6 +1,6 @@ { "format_version": 1, "repository": "DevelopmentFinanceObservatory/apis", - "commit": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", + "commit": "635943e03a297f686ca5af32f6d027181d1971d4", "captured_from": "dfo_apis.app.create_app() in process" } diff --git a/python/client-contract/src/dfo_client_contract/served/openapi.json b/python/client-contract/src/dfo_client_contract/served/openapi.json index 5ef64e0..ccdc35a 100644 --- a/python/client-contract/src/dfo_client_contract/served/openapi.json +++ b/python/client-contract/src/dfo_client_contract/served/openapi.json @@ -7,8 +7,11 @@ "paths": { "/api/search/resolve": { "post": { - "summary": "Resolve Endpoint", - "operationId": "resolve_endpoint_api_search_resolve_post", + "tags": [ + "Search" + ], + "summary": "Resolve", + "operationId": "search_resolve", "requestBody": { "content": { "application/json": { @@ -36,7 +39,7 @@ "$ref": "#/components/schemas/DeclinedAnswer" } ], - "title": "Response Resolve Endpoint Api Search Resolve Post", + "title": "Response Search Resolve", "discriminator": { "propertyName": "kind", "mapping": { @@ -81,9 +84,12 @@ }, "/api/search/options": { "post": { - "summary": "Options Endpoint", + "tags": [ + "Search" + ], + "summary": "List Options", "description": "The options door: on-demand candidate enumeration for one resolved\nentity role (origin, destination, or observationAbout) of a posted\nidentity, queried independently of the /resolve pipeline and fetched\nlazily when a user opens an editor.\n\nComposes engine.options.resolve.resolve_options_target (derive the\nposted identity's own StatVar population, typed anchors and\nrole-target validity, server-side, with no resubmit or materialise\npipeline) with engine.options.surface.compute_options (compute the\nper-role option surface), then assembles the envelope here --\nsee those two modules' own docstrings for the full design, including\nthe option_target_invalid (422) role check that runs inside\nresolution. Every EngineInputError either half raises propagates\nuncaught to classify_search_exception above, the same RFC 9457\nproblem body every other door's refusal returns -- no bespoke\nhandling here.\n\nresolve_options_target always runs, hit or miss on the response\ncache below: it is what runs validate_edited_identity and the role/\nanchor refusals, and none of those may be skipped just because an\nidentical target was already answered once. Only build_options_\nresponse's own compute -- the graph/SDMX work -- is what a cache hit\nskips; see options.options_response_cache's own module docstring for\nthe key and the warning-free-result caching rule.", - "operationId": "options_endpoint_api_search_options_post", + "operationId": "search_list_options", "requestBody": { "content": { "application/json": { @@ -130,8 +136,11 @@ }, "/api/search/healthz": { "get": { - "summary": "Healthz", - "operationId": "healthz_api_search_healthz_get", + "tags": [ + "Search" + ], + "summary": "Get Health", + "operationId": "search_get_health", "responses": { "200": { "description": "Successful Response", @@ -158,8 +167,11 @@ }, "/api/search/schema": { "get": { - "summary": "Schema", - "operationId": "schema_api_search_schema_get", + "tags": [ + "Search" + ], + "summary": "Get Schema", + "operationId": "search_get_schema", "responses": { "200": { "description": "Successful Response", @@ -209,8 +221,11 @@ }, "/api/search/capabilities": { "get": { - "summary": "Capabilities", - "operationId": "capabilities_api_search_capabilities_get", + "tags": [ + "Search" + ], + "summary": "Get Capabilities", + "operationId": "search_get_capabilities", "responses": { "200": { "description": "Successful Response", @@ -237,9 +252,12 @@ }, "/api/search/catalogue": { "get": { - "summary": "Catalogue Endpoint", + "tags": [ + "Search" + ], + "summary": "Get Catalogue", "description": "What DFO holds and example sentences to ask of it, from the published\nsearch catalogue. `place` scopes the counts to one country and offers the\nexamples whose StatVar has data there, filled with its name.", - "operationId": "catalogue_endpoint_api_search_catalogue_get", + "operationId": "search_get_catalogue", "parameters": [ { "name": "place", @@ -297,8 +315,11 @@ }, "/api/datasets/healthz": { "get": { - "summary": "Healthz", - "operationId": "healthz_api_datasets_healthz_get", + "tags": [ + "Datasets" + ], + "summary": "Get Health", + "operationId": "datasets_get_health", "responses": { "200": { "description": "Successful Response", @@ -325,8 +346,11 @@ }, "/api/datasets/schema": { "get": { - "summary": "Schema", - "operationId": "schema_api_datasets_schema_get", + "tags": [ + "Datasets" + ], + "summary": "Get Schema", + "operationId": "datasets_get_schema", "responses": { "200": { "description": "Successful Response", @@ -436,8 +460,11 @@ }, "/api/datasets/capabilities": { "get": { - "summary": "Capabilities", - "operationId": "capabilities_api_datasets_capabilities_get", + "tags": [ + "Datasets" + ], + "summary": "Get Capabilities", + "operationId": "datasets_get_capabilities", "responses": { "200": { "description": "Successful Response", @@ -464,8 +491,11 @@ }, "/api/datasets/operations/{operation_id}": { "get": { + "tags": [ + "Datasets" + ], "summary": "Get Operation", - "operationId": "get_operation_api_datasets_operations__operation_id__get", + "operationId": "datasets_get_operation", "parameters": [ { "name": "operation_id", @@ -533,8 +563,11 @@ }, "/api/datasets/register": { "post": { - "summary": "Register Endpoint", - "operationId": "register_endpoint_api_datasets_register_post", + "tags": [ + "Datasets" + ], + "summary": "Register", + "operationId": "datasets_register", "requestBody": { "content": { "application/json": { @@ -581,8 +614,11 @@ }, "/api/datasets": { "post": { - "summary": "Mint Endpoint", - "operationId": "mint_endpoint_api_datasets_post", + "tags": [ + "Datasets" + ], + "summary": "Mint", + "operationId": "datasets_mint", "requestBody": { "content": { "application/json": { @@ -604,6 +640,31 @@ } } }, + "202": { + "description": "The build runs as a background operation. Poll `Location` until the operation is done; the done poll carries the manifest.", + "headers": { + "Location": { + "description": "The operation's poll URL, `operation.poll` in the body.", + "schema": { + "type": "string" + } + }, + "Retry-After": { + "description": "Whole seconds to wait before the next poll, rounded up from `operation.retry_after_ms`. The value grows as the build runs.", + "schema": { + "type": "integer", + "minimum": 1.0 + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OperationResource" + } + } + } + }, "default": { "description": "any non-2xx response uses this envelope", "content": { @@ -629,8 +690,11 @@ }, "/api/datasets/{id}": { "get": { + "tags": [ + "Datasets" + ], "summary": "Get Definition", - "operationId": "get_definition_api_datasets__id__get", + "operationId": "datasets_get_definition", "parameters": [ { "name": "id", @@ -653,6 +717,31 @@ } } }, + "202": { + "description": "The build runs as a background operation. Poll `Location` until the operation is done; the done poll carries the manifest.", + "headers": { + "Location": { + "description": "The operation's poll URL, `operation.poll` in the body.", + "schema": { + "type": "string" + } + }, + "Retry-After": { + "description": "Whole seconds to wait before the next poll, rounded up from `operation.retry_after_ms`. The value grows as the build runs.", + "schema": { + "type": "integer", + "minimum": 1 + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OperationResource" + } + } + } + }, "default": { "description": "any non-2xx response uses this envelope", "content": { @@ -678,9 +767,12 @@ }, "/api/datasets/{id}/options": { "get": { + "tags": [ + "Datasets" + ], "summary": "Get Definition Options", "description": "The definition's current version with no rendering, reported as\n`output_options`: what the data honours. A rebuild records the version and advances\nthe head as a GET does. Any query key refuses `request_invalid` with an\n`/options/` pointer, the same `QueryOptionsInvalid` this door's `get_definition`\nraises for a query key outside its own namespace, through the same\n`query_options.pointer_for_key` mapping.", - "operationId": "get_definition_options_api_datasets__id__options_get", + "operationId": "datasets_get_definition_options", "parameters": [ { "name": "id", @@ -726,9 +818,12 @@ } }, "post": { + "tags": [ + "Datasets" + ], "summary": "Post Definition Options", "description": "The GET route's envelope for a spec id whose canonical `definition` the body\ncarries, registered or not. An unregistered definition is admitted as a mint admits a\nsidecar, registered, and served as the GET route serves a registered one, so the\nmint that follows is a head hit. Query keys refuse as on the GET route.", - "operationId": "post_definition_options_api_datasets__id__options_post", + "operationId": "datasets_post_definition_options", "parameters": [ { "name": "id", @@ -786,9 +881,12 @@ }, "/api/datasets/{id}/members": { "post": { + "tags": [ + "Datasets" + ], "summary": "Post Definition Members", "description": "The members a mint of the spec serves, resolved without materialising a frame:\neach member's ref, label, declared roles and constraints, their count, and the\nfamily's count and digest. The body may carry the spec's canonical `definition`,\nwhich an unregistered id needs; it is admitted as a mint admits a sidecar and nothing\nis registered. Refusals are the mint's member refusals. Query keys refuse as on the\noptions route.", - "operationId": "post_definition_members_api_datasets__id__members_post", + "operationId": "datasets_post_definition_members", "parameters": [ { "name": "id", @@ -853,9 +951,12 @@ }, "/api/datasets/frames/refresh": { "post": { + "tags": [ + "Datasets" + ], "summary": "Refresh Frame", "description": "Whether the named dataset frame is still its rendering's current frame. Answers\n`current`, `moved` with the current frame, or `pending` with the queued rebuild.", - "operationId": "refresh_frame_api_datasets_frames_refresh_post", + "operationId": "datasets_refresh_frame", "requestBody": { "content": { "application/json": { @@ -883,7 +984,7 @@ "$ref": "#/components/schemas/FramePending" } ], - "title": "Response Refresh Frame Api Datasets Frames Refresh Post", + "title": "Response Datasets Refresh Frame", "discriminator": { "propertyName": "status", "mapping": { @@ -921,8 +1022,11 @@ }, "/api/datasets/frames/{spec_id}/{content_version}/recipe": { "put": { + "tags": [ + "Datasets" + ], "summary": "Put Recipe", - "operationId": "put_recipe_api_datasets_frames__spec_id___content_version__recipe_put", + "operationId": "datasets_put_recipe", "parameters": [ { "name": "spec_id", @@ -989,8 +1093,11 @@ } }, "get": { + "tags": [ + "Datasets" + ], "summary": "Get Recipe", - "operationId": "get_recipe_api_datasets_frames__spec_id___content_version__recipe_get", + "operationId": "datasets_get_recipe", "parameters": [ { "name": "spec_id", @@ -1049,8 +1156,11 @@ }, "/api/datasets/recipes/replays/{replay_key}": { "get": { + "tags": [ + "Datasets" + ], "summary": "Get Replay", - "operationId": "get_replay_api_datasets_recipes_replays__replay_key__get", + "operationId": "datasets_get_replay", "parameters": [ { "name": "replay_key", @@ -1099,8 +1209,11 @@ }, "/api/datasets/{id}/versions": { "get": { - "summary": "Get Versions", - "operationId": "get_versions_api_datasets__id__versions_get", + "tags": [ + "Datasets" + ], + "summary": "List Versions", + "operationId": "datasets_list_versions", "parameters": [ { "name": "id", @@ -1110,6 +1223,34 @@ "type": "string", "title": "Id" } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 500, + "default": 100, + "title": "Limit" + } + }, + { + "name": "cursor", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Cursor" + } } ], "responses": { @@ -1118,7 +1259,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DatasetVersionsResponse" + "$ref": "#/components/schemas/DatasetVersionsPage" } } } @@ -1148,8 +1289,11 @@ }, "/api/datasets/{id}/{content_version}": { "get": { + "tags": [ + "Datasets" + ], "summary": "Get Snapshot", - "operationId": "get_snapshot_api_datasets__id___content_version__get", + "operationId": "datasets_get_snapshot", "parameters": [ { "name": "id", @@ -1206,8 +1350,11 @@ }, "/api/datasets/{id}/{content_version}/description": { "get": { + "tags": [ + "Datasets" + ], "summary": "Get Description", - "operationId": "get_description_api_datasets__id___content_version__description_get", + "operationId": "datasets_get_description", "parameters": [ { "name": "id", @@ -1277,8 +1424,11 @@ }, "/api/datasets/{id}/{content_version}/description/values": { "get": { + "tags": [ + "Datasets" + ], "summary": "Get Description Values", - "operationId": "get_description_values_api_datasets__id___content_version__description_values_get", + "operationId": "datasets_get_description_values", "parameters": [ { "name": "id", @@ -1370,8 +1520,11 @@ }, "/api/datasets/{id}/{content_version}/files/{digest}": { "get": { + "tags": [ + "Datasets" + ], "summary": "Get File", - "operationId": "get_file_api_datasets__id___content_version__files__digest__get", + "operationId": "datasets_get_file", "parameters": [ { "name": "id", @@ -1436,10 +1589,113 @@ } } }, + "/api/datasets/{id}/{content_version}/file": { + "get": { + "tags": [ + "Datasets" + ], + "summary": "Get Version File", + "description": "Redirect to the version's file in the format, bundle and layout the query names,\nrenewing an aged copy whose bytes survive, else rendering it from the version's stored\nframe.", + "operationId": "datasets_get_version_file", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + }, + { + "name": "content_version", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Content Version" + } + }, + { + "name": "format", + "in": "query", + "required": false, + "description": "the file format; csv when absent", + "schema": { + "type": "string", + "enum": [ + "csv", + "xlsx", + "parquet" + ], + "default": "csv" + } + }, + { + "name": "bundle", + "in": "query", + "required": false, + "description": "true for a zip bundle with its documentation; true when absent", + "schema": { + "type": "boolean", + "default": true + } + }, + { + "name": "layout", + "in": "query", + "required": false, + "description": "frame for a bare parquet file in the frame layout; needs format=parquet and bundle=false", + "schema": { + "type": "string", + "enum": [ + "frame" + ] + } + } + ], + "responses": { + "302": { + "description": "a redirect to the artifact's bytes", + "headers": { + "Location": { + "description": "a GET URL signed for at most five minutes", + "schema": { + "type": "string" + } + } + } + }, + "default": { + "description": "any non-2xx response uses this envelope", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "400": { + "description": "the request body or parameters failed validation (request_invalid)", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, "/api/datasets/{id}/{content_version}/observations": { "get": { + "tags": [ + "Datasets" + ], "summary": "Get Observations", - "operationId": "get_observations_api_datasets__id___content_version__observations_get", + "operationId": "datasets_get_observations", "parameters": [ { "name": "id", @@ -1496,8 +1752,12 @@ }, "/api/datasets/{id}/{content_version}/pin": { "post": { + "tags": [ + "Datasets" + ], "summary": "Post Pin", - "operationId": "post_pin_api_datasets__id___content_version__pin_post", + "description": "Pin an artifact of a version, and the frame its files render from: the version's own frame and, for a derived version, its base version's frame, servable or aged, so every format stays fetchable and the version reports `retention.pinned`. A frame whose bytes are gone stays unpinned: the named artifact still pins, and `retention` keeps that frame's `held_until`. Only the named artifact's copy waits on the daily pin budget; the frame copies skip it and count toward later calls, so one pin can add up to three copies to the count.", + "operationId": "datasets_post_pin", "parameters": [ { "name": "id", @@ -1564,9 +1824,12 @@ }, "/api/datasets/frames/publish": { "post": { + "tags": [ + "Datasets" + ], "summary": "Post Publish", "description": "Publish a validated body under the permit the route class took for this request.", - "operationId": "post_publish_api_datasets_frames_publish_post", + "operationId": "datasets_post_publish", "requestBody": { "content": { "application/json": { @@ -1613,8 +1876,11 @@ }, "/api/graph/healthz": { "get": { - "summary": "Healthz", - "operationId": "healthz_api_graph_healthz_get", + "tags": [ + "Graph" + ], + "summary": "Get Health", + "operationId": "graph_get_health", "responses": { "200": { "description": "Successful Response", @@ -1641,8 +1907,11 @@ }, "/api/graph/capabilities": { "get": { - "summary": "Capabilities", - "operationId": "capabilities_api_graph_capabilities_get", + "tags": [ + "Graph" + ], + "summary": "Get Capabilities", + "operationId": "graph_get_capabilities", "responses": { "200": { "description": "Successful Response", @@ -1669,8 +1938,11 @@ }, "/api/graph/schema": { "get": { - "summary": "Schema", - "operationId": "schema_api_graph_schema_get", + "tags": [ + "Graph" + ], + "summary": "Get Schema", + "operationId": "graph_get_schema", "responses": { "200": { "description": "Successful Response", @@ -1697,8 +1969,11 @@ }, "/api/graph/resolve": { "post": { - "summary": "Resolve Endpoint", - "operationId": "resolve_endpoint_api_graph_resolve_post", + "tags": [ + "Graph" + ], + "summary": "Resolve", + "operationId": "graph_resolve", "requestBody": { "content": { "application/json": { @@ -1745,8 +2020,11 @@ }, "/api/graph/documentation/{dcid}": { "get": { - "summary": "Sources Endpoint", - "operationId": "sources_endpoint_api_graph_documentation__dcid__get", + "tags": [ + "Graph" + ], + "summary": "Get Documentation", + "operationId": "graph_get_documentation", "parameters": [ { "name": "dcid", @@ -1794,8 +2072,11 @@ }, "/api/graph/sources": { "get": { - "summary": "Sources Catalogue Endpoint", - "operationId": "sources_catalogue_endpoint_api_graph_sources_get", + "tags": [ + "Graph" + ], + "summary": "List Sources", + "operationId": "graph_list_sources", "responses": { "200": { "description": "Successful Response", @@ -1822,8 +2103,11 @@ }, "/api/graph/node/{dcid}/members": { "get": { - "summary": "Members Endpoint", - "operationId": "members_endpoint_api_graph_node__dcid__members_get", + "tags": [ + "Graph" + ], + "summary": "List Members", + "operationId": "graph_list_members", "parameters": [ { "name": "dcid", @@ -1996,8 +2280,11 @@ }, "/api/graph/roots": { "get": { - "summary": "Roots Endpoint", - "operationId": "roots_endpoint_api_graph_roots_get", + "tags": [ + "Graph" + ], + "summary": "List Roots", + "operationId": "graph_list_roots", "responses": { "200": { "description": "Successful Response", @@ -2024,8 +2311,11 @@ }, "/api/graph/node/{dcid}": { "get": { - "summary": "Node Endpoint", - "operationId": "node_endpoint_api_graph_node__dcid__get", + "tags": [ + "Graph" + ], + "summary": "Get Node", + "operationId": "graph_get_node", "parameters": [ { "name": "dcid", @@ -2131,7 +2421,7 @@ "other": "#/components/schemas/OtherNode" } }, - "title": "Response Node Endpoint Api Graph Node Dcid Get" + "title": "Response Graph Get Node" } } } @@ -2161,8 +2451,11 @@ }, "/api/graph/nodes": { "post": { - "summary": "Nodes Endpoint", - "operationId": "nodes_endpoint_api_graph_nodes_post", + "tags": [ + "Graph" + ], + "summary": "Get Nodes", + "operationId": "graph_get_nodes", "requestBody": { "content": { "application/json": { @@ -2209,8 +2502,11 @@ }, "/api/presentation/healthz": { "get": { - "summary": "Healthz", - "operationId": "healthz_api_presentation_healthz_get", + "tags": [ + "Presentation" + ], + "summary": "Get Health", + "operationId": "presentation_get_health", "responses": { "200": { "description": "Successful Response", @@ -2237,8 +2533,11 @@ }, "/api/presentation/capabilities": { "get": { - "summary": "Capabilities", - "operationId": "capabilities_api_presentation_capabilities_get", + "tags": [ + "Presentation" + ], + "summary": "Get Capabilities", + "operationId": "presentation_get_capabilities", "responses": { "200": { "description": "Successful Response", @@ -2265,8 +2564,11 @@ }, "/api/presentation/components": { "post": { + "tags": [ + "Presentation" + ], "summary": "Create Component", - "operationId": "create_component_api_presentation_components_post", + "operationId": "presentation_create_component", "parameters": [ { "name": "x-dfo-write-token", @@ -2331,8 +2633,11 @@ }, "/api/presentation/components/{component_id}": { "patch": { + "tags": [ + "Presentation" + ], "summary": "Revise Component", - "operationId": "revise_component_api_presentation_components__component_id__patch", + "operationId": "presentation_revise_component", "parameters": [ { "name": "component_id", @@ -2404,8 +2709,11 @@ } }, "get": { + "tags": [ + "Presentation" + ], "summary": "Read Component", - "operationId": "read_component_api_presentation_components__component_id__get", + "operationId": "presentation_read_component", "parameters": [ { "name": "component_id", @@ -2470,8 +2778,11 @@ }, "/api/presentation/components/{component_id}/revisions/{revision}/data": { "get": { + "tags": [ + "Presentation" + ], "summary": "Read Component Data", - "operationId": "read_component_data_api_presentation_components__component_id__revisions__revision__data_get", + "operationId": "presentation_read_component_data", "parameters": [ { "name": "component_id", @@ -2553,9 +2864,12 @@ }, "/api/presentation/components/{component_id}/revisions/{revision}/render": { "post": { + "tags": [ + "Presentation" + ], "summary": "Render Component Revision", "description": "Draw one stored revision on the frame the body names. Appends no revision.", - "operationId": "render_component_revision_api_presentation_components__component_id__revisions__revision__render_post", + "operationId": "presentation_render_component_revision", "parameters": [ { "name": "component_id", @@ -2623,9 +2937,12 @@ }, "/api/presentation/components/{component_id}/revisions/{revision}/render/data": { "get": { + "tags": [ + "Presentation" + ], "summary": "Read Rendered Component Data", "description": "The data export of one stored revision drawn on the frame the query names.", - "operationId": "read_rendered_component_data_api_presentation_components__component_id__revisions__revision__render_data_get", + "operationId": "presentation_read_rendered_component_data", "parameters": [ { "name": "component_id", @@ -2725,8 +3042,11 @@ }, "/api/presentation/frames/{spec_id}/{content_version}": { "get": { + "tags": [ + "Presentation" + ], "summary": "Get Frame", - "operationId": "get_frame_api_presentation_frames__spec_id___content_version__get", + "operationId": "presentation_get_frame", "parameters": [ { "name": "spec_id", @@ -2796,7 +3116,7 @@ "$ref": "#/components/schemas/FrameFilteredViewResponse" } ], - "title": "Response 200 Get Frame Api Presentation Frames Spec Id Content Version Get" + "title": "Response 200 Presentation Get Frame" } } } @@ -2826,8 +3146,11 @@ }, "/api/presentation/release": { "get": { + "tags": [ + "Presentation" + ], "summary": "Get Release", - "operationId": "get_release_api_presentation_release_get", + "operationId": "presentation_get_release", "responses": { "200": { "description": "Successful Response", @@ -2852,173 +3175,13 @@ } } }, - "/api/skills/healthz": { - "get": { - "summary": "Healthz", - "operationId": "healthz_api_skills_healthz_get", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HealthResponse" - } - } - } - }, - "default": { - "description": "any non-2xx response uses this envelope", - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - } - } - } - }, - "/api/skills": { - "get": { - "summary": "List Endpoint", - "operationId": "list_endpoint_api_skills_get", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SkillListResponse" - } - } - } - }, - "default": { - "description": "any non-2xx response uses this envelope", - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - } - } - } - }, - "/api/skills/{skill_id}": { - "get": { - "summary": "Fetch Endpoint", - "operationId": "fetch_endpoint_api_skills__skill_id__get", - "parameters": [ - { - "name": "skill_id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Skill Id" - } - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SkillBody" - } - } - } - }, - "default": { - "description": "any non-2xx response uses this envelope", - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - }, - "400": { - "description": "the request body or parameters failed validation (request_invalid)", - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - } - } - } - }, - "/api/skills/{skill_id}/resources/{path}": { - "get": { - "summary": "Resource Endpoint", - "operationId": "resource_endpoint_api_skills__skill_id__resources__path__get", - "parameters": [ - { - "name": "skill_id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Skill Id" - } - }, - { - "name": "path", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Path" - } - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SkillResourceContent" - } - } - } - }, - "default": { - "description": "any non-2xx response uses this envelope", - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - }, - "400": { - "description": "the request body or parameters failed validation (request_invalid)", - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - } - } - } - }, "/codes/{code}": { "get": { - "summary": "Code Registry Entry", - "operationId": "code_registry_entry_codes__code__get", + "tags": [ + "Codes" + ], + "summary": "Get Code", + "operationId": "codes_get_code", "parameters": [ { "name": "code", @@ -3233,7 +3396,7 @@ "kind" ], "title": "AmbiguousEntityCandidate", - "description": "One graph node an ambiguous query wording could name -- one entry of\nan AmbiguousEntityGroup's own `candidates`. Mirrors engine.region.result.\nAmbiguousEntityCandidate field-for-field, with `label` in place of that\ndataclass's `name` (this contract's own vocabulary for a display\nstring, matching ResolvedEntity.label)." + "description": "One graph node an ambiguous query wording could name -- one entry of\nan AmbiguousEntityGroup's own `candidates`. Mirrors engine.region.result.\nAmbiguousEntityCandidate field-for-field, with `label` in place of that\ndataclass's `name` (this contract's own vocabulary for a display\nstring, matching ResolvedEntity.label), except that it omits `group_node`\nand `group_name`, which only NoData.options read." }, "AmbiguousEntityGroup": { "properties": { @@ -3387,6 +3550,52 @@ ], "title": "ArtifactEntryModel" }, + "Assumption": { + "properties": { + "kind": { + "type": "string", + "enum": [ + "declared_default", + "open_role", + "place_scope" + ], + "title": "Kind", + "description": "what the engine filled. 'declared_default' is a slot the request left open that its code system's or shape's declared default fixed. 'open_role' is a flow role no request word asked for, read across every entity on it with data, as one series per member where the role scope default filled it and the shape declares the role, else as the total over them. 'place_scope' is a request that named no place, read across every place with data" + }, + "binding_ref": { + "type": "string", + "maxLength": 1036, + "title": "Binding Ref", + "description": "the identity binding whose edit replaces this assumption: 'how:' for a declared default, 'origin:' or 'where:' for a role or the place scope, as on the sentence's own tokens" + }, + "text": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Text", + "description": "the words the sentence's assumptions clause states for this fill: the bound code's full label for a declared default ('official development assistance' for CRSTypeOfFlow10, whose short name is 'ODA'), 'every' and the role's noun in the answer's flow family for an open role ('every provider', 'every creditor'), and 'every country', 'every place' or 'the world as a whole' for the place scope, as its members are typed" + }, + "refs": { + "items": { + "type": "string", + "maxLength": 1024 + }, + "type": "array", + "maxItems": 1, + "title": "Refs", + "description": "the value dcid a declared default bound its slot to, as the slot's trace.slot_filters[].refs list it (['CRSTypeOfFlow10'] for official development assistance). An open role and the place scope carry []. A dataset_resubmit echo matches a declared default to its slot by these values" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind", + "binding_ref", + "text" + ], + "title": "Assumption", + "description": "One value the answer filled that its request did not ask for, stated for people\nin `text` and for code in `kind`, `binding_ref` and `refs`.\n\nAssumptions live on the part (`_PartBase.assumptions`), and a candidates part holds\neach shown reading's own list as well (`CandidatesPart.reading_assumptions`), the one\na client echoes on a dataset_resubmit after picking that reading. The sentence that\ncarries the part closes with them as one clause: \"Assumed: official development\nassistance; every provider.\"" + }, "Authority": { "properties": { "name": { @@ -3973,7 +4182,7 @@ "specs": { "items": { "$ref": "#/components/schemas/Spec", - "description": "the resolved Spec answering this part. Several parts sharing one five-tuple shape carry the identical spec verbatim (the same spec_id); a part that shares the spec without minting it carries a part-scoped binding_folded warning" + "description": "the resolved Spec answering this part. Parts whose specs share a spec_id are one reading of the data, the same series, entities and years. A later part that folds into an earlier part's spec carries binding_folded. A part posted with separate: true never folds and keeps its own part, so two separate parts can carry one spec_id by request. Parts sharing a spec_id can differ in assumptions, so a client never dedupes parts by spec_id" }, "type": "array", "minItems": 2, @@ -4014,7 +4223,7 @@ "separate": { "type": "boolean", "title": "Separate", - "description": "true when this part was asked beside the others to be compared with them. A client resubmitting an identity, candidate set, or placeholder posts this flag on that entry to preserve the comparison. False, the default, is omitted", + "description": "true when this part was asked beside the others to be compared with them. A client resubmitting an identity, candidate set, or placeholder posts this flag on that entry to preserve the comparison. Two parts marked separate that resolve to one reading carry the same spec_id and stay two parts. False, the default, is omitted", "default": false }, "warnings": { @@ -4046,7 +4255,7 @@ } ], "title": "Rendered Sentence", - "description": "a human-readable string. For candidates, a header naming how many readings there are ('3 readings.'), then each shown candidate's heading and a byline led by the source and span that set it apart; for no_data, a heading in the same claim form naming the entity, measure, and counterpart that were checked. Either ends with the text of this part's departures, in order. For a definite part this stays null or omitted: the confirmation sentence (heading and byline) lives at spec.resolved.rendered_sentence, and its departures reach the envelope's composed sentence." + "description": "a human-readable string. For candidates, a header naming how many readings there are ('3 readings.'), then each shown candidate's heading and a byline led by the source and span that set it apart; for no_data, a heading in the same claim form naming the entity, measure, and counterpart that were checked. Either ends with the text of this part's departures, in order, and a candidates part's then closes with its assumptions clause. For a definite part this stays null or omitted: the confirmation sentence (heading and byline) lives at spec.resolved.rendered_sentence, and its departures reach the envelope's composed sentence." }, "sentence_plan": { "anyOf": [ @@ -4090,6 +4299,14 @@ "title": "Departures", "description": "every way this part's answer differs from what its request asked, ordered by how much each changes the number: closest_match, measure_not_applied, operation_not_applied, breakdown_not_applied, entity_unavailable, year_unavailable, modelled_values, group_read_as_members, direction_discarded, direction_inferred, scope_limited. [] when the answer is what was asked. A client that renders its own sentence reads them here; each one's text also closes the sentence that carries this part (see Departure.text). A warning on the same part reports run health and stays separate" }, + "assumptions": { + "items": { + "$ref": "#/components/schemas/Assumption" + }, + "type": "array", + "title": "Assumptions", + "description": "every value the engine filled that the request did not ask for, in clause order. Declared defaults come first, in the order of the Spec's trace.slot_filters, then open roles, then the place scope. A declared default is a slot the request left open that its code system's or shape's declared default fixed, named by the bound code's full label. An open role is a flow role no request word asked for, read across every entity on it with data. It is either a role the role scope default filled (resolved.scope on that axis), whatever its member count, served as one series per member where the shape declares the role, or a role the heading states with no entity of its own ('from 164 providers', 'owed to all creditors'), served as the total over its members. A role the identity binds in entities or lists in open_roles, that one of the part's operations runs over ('top 5 donors'), or that the request's words asked every member of ('all donors'), is asked. The place scope is a request that named no place, read across every place with data. Every door fills assumptions. A definite part reads them from its Spec, a candidates part carries the items every list in CandidatesPart.reading_assumptions holds alike, text included, and no_data and unsupported parts carry []. A dataset_resubmit identity entry posts every slot bound, so its part states the items of the entry's assumptions echo that still hold (see ResubmitIdentityEntry.assumptions), and a candidates entry reads each reading with its candidate's echo (see ResubmitCandidate.assumptions). The sentence that carries this part closes with them as one segment='assumption' clause ('Assumed: official development assistance; every provider.'), after its departures. [] when the answer fills nothing" + }, "status": { "type": "string", "const": "candidates", @@ -4099,6 +4316,17 @@ "candidates": { "$ref": "#/components/schemas/CandidateSet", "description": "2..N competing Specs" + }, + "reading_assumptions": { + "additionalProperties": { + "items": { + "$ref": "#/components/schemas/Assumption" + }, + "type": "array" + }, + "type": "object", + "title": "Reading Assumptions", + "description": "each shown reading's own assumptions, keyed by its Spec's spec_id (candidates.specs[].spec_id). Each list is the one a definite part answering that Spec for this part's request carries, read with the part's operations and the axes the request's words asked every member of. The part's own assumptions are the items every list here holds alike, text included, so an open role one reading reads, or an item two readings word differently ('every provider' against 'every creditor'), is stated here alone. A client that picks a reading posts its identity as a dataset_resubmit identity entry and echoes reading_assumptions[spec_id] as the entry's assumptions, so the picked answer states what that reading assumed. A client that edits the set echoes each reading's entry as its candidate's assumptions. [] for a reading that assumes nothing" } }, "additionalProperties": false, @@ -4277,7 +4505,8 @@ "required": [ "query_echo", "diagnostics", - "scope" + "scope", + "kind" ], "title": "CatalogueAnswer", "description": "A resolve response to a question that asks what DFO holds and names\nneither an indicator nor a subject, such as \"what data do you have?\". It\ncarries the country the question named, when the resolver confirms one." @@ -5346,8 +5575,7 @@ "required": [ "name", "kind", - "droppable", - "distinct" + "droppable" ], "title": "ColumnOptionModel", "description": "One frame column, verbatim from `materialise.profile.ColumnProfile`." @@ -6761,7 +6989,7 @@ } ], "title": "Base Content Version", - "description": "the raw version a derived version (a full groupby collapse, a party-totals cut, or both) was rendered from; null on every other version" + "description": "the raw version a derived version (a full groupby collapse, a party-totals cut, or both) was rendered from. Null on every other version" }, "rendering": { "type": "string", @@ -6783,12 +7011,12 @@ "type": "null" } ], - "description": "the groupby a collapse was summed by, as its file's rendering records it; null unless `rendering` is groupby" + "description": "the groupby a collapse was summed by, as its file's rendering records it. Null unless `rendering` is groupby" }, "without_party_totals": { "type": "boolean", "title": "Without Party Totals", - "description": "true when the derived version's frame leaves out the group totals of its open party roles, as its file's rendering records it; absent when false", + "description": "true when the derived version's frame leaves out the group totals of its open party roles, as its file's rendering records it. Absent when false", "default": false } }, @@ -6802,7 +7030,7 @@ ], "title": "DatasetVersion" }, - "DatasetVersionsResponse": { + "DatasetVersionsPage": { "properties": { "schema_version": { "type": "integer", @@ -6820,16 +7048,35 @@ }, "type": "array", "title": "Versions", - "description": "stored versions, newest first" + "description": "stored versions that are not revoked, newest first" + }, + "next_cursor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Next Cursor", + "description": "continues the list after this page's last version; null when complete" + }, + "complete": { + "type": "boolean", + "title": "Complete", + "description": "true when this page reaches the end of the list" } }, "additionalProperties": false, "type": "object", "required": [ "spec_id", - "versions" + "versions", + "next_cursor", + "complete" ], - "title": "DatasetVersionsResponse" + "title": "DatasetVersionsPage" }, "DateRange": { "properties": { @@ -6907,7 +7154,8 @@ "query_echo", "diagnostics", "reason", - "scope" + "scope", + "kind" ], "title": "DeclinedAnswer", "description": "A resolve response to a question search does not answer." @@ -6929,7 +7177,7 @@ "separate": { "type": "boolean", "title": "Separate", - "description": "true when this part was asked beside the others to be compared with them. A client resubmitting an identity, candidate set, or placeholder posts this flag on that entry to preserve the comparison. False, the default, is omitted", + "description": "true when this part was asked beside the others to be compared with them. A client resubmitting an identity, candidate set, or placeholder posts this flag on that entry to preserve the comparison. Two parts marked separate that resolve to one reading carry the same spec_id and stay two parts. False, the default, is omitted", "default": false }, "warnings": { @@ -6961,7 +7209,7 @@ } ], "title": "Rendered Sentence", - "description": "a human-readable string. For candidates, a header naming how many readings there are ('3 readings.'), then each shown candidate's heading and a byline led by the source and span that set it apart; for no_data, a heading in the same claim form naming the entity, measure, and counterpart that were checked. Either ends with the text of this part's departures, in order. For a definite part this stays null or omitted: the confirmation sentence (heading and byline) lives at spec.resolved.rendered_sentence, and its departures reach the envelope's composed sentence." + "description": "a human-readable string. For candidates, a header naming how many readings there are ('3 readings.'), then each shown candidate's heading and a byline led by the source and span that set it apart; for no_data, a heading in the same claim form naming the entity, measure, and counterpart that were checked. Either ends with the text of this part's departures, in order, and a candidates part's then closes with its assumptions clause. For a definite part this stays null or omitted: the confirmation sentence (heading and byline) lives at spec.resolved.rendered_sentence, and its departures reach the envelope's composed sentence." }, "sentence_plan": { "anyOf": [ @@ -7005,6 +7253,14 @@ "title": "Departures", "description": "every way this part's answer differs from what its request asked, ordered by how much each changes the number: closest_match, measure_not_applied, operation_not_applied, breakdown_not_applied, entity_unavailable, year_unavailable, modelled_values, group_read_as_members, direction_discarded, direction_inferred, scope_limited. [] when the answer is what was asked. A client that renders its own sentence reads them here; each one's text also closes the sentence that carries this part (see Departure.text). A warning on the same part reports run health and stays separate" }, + "assumptions": { + "items": { + "$ref": "#/components/schemas/Assumption" + }, + "type": "array", + "title": "Assumptions", + "description": "every value the engine filled that the request did not ask for, in clause order. Declared defaults come first, in the order of the Spec's trace.slot_filters, then open roles, then the place scope. A declared default is a slot the request left open that its code system's or shape's declared default fixed, named by the bound code's full label. An open role is a flow role no request word asked for, read across every entity on it with data. It is either a role the role scope default filled (resolved.scope on that axis), whatever its member count, served as one series per member where the shape declares the role, or a role the heading states with no entity of its own ('from 164 providers', 'owed to all creditors'), served as the total over its members. A role the identity binds in entities or lists in open_roles, that one of the part's operations runs over ('top 5 donors'), or that the request's words asked every member of ('all donors'), is asked. The place scope is a request that named no place, read across every place with data. Every door fills assumptions. A definite part reads them from its Spec, a candidates part carries the items every list in CandidatesPart.reading_assumptions holds alike, text included, and no_data and unsupported parts carry []. A dataset_resubmit identity entry posts every slot bound, so its part states the items of the entry's assumptions echo that still hold (see ResubmitIdentityEntry.assumptions), and a candidates entry reads each reading with its candidate's echo (see ResubmitCandidate.assumptions). The sentence that carries this part closes with them as one segment='assumption' clause ('Assumed: official development assistance; every provider.'), after its departures. [] when the answer fills nothing" + }, "status": { "type": "string", "const": "definite", @@ -7013,7 +7269,7 @@ }, "spec": { "$ref": "#/components/schemas/Spec", - "description": "the resolved Spec answering this part. Several parts sharing one five-tuple shape carry the identical spec verbatim (the same spec_id); a part that shares the spec without minting it carries a part-scoped binding_folded warning" + "description": "the resolved Spec answering this part. Parts whose specs share a spec_id are one reading of the data, the same series, entities and years. A later part that folds into an earlier part's spec carries binding_folded. A part posted with separate: true never folds and keeps its own part, so two separate parts can carry one spec_id by request. Parts sharing a spec_id can differ in assumptions, so a client never dedupes parts by spec_id" } }, "additionalProperties": false, @@ -8665,25 +8921,6 @@ "title": "Freshness", "description": "A source's own refresh cadence, read from DCP provenance arcs that imports populate\nunevenly: `dc/base/WHO_COVID19` carries both `sourceReleaseFrequency` and\n`automaticRefreshType`, `dc/base/BIS_CentralBankPolicyRate` only the second, and\n`dc/base/WHO_GHO` neither. Nullability is the contract.\n\n`release_frequency` is the raw `sourceReleaseFrequency` ISO 8601 duration (`P1M`);\n`release_frequency_label` is `materialise.cadence.cadence_label`'s display label for it\n(`Monthly`), or the raw token when that module does not recognise it.\n\n`refresh_type` is `automaticRefreshType`'s value: how this deployment refreshes the\nsource, such as `GCPCloudRunAutomaticRefresh`, or the sentinel `NoAutomaticRefresh`." }, - "FrontMatterValue": { - "anyOf": [ - { - "type": "string" - }, - { - "items": { - "$ref": "#/components/schemas/FrontMatterValue" - }, - "type": "array" - }, - { - "additionalProperties": { - "$ref": "#/components/schemas/FrontMatterValue" - }, - "type": "object" - } - ] - }, "GraphRef": { "properties": { "ref": { @@ -9624,6 +9861,17 @@ ], "title": "Series Coverage Stamp", "description": "the series_coverage artifact stamp this request's sync-admission estimate was computed against, kept as lineage only. content_version is a pure function of the frame and does not fold this in. Not the same coverage as the 'coverage' field above (materialise.window.Coverage's row/dimension/window report)" + }, + "retention": { + "anyOf": [ + { + "$ref": "#/components/schemas/RetentionModel" + }, + { + "type": "null" + } + ], + "description": "how long this version can still be fetched: the retention of the frame every file renders from (a derived version's base frame). Each door sets it on its response" } }, "additionalProperties": false, @@ -10306,7 +10554,7 @@ }, "type": "array", "title": "Entity Terms", - "description": "the query entity text responsible for an entity-resolution outcome, in query order: every entity the engine could not resolve for entity_not_resolved, every ambiguous wording for entity_ambiguous, or every resolved-but-unadmitted entity for entity_role_not_admitted. Empty for every other no_data reason. This structured list is the client-facing source of those terms; rendered_sentence may quote the same wording for people, but clients must not parse it." + "description": "the query entity text responsible for an entity-resolution outcome, in query order: every entity the engine could not resolve for entity_not_resolved, every ambiguous wording for entity_ambiguous, every resolved-but-unadmitted entity for entity_role_not_admitted, or every name whose flow direction the query leaves untold for role_not_resolved. Empty for every other no_data reason. This structured list is the client-facing source of those terms; rendered_sentence may quote the same wording for people, but clients must not parse it." }, "ambiguous_entities": { "items": { @@ -10330,7 +10578,7 @@ }, "type": "array", "title": "Ambiguous Sources", - "description": "every ambiguous source wording responsible for a source_ambiguous outcome, in query order, each paired with the admitted sources it could name, and for source_code_ambiguous the part's source_code paired with the provenances holding it. Empty for every other no_data reason. A client posts the chosen candidate's ref on that mention of data_query, or for a source code as a new mention in its sources, and posts the part back." + "description": "every ambiguous source wording responsible for a source_ambiguous outcome, in query order, each paired with the admitted sources it could name, and for source_code_ambiguous the part's source_code paired with the provenances holding it. Empty for every other no_data reason. A client posts the matching entry of options." }, "unit_alternatives": { "anyOf": [ @@ -10366,16 +10614,13 @@ ], "description": "the denominator the question named and the one the flagged match divides by, set on every denominator_not_available refusal the engine returns after electing a series; null for every other no_data reason. A client can offer the flagged match, or fetch its nearest_real level and the denominator asked and divide them" }, - "data_query": { - "anyOf": [ - { - "$ref": "#/components/schemas/ParsedInput" - }, - { - "type": "null" - } - ], - "description": "the parsed form of this part, one part long, set when reason is entity_ambiguous, source_ambiguous or source_code_ambiguous: its variable text, entities with role_text, time, unit, sources, and operations. On entity_ambiguous every entity that resolved to one graph node is pinned to its dcid and each ambiguous wording left unpinned. A named group stays unpinned too, so it resolves to the same members again. On source_ambiguous every source mention that resolved carries its ref and each ambiguous wording carries none. On source_code_ambiguous it carries the code and the part's mentions. A client pins the candidate the user picks from ambiguous_entities or ambiguous_sources and posts the part back, through the parsed door or as a dataset_resubmit parsed entry. It is set when the part has no restatement too: an entity whose direction the question leaves unnamed carries no role_text. Null for every other no_data reason, and when the part's inputs exceed the ParsedPart bounds" + "options": { + "items": { + "$ref": "#/components/schemas/NoDataOption" + }, + "type": "array", + "title": "Options", + "description": "one ready request per choice of an entity_ambiguous, source_ambiguous, source_code_ambiguous, role_not_resolved or unit_not_resolved refusal, in query then candidate order. An entity option pins the candidate on every row with the ambiguous wording and every entity that resolved to one node; named groups, sets read as members and other ambiguous wordings stay unpinned, so a second ambiguity refuses again with the first pick kept. A candidate that is a group's own node, asked for its members, posts the group's registry name with no dcid, and has no option when no registry name resolves to the group alone. A source option sets the candidate's ref on the ambiguous mention; a source-code option names the holding provenance as the part's only included source. A role option states a direction for every name the question left unstated, so that every axis the shape declares a role on and the part does not ask open holds a place, offered while that gives at most six readings. A unit option names one of unit_alternatives in place of the ambiguous currency words. An option whose part breaks the ParsedPart bounds, or states a direction its own wording contradicts, is left out. Empty for other reasons; when the part's inputs exceed the ParsedPart bounds; on a role_not_resolved refusal with more than six readings, with no reading that leaves a place on every such axis, whose readings were all read with none holding data, or that the shape refused before placing names; and on a unit_not_resolved refusal without unit_alternatives" } }, "additionalProperties": false, @@ -10416,6 +10661,36 @@ "title": "NoDataDenominator", "description": "The denominators a denominator_not_available refusal compared: the one the question\nnamed and the one its flagged match divides by -- NoData.denominator." }, + "NoDataOption": { + "properties": { + "mentions": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Mentions", + "description": "the request's own words this option settles, in query order: the ambiguous entity wording, the ambiguous source wording, the part's source_code, the part's unit_text, or for role_not_resolved every name whose direction the option states" + }, + "label": { + "type": "string", + "title": "Label", + "description": "the choice in words for a menu: the candidate's display name, prefixed 'Excluding' for a source the part excludes; for role_not_resolved the direction the option reads, such as 'France to Germany' or 'To Kenya and Uganda'; for a role currency the role's currency, such as \"recipient's currency\". Clients must not parse it" + }, + "data_query": { + "$ref": "#/components/schemas/ParsedInput", + "description": "a one-part parsed input settling this choice only. Post it unchanged as the input of /api/search/resolve; its one part is a dataset_resubmit parsed entry's part. A second ambiguous wording refuses again. Whether data exists for it is not checked" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "mentions", + "label", + "data_query" + ], + "title": "NoDataOption", + "description": "One answer to the choice a no_data refusal asks for: the words it settles, a label\nfor people, and the request that settles them. It is one entry of NoData.options." + }, "NoDataPart": { "properties": { "variable_text": { @@ -10433,7 +10708,7 @@ "separate": { "type": "boolean", "title": "Separate", - "description": "true when this part was asked beside the others to be compared with them. A client resubmitting an identity, candidate set, or placeholder posts this flag on that entry to preserve the comparison. False, the default, is omitted", + "description": "true when this part was asked beside the others to be compared with them. A client resubmitting an identity, candidate set, or placeholder posts this flag on that entry to preserve the comparison. Two parts marked separate that resolve to one reading carry the same spec_id and stay two parts. False, the default, is omitted", "default": false }, "warnings": { @@ -10465,7 +10740,7 @@ } ], "title": "Rendered Sentence", - "description": "a human-readable string. For candidates, a header naming how many readings there are ('3 readings.'), then each shown candidate's heading and a byline led by the source and span that set it apart; for no_data, a heading in the same claim form naming the entity, measure, and counterpart that were checked. Either ends with the text of this part's departures, in order. For a definite part this stays null or omitted: the confirmation sentence (heading and byline) lives at spec.resolved.rendered_sentence, and its departures reach the envelope's composed sentence." + "description": "a human-readable string. For candidates, a header naming how many readings there are ('3 readings.'), then each shown candidate's heading and a byline led by the source and span that set it apart; for no_data, a heading in the same claim form naming the entity, measure, and counterpart that were checked. Either ends with the text of this part's departures, in order, and a candidates part's then closes with its assumptions clause. For a definite part this stays null or omitted: the confirmation sentence (heading and byline) lives at spec.resolved.rendered_sentence, and its departures reach the envelope's composed sentence." }, "sentence_plan": { "anyOf": [ @@ -10509,6 +10784,14 @@ "title": "Departures", "description": "every way this part's answer differs from what its request asked, ordered by how much each changes the number: closest_match, measure_not_applied, operation_not_applied, breakdown_not_applied, entity_unavailable, year_unavailable, modelled_values, group_read_as_members, direction_discarded, direction_inferred, scope_limited. [] when the answer is what was asked. A client that renders its own sentence reads them here; each one's text also closes the sentence that carries this part (see Departure.text). A warning on the same part reports run health and stays separate" }, + "assumptions": { + "items": { + "$ref": "#/components/schemas/Assumption" + }, + "type": "array", + "title": "Assumptions", + "description": "every value the engine filled that the request did not ask for, in clause order. Declared defaults come first, in the order of the Spec's trace.slot_filters, then open roles, then the place scope. A declared default is a slot the request left open that its code system's or shape's declared default fixed, named by the bound code's full label. An open role is a flow role no request word asked for, read across every entity on it with data. It is either a role the role scope default filled (resolved.scope on that axis), whatever its member count, served as one series per member where the shape declares the role, or a role the heading states with no entity of its own ('from 164 providers', 'owed to all creditors'), served as the total over its members. A role the identity binds in entities or lists in open_roles, that one of the part's operations runs over ('top 5 donors'), or that the request's words asked every member of ('all donors'), is asked. The place scope is a request that named no place, read across every place with data. Every door fills assumptions. A definite part reads them from its Spec, a candidates part carries the items every list in CandidatesPart.reading_assumptions holds alike, text included, and no_data and unsupported parts carry []. A dataset_resubmit identity entry posts every slot bound, so its part states the items of the entry's assumptions echo that still hold (see ResubmitIdentityEntry.assumptions), and a candidates entry reads each reading with its candidate's echo (see ResubmitCandidate.assumptions). The sentence that carries this part closes with them as one segment='assumption' clause ('Assumed: official development assistance; every provider.'), after its departures. [] when the answer fills nothing" + }, "status": { "type": "string", "const": "no_data", @@ -10693,8 +10976,33 @@ "description": "A batch entry for a dcid where `GET /api/graph/node/{dcid}` answers 404\n`node_not_held`." }, "ObservationPoint": { - "additionalProperties": true, - "type": "object" + "properties": { + "date": { + "type": "string", + "title": "Date", + "description": "the observation date, e.g. '2018'" + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Value", + "description": "the observed value; null when the graph reports a date with no value" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "date", + "value" + ], + "title": "ObservationPoint", + "description": "One (date, value) pair from a resolved StatVar's observation series." }, "ObservationSeries": { "properties": { @@ -11089,7 +11397,8 @@ "operation_id": { "type": "string", "pattern": "^op_", - "title": "Operation Id" + "title": "Operation Id", + "description": "`op_` plus the SHA-256 of the subject and its sorted member dcids, the origin catalogue build, and the rendering key. A repeat submission with the same identity joins the running operation and returns this id. Synchronous builds coalesce per API instance only." }, "status": { "type": "string", @@ -11122,7 +11431,7 @@ } ], "title": "Retry After Ms", - "description": "present only on the initial 202 submit response; absent on a pending/running poll -- a caller polling with no backoff strategy of its own gets no ongoing pacing guidance from this field past the first response" + "description": "Milliseconds to wait before the next poll. Present on the 202 submit response and on every pending or running poll. Absent on a done poll. It grows as the build runs, at a quarter of the time since the operation's current submission, from 1,500 to 8,000. The `Retry-After` response header carries the same value in whole seconds, rounded up." }, "progress": { "anyOf": [ @@ -11890,7 +12199,7 @@ "separate": { "type": "boolean", "title": "Separate", - "description": "true when this part is asked beside the others to be compared with them, as in 'health ODA versus education ODA': it answers as its own part and never folds into another part of the same shape (binding_folded). False, the default, folds parts that share a shape into one set answer", + "description": "true when this part is asked beside the others to be compared with them, as in 'health ODA versus education ODA': it answers as its own part and never folds into another part of the same shape (binding_folded). False, the default, folds parts that share a shape into one set answer. Two parts marked separate that resolve to one reading carry the same spec_id and stay two parts", "default": false } }, @@ -13354,7 +13663,7 @@ } ], "title": "Rendered Sentence", - "description": "the envelope-level confirmation sentence describing the whole query, composed across every part's own sentence in query order. When every contributing part is definite, their headings join into one sentence. A qualifier axis (where, when, or source, each a wire value of axis, plus origin, identified by role=='origin' instead since SentenceAxis has no 'origin' member) whose bound value agrees across every contributing part is stated once after the joined phrases, a possessive lead every part shares opens the sentence once, and the byline follows once. A qualifier that differs stays inline in each part's own phrase. The response falls back to one sentence per part, each part's own text left exactly as that part rendered it, when a part is still resolving, when the parts' bylines differ, or when a differing qualifier's connective opens with a comma (a period range). A part still resolving contributes up to three tokens of its own: an optional prefix text token, its own variable_text as an editable slot, and a text token stating the outcome. A lone part that is not definite composes to exactly that part's own sentence. After the headings and bylines, each part's departures follow in part order as segment='departure' tokens carrying that part's part_index. This is the one sentence that writes out a definite part's departures." + "description": "the envelope-level confirmation sentence describing the whole query, composed across every part's own sentence in query order. When every contributing part is definite, their headings join into one sentence. A qualifier axis (where, when, or source, each a wire value of axis, plus origin, identified by role=='origin' instead since SentenceAxis has no 'origin' member) whose bound value agrees across every contributing part is stated once after the joined phrases, a possessive lead every part shares opens the sentence once, and the byline follows once. A qualifier that differs stays inline in each part's own phrase. The response falls back to one sentence per part, each part's own text left exactly as that part rendered it, when a part is still resolving, when the parts' bylines differ, or when a differing qualifier's connective opens with a comma (a period range). A part still resolving contributes up to three tokens of its own: an optional prefix text token, its own variable_text as an editable slot, and a text token stating the outcome. A lone part that is not definite composes to exactly that part's own sentence. After the headings and bylines, each part's departures follow in part order as segment='departure' tokens carrying that part's part_index. This is the one sentence that writes out a definite part's departures. The parts' assumptions close the sentence as segment='assumption' tokens. A joined sentence takes one clause, each item carrying the part_index of its part and an item two parts share carrying none. A sentence written part by part takes each part's own clause after its departures. There, a part whose sentence and clause both repeat an earlier part's is stated once with it, that sentence and clause carrying no part_index, followed by each part's own departures, and a part whose clause differs keeps its own sentence. On a mixed resolution with at least one definite part, the sentence opens 'Answered N of M parts.', where N counts the definite parts, folded ones included, and M is len(parts)." }, "sentence_plan": { "anyOf": [ @@ -13369,7 +13678,7 @@ } ], "title": "Sentence Plan", - "description": "the ordered token form of rendered_sentence, present under the same condition; null or omitted otherwise. Composed the same way rendered_sentence is, from every part's own sentence_plan -- see SentenceToken.part_index for how a client recovers which parts[i] each variable phrase and attached qualifier belongs to, and which tokens are shared skeleton (an inter-phrase connective, a hoisted shared qualifier, the terminal '.', or the shared ' ' the per-part fallback puts between two sentences) rather than any one part's own." + "description": "the ordered token form of rendered_sentence, present under the same condition; null or omitted otherwise. Composed the same way rendered_sentence is, from every part's own sentence_plan -- see SentenceToken.part_index for how a client recovers which parts[i] each variable phrase and attached qualifier belongs to, and which tokens are shared skeleton (an inter-phrase connective, a hoisted shared qualifier, the terminal '.', or the shared ' ' the per-part fallback puts between two sentences) rather than any one part's own. On a mixed resolution with at least one definite part, the plan opens with two segment='coverage' tokens carrying no part_index, 'Answered N of M parts.' and ' '. A mixed resolution with no definite part has no opener." }, "skills": { "anyOf": [ @@ -13405,7 +13714,8 @@ "query_echo", "diagnostics", "parts", - "status" + "status", + "kind" ], "title": "Resolution", "description": "A resolve response that resolved the question into data: one part per\nvariable asked, in query order, each a complete outcome carrying its own\nstatus and payload.\n\nA single-variable query is one part, so `status` reads that one part's\nstatus directly. A query in which extraction found no variable is also\none part, whose `variable_text` is the whole query text.\n\n`status` below is a computed field that rides in every serialised\nresponse body without being a settable input, so this class stays a\nplain `BaseModel`, which allows unknown fields. `StrictModel` forbids them,\nwhich would make `Resolution.model_validate` reject its own `model_dump()`\noutput, breaking every round-trip a client or this codebase does on a\nfetched response body. A posted `status` is ignored and recomputed.\n\nUsage::\n\n resp = RESOLVE_RESPONSE_ADAPTER.validate_python(obj)\n if resp.kind == \"resolution\":\n resp.status # \"definite\" | \"candidates\" | \"no_data\" | \"unsupported\" | \"mixed\"\n resp.parts[0].status # this part's own status" @@ -14596,6 +14906,22 @@ ], "title": "Entity Groups", "description": "the named group each role's entities were asked for as, keyed by entity role key. Post a prior Spec's resolved.entity_groups beside any identity derived from that Spec. A group is kept when it posts a dcid and the graph's members of that node are exactly the identity's entities on the role; any other group, including one on a role the identity binds no entity on, is dropped" + }, + "assumptions": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/Assumption" + }, + "type": "array", + "maxItems": 67 + }, + { + "type": "null" + } + ], + "title": "Assumptions", + "description": "the assumptions of the reading this candidate rebuilds, echoed as the response gave them, which are the candidates part's reading_assumptions under the reading's spec_id. The rebuilt reading's reading_assumptions entry states the echoed items that still hold, each worded from the rebuilt reading by the rule ResubmitIdentityEntry.assumptions states, and the rebuilt part's assumptions are the items every reading_assumptions list holds alike. An item the echo lacks is not stated, so an edit of a defaulted slot to another value drops that default, and [], the echo of a reading that stated none, states none. None, the default, means the client echoes nothing for this reading, which yields what a fresh request would: no declared default, since the posted identity binds every slot, and the open roles and place scope the reading reads" } }, "additionalProperties": false, @@ -14729,6 +15055,22 @@ "maxItems": 8, "title": "Operations", "description": "the operations the question asks for over this part's data, in query order; the engine echoes them onto the part it resolves. Empty when the question asks for none" + }, + "assumptions": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/Assumption" + }, + "type": "array", + "maxItems": 67 + }, + { + "type": "null" + } + ], + "title": "Assumptions", + "description": "the assumptions of the part this entry rebuilds, echoed as the response gave them. For a definite part these are its assumptions. For a reading picked from a candidates part they are that part's reading_assumptions under the reading's spec_id. The rebuilt part states the echoed items that still hold, each worded from the rebuilt answer: a declared_default whose slot (binding_ref) still binds the echoed refs, an open_role whose axis the answer still reads across every member with no entity of the identity's, and a place_scope on an answer that still names no place. An item the echo lacks is not stated, since the posted identity or its edit asked for it. An edit of a defaulted slot to another value therefore drops that default, and [], the echo of a part that stated none, states none. None, the default, means the client echoes nothing, and the part states what a fresh request would: no declared default, since the posted identity binds every slot, and the open roles and place scope the answer reads. The engine cannot tell an echoed default from one the caller writes for a slot it chose itself, and states such an item while the slot binds its refs. An echo shapes only the caller's own response" } }, "additionalProperties": false, @@ -14859,6 +15201,35 @@ "title": "ResubmitPlaceholderEntry", "description": "One part restated as a stub from a no_data/unsupported outcome the\nclient already holds -- zero graph round-trips, zero LLM calls. Carried\nforward unresolved so its sibling parts' composed sentence and fold can\nstill be computed across the whole dataset; the engine stamps a\npart-scoped `part_restated` info warning on the rebuilt part." }, + "RetentionModel": { + "properties": { + "pinned": { + "type": "boolean", + "title": "Pinned", + "description": "whether the frame the version's files render from is in the pinned tier, which has no expiry" + }, + "held_until": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Held Until", + "description": "when the working-tier frame stops being guaranteed, 30 days after it was stored. A download of the frame after `held_until`, while its bytes survive, renews it for 30 days. After it, a file selector or download link request that must render its file again renews the frame for 30 days if the frame's bytes survive, and otherwise refuses `artifact_expired`. A rebuild of unchanged data through `GET /api/datasets/{id}` or `POST /api/datasets` stores the frame again. Absent when pinned. It can be in the past" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "pinned" + ], + "title": "RetentionModel", + "description": "How long a version can still be fetched, which `datasets_api.retention` computes when a\ndoor serves the version. No stored body holds it." + }, "RoleAxis": { "type": "string", "enum": [ @@ -15019,7 +15390,8 @@ "type": "null" } ], - "title": "Window" + "title": "Window", + "description": "the years to serve. Replaces the spec's window whole" }, "entities": { "anyOf": [ @@ -15036,7 +15408,8 @@ "type": "null" } ], - "title": "Entities" + "title": "Entities", + "description": "role name to dcids. Replaces the spec's whole entity binding. A role this map omits is unbound, so a client narrowing one role repeats the spec's other roles, and {} unbinds every bound role. An open role the map binds is no longer open" }, "facets": { "anyOf": [ @@ -15074,13 +15447,14 @@ "type": "null" } ], - "title": "Facets" + "title": "Facets", + "description": "axis to binding. Replaces the spec's whole facet binding" } }, "additionalProperties": false, "type": "object", "title": "Scope", - "description": "The `scope` block a mint request may carry: an omitted member means\nunbound (everything). `window` narrows the result to `all`, `latest`,\nor a `start_year`/`end_year` range. `entities` binds role names to\nnon-empty lists of dcids (a role's values must each be non-empty and\nmust not contain `+` or `,`). `facets` binds a known axis\n(`provenance`, `measurementMethod`, `unit`) to a specific ref, or\n`measurementMethod` or `unit` to a null ref. The `unit` axis alone may\ninstead carry a conversion request (`FacetUnitRequestBinding`) or ask for\neach entity's own currency (`FacetNationalCurrencyBinding`)." + "description": "The `scope` block a mint request may carry. On a `spec_id` input each\nsupplied member replaces the stored spec's value for that member whole,\nand an omitted member keeps the spec's value. On a `statvar_set` input,\nwhich has no stored spec, an omitted member is unbound (everything).\n`window` narrows the result to `all`, `latest`, or a\n`start_year`/`end_year` range. `entities` binds role names to non-empty\nlists of dcids (a role's values must each be non-empty and must not\ncontain `+` or `,`). `facets` binds a known axis (`provenance`,\n`measurementMethod`, `unit`) to a specific ref, or `measurementMethod`\nor `unit` to a null ref. The `unit` axis alone may instead carry a\nconversion request (`FacetUnitRequestBinding`) or ask for each entity's\nown currency (`FacetNationalCurrencyBinding`)." }, "Scope-Output": { "properties": { @@ -15190,12 +15564,14 @@ "segment": { "type": "string", "enum": [ + "coverage", "heading", "byline", - "departure" + "departure", + "assumption" ], "title": "Segment", - "description": "the part of the sentence this token belongs to: 'heading' (what the answer is), 'byline' (latest-year label, unit, source, and a bound method), or 'departure' (the text of one Departure on the same part, never on a Spec's own plan). A client styles each segment as a block; the plain join of every token's text still equals rendered_sentence", + "description": "the part of the sentence this token belongs to: 'coverage' (the 'Answered N of M parts.' a mixed envelope sentence opens with, never on a part's or a Spec's own plan), 'heading' (what the answer is), 'byline' (latest-year label, unit, source, and a bound method), 'departure' (the text of one Departure on the same part, never on a Spec's own plan), or 'assumption' (the closing clause naming what the answer assumed, from the parts' assumptions, never on a Spec's own plan). A client styles each segment as a block; the plain join of every token's text still equals rendered_sentence", "default": "heading" }, "property_dcid": { @@ -15219,7 +15595,7 @@ "type": "null" } ], - "description": "origin/destination when this token renders a directional entity role (the flow's two endpoints read back), or the directional scope an unbound where slot resolved to. entity_refs is the discriminator: non-empty on the entity read-back, empty on the unbound-where-slot fallback. binding_ref is not: an entity read-back carries binding_ref too whenever the shape declares a where slot backing the 'destination' axis (e.g. dev-finance), the same condition under which the unbound-where-slot fallback always carries it, so a present binding_ref value never separates the two. Both kinds join to the Spec.resolved.entity_options entry on the same role. A third token sits on an entity_ambiguous no_data plan, which has no Spec: the ambiguous wording, with the role the request gave it (null when it gave none), no entity_refs and no binding_ref, and text equal to one NoData.ambiguous_entities[i].text on the same part. The client titles that wording's candidate menu by this role and pins the pick into NoData.data_query." + "description": "origin/destination when this token renders a directional entity role (the flow's two endpoints read back), or the directional scope an unbound where slot resolved to. entity_refs is the discriminator: non-empty on the entity read-back, empty on the unbound-where-slot fallback. binding_ref is not: an entity read-back carries binding_ref too whenever the shape declares a where slot backing the 'destination' axis (e.g. dev-finance), the same condition under which the unbound-where-slot fallback always carries it, so a present binding_ref value never separates the two. Both kinds join to the Spec.resolved.entity_options entry on the same role. A third token sits on an entity_ambiguous no_data plan, which has no Spec: the ambiguous wording, with the role the request gave it (null when it gave none), no entity_refs and no binding_ref, and text equal to one NoData.ambiguous_entities[i].text on the same part. The client titles that wording's candidate menu by this role and posts the pick's entry of NoData.options." }, "binding_ref": { "anyOf": [ @@ -15271,7 +15647,7 @@ } ], "title": "Part Index", - "description": "this token's position in Resolution.parts, when this plan is the envelope-level composed sentence (Resolution.sentence_plan) and this token belongs to exactly one part's own contribution -- a variable phrase token, or a qualifier attached to it because it did not agree across every part, or a token of a part composed as its own sentence. Null carries three distinct readings a client must not conflate: on a part's own plan (DefinitePart.spec.resolved.sentence_plan, or the candidates/no_data/unsupported sentence_plan on _PartBase) the field has no meaning at all and is never set; on a composer-minted connective, it means the token belongs to the sentence as a whole rather than to any one part (the Oxford-joined ' and '/', ', the plan's own terminal '.', and the shared ' ' the per-part fallback puts between two sentences are all such tokens); and on a token every contributing part states alike and the join states once (a hoisted qualifier on the where, when, or source axis, each a wire value of axis, or the origin role, identified by role=='origin' instead since SentenceAxis has no 'origin' member; a shared possessive lead; the shared byline; or a heading or byline token of a part a later part folded into, binding_folded, which both parts state) it means the token no longer describes a single variable." + "description": "this token's position in Resolution.parts, when this plan is the envelope-level composed sentence (Resolution.sentence_plan) and this token belongs to exactly one part's own contribution -- a variable phrase token, or a qualifier attached to it because it did not agree across every part, or a token of a part composed as its own sentence. Null carries four distinct readings a client must not conflate: on a part's own plan (DefinitePart.spec.resolved.sentence_plan, or the candidates/no_data/unsupported sentence_plan on _PartBase) the field has no meaning at all and is never set; on a composer-minted token, it means the token belongs to the sentence as a whole rather than to any one part (the Oxford-joined ' and '/', ', the plan's own terminal '.', the shared ' ' the per-part fallback puts between two sentences, the 'coverage' opener, and an assumptions clause's lead, separators and '.' when no one part carries every item it names are all such tokens); on a token every contributing part states alike and the join states once (a hoisted qualifier on the where, when, or source axis, each a wire value of axis, or the origin role, identified by role=='origin' instead since SentenceAxis has no 'origin' member; a shared possessive lead; the shared byline; or a heading or byline token of a part a later part folded into, binding_folded, which both parts state) it means the token no longer describes a single variable; and on an 'assumption' item it means more than one part assumed it, and each part's own assumptions list says which." } }, "additionalProperties": false, @@ -15281,7 +15657,7 @@ "text" ], "title": "SentenceToken", - "description": "One token in the ordered sentence plan: a \"text\" token (invariant\nwording such as a connective, a bare separator, the terminal period, or a\ndeparture sentence) or a \"slot\" token (a slot- or entity-bound phrase, or\nthe wording of an ambiguous entity).\n\n``rendered_sentence`` (the flat string) is the plain concatenation of every\ntoken's ``text``, in order. The two are computed together and cannot drift.\nA \"slot\" token with nothing bound appears too, with ``text=\"\"``: the same\ntoken structure serves a loading skeleton (before binding is known) and the\nfinal sentence (after it is). The first non-empty token's text is\ncapitalised.\n\nEvery token belongs to one ``segment``. The heading states what the answer\nis: actor, measure noun, counterpart, and period, in possessive order, one\nslot token per axis (\"Germany's gross ODA disbursements to Kenya, 1973 to\n2024\"). A unit that changes the magnitude (per capita, percent of GDP, PPP\ninternational dollars) stays in the heading. The byline follows it: the\nlatest-year label when one applies, the plain unit with its price basis\n(\"current US dollars\", \"constant 2022 US dollars\") as a slot token with\naxis \"unit\", the source, and, when the identity binds measurementMethod, the\nmethod as a slot token with axis \"method\". Departures come last and sit only on a part's or\nthe envelope's sentence, so ``spec.resolved.sentence_plan`` carries none." + "description": "One token in the ordered sentence plan: a \"text\" token (invariant\nwording such as a connective, a bare separator, the terminal period, or a\ndeparture sentence) or a \"slot\" token (a slot- or entity-bound phrase, or\nthe wording of an ambiguous entity).\n\n``rendered_sentence`` (the flat string) is the plain concatenation of every\ntoken's ``text``, in order. The two are computed together and cannot drift.\nA \"slot\" token with nothing bound appears too, with ``text=\"\"``: the same\ntoken structure serves a loading skeleton (before binding is known) and the\nfinal sentence (after it is). The first non-empty token's text is\ncapitalised.\n\nEvery token belongs to one ``segment``. The heading states what the answer\nis: actor, measure noun, counterpart, and period, in possessive order, one\nslot token per axis (\"Germany's gross ODA disbursements to Kenya, 1973 to\n2024\"). A unit that changes the magnitude (per capita, percent of GDP, PPP\ninternational dollars) stays in the heading. The byline follows it: the\nlatest-year label when one applies, the plain unit with its price basis\n(\"current US dollars\", \"constant 2022 US dollars\") as a slot token with\naxis \"unit\", the source, and, when the identity binds measurementMethod, the\nmethod as a slot token with axis \"method\". Departures come next, then the\nassumptions clause, and both sit only on a part's or the envelope's sentence, so\n``spec.resolved.sentence_plan`` carries neither." }, "Series": { "properties": { @@ -15758,455 +16134,105 @@ "member_count" ], "title": "Shape", - "description": "The structural family chosen for the query." - }, - "ShapeUpstream": { - "properties": { - "source": { - "$ref": "#/components/schemas/SourceRef", - "description": "the organisation behind every member's data" - }, - "data_commons": { - "$ref": "#/components/schemas/search__models__grammar__DataCommonsRef", - "description": "the Data Commons serving that data" - } - }, - "additionalProperties": false, - "type": "object", - "required": [ - "source", - "data_commons" - ], - "title": "ShapeUpstream", - "description": "The one source, and the Data Commons serving it, behind every member of\nan upstream shape." - }, - "SimpleUnit": { - "properties": { - "ref": { - "type": "string", - "maxLength": 512, - "minLength": 1, - "title": "Ref" - }, - "currency": { - "type": "string", - "pattern": "^[A-Z]{3}$", - "title": "Currency" - }, - "label": { - "type": "string", - "maxLength": 512, - "minLength": 1, - "title": "Label" - }, - "at_mint": { - "type": "boolean", - "const": true, - "title": "At Mint" - }, - "prices": { - "type": "string", - "enum": [ - "current", - "constant" - ], - "title": "Prices" - }, - "base_year": { - "type": "integer", - "maximum": 2100.0, - "minimum": 1900.0, - "title": "Base Year" - } - }, - "additionalProperties": false, - "type": "object", - "title": "SimpleUnit", - "description": "A unit by reference, by currency, or both, with optional words.\n\n`ref` is the unit's dcid. `currency` is an ISO 4217 code, which a converted unit\n`{currency, prices, base_year}` names in place of a dcid. `prices` says whether money is\nin `current` or `constant` prices, and `base_year` names the year constant prices are\nexpressed in; it is present exactly when prices are constant." - }, - "Skill": { - "properties": { - "id": { - "type": "string", - "title": "Id", - "description": "the skill's stable id; the key this entry is filed under" - }, - "name": { - "type": "string", - "title": "Name", - "description": "the skill's declared name" - }, - "description": { - "type": "string", - "title": "Description", - "description": "the skill's declared description" - }, - "content_version": { - "type": "string", - "title": "Content Version", - "description": "sha256: over the skill's manifest, SKILL.md then its references in path order, so any edit to any file in the bundle changes it" - } - }, - "additionalProperties": false, - "type": "object", - "required": [ - "id", - "name", - "description", - "content_version" - ], - "title": "Skill", - "description": "One skill's front matter on the wire, keyed by id in\nResolution.skills. Mirrors skills_index.SkillFrontMatter's four\nmembers -- the search API's own wire model, not that dataclass itself,\nso it carries its own field descriptions the way every other response\nmodel does." - }, - "SkillBody": { - "properties": { - "id": { - "type": "string", - "title": "Id", - "description": "the skill's id, its dcid without the `skill/` prefix" - }, - "name": { - "type": "string", - "title": "Name", - "description": "the front matter's `name`, equal to `id`" - }, - "description": { - "type": "string", - "title": "Description", - "description": "the front matter's `description`" - }, - "frontmatter": { - "additionalProperties": { - "$ref": "#/components/schemas/FrontMatterValue" - }, - "type": "object", - "title": "Frontmatter", - "description": "the whole parsed front matter, every scalar a string" - }, - "content_version": { - "type": "string", - "title": "Content Version", - "description": "`sha256:` digest over the manifest's paths and digests, in order" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Url", - "description": "the skill's source directory for a human reader, never fetched here" - }, - "attached": { - "type": "boolean", - "title": "Attached", - "description": "true when the skill's reach names at least one node on this build, so search can name it" - }, - "excluded": { - "type": "boolean", - "title": "Excluded", - "description": "true when search cannot match this skill on this build: its reach broke a bound or a read the build depended on did not complete" - }, - "statvar_count": { - "type": "integer", - "title": "Statvar Count", - "description": "the distinct StatVars this skill's downward reach carries. A provenance attachment adds nothing to the count, so a skill attached only to provenances reports 0 while covering every series of those datasets" - }, - "statvar_count_truncated": { - "type": "boolean", - "title": "Statvar Count Truncated", - "description": "true when statvar_count stopped at this deployment's count bound rather than exhausting the reach" - }, - "warnings": { - "items": { - "$ref": "#/components/schemas/SkillWarning" - }, - "type": "array", - "title": "Warnings", - "description": "this skill's own warnings" - }, - "resources": { - "items": { - "$ref": "#/components/schemas/SkillFileListing" - }, - "type": "array", - "title": "Resources", - "description": "the skill's manifest: `SKILL.md` first, then its references in path order" - }, - "content_text": { - "type": "string", - "title": "Content Text", - "description": "`SKILL.md` verbatim, front matter included" - } - }, - "type": "object", - "required": [ - "id", - "name", - "description", - "frontmatter", - "content_version", - "url", - "attached", - "excluded", - "statvar_count", - "statvar_count_truncated", - "warnings", - "resources", - "content_text" - ], - "title": "SkillBody", - "description": "The skill door's response: the list entry plus the skill's text." - }, - "SkillFileListing": { - "properties": { - "path": { - "type": "string", - "title": "Path", - "description": "the file's path, relative to its skill's own bundle" - }, - "size": { - "type": "integer", - "title": "Size", - "description": "the byte size of the file's UTF-8 content" - }, - "digest": { - "type": "string", - "title": "Digest", - "description": "`sha256:` plus the lower-case hex SHA-256 of that content" - }, - "media_type": { - "type": "string", - "title": "Media Type", - "description": "the file's media type, from its extension" - } - }, - "type": "object", - "required": [ - "path", - "size", - "digest", - "media_type" - ], - "title": "SkillFileListing", - "description": "One file in a skill's manifest. The client fetches it at the resources door\nby the skill id and this `path`." - }, - "SkillListResponse": { - "properties": { - "skills": { - "items": { - "$ref": "#/components/schemas/SkillSummary" - }, - "type": "array", - "title": "Skills", - "description": "every served skill, ordered by id" + "description": "The structural family chosen for the query." + }, + "ShapeUpstream": { + "properties": { + "source": { + "$ref": "#/components/schemas/SourceRef", + "description": "the organisation behind every member's data" }, - "warnings": { - "items": { - "$ref": "#/components/schemas/SkillWarning" - }, - "type": "array", - "title": "Warnings", - "description": "corpus warnings, including one per skill left out of the catalogue" + "data_commons": { + "$ref": "#/components/schemas/search__models__grammar__DataCommonsRef", + "description": "the Data Commons serving that data" } }, + "additionalProperties": false, "type": "object", "required": [ - "skills", - "warnings" + "source", + "data_commons" ], - "title": "SkillListResponse", - "description": "`GET /api/skills`'s response body: every served skill's entry, ordered by\nid, plus the corpus warnings. A per-skill warning rides on that skill's own\nentry." + "title": "ShapeUpstream", + "description": "The one source, and the Data Commons serving it, behind every member of\nan upstream shape." }, - "SkillResourceContent": { + "SimpleUnit": { "properties": { - "skill_id": { + "ref": { "type": "string", - "title": "Skill Id", - "description": "the skill this file belongs to" + "maxLength": 512, + "minLength": 1, + "title": "Ref" }, - "path": { + "currency": { "type": "string", - "title": "Path", - "description": "the file's path, relative to its skill's own bundle" - }, - "size": { - "type": "integer", - "title": "Size", - "description": "the byte size of the file's UTF-8 content" + "pattern": "^[A-Z]{3}$", + "title": "Currency" }, - "digest": { + "label": { "type": "string", - "title": "Digest", - "description": "`sha256:` plus the lower-case hex SHA-256 of that content" + "maxLength": 512, + "minLength": 1, + "title": "Label" }, - "media_type": { - "type": "string", - "title": "Media Type", - "description": "the file's media type, from its extension" + "at_mint": { + "type": "boolean", + "const": true, + "title": "At Mint" }, - "content_text": { + "prices": { "type": "string", - "title": "Content Text", - "description": "the file's text" + "enum": [ + "current", + "constant" + ], + "title": "Prices" + }, + "base_year": { + "type": "integer", + "maximum": 2100.0, + "minimum": 1900.0, + "title": "Base Year" } }, + "additionalProperties": false, "type": "object", - "required": [ - "skill_id", - "path", - "size", - "digest", - "media_type", - "content_text" - ], - "title": "SkillResourceContent", - "description": "The resources door's response: one manifest file and its text.\n\nCarries `skill_id` and `path` so a client that fires several requests\nconcurrently can tell which response answers which request." + "title": "SimpleUnit", + "description": "A unit by reference, by currency, or both, with optional words.\n\n`ref` is the unit's dcid. `currency` is an ISO 4217 code, which a converted unit\n`{currency, prices, base_year}` names in place of a dcid. `prices` says whether money is\nin `current` or `constant` prices, and `base_year` names the year constant prices are\nexpressed in; it is present exactly when prices are constant." }, - "SkillSummary": { + "Skill": { "properties": { "id": { "type": "string", "title": "Id", - "description": "the skill's id, its dcid without the `skill/` prefix" + "description": "the skill's stable id; the key this entry is filed under" }, "name": { "type": "string", "title": "Name", - "description": "the front matter's `name`, equal to `id`" + "description": "the skill's declared name" }, "description": { "type": "string", "title": "Description", - "description": "the front matter's `description`" - }, - "frontmatter": { - "additionalProperties": { - "$ref": "#/components/schemas/FrontMatterValue" - }, - "type": "object", - "title": "Frontmatter", - "description": "the whole parsed front matter, every scalar a string" + "description": "the skill's declared description" }, "content_version": { "type": "string", "title": "Content Version", - "description": "`sha256:` digest over the manifest's paths and digests, in order" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Url", - "description": "the skill's source directory for a human reader, never fetched here" - }, - "attached": { - "type": "boolean", - "title": "Attached", - "description": "true when the skill's reach names at least one node on this build, so search can name it" - }, - "excluded": { - "type": "boolean", - "title": "Excluded", - "description": "true when search cannot match this skill on this build: its reach broke a bound or a read the build depended on did not complete" - }, - "statvar_count": { - "type": "integer", - "title": "Statvar Count", - "description": "the distinct StatVars this skill's downward reach carries. A provenance attachment adds nothing to the count, so a skill attached only to provenances reports 0 while covering every series of those datasets" - }, - "statvar_count_truncated": { - "type": "boolean", - "title": "Statvar Count Truncated", - "description": "true when statvar_count stopped at this deployment's count bound rather than exhausting the reach" - }, - "warnings": { - "items": { - "$ref": "#/components/schemas/SkillWarning" - }, - "type": "array", - "title": "Warnings", - "description": "this skill's own warnings" - }, - "resources": { - "items": { - "$ref": "#/components/schemas/SkillFileListing" - }, - "type": "array", - "title": "Resources", - "description": "the skill's manifest: `SKILL.md` first, then its references in path order" + "description": "sha256: over the skill's manifest, SKILL.md then its references in path order, so any edit to any file in the bundle changes it" } }, + "additionalProperties": false, "type": "object", "required": [ "id", "name", "description", - "frontmatter", - "content_version", - "url", - "attached", - "excluded", - "statvar_count", - "statvar_count_truncated", - "warnings", - "resources" - ], - "title": "SkillSummary", - "description": "One skill's list entry: front matter, attachment and breadth figures, own\nwarnings, and manifest. `SkillBody` adds the skill's text.\n\n`url` is the skill's source directory for a human reader. The platform never\nfetches it." - }, - "SkillWarning": { - "properties": { - "code": { - "type": "string", - "title": "Code", - "description": "stable machine code from the platform's code registry" - }, - "severity": { - "type": "string", - "enum": [ - "info", - "warn", - "degraded" - ], - "title": "Severity", - "description": "the severity level" - }, - "message": { - "type": "string", - "title": "Message", - "description": "human-readable explanation of the warning" - }, - "skill_id": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Skill Id", - "description": "the served skill's id, the dcid of a skill left out of the catalogue, or null for a corpus-level warning" - } - }, - "type": "object", - "required": [ - "code", - "severity", - "message", - "skill_id" + "content_version" ], - "title": "SkillWarning", - "description": "One corpus-level or skill-level issue, on the wire. `skill_id` is the\ncatalogue id for an issue about a served skill, the roster dcid for a skill\nleft out of the catalogue, or `None` for an issue about the whole corpus.\nOnly an issue about a served skill rides on that skill's entry. The other two\nare corpus warnings on the list door." + "title": "Skill", + "description": "One skill's front matter on the wire, keyed by id in\nResolution.skills. Mirrors skills_index.SkillFrontMatter's four\nmembers -- the search API's own wire model, not that dataclass itself,\nso it carries its own field descriptions the way every other response\nmodel does." }, "Slot": { "properties": { @@ -16305,8 +16331,132 @@ "description": "A slot's typed identity: axis, constraint property, and human label." }, "SlotOption": { - "additionalProperties": true, - "type": "object" + "properties": { + "value": { + "$ref": "#/components/schemas/SlotValue", + "description": "one taxonomy member or observed facet value" + }, + "coverage": { + "anyOf": [ + { + "oneOf": [ + { + "$ref": "#/components/schemas/CoverageExact" + }, + { + "$ref": "#/components/schemas/CoverageBreadth" + }, + { + "$ref": "#/components/schemas/CoverageBare" + } + ], + "discriminator": { + "propertyName": "kind", + "mapping": { + "bare": "#/components/schemas/CoverageBare", + "breadth": "#/components/schemas/CoverageBreadth", + "exact": "#/components/schemas/CoverageExact" + } + } + }, + { + "type": "null" + } + ], + "title": "Coverage", + "description": "this option's observation footprint if it were bound instead of the current value; populated when response_options.include_option_coverage is true" + }, + "relation": { + "anyOf": [ + { + "type": "string", + "enum": [ + "child", + "parent", + "root" + ] + }, + { + "type": "null" + } + ], + "title": "Relation", + "description": "where this option sits in a level-scoped constraint-slot menu on a code-index-carried taxonomy: 'child' or 'parent' of the slot's bound value, and 'root' for every other classification root beside a bound root; for an unbound hierarchical slot, 'root' for a classification root and 'child' for a child of the root named in parent; 'root' for every value of a flat code system. None on every other surface this type serves -- entity_options, facet_options, and the options door's OptionsSet -- none of which classify their candidates by level" + }, + "parent": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parent", + "description": "dcid of this option's parent in a hierarchical code system, for a level-scoped constraint-slot option that has one; None for a root, for a flat code system's values, and on every surface where relation is None" + }, + "member_count": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Member Count", + "description": "how many StatVars this index holds coded directly to this option's value (not a subtree rollup), for a level-scoped constraint-slot option; None on every other surface this type serves -- entity_options, facet_options, and the options door's OptionsSet -- none of which count members from the code index" + }, + "served_rows": { + "anyOf": [ + { + "type": "integer", + "minimum": 0.0 + }, + { + "type": "null" + } + ], + "title": "Served Rows", + "description": "the rows this answer's file would hold if this option were bound instead of the current value, in the terms of ResolvedSpec.download.rows: one per series and year with a point inside the requested window, or under 'latest' one per series holding its StatVar's latest year. A series is a served StatVar carrying the option or one of its code-index descendants (the widening the binder applies to a bound value) at one entity, or donor and recipient pair. An unbound slot counts the answer's own family; a bound slot counts the family with that slot left unbound and every other binding kept. An option this answer would serve nothing for is omitted from the menu, except the slot's current value. None where the option is not counted: on entity_options, facet_options and the options door, and on a bound slot whose family needs graph reads to count, where a trailing slot_options event can supply it. A StatVar the coverage artifact does not hold adds no rows: the count covers the pick's other StatVars, and an option all of whose StatVars are missing from the artifact is omitted" + }, + "served_rows_exact": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Served Rows Exact", + "description": "true when served_rows equals the download.rows a pick of this option would state; false when it is an upper bound: a counted StatVar whose series sit in more than one facet group (provenance, method and unit) in the window, of which the pick's read elects one; an answer read in bulk whose pick's StatVars sit in more than one facet, since a bulk read elects one; under 'latest', a StatVar with a facet observed more often than yearly; an answer that pins a facet value; a unit request whose conversion cannot be read as download.rows_exact describes, that converts a counted series from a currency the answer does not serve, or whose options the coverage probe counts (a bound slot of a subject-place family, a candidates reading); or a series whose facets carry no complete date list. Null exactly when served_rows is null" + }, + "party_kind": { + "anyOf": [ + { + "type": "string", + "enum": [ + "party", + "total", + "residual" + ] + }, + { + "type": "null" + } + ], + "title": "Party Kind", + "description": "on an origin or destination entity option, what the party is beside the others on its side: 'party' (a country, territory or organisation), 'total' (other parties' figures, so a sum across the role that counts it counts its members twice) or 'residual' (figures no other party holds), as the code index lists it. Absent for a party the index does not list, and on every other option" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "value" + ], + "title": "SlotOption", + "description": "One candidate value the binder had available for a slot." }, "SlotOptions": { "properties": { @@ -18556,7 +18706,7 @@ "separate": { "type": "boolean", "title": "Separate", - "description": "true when this part was asked beside the others to be compared with them. A client resubmitting an identity, candidate set, or placeholder posts this flag on that entry to preserve the comparison. False, the default, is omitted", + "description": "true when this part was asked beside the others to be compared with them. A client resubmitting an identity, candidate set, or placeholder posts this flag on that entry to preserve the comparison. Two parts marked separate that resolve to one reading carry the same spec_id and stay two parts. False, the default, is omitted", "default": false }, "warnings": { @@ -18588,7 +18738,7 @@ } ], "title": "Rendered Sentence", - "description": "a human-readable string. For candidates, a header naming how many readings there are ('3 readings.'), then each shown candidate's heading and a byline led by the source and span that set it apart; for no_data, a heading in the same claim form naming the entity, measure, and counterpart that were checked. Either ends with the text of this part's departures, in order. For a definite part this stays null or omitted: the confirmation sentence (heading and byline) lives at spec.resolved.rendered_sentence, and its departures reach the envelope's composed sentence." + "description": "a human-readable string. For candidates, a header naming how many readings there are ('3 readings.'), then each shown candidate's heading and a byline led by the source and span that set it apart; for no_data, a heading in the same claim form naming the entity, measure, and counterpart that were checked. Either ends with the text of this part's departures, in order, and a candidates part's then closes with its assumptions clause. For a definite part this stays null or omitted: the confirmation sentence (heading and byline) lives at spec.resolved.rendered_sentence, and its departures reach the envelope's composed sentence." }, "sentence_plan": { "anyOf": [ @@ -18632,6 +18782,14 @@ "title": "Departures", "description": "every way this part's answer differs from what its request asked, ordered by how much each changes the number: closest_match, measure_not_applied, operation_not_applied, breakdown_not_applied, entity_unavailable, year_unavailable, modelled_values, group_read_as_members, direction_discarded, direction_inferred, scope_limited. [] when the answer is what was asked. A client that renders its own sentence reads them here; each one's text also closes the sentence that carries this part (see Departure.text). A warning on the same part reports run health and stays separate" }, + "assumptions": { + "items": { + "$ref": "#/components/schemas/Assumption" + }, + "type": "array", + "title": "Assumptions", + "description": "every value the engine filled that the request did not ask for, in clause order. Declared defaults come first, in the order of the Spec's trace.slot_filters, then open roles, then the place scope. A declared default is a slot the request left open that its code system's or shape's declared default fixed, named by the bound code's full label. An open role is a flow role no request word asked for, read across every entity on it with data. It is either a role the role scope default filled (resolved.scope on that axis), whatever its member count, served as one series per member where the shape declares the role, or a role the heading states with no entity of its own ('from 164 providers', 'owed to all creditors'), served as the total over its members. A role the identity binds in entities or lists in open_roles, that one of the part's operations runs over ('top 5 donors'), or that the request's words asked every member of ('all donors'), is asked. The place scope is a request that named no place, read across every place with data. Every door fills assumptions. A definite part reads them from its Spec, a candidates part carries the items every list in CandidatesPart.reading_assumptions holds alike, text included, and no_data and unsupported parts carry []. A dataset_resubmit identity entry posts every slot bound, so its part states the items of the entry's assumptions echo that still hold (see ResubmitIdentityEntry.assumptions), and a candidates entry reads each reading with its candidate's echo (see ResubmitCandidate.assumptions). The sentence that carries this part closes with them as one segment='assumption' clause ('Assumed: official development assistance; every provider.'), after its departures. [] when the answer fills nothing" + }, "status": { "type": "string", "const": "unsupported", @@ -20407,5 +20565,27 @@ "type": "object" } } - } + }, + "tags": [ + { + "name": "Search", + "description": "Resolve a plain-language data question to dataset definitions and their options." + }, + { + "name": "Datasets", + "description": "Register and mint datasets, poll their operations, and read versions, observations and files." + }, + { + "name": "Graph", + "description": "Resolve names to graph nodes and read nodes, members, sources and documentation." + }, + { + "name": "Presentation", + "description": "Create, revise and render presentation components, and read frames and the release." + }, + { + "name": "Codes", + "description": "Look up a problem code's registry entry." + } + ] } diff --git a/tools/README.md b/tools/README.md index 7362495..f41446e 100644 --- a/tools/README.md +++ b/tools/README.md @@ -44,7 +44,7 @@ uv run tools/validate_descriptions_vectors.py uv run tools/validate_client_contract.py ``` -`capture_client_contract.py` refreshes the client contract from dfo-apis. `openapi --dfo-apis PATH` builds the composed app in that checkout's environment, in process, and writes `served/openapi.json` and `served/SOURCE.json`, refusing a checkout with uncommitted changes or untracked files and an environment out of step with its `uv.lock`; `record` runs the contract's scenarios against a base URL, dev by default, writes the records with every absolute URL's query redacted, derives the synthetic ones and validates the result, and `record --offline` derives the outcomes again from the records with no request. It imports its outcome rules from `validate_client_contract.py`. `python/client-contract/README.md` has the recipe. A PEP 723 script; its tests run without network or pyarrow: +`capture_client_contract.py` refreshes the client contract from dfo-apis. `openapi --dfo-apis PATH` builds the composed app in that checkout's environment, in process, and writes `served/openapi.json` and `served/SOURCE.json`, refusing a checkout with uncommitted changes or untracked files and an environment out of step with its `uv.lock`; `record` runs the contract's scenarios against a base URL, dev by default, writes the records with every absolute URL's query redacted and a local app's signed URLs written as storage URLs, derives the synthetic ones and validates the result, and `record --offline` derives the outcomes again from the records with no request. It imports its outcome rules from `validate_client_contract.py`. `python/client-contract/README.md` has the recipe. A PEP 723 script; its tests run without network or pyarrow: ```bash uv run tools/capture_client_contract.py record diff --git a/tools/capture_client_contract.py b/tools/capture_client_contract.py index 7b1b56b..e8bf4dc 100644 --- a/tools/capture_client_contract.py +++ b/tools/capture_client_contract.py @@ -12,13 +12,14 @@ uv run tools/capture_client_contract.py record [--base-url URL] [--only NAME ...] [--offline] [--scenarios-dir DIR] -`openapi` builds the composed dfo-apis app from the checkout at PATH, every -surface flag on, by calling `dfo_apis.app.create_app()` in that checkout's -environment, and writes `app.openapi()` to `served/openapi.json` and the +`openapi` builds the composed dfo-apis app from the checkout at PATH, with +the deployed surfaces (Search, Datasets, Graph and Presentation), by +calling `dfo_apis.app.create_app()` in that checkout's environment, and +writes `app.openapi()` to `served/openapi.json` and the checkout's commit to `served/SOURCE.json`. No server runs. The surfaces load -an origin catalogue and a coverage index when they are built, so the capture -gives them the checkout's own test fixtures; the document does not depend on -the data they hold. A checkout with uncommitted changes to tracked files is +an origin catalogue and a graph release when they are built, so the capture +publishes the checkout's own test catalogue and test release into a temporary +directory; the document does not depend on the data they hold. A checkout with uncommitted changes to tracked files is refused, because the commit would not describe the document. `record` runs every scenario this file defines against the API at the base @@ -33,10 +34,11 @@ refreshes both, and a synthetic record names its parent's body files rather than copies. Every absolute URL a record keeps, a signed download or a `location` header, keeps its path, and its query becomes -`X-Goog-Signature=redacted`. A scenario that needs a route or status -`served/openapi.json` does not declare, or whose parent does, waits: the -run names it and writes nothing for it, unless `--scenarios-dir` writes -outside the package. The run ends by validating the whole contract with +`X-Goog-Signature=redacted`, and a local app's blob URL becomes the storage +URL a deployment signs, so no signed URL names the base URL's host. The +long builds need two specs the server has not built, so a local recording +starts on a fresh datasets database. `--scenarios-dir` writes outside the +package, unvalidated. The run ends by validating the whole contract with `tools/validate_client_contract.py`, and fails when it reports a problem or the binary bodies pass 5 MB. @@ -65,7 +67,7 @@ from datetime import UTC, datetime from pathlib import Path from typing import Any, Protocol -from urllib.parse import urlsplit, urlunsplit +from urllib.parse import quote, unquote, urlsplit, urlunsplit from validate_client_contract import ( FILE_EXPIRED, @@ -80,7 +82,6 @@ answer_gaps, answer_members, answer_outcome, - candidate_answer, choice_for, choice_input, data_warning, @@ -99,6 +100,7 @@ search_warns, selector_path, sentence_entry, + versions_path, ) from validate_client_contract import main as validate_main @@ -133,26 +135,28 @@ def _write_json(path: Path, document: Any) -> None: from pathlib import Path with tempfile.TemporaryDirectory() as tmp: + from tests.graph_release.support import build_session_release from tests.origin_catalogue.support import publish_sample os.environ["ORIGIN_CATALOGUE_URI"] = f"file://{tmp}/origin-catalogue" publish_sample(os.environ["ORIGIN_CATALOGUE_URI"]) + os.environ["GRAPH_RELEASE_URI"] = f"file://{tmp}/releases" + build_session_release(os.environ["GRAPH_RELEASE_URI"]) from dfo_apis.app import create_app document = create_app().openapi() Path(sys.argv[1]).write_text(json.dumps(document), encoding="utf-8") """ -# Placeholders the surfaces need to be built. None of them reaches the document. +# The deployed composition's surface flags, Search always mounted beside them, +# and placeholders the surfaces need to be built, none of which reaches the +# document. Skills is not deployed, so its routes stay out of the document. _CAPTURE_ENV = { "SEARCH_GRAPH_BASE": "https://graph.offline.invalid", "DFO_PUBLIC_SITE_URL": "https://site.example", - "COVERAGE_RECHECK_SECONDS": "0", - "COVERAGE_INDEX_CHECK": "off", "DFO_DATASETS_SURFACE": "1", "DFO_GRAPH_SURFACE": "1", "DFO_PRESENTATION_SURFACE": "1", - "DFO_SKILLS_SURFACE": "1", } _PASSED_ENV = ("HOME", "PATH", "TMPDIR", "UV_CACHE_DIR", "UV_PYTHON") # The dfo-apis extras the composed app imports. @@ -161,13 +165,11 @@ def _write_json(path: Path, document: Any) -> None: ) -def capture_env(checkout: Path, environ: Mapping[str, str]) -> dict[str, str]: +def capture_env(environ: Mapping[str, str]) -> dict[str, str]: """The capture's environment: a few of the caller's variables and the placeholders, so a variable in the caller's shell cannot reach the app.""" env = {name: environ[name] for name in _PASSED_ENV if name in environ} env.update(_CAPTURE_ENV) - coverage = checkout / "tests" / "fixtures" / "coverage_slice" - env["COVERAGE_ARTIFACT_URI"] = coverage.as_uri() return env @@ -218,7 +220,7 @@ def capture_openapi(checkout: Path) -> tuple[dict[str, Any], str]: str(out), ], cwd=checkout, - env=capture_env(checkout, os.environ), + env=capture_env(os.environ), capture_output=True, text=True, check=False, @@ -299,12 +301,25 @@ def _lower(items: Any) -> dict[str, str]: return {name.lower(): value for name, value in items} +# A local composed app signs no URL: its launcher serves each file at +# `/__e2e__/blob/{bucket}/{object}` on the API's own origin. A record states +# such a URL as the storage URL a deployment signs for the same object. +LOCAL_BLOB_PREFIX = "/__e2e__/blob/" +STORAGE_ORIGIN = "https://storage.googleapis.com" + + def redact_external_url(url: str) -> str: """An absolute `url` with its query, whatever signs it, replaced by - `X-Goog-Signature=redacted`; a root-relative URL as it stands.""" + `X-Goog-Signature=redacted`, and a local app's blob URL rewritten to + `STORAGE_ORIGIN/{bucket}/{object}`, the object name percent-encoded as + storage signs it; a root-relative URL as it stands.""" parts = urlsplit(url) if not parts.netloc: return url + if parts.path.startswith(LOCAL_BLOB_PREFIX): + bucket, _, name = parts.path.removeprefix(LOCAL_BLOB_PREFIX).partition("/") + path = f"/{bucket}/{quote(unquote(name), safe='/')}" + parts = urlsplit(STORAGE_ORIGIN)._replace(path=path) return urlunsplit(parts._replace(query="X-Goog-Signature=redacted")) @@ -617,10 +632,8 @@ def choose( self, answer: Answer, option: int | str, *, part: int | str | None = None ) -> Answer | None: """Settles a part by the rules `choice_for` and `choice_input` state, - and returns the new answer, or None when the choice refused. - - A choice among one part's candidates is local; any other choice posts - to Search.""" + posting the choice to Search, and returns the answer Search gives, or + None when the choice refused.""" step: dict[str, Any] = {"op": "choose"} if part is not None: step["part"] = part @@ -629,11 +642,7 @@ def choose( def run() -> dict[str, Any]: choice = choice_for(answer, self.gap_kinds, part, option) - posts = choice_input(answer, choice) - if posts is not None: - answers.append(self._resolve(posts)) - elif choice.candidate is not None: - answers.append(candidate_answer(answer, choice.part, choice.candidate)) + answers.append(self._resolve(choice_input(answer, choice))) return self._answered(answers[0]) self._step(step, run) @@ -962,9 +971,7 @@ def _stored_file( def _newest(self, spec_id: str) -> str | None: try: - body = self._acted( - self.recorder.api("GET", f"/datasets/{spec_id}/versions") - ) + body = self._acted(self.recorder.api("GET", versions_path(spec_id))) except ClientError as error: if error.error_class(self.client_codes) in NO_VERSIONS: return None @@ -1007,35 +1014,6 @@ def _build_body( return {"schema_version": 1, "input": input_, "options": dict(rendering)} -def with_place_options(body: Any) -> Any: - """`body` with each no_data `data_query` replaced by the `options` a - choice refusal carries once Search serves them: per ambiguous wording and - candidate, the data_query with that candidate pinned on every row that - has the wording.""" - body = copy.deepcopy(body) - for part in body.get("parts", []) if isinstance(body, dict) else []: - no_data = part.get("no_data") - if not no_data or "data_query" not in no_data: - continue - base = no_data.pop("data_query") - options = [] - for group in no_data.get("ambiguous_entities", []): - for candidate in group["candidates"]: - query = copy.deepcopy(base) - for row in query["parts"][0]["entities"]: - if row["text"] == group["text"]: - row["dcid"] = candidate["ref"] - options.append( - { - "mentions": [group["text"]], - "label": candidate["label"], - "data_query": query, - } - ) - no_data["options"] = options - return body - - # --- scenarios -------------------------------------------------------------- DEFINITE = "ODA disbursements from Germany to Nigeria for basic health care" @@ -1047,6 +1025,7 @@ def with_place_options(body: Any) -> Any: DECLINED = "should donors give more aid to Kenya?" CATALOGUE = "what data do you have?" TOP5 = "top 5 donors to Ethiopia in 2022" +PLACE_LABELS = ["Congo [DRC]", "Congo [Republic]"] CANDIDATES_BESIDE_GROUP = ( "GNI of Germany from 2015 to 2022, and ODA disbursements from Germany to " "sub-Saharan Africa" @@ -1055,7 +1034,12 @@ def with_place_options(body: Any) -> Any: CANDIDATES_BESIDE_UNRESTATED = "GNI of Germany and debt of Kenya from 2015 to 2022" GROUP_DEFINITE = "GDP of the least developed countries" GROUPED_FLOW = "Germany's ODA to the least developed countries" +CANDIDATES_BESIDE_ASSUMED = "GNI of Germany and aid flows to Kenya" +# Two specs just above the 100,000-row sync budget, one for the mint and one +# for the operation another process started: a version the server has built +# answers inline, so each long build needs a spec the server has not built. ASYNC = "ODA received by every recipient country from every provider (DAC2a) from 2018 to 2024" +ASYNC_RESUMED = "ODA received by every recipient country from every provider (DAC2a) from 2017 to 2024" NARROW_WINDOW = (2020, 2023) REBOUND_ORIGIN = "country/FRA" SYNC_ROWS = 100_000 @@ -1115,9 +1099,10 @@ def definite_ref(self) -> dict[str, Any]: self._cache["ref"] = {"format_version": 1, "members": [member.ref()]} return self._cache["ref"] - def async_spec(self) -> Spec: - """The spec whose estimate is just above the sync budget.""" - (part,) = self.definite_answer(ASYNC).parts + def async_spec(self, question: str = ASYNC) -> Spec: + """The spec `question` answers, whose estimate is just above the sync + budget.""" + (part,) = self.definite_answer(question).parts rows = part["spec"]["resolved"].get("download", {}).get("rows") or 0 require( SYNC_ROWS < rows < 2 * SYNC_ROWS, @@ -1129,38 +1114,16 @@ def running_operation(self) -> str: """The id of a long build another process started.""" if "operation" not in self._cache: self._cache["operation"] = self.session("prerequisite").mint( - self.async_spec() + self.async_spec(ASYNC_RESUMED) ) return self._cache["operation"] -# A route and status the served document must declare before a scenario that -# needs them is recorded: the method, the route template as the served -# document names it, and the status. -type Need = tuple[str, str, str] -ASYNC_BUILD: Need = ("POST", "/api/datasets", "202") -FILE_SELECTOR: Need = ("GET", "/api/datasets/{id}/{content_version}/file", "302") - - -def unmet(needs: Sequence[Need], openapi: Mapping[str, Any]) -> list[Need]: - """The needs the served document does not declare.""" - return [ - (method, path, status) - for method, path, status in needs - if status - not in openapi["paths"] - .get(path, {}) - .get(method.lower(), {}) - .get("responses", {}) - ] - - @dataclass(frozen=True) class Recorded: name: str description: str run: Callable[[Session, Context], None] - needs: tuple[Need, ...] = () def _answer_definite_fetch(s: Session, ctx: Context) -> None: @@ -1174,7 +1137,16 @@ def _answer_candidates(s: Session, ctx: Context) -> None: require( answer.status == "candidates" and len(answer.parts) == 1, "one candidates part" ) - s.fetch_answer(s.choose(answer, 0)) + picked = answer.parts[0]["candidates"]["specs"][0]["spec_id"] + chosen = s.choose(answer, 0) + require( + chosen is not None + and _statuses(chosen) == ["definite"] + and chosen.parts[0]["spec"]["spec_id"] == picked, + "Search answers the picked reading definite", + ) + if chosen is not None: + s.fetch_answer(chosen) def _answer_mixed_raises(s: Session, ctx: Context) -> None: @@ -1284,7 +1256,7 @@ def _fetch_ref_unknown_version(s: Session, ctx: Context) -> None: def _mint_async(s: Session, ctx: Context) -> None: - s.mint(ctx.async_spec()) + s.mint(ctx.async_spec(ASYNC)) s.result() @@ -1307,13 +1279,45 @@ def run(s: Session, ctx: Context) -> None: return run +def _place_answer(s: Session, question: str, parts: int) -> Answer: + """The answer to `question`: `parts` entity_ambiguous parts, each with an + option per Congo.""" + answer = s.search(question) + require( + [p.get("no_data", {}).get("reason") for p in answer.parts] + == ["entity_ambiguous"] * parts, + f"{parts} entity_ambiguous part(s)", + ) + require( + all( + [o["label"] for o in p["no_data"].get("options", [])] == PLACE_LABELS + for p in answer.parts + ), + f"each part offers {PLACE_LABELS}", + ) + return answer + + def _search_place(question: str, parts: int) -> Callable[[Session, Context], None]: def run(s: Session, ctx: Context) -> None: - answer = s.search(question) + _place_answer(s, question, parts) + + return run + + +def _choose_place( + question: str, parts: int, part: int | str | None +) -> Callable[[Session, Context], None]: + """Chooses "Congo [DRC]" on `part` of the answer to `question`, and checks + the chosen part answers definite.""" + + def run(s: Session, ctx: Context) -> None: + answer = _place_answer(s, question, parts) + chosen = s.choose(answer, PLACE_LABELS[0], part=part) + index = part if isinstance(part, int) else 0 require( - [p.get("no_data", {}).get("reason") for p in answer.parts] - == ["entity_ambiguous"] * parts, - f"{parts} entity_ambiguous part(s)", + chosen is not None and _statuses(chosen)[index] == "definite", + "the chosen part answers definite", ) return run @@ -1362,6 +1366,27 @@ def _resubmit_candidates_sibling(s: Session, ctx: Context) -> None: require(before == after, "the candidates keep their posted order") +def _choose_candidate_echoes_assumptions(s: Session, ctx: Context) -> None: + answer = s.search(CANDIDATES_BESIDE_ASSUMED) + require(_statuses(answer) == ["candidates", "definite"], "candidates, definite") + stated = answer.parts[1].get("assumptions") + require(bool(stated), "the definite part states assumptions") + require( + "reading_assumptions" in answer.parts[0], + "the candidates part states its readings' assumptions", + ) + chosen = s.choose(answer, 0, part=0) + require( + chosen is not None and _statuses(chosen) == ["definite", "definite"], + "the choice answers both parts definite", + ) + if chosen is not None: + require( + chosen.parts[1].get("assumptions") == stated, + "the rebuilt definite part states the echoed assumptions", + ) + + def _resubmit_placeholder(s: Session, ctx: Context) -> None: answer = s.search(CANDIDATES_BESIDE_UNRESTATED) require(_statuses(answer) == ["candidates", "no_data"], "candidates, no_data") @@ -1385,9 +1410,10 @@ def _resubmit_placeholder(s: Session, ctx: Context) -> None: Recorded( "answer-candidates-choose-fetch", "A question with three readings answers one candidates part, a choice gap with three " - "options. Choosing option 0 makes no request: the new answer is definite, its sentence " - "is that candidate's spec.resolved.rendered_sentence, and fetching it builds that " - "candidate's spec.", + "options. Choosing option 0 posts that candidate's identity to Search as the one " + "dataset_resubmit identity entry, echoing the part's reading_assumptions under its " + "spec_id as assumptions. Search answers that reading definite with its own sentence, " + "and fetching the answer builds that candidate's spec.", _answer_candidates, ), Recorded( @@ -1487,7 +1513,6 @@ def _resubmit_placeholder(s: Session, ctx: Context) -> None: "backing off from 1 to 8 seconds otherwise, until done; the done manifest's file is " "then downloaded.", _mint_async, - needs=(ASYNC_BUILD,), ), Recorded( "operation-resume", @@ -1497,7 +1522,6 @@ def _resubmit_placeholder(s: Session, ctx: Context) -> None: 'identity with variable_text "dataset", then downloads the file. A resumed build holds ' "no request, so a failed operation is not posted again.", _operation_resume, - needs=(ASYNC_BUILD,), ), Recorded( "fetch-spec-frame-layout", @@ -1521,17 +1545,36 @@ def _resubmit_placeholder(s: Session, ctx: Context) -> None: Recorded( "search-place-ambiguous", "A question naming a place that matches two countries answers with one no_data part " - "whose entity_ambiguous reason makes a choice gap. This build carries no options, so " - "the gap offers none.", + "whose entity_ambiguous reason makes a choice gap, with one option per country: each " + "option's data_query pins that country on the ambiguous wording.", _search_place(PLACE, 1), ), Recorded( "search-two-parts-place-ambiguous", "A two-part question naming a place that matches two countries answers no_data on both " - "parts, each an entity_ambiguous choice gap. This build carries no options, so the gaps " - "offer none.", + "parts, each an entity_ambiguous choice gap with one option per country.", _search_place(TWO_PLACES, 2), ), + Recorded( + "choose-place-one-part", + 'Choosing "Congo [DRC]" by label in a one-part answer posts that option\'s data_query ' + "unchanged as the input of a new search, which answers definite.", + _choose_place(PLACE, 1, None), + ), + Recorded( + "choose-part-by-mention", + 'Naming the part by "Congo", a word its options mention, and the option by label posts ' + "that option's data_query, as naming the part by index does.", + _choose_place(PLACE, 1, "Congo"), + ), + Recorded( + "choose-place-two-parts", + 'Choosing "Congo [DRC]" on part 1 of a two-part answer posts dataset_resubmit with one ' + "entry per part in part order: the chosen option's data_query part as a parsed entry, " + "and part 0, still a refusal, as a parsed entry of its restatement. Part 1 answers " + "definite.", + _choose_place(TWO_PLACES, 2, 1), + ), Recorded( "search-warning-top5", "A question asking for a ranking answers one definite part that does not run the rank, " @@ -1555,6 +1598,15 @@ def _resubmit_placeholder(s: Session, ctx: Context) -> None: "its ordering and truncated echoed. Part 1 answers candidates again in the same order.", _resubmit_candidates_sibling, ), + Recorded( + "choose-candidate-echoes-assumptions", + "Choosing candidate 0 on part 0 beside a definite part that states assumptions posts " + "each identity entry with its reading's assumptions echoed: the chosen candidate's " + "reading_assumptions entry, [] here, and the definite part's own assumptions. The " + "rebuilt definite part states the same assumptions; an entry with no assumptions " + "would be read as a fresh request.", + _choose_candidate_echoes_assumptions, + ), Recorded( "resubmit-placeholder-without-restatement", "Choosing candidate 0 on part 0 posts part 1, a no_data part with no restatement, as a " @@ -1624,8 +1676,7 @@ class Derived: @dataclass(frozen=True) class Synthetic: """A scenario derived from a recorded one. A `live` derivation records - some of its exchanges against the base URL. A synthetic scenario waits - for its own needs and its parent's.""" + some of its exchanges against the base URL.""" name: str derived_from: str @@ -1633,7 +1684,6 @@ class Synthetic: description: str derive: Callable[[dict[str, Any], Context], Derived] live: bool = False - needs: tuple[Need, ...] = () def _same(parent: dict[str, Any], exchanges: list[dict[str, Any]]) -> Derived: @@ -1703,6 +1753,13 @@ def _build_index(parent: dict[str, Any]) -> int: "The spec's variable no longer resolves in the graph.", retryable=False, ) +_CAPABILITY_UNAVAILABLE = _problem( + "capability_unavailable", + 501, + "Not Implemented", + "This deployment does not enable the frame layout.", + retryable=False, +) _OPERATION_FAILED = _problem( "operation_failed", 500, @@ -1757,6 +1814,14 @@ def _not_resolvable( return [_refusal(build["request"], 422, _NOT_RESOLVABLE)], error +def _capability_unavailable( + build: dict[str, Any], ctx: Context +) -> tuple[list[dict[str, Any]], dict[str, Any]]: + problem = _CAPABILITY_UNAVAILABLE + error = refusal_error(501, problem, ctx.actions).outcome(ctx.client_codes) + return [_refusal(build["request"], 501, problem)], error + + def _strict_warning(parent: dict[str, Any], ctx: Context) -> Derived: index = _build_index(parent) manifest = parent["exchanges"][index]["response"]["json"] @@ -2013,7 +2078,7 @@ def _unknown_enum_value(parent: dict[str, Any], ctx: Context) -> Derived: def _null_member(parent: dict[str, Any], ctx: Context) -> Derived: - """Flips the status column's `distinct`, a required member that admits + """Flips the status column's `distinct`, an optional member that admits null, between left out and served as null.""" exchanges = copy.deepcopy(parent["exchanges"]) manifest = exchanges[_build_index(parent)]["response"]["json"] @@ -2042,10 +2107,6 @@ def _renamed_strict_field(parent: dict[str, Any], ctx: Context) -> Derived: type BodyEdit = Callable[[Any, Context], Any] -def _with_options(body: Any, ctx: Context) -> Any: - return with_place_options(body) - - def _choice( option: int | str, part: int | str | None = None, @@ -2053,15 +2114,14 @@ def _choice( edit: BodyEdit | None = None, ) -> Callable[[dict[str, Any], Context], Derived]: """The parent's search, its answer body changed by `edit`, then a choice. - A choice that posts is recorded live, its answer changed by - `with_place_options`; one that refuses makes no request.""" + A choice that posts is recorded live; one that refuses makes no request.""" def derive(parent: dict[str, Any], ctx: Context) -> Derived: canned = copy.deepcopy(parent["exchanges"][:1]) if edit is not None: response = canned[0]["response"] response["json"] = edit(response["json"], ctx) - session = ctx.session("synthetic", canned=canned, edit=with_place_options) + session = ctx.session("synthetic", canned=canned) answer = session.search(parent["call"][0]["question"]) session.choose(answer, option, part=part) return Derived(session.call, session.recorder.exchanges, session.expect) @@ -2071,8 +2131,8 @@ def derive(parent: dict[str, Any], ctx: Context) -> Derived: def _definite_beside(body: Any, ctx: Context) -> Any: """Part 0 becomes the definite part a live search for GROUP_DEFINITE - answers, and the other part's data_query becomes options.""" - body = with_place_options(body) + answers.""" + body = copy.deepcopy(body) (part,) = copy.deepcopy(ctx.definite_answer(GROUP_DEFINITE).parts) require(bool(part["spec"]["resolved"].get("entity_groups")), "a group part") body["parts"][0] = part @@ -2080,10 +2140,18 @@ def _definite_beside(body: Any, ctx: Context) -> Any: return body +def _without_options(body: Any, ctx: Context) -> Any: + """Each no_data part's options go, as from a build that serves none.""" + body = copy.deepcopy(body) + for part in body["parts"]: + part.get("no_data", {}).pop("options", None) + return body + + def _choice_refused( - option: int | str, part: int | str | None = None, *, options: bool = False + option: int | str, part: int | str | None = None, *, edit: BodyEdit | None = None ) -> Callable[[dict[str, Any], Context], Derived]: - choose = _choice(option, part, edit=_with_options if options else None) + choose = _choice(option, part, edit=edit) def derive(parent: dict[str, Any], ctx: Context) -> Derived: derived = choose(parent, ctx) @@ -2155,6 +2223,67 @@ def _partial_nothing_answered(parent: dict[str, Any], ctx: Context) -> Derived: } +# A declared default as a recorded definite part states it, the item +# `choose-candidate-echoes-assumptions` records on its definite part. +_DECLARED_DEFAULT = { + "kind": "declared_default", + "binding_ref": "how:dac2aAidType", + "text": "official development assistance", + "refs": ["DAC2aAidType206"], +} + + +def _assumption_clause(part_index: int, texts: Sequence[str]) -> list[dict[str, Any]]: + """The sentence plan tokens Search renders for a part's assumptions: + one `segment="assumption"` clause, "Assumed: a; b.".""" + + def token(text: str) -> dict[str, Any]: + return { + "kind": "text", + "text": text, + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": part_index, + } + + clause = [token(" "), token("Assumed: ")] + for index, text in enumerate(texts): + clause.extend([token("; "), token(text)] if index else [token(text)]) + return [*clause, token(".")] + + +def _picked_reading_assumes(parent: dict[str, Any], ctx: Context) -> Derived: + """The parent's search and pick, with the picked reading's + reading_assumptions entry holding one declared default: the resubmit + echoes it unchanged, and Search's answer states it.""" + exchanges = copy.deepcopy(parent["exchanges"][:2]) + search, resubmit = exchanges + part = search["response"]["json"]["parts"][0] + spec_id = part["candidates"]["specs"][0]["spec_id"] + require(part["reading_assumptions"][spec_id] == [], "the reading assumes nothing") + part["reading_assumptions"][spec_id] = [copy.deepcopy(_DECLARED_DEFAULT)] + (entry,) = resubmit["request"]["json"]["input"]["entries"] + entry["assumptions"] = [copy.deepcopy(_DECLARED_DEFAULT)] + body = resubmit["response"]["json"] + body["parts"][0]["assumptions"] = [copy.deepcopy(_DECLARED_DEFAULT)] + clause = _assumption_clause(0, [_DECLARED_DEFAULT["text"]]) + body["sentence_plan"].extend(clause) + body["rendered_sentence"] += "".join(token["text"] for token in clause) + answer = answer_from_body(search["response"]["json"]) + kinds = gap_kinds(ctx.actions) + posted = choice_input(answer, choice_for(answer, kinds, None, 0)) + require(posted == resubmit["request"]["json"]["input"], "the pick echoes the list") + return Derived( + copy.deepcopy(parent["call"][:2]), + exchanges, + [ + answer_outcome(answer, kinds), + answer_outcome(answer_from_body(body), kinds), + ], + ) + + def _strict_info_notice(parent: dict[str, Any], ctx: Context) -> Derived: exchanges = copy.deepcopy(parent["exchanges"]) exchanges[0]["response"]["json"]["parts"][0]["warnings"].append(dict(_INFO_NOTICE)) @@ -2218,6 +2347,15 @@ def _strict_info_notice(parent: dict[str, Any], ctx: Context) -> Derived: "the server's code, and makes no further request.", _ends_at_build(_not_resolvable), ), + Synthetic( + "fetch-spec-capability-unavailable", + "fetch-spec-frame-layout", + "A 501 capability_unavailable answers the build.", + "A well-formed build that asks for a rendering this deployment does not enable " + "refuses 501 capability_unavailable, which raises InvalidRequestError, since the " + "caller asks for another rendering, and makes no further request.", + _ends_at_build(_capability_unavailable), + ), Synthetic( "fetch-spec-strict-warning", "fetch-spec-known-sentence", @@ -2272,10 +2410,10 @@ def _strict_info_notice(parent: dict[str, Any], ctx: Context) -> Derived: "fetch-ref-expired-not-reproducible", "fetch-ref", "The snapshot refuses 410 artifact_expired and the rebuild 422 member_not_resolvable; the versions route is recorded live.", - "When the stored version has expired and the build is refused, the client reads the " - "versions route for the newest version. Dev refuses the keyless recorder 403 " - "publish_not_permitted there, so the client raises VersionUnavailableError with the " - "snapshot's artifact_expired code and no newest version.", + "When the stored version has expired and the build is refused, the client asks the " + "versions route for the newest version alone with limit=1, since the route lists " + "versions newest first, and raises VersionUnavailableError with the snapshot's " + "artifact_expired code and that version as the newest.", _expired_not_reproducible, live=True, ), @@ -2287,7 +2425,6 @@ def _strict_info_notice(parent: dict[str, Any], ctx: Context) -> Derived: "the stored version in the ref's rendering and downloads the file it redirects to, " "which hashes to the stored digest.", _expired_file_selector, - needs=(FILE_SELECTOR,), ), Synthetic( "fetch-spec-async-build", @@ -2343,9 +2480,9 @@ def _strict_info_notice(parent: dict[str, Any], ctx: Context) -> Derived: "fetch-null-member", "answer-definite-fetch", "The manifest's status column distinct flips between left out and served as null.", - "A required member that admits null may be left out or served as null; a client reads " - "both as null, and neither changes the outcome. The recording and this record carry " - "the two forms of the status column's distinct.", + "A member that admits null may be left out or served as null; a client reads both as " + "null, and neither changes the outcome. The recording and this record carry the two " + "forms of the status column's distinct.", _null_member, ), Synthetic( @@ -2356,47 +2493,17 @@ def _strict_info_notice(parent: dict[str, Any], ctx: Context) -> Derived: "response, before any download.", _renamed_strict_field, ), - Synthetic( - "choose-place-one-part", - "search-place-ambiguous", - "Each refusal's data_query becomes the no_data options Search serves, and the chosen option's answer is recorded live.", - "A place refusal offers one option per candidate, so its choice gap has two options. " - 'Choosing "Congo [DRC]" by label in a one-part answer posts that option\'s data_query ' - "unchanged as the input of a new search, which answers definite.", - _choice("Congo [DRC]", edit=_with_options), - live=True, - ), - Synthetic( - "choose-place-two-parts", - "search-two-parts-place-ambiguous", - "Each refusal's data_query becomes the no_data options Search serves, and the chosen option's answer is recorded live.", - 'Choosing "Congo [DRC]" on part 1 of a two-part answer posts dataset_resubmit with one ' - "entry per part in part order: the chosen option's data_query part as a parsed entry, " - "and part 0, still a refusal, as a parsed entry of its restatement. Part 1 answers " - "definite and part 0 refuses again with its two options.", - _choice("Congo [DRC]", 1, edit=_with_options), - live=True, - ), Synthetic( "choose-place-beside-definite", "search-two-parts-place-ambiguous", f"Part 0 becomes the definite part, entity groups included, of a live search for " - f'"{GROUP_DEFINITE}"; part 1\'s data_query becomes options; the choice is recorded live.', + f'"{GROUP_DEFINITE}", and the choice is recorded live.', 'Choosing "Congo [DRC]" on part 1 beside a definite part posts dataset_resubmit with the ' "definite part's identity and entity_groups as an identity entry, and the chosen " "option's data_query part as a parsed entry. Both parts answer definite.", _choice("Congo [DRC]", 1, edit=_definite_beside), live=True, ), - Synthetic( - "choose-part-by-mention", - "search-place-ambiguous", - "The refusal's data_query becomes options, and the choice is recorded live.", - 'Naming the part by "Congo", a word its options mention, and the option by label posts ' - "that option's data_query, as naming the part by index does.", - _choice("Congo [DRC]", "Congo", edit=_with_options), - live=True, - ), Synthetic( "answer-timed-out", "answer-mixed-fetch-raises", @@ -2456,10 +2563,21 @@ def _strict_info_notice(parent: dict[str, Any], ctx: Context) -> Derived: Synthetic( "choose-refused-no-options", "search-place-ambiguous", - "A choice of option 0 follows the search.", + "The no_data part's options go, and a choice of option 0 follows the search.", "Choosing in a choice gap that offers no options raises InvalidRequestError with no " "request.", - _choice_refused(0), + _choice_refused(0, edit=_without_options), + ), + Synthetic( + "choose-candidate-assumed-reading", + "answer-candidates-choose-fetch", + "The picked reading's reading_assumptions entry holds one declared default, the pick " + "echoes it, Search's answer states it, and the fetch goes.", + "Picking a candidate whose reading_assumptions entry holds an assumption posts that " + "list unchanged as the identity entry's assumptions. The picked answer's assumptions " + 'and its sentence, closed by the assumption clause ("Assumed: official development ' + "assistance.\"), are Search's response, which the client takes as it stands.", + _picked_reading_assumes, ), Synthetic( "choose-refused-option-out-of-range", @@ -2471,10 +2589,10 @@ def _strict_info_notice(parent: dict[str, Any], ctx: Context) -> Derived: Synthetic( "choose-refused-unknown-label", "search-place-ambiguous", - 'The refusal\'s data_query becomes options, and a choice of "Congo [Nowhere]" follows.', + 'A choice of "Congo [Nowhere]" follows the search.', "Choosing an option by a label no option has raises InvalidRequestError with no " "request.", - _choice_refused("Congo [Nowhere]", options=True), + _choice_refused("Congo [Nowhere]"), ), Synthetic( "choose-refused-answered-part", @@ -2495,10 +2613,10 @@ def _strict_info_notice(parent: dict[str, Any], ctx: Context) -> Derived: Synthetic( "choose-refused-mention-names-two-parts", "search-two-parts-place-ambiguous", - 'Each refusal\'s data_query becomes options, and a choice on part "Congo" follows.', + 'A choice of "Congo [DRC]" on part "Congo" follows the search.', 'Naming a part by "Congo", a word both parts\' options mention, raises ' "InvalidRequestError with no request.", - _choice_refused("Congo [DRC]", "Congo", options=True), + _choice_refused("Congo [DRC]", "Congo"), ), ) @@ -2542,6 +2660,19 @@ def write_record( _write_json(path, record) +def _refuse_local_host(record: dict[str, Any], base_url: str) -> None: + """Refuses a record whose signed download or `location` header names the + base URL's host: a client fetches those cross-origin, without its key.""" + local = urlsplit(base_url).netloc + for exchange in record["exchanges"]: + urls = [ + exchange["request"].get("url"), + exchange["response"].get("headers", {}).get("location"), + ] + if any(url and urlsplit(url).netloc == local for url in urls): + raise SystemExit(f"{record['name']}: a signed URL still names {local}") + + def record_recorded(definition: Recorded, ctx: Context, directory: Path) -> None: recorded_at = _now() session = ctx.session(definition.name) @@ -2561,6 +2692,7 @@ def record_recorded(definition: Recorded, ctx: Context, directory: Path) -> None } derived = Derived(session.call, session.recorder.exchanges, session.expect) record = _record(definition.name, definition.description, origin, derived) + _refuse_local_host(record, ctx.base_url) write_record(directory, record, session.recorder.bodies) @@ -2573,11 +2705,9 @@ def record_synthetic(definition: Synthetic, ctx: Context, directory: Path) -> No "derived_from": definition.derived_from, "edit": definition.edit, } - write_record( - directory, - _record(definition.name, definition.description, origin, derived), - derived.bodies, - ) + record = _record(definition.name, definition.description, origin, derived) + _refuse_local_host(record, ctx.base_url) + write_record(directory, record, derived.bodies) def binary_total(directory: Path) -> int: @@ -2726,20 +2856,6 @@ def rederive_recorded(name: str, ctx: Context, directory: Path) -> None: ) -def waiting(openapi: Mapping[str, Any]) -> dict[str, list[str]]: - """Each scenario that waits for a route or status `openapi` does not - declare, its own or its parent's, with what it waits for.""" - recorded = {d.name: d.needs for d in RECORDED} - found = {} - for definition in (*RECORDED, *SYNTHETIC): - needs = definition.needs - if isinstance(definition, Synthetic): - needs = (*needs, *recorded.get(definition.derived_from, ())) - if missing := unmet(needs, openapi): - found[definition.name] = [" ".join(need) for need in missing] - return found - - def run_record(args: argparse.Namespace) -> int: package_dir: Path = args.package_dir directory: Path = args.scenarios_dir or package_dir / "scenarios" @@ -2747,17 +2863,7 @@ def run_record(args: argparse.Namespace) -> int: unknown = set(args.only or ()) - names if unknown: raise SystemExit(f"no scenario is named {sorted(unknown)}") - served = json.loads( - (package_dir / "served" / "openapi.json").read_text(encoding="utf-8") - ) chosen = set(args.only or names) - # A record outside the package is not validated, so it waits for nothing. - for name, needs in waiting(served).items() if args.scenarios_dir is None else (): - if name in chosen: - print( - f"waiting {name}: the served document declares no {needs}", flush=True - ) - chosen.discard(name) live = sorted(d.name for d in SYNTHETIC if d.live and d.name in chosen) if args.offline and live: raise SystemExit(f"--offline derives no live scenario, and {live} are live") diff --git a/tools/tests/test_capture_client_contract.py b/tools/tests/test_capture_client_contract.py index 611d931..901b980 100644 --- a/tools/tests/test_capture_client_contract.py +++ b/tools/tests/test_capture_client_contract.py @@ -62,36 +62,14 @@ def _without_shapes(expect: list[dict[str, Any]]) -> list[dict[str, Any]]: _LIVE = sorted(d.name for d in capture.SYNTHETIC if d.live) -_SERVED = json.loads( - (capture.PACKAGE_DIR / "served" / "openapi.json").read_text(encoding="utf-8") -) -_WAITING = capture.waiting(_SERVED) def test_every_record_has_a_definition_and_every_definition_a_record() -> None: - """Each definition has its record unless it waits for the served document.""" for kind, definitions in ( ("recorded", capture.RECORDED), ("synthetic", capture.SYNTHETIC), ): - landed = sorted(d.name for d in definitions if d.name not in _WAITING) - assert landed == _records(kind) - - -def test_a_scenario_waits_for_its_own_needs_and_its_parents() -> None: - assert _WAITING == { - "mint-async-build": ["POST /api/datasets 202"], - "operation-resume": ["POST /api/datasets 202"], - "fetch-spec-async-build": ["POST /api/datasets 202"], - "fetch-spec-poll-rate-limited": ["POST /api/datasets 202"], - "fetch-spec-operation-failed-resubmitted": ["POST /api/datasets 202"], - "fetch-ref-expired-file-selector": [ - "GET /api/datasets/{id}/{content_version}/file 302" - ], - } - served = copy.deepcopy(_SERVED) - served["paths"]["/api/datasets"]["post"]["responses"]["202"] = {} - assert sorted(capture.waiting(served)) == ["fetch-ref-expired-file-selector"] + assert sorted(d.name for d in definitions) == _records(kind) @pytest.mark.parametrize("name", [*_records("recorded"), *_LIVE]) @@ -169,13 +147,42 @@ def transport(method: str, url: str, **kwargs: Any) -> Any: "/api/datasets/operations/op_1?page=2", "/api/datasets/operations/op_1?page=2", ), + ( + "http://127.0.0.1:19493/__e2e__/blob/e2e-working/sha256:ab?response_type=x", + "https://storage.googleapis.com/e2e-working/sha256%3Aab?X-Goog-Signature=redacted", + ), ], - ids=["v4-signed", "v2-signed", "no-query", "root-relative"], + ids=["v4-signed", "v2-signed", "no-query", "root-relative", "local-blob"], ) def test_every_absolute_url_loses_its_query(url: str, expected: str) -> None: assert capture.redact_external_url(url) == expected +@pytest.mark.parametrize( + ("location", "refused"), + [ + ("http://127.0.0.1:19493/__e2e__/blob/b/o?X-Goog-Signature=redacted", True), + ("https://storage.googleapis.com/b/o?X-Goog-Signature=redacted", False), + ("/api/datasets/operations/op_1", False), + ], + ids=["local-signed-url", "storage-url", "root-relative"], +) +def test_a_record_whose_signed_url_names_the_local_host_is_refused( + location: str, refused: bool +) -> None: + exchange = { + "request": {"method": "GET", "path": "/datasets/s/v/file"}, + "response": {"status": 302, "headers": {"location": location}}, + } + record = {"name": "s", "exchanges": [exchange]} + base_url = "http://127.0.0.1:19493/api" + if refused: + with pytest.raises(SystemExit, match=r"still names 127\.0\.0\.1:19493"): + capture._refuse_local_host(record, base_url) + else: + capture._refuse_local_host(record, base_url) + + @pytest.mark.parametrize("name", [n for n in _records("synthetic") if n not in _LIVE]) def test_each_derived_record_follows_from_its_parent(name: str) -> None: record = _load(name) @@ -221,26 +228,6 @@ def test_a_renamed_strict_field_ends_the_call_at_the_build() -> None: } -def test_place_options_pin_each_candidate_on_the_ambiguous_wording() -> None: - body = _load("search-place-ambiguous")["exchanges"][0]["response"]["json"] - no_data = capture.with_place_options(body)["parts"][0]["no_data"] - assert "data_query" not in no_data - assert [o["label"] for o in no_data["options"]] == [ - "Congo [DRC]", - "Congo [Republic]", - ] - assert [o["mentions"] for o in no_data["options"]] == [["Congo"], ["Congo"]] - pins = [ - {e["text"]: e.get("dcid") for e in o["data_query"]["parts"][0]["entities"]} - for o in no_data["options"] - ] - assert pins == [ - {"Germany": "country/DEU", "Congo": "country/COD"}, - {"Germany": "country/DEU", "Congo": "country/COG"}, - ] - assert "options" not in body["parts"][0]["no_data"], "the input is left unchanged" - - @pytest.mark.parametrize( ("timed_out", "status", "expected"), [ @@ -325,23 +312,17 @@ def record(*body_files: str) -> dict[str, Any]: assert (tmp_path / "s.parquet").read_bytes() == b"3" -def test_the_capture_environment_takes_nothing_else_from_the_caller( - tmp_path: Path, -) -> None: +def test_the_capture_environment_takes_nothing_else_from_the_caller() -> None: caller = { "PATH": "/bin", "HOME": "/home/x", "DFO_DATASETS_SURFACE": "0", "GEMINI_API_KEY": "k", } - env = capture.capture_env(tmp_path, caller) + env = capture.capture_env(caller) assert env["DFO_DATASETS_SURFACE"] == "1" assert "GEMINI_API_KEY" not in env assert env["PATH"] == "/bin" - assert ( - env["COVERAGE_ARTIFACT_URI"] - == (tmp_path / "tests" / "fixtures" / "coverage_slice").as_uri() - ) def _checkout(path: Path) -> Path: diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index ca586a4..f98564e 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -42,6 +42,8 @@ _REQUEST_INVALID = "scenarios/fetch-spec-request-invalid.json" _UNKNOWN_VERSION = "scenarios/fetch-ref-unknown-version.json" _NEWER = "scenarios/fetch-ref-expired-newer-version.json" +_NOT_REPRODUCIBLE = "scenarios/fetch-ref-expired-not-reproducible.json" +_ECHOES = "scenarios/choose-candidate-echoes-assumptions.json" _REBOUND = "scenarios/fetch-spec-entity-rebound.json" _DROPPED = "scenarios/fetch-spec-entity-dropped.json" _GROUP_NARROWED = "scenarios/fetch-spec-group-narrowed.json" @@ -192,6 +194,23 @@ def _last_response(change: Callable[[Any], None]) -> Callable[[Any], None]: return lambda doc: change(doc["exchanges"][-1]["response"]) +def _versions_forbidden(response: Any) -> None: + """The versions route refuses 403 publish_not_permitted.""" + response.update( + status=403, + json={ + "type": "/codes/publish_not_permitted", + "title": "Forbidden", + "status": 403, + "detail": "This caller may not list versions.", + "code": "publish_not_permitted", + "trace_id": "0" * 32, + "capability_version": "synthetic", + "retryable": False, + }, + ) + + @pytest.mark.parametrize( ("target", "change", "expected"), [ @@ -332,6 +351,11 @@ def _last_response(change: Callable[[Any], None]) -> Callable[[Any], None]: _set_action("snapshot_not_found", action="report"), "scenarios/fetch-ref-unknown-version.json: step 0 expects", ), + ( + "actions.json", + _set_action("capability_unavailable", action="report"), + "scenarios/fetch-spec-capability-unavailable.json: step 0 expects", + ), ( "actions.json", _set_action("variable_not_resolved", gap_kind="no_data"), @@ -412,7 +436,7 @@ def _last_response(change: Callable[[Any], None]) -> Callable[[Any], None]: ( "scenarios/choose-refused-option-out-of-range.json", _set_step(1, option=2), - "step 1 expects", + "the steps make a POST /search/resolve the record lacks", ), ( "scenarios/choose-refused-mention-names-two-parts.json", @@ -709,6 +733,49 @@ def _last_response(change: Callable[[Any], None]) -> Callable[[Any], None]: lambda doc: doc["call"][1].pop("layout"), "the steps make a POST /datasets the record lacks", ), + ( + _ECHOES, + _posted(1, lambda entry: entry.pop("assumptions")), + "where the rules post", + ), + ( + _ECHOES, + _posted(0, lambda entry: entry.pop("assumptions")), + "where the rules post", + ), + ( + "scenarios/resubmit-candidates-sibling.json", + _posted(1, lambda entry: entry["candidates"][0].pop("assumptions")), + "where the rules post", + ), + ( + "scenarios/answer-candidates-choose-fetch.json", + _posted(0, lambda entry: entry.pop("assumptions")), + "where the rules post", + ), + ( + "scenarios/choose-candidate-assumed-reading.json", + _posted(0, lambda entry: entry["assumptions"][0].update(text="ODA")), + "where the rules post", + ), + ( + "scenarios/choose-candidate-assumed-reading.json", + _set_body(1, lambda body: body.update(rendered_sentence="Other.")), + "step 1 expects", + ), + ( + _NOT_REPRODUCIBLE, + lambda doc: doc["exchanges"][-1]["request"].update( + path=doc["exchanges"][-1]["request"]["path"].removesuffix("?limit=1") + ), + "where the steps make a GET", + ), + (_NOT_REPRODUCIBLE, _last_response(_versions_forbidden), "step 0 expects"), + ( + "scenarios/mint-async-build.json", + _set_step(0, window=[2020, 2023]), + "scenarios/mint-async-build.json: schema: call/0", + ), ], ids=[ "strict-pointer-unresolved", @@ -736,6 +803,7 @@ def _last_response(change: Callable[[Any], None]) -> Callable[[Any], None]: "expect-wrong-option-count", "expect-wrong-complete", "expect-stale-after-action-change", + "capability-unavailable-reported", "expect-stale-after-gap-kind-change", "answer-without-kind", "expect-wrong-content-version", @@ -806,6 +874,15 @@ def _last_response(change: Callable[[Any], None]) -> Callable[[Any], None]: "frame-build-posts-long-options", "resubmit-answering-another-spec", "several-readings-fetched-long", + "definite-entry-without-its-assumptions", + "chosen-entry-without-its-reading-assumptions", + "candidate-without-its-reading-assumptions", + "one-part-pick-without-its-reading-assumptions", + "one-part-pick-rewords-its-reading-assumptions", + "picked-sentence-not-taken-from-the-response", + "versions-without-limit", + "versions-forbidden-raises", + "mint-step-narrowed", ], ) def test_a_broken_contract_is_reported( @@ -838,6 +915,17 @@ def test_an_orphan_body_file_is_reported(package_dir: Path) -> None: assert any("no scenario names this body file" in p for p in problems), problems +def test_a_required_member_that_admits_null_stays_required() -> None: + """A recorded body must carry a required member, null or not.""" + served = validator.PACKAGE_DIR / "served" / "openapi.json" + routes = validator._Routes(json.loads(served.read_text(encoding="utf-8"))) + page = "/components/schemas/DatasetVersionsPage" + body = {"spec_id": "spec_" + "0" * 32, "versions": [], "complete": True} + assert routes.validate(page, {**body, "next_cursor": None}) == [] + problems = routes.validate(page, body) + assert any("'next_cursor' is a required property" in p for p in problems) + + def test_no_scenarios_is_a_hard_failure(package_dir: Path) -> None: for path in (package_dir / "scenarios").iterdir(): path.unlink() diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index e5ba433..4cc523d 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -390,11 +390,7 @@ class _Routes: def __init__(self, openapi: dict[str, Any]) -> None: self.openapi = openapi self._templates = [(t, t.split("/")) for t in openapi["paths"]] - registry = _openapi_registry(openapi) - self._validator = jsonschema.validators.extend( - jsonschema.Draft202012Validator, {"required": _required_unless_nullable} - ) - self._registry = registry + self._registry = _openapi_registry(openapi) def template(self, path: str) -> str | None: """The route template matching `path`, preferring a literal segment @@ -440,7 +436,7 @@ def response_schema( return None if media is None else content[media].get("schema") def validate(self, pointer: str, body: Any) -> list[str]: - validator = self._validator( + validator = jsonschema.Draft202012Validator( {"$ref": f"{_OPENAPI_URI}#{pointer}"}, registry=self._registry ) return [ @@ -449,23 +445,6 @@ def validate(self, pointer: str, body: Any) -> list[str]: ] -def _required_unless_nullable( - validator: Any, required: list[str], instance: Any, schema: dict[str, Any] -) -> Iterator[jsonschema.ValidationError]: - """`required`, except that a member whose schema admits null may be - absent: the server leaves null members out of the bodies it serves.""" - if not validator.is_type(instance, "object"): - return - properties = schema.get("properties", {}) - for name in required: - if name in instance: - continue - member = properties.get(name) - if member is not None and validator.evolve(schema=member).is_valid(None): - continue - yield jsonschema.ValidationError(f"{name!r} is a required property") - - def _api_path(base_path: str, request: dict[str, Any]) -> str: """The path an API request reaches: a `path` under the base URL's path, or an `origin_path` as it stands.""" @@ -792,21 +771,6 @@ def answer_from_body(body: dict[str, Any]) -> Answer: ) -def candidate_answer(answer: Answer, part: int, spec: dict[str, Any]) -> Answer: - """The answer a choice among one part's candidates makes with no request: - that part definite on the chosen spec, keeping its other members, with - that spec's sentence.""" - chosen = answer.parts[part] - definite = { - **{k: v for k, v in chosen.items() if k != "candidates"}, - "status": "definite", - "spec": spec, - } - return Answer( - answer.body, [definite], spec["resolved"]["rendered_sentence"], "definite" - ) - - # --- choices ---------------------------------------------------------------- @@ -889,14 +853,12 @@ def _options(answer: Answer, index: int) -> list[dict[str, Any]]: return answer.parts[index].get("no_data", {}).get("options", []) -def choice_input(answer: Answer, choice: Choice) -> dict[str, Any] | None: - """The Search input a choice posts, or None for a choice among one part's - candidates, which makes no request. In a one-part answer an option posts - its data_query; in a several-part answer the choice posts - dataset_resubmit with one entry per part, in part order.""" - if len(answer.parts) == 1: - if choice.option is None: - return None +def choice_input(answer: Answer, choice: Choice) -> dict[str, Any]: + """The Search input a choice posts. In a one-part answer an option posts + its data_query; any other choice posts dataset_resubmit with one entry + per part, in part order, so a picked candidate in a one-part answer posts + its identity as the one entry, and Search answers the picked reading.""" + if len(answer.parts) == 1 and choice.option is not None: return choice.option["data_query"] entries = [ resubmit_entry(part, choice if index == choice.part else None) @@ -910,9 +872,17 @@ def resubmit_entry(part: dict[str, Any], choice: Choice | None) -> dict[str, Any identity and the chosen option its one parsed part. Otherwise a definite part posts its spec's identity, a candidates part its candidate set in the server's order with its ordering and truncated echoed, and any other part - its restatement as a parsed entry, or a placeholder when it has none.""" + its restatement as a parsed entry, or a placeholder when it has none. + Each identity, the chosen candidate's, a definite part's and each of a + candidates entry's, echoes its reading's assumptions as `reading_echo` + gives them.""" if choice is not None and choice.candidate is not None: - return _echo(part, entry_kind="identity", **_identity(choice.candidate)) + candidate = choice.candidate + return _echo( + part, + entry_kind="identity", + **_identity(candidate, reading_echo(part, candidate)), + ) if choice is not None and choice.option is not None: parts = choice.option["data_query"].get("parts") if not isinstance(parts, list) or len(parts) != 1: @@ -920,7 +890,10 @@ def resubmit_entry(part: dict[str, Any], choice: Choice | None) -> dict[str, Any return {"entry_kind": "parsed", "part": parts[0]} match part.get("status"): case "definite": - return _echo(part, entry_kind="identity", **_identity(part["spec"])) + spec = part["spec"] + return _echo( + part, entry_kind="identity", **_identity(spec, reading_echo(part, spec)) + ) case "candidates": candidates = part["candidates"] return _echo( @@ -928,11 +901,25 @@ def resubmit_entry(part: dict[str, Any], choice: Choice | None) -> dict[str, Any entry_kind="candidates", ordering=candidates.get("ordering"), truncated=candidates.get("truncated") is True, - candidates=[_identity(spec) for spec in candidates["specs"]], + candidates=[ + _identity(spec, reading_echo(part, spec)) + for spec in candidates["specs"] + ], ) return _restated_entry(part) +def reading_echo(part: Mapping[str, Any], spec: Mapping[str, Any]) -> Any: + """The assumptions a resubmitted reading of `part` echoes: a definite + part's `assumptions`, or a candidates part's `reading_assumptions` under + the reading's spec_id. None, when the part carries no such member, posts + no `assumptions`, and Search reads the reading as a fresh request does; + `[]` states none.""" + if part.get("status") == "candidates": + return (part.get("reading_assumptions") or {}).get(spec["spec_id"]) + return part.get("assumptions") + + def _restated_entry(part: dict[str, Any]) -> dict[str, Any]: """A part without a reading: its restatement as a parsed entry, else a placeholder of its no_data reason or unsupported code. A part of unknown @@ -953,12 +940,15 @@ def _restated_entry(part: dict[str, Any]) -> dict[str, Any]: raise _refuse() -def _identity(spec: dict[str, Any]) -> dict[str, Any]: - """A spec's identity, and its entity groups when it has any.""" +def _identity(spec: dict[str, Any], assumptions: Any = None) -> dict[str, Any]: + """A spec's identity, its entity groups when it has any, and the + reading's `assumptions` echo unless it is None.""" item: dict[str, Any] = {"identity": spec["definition"]["identity"]} groups = spec.get("resolved", {}).get("entity_groups") if groups: item["entity_groups"] = groups + if assumptions is not None: + item["assumptions"] = assumptions return item @@ -1207,7 +1197,7 @@ class _UnfitError(Exception): REBUILD_REFUSED = frozenset( {"InvalidRequestError", "NotFoundError", VERSION_UNAVAILABLE} ) -NO_VERSIONS = frozenset({"NotFoundError", "PermissionDeniedError"}) +NO_VERSIONS = frozenset({"NotFoundError"}) OPERATION_FAILED = "operation_failed" @@ -1217,7 +1207,7 @@ def rendering_for(layout: str | None) -> dict[str, Any]: def posted_scope(step: Mapping[str, Any]) -> dict[str, Any] | None: - """The `input.scope` a fetch or mint of a spec posts for the step's + """The `input.scope` a fetch of a spec posts for the step's narrowing, or None when it narrows nothing. The server's `scope.entities` replaces the spec's whole entity binding, so the client posts the spec's bound roles with each role the step names @@ -1243,6 +1233,12 @@ def posted_scope(step: Mapping[str, Any]) -> dict[str, Any] | None: return scope or None +def versions_path(spec_id: str) -> str: + """The versions route asked for the newest stored version alone: the + route lists versions newest first, so `limit=1` returns just it.""" + return f"/datasets/{spec_id}/versions?limit=1" + + def pick_artifact( manifest: Mapping[str, Any], rendering: Mapping[str, Any] ) -> dict[str, Any] | None: @@ -1779,10 +1775,10 @@ def stored_file( return True, None def newest(self, spec_id: str) -> str | None: - """The newest stored version the versions route lists first, or None - when it lists none or refuses as unknown or forbidden.""" + """The newest stored version, the one the versions route lists first, + or None when it lists none or refuses the spec as unknown.""" try: - body = self.acted_on(self.call("GET", f"/datasets/{spec_id}/versions")) + body = self.acted_on(self.call("GET", versions_path(spec_id))) except ClientError as error: if error.error_class(self.client_codes) in NO_VERSIONS: return None @@ -1826,13 +1822,7 @@ def _search(self, step: dict[str, Any]) -> dict[str, Any]: def _choose(self, step: dict[str, Any]) -> dict[str, Any]: answer = self._answered() choice = choice_for(answer, self.kinds, step.get("part"), step["option"]) - posts = choice_input(answer, choice) - if posts is not None: - chosen = self.resolve(posts) - elif choice.candidate is not None: - chosen = candidate_answer(answer, choice.part, choice.candidate) - else: - raise _UnfitError("a choice posts unless it picks a candidate") + chosen = self.resolve(choice_input(answer, choice)) self.answer = chosen return answer_outcome(chosen, self.kinds) @@ -1880,7 +1870,7 @@ def _fetch_ref(self, step: dict[str, Any]) -> dict[str, Any]: def _mint(self, step: dict[str, Any]) -> dict[str, Any]: rendering = rendering_for(step.get("layout")) - exchange = self.posted_build(rendering, posted_scope(step)) + exchange = self.posted_build(rendering, None) if exchange["response"]["status"] == 200: raise _UnfitError("a mint step's build answers an operation") resource = self.acted_on(exchange, _OPERATION) From 8b17e17366ae9afb9b88086a987eeb91c924472e Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Wed, 21 Oct 2026 11:35:55 +0200 Subject: [PATCH 18/39] fix(client-contract): check what each replayed exchange carries The validator now refuses what a client replay would reject. A repeat of a refused request counts as a retry only while the refusal is retryable and the budget allows: two retries, one for a build cut off by a 504. A POST record carries its body, and every build's posted body is compared whole with the spec it builds. A poll names the operation the client holds, a download follows the files route's Location exactly, and synthetic exchanges go through the same problem code check as recorded ones. served/openapi.json must hold the Search, Datasets, Graph and Presentation surfaces and nothing else. A recorded scenario holds only exchanges the server made: the capture refuses to write one with a canned answer, and no synthetic derivation can make a request. choose-option-beside-definite and fetch-ref-newest-version are recorded at 635943e03, and fetch-ref-expired-not-reproducible derives from the latter through a new newest_version step. The README states every rule the validator derives, including the retry, warning, long-build and choice refusal rules. 68 scenarios, 31 recorded and 37 synthetic. --- python/client-contract/CHANGELOG.md | 2 +- python/client-contract/README.md | 24 +- .../dfo_client_contract/scenario.schema.json | 66 +- ...son => choose-option-beside-definite.json} | 8470 +++++++++-------- .../scenarios/fetch-null-member.json | 2 +- .../fetch-ref-expired-not-reproducible.json | 112 +- .../scenarios/fetch-ref-newest-version.json | 122 + tools/README.md | 4 +- tools/capture_client_contract.py | 197 +- tools/tests/test_capture_client_contract.py | 60 +- tools/tests/test_validate_client_contract.py | 147 +- tools/validate_client_contract.py | 223 +- 12 files changed, 5458 insertions(+), 3971 deletions(-) rename python/client-contract/src/dfo_client_contract/scenarios/{choose-place-beside-definite.json => choose-option-beside-definite.json} (57%) create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-newest-version.json diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index 8baaa8c..0a052ec 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -11,7 +11,7 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be - `strict-fields.json` and its schema: 25 members that stay required and non-nullable, and the answer kinds, part statuses and operation statuses the clients branch on. - `actions.json` and its schema: the caller's next step for each of the 101 active refusal codes on `problem_details` or `no_data_reason`, with the gap kind of each no_data reason. - The status fallback for a refusal whose code has no row: 400 and 422 to `InvalidRequestError`, 401 to `AuthenticationError`, 403 to `PermissionDeniedError`, 404 and 410 to `NotFoundError`, 408 to `DfoTimeoutError`, 429 to `RateLimitError`, and any other 4xx or 5xx to `InvalidRequestError` or `ServerError`. -- `scenario.schema.json`, the scenario record, and 67 scenarios: 29 recorded against the composed dfo-apis app at `635943e03`, and 38 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 2,105,201 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, an identity resubmit answering another spec, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, a failed operation posted again, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route. +- `scenario.schema.json`, the scenario record, and 68 scenarios: 31 recorded against the composed dfo-apis app at `635943e03`, and 37 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 2,105,201 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, an identity resubmit answering another spec, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, a failed operation posted again, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route. - `client-codes.json` and its schema: the 16 codes a client sets on the errors it raises itself, each with its error class and condition, disjoint from `actions.json` and `registries/codes.json`, and the `client_codes()` and `client_codes_schema()` accessors. Every scenario error the client raises itself carries its code, and `refusal_without_code` names a refusal whose body carries no code. - `dataset-ref.schema.json`, the frozen `DatasetRef` format, with accepted and rejected examples. - `tools/capture_client_contract.py`, which captures `served/openapi.json` from a dfo-apis checkout in process and records the scenarios against a base URL, dev by default, or with `record --offline` derives their outcomes again from the records with no request. A local app's signed URLs are written as the storage URLs a deployment signs. diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 821a034..78c0bba 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -124,17 +124,17 @@ A scenario is one client-level call, the HTTP exchanges it makes, and the outcom | `name` | The kebab-case name, equal to the file name's stem | | `description` | One or two sentences on what the scenario proves | | `origin` | `recorded`, with the `base_url`, the deployed `dfo_commit` and `recorded_at`; or `synthetic`, with the recorded scenario it is `derived_from` and a one-line `edit` | -| `call` | The steps, in order: `search`; `choose`; `fetch` of the previous answer, of a `spec` with `window`, `entities` and `facets`, or of a `ref`; `mint`; `operation`, which resumes a long build by its `operation_id`; `result` | +| `call` | The steps, in order: `search`; `choose`; `fetch` of the previous answer, of a `spec` with `window`, `entities` and `facets`, or of a `ref`; `mint`; `operation`, which resumes a long build by its `operation_id`; `result`; `newest_version` of a `spec` | | `exchanges` | The requests the call makes, in order, each with the response to give | -| `expect` | One outcome per step: an `answer`, a `dataset`, an `operation` or an `error` | +| `expect` | One outcome per step: an `answer`, a `dataset`, an `operation`, a `newest_version` or an `error` | A step that acts on an earlier result follows one: `choose` follows `search` or `choose`, a `fetch` with no target follows `search`, `choose` or another `fetch` with no target and acts on the last answer, and `result` follows `mint` or `operation`. A `fetch` of an answer or a spec, `mint` and `operation` take a `layout`, `long` by default or `frame`, and a `fetch` of an answer or a spec takes `strict`. A `spec` in a step holds `spec_id`, the server's unmodified `definition`, the `sentence` when the client knows it, and the server's `resolved.entity_groups` as `entity_groups` when it names any. An exchange's request names its target in one of three ways. `path` is a path the client composes under the base URL, such as `/search/resolve`. `origin_path` is a root-relative URL the server returned, such as an artifact's `url`, which resolves against the base URL's origin and never against its path. `url` is an absolute URL outside the API, such as the signed storage URL a files route redirects to, which the client fetches with a bare request carrying no client header and no key. `json` holds the request body members that must match; a recorded scenario lists every member the client sent. The response gives `status`, the `headers` a client reads, and a `json` body or a `body_file`, a binary body in `scenarios/`. A scenario's own body files are named `.` and `-.`; a synthetic scenario may instead name a body file its parent names. -An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a warning's code, which for a `SearchWarning` may be null, or for any other error the client raises itself its code in `client-codes.json`. A `VersionUnavailableError` also gives `newest_version`, the version the lookup found, or null. A dataset or error outcome of a step that made a long build gives `long_builds`, one entry per build the server ran on, in order: the `operation_id` the client polled last, the `poll_waits` in seconds before each poll, and the number of `resubmissions`. +A `newest_version` outcome gives the `content_version` the step found, or null. An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a warning's code, which for a `SearchWarning` may be null, or for any other error the client raises itself its code in `client-codes.json`. A `VersionUnavailableError` also gives `newest_version`, the version the lookup found, or null. A dataset or error outcome of a step that made a long build gives `long_builds`, one entry per build the server ran on, in order: the `operation_id` the client polled last, the `poll_waits` in seconds before each poll, and the number of `resubmissions`. -Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry, except on a poll, where the long-build rules count retries, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, each build posts the `scope` the rules give, and each Search request posts the input the rules give: the question, a choice's input, or a member's identity. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. +Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry where the retry rules allow one, except on a poll, where the long-build rules count retries, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, each POST carries its body, each build posts the body the rules give for the spec it builds, so the builds' order and spec_ids are checked, each Search request posts the input the rules give: the question, a choice's input, or a member's identity, each poll names the operation the client holds, and each signed download is the URL the files route's `location` names. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. A recorded scenario's request and response bodies validate against their route's schemas in `served/openapi.json`. A required member stays required when its schema admits null: the body carries it, as null or a value. A member the schema leaves optional may be absent or null, and a client reads both as null. @@ -153,7 +153,7 @@ The records also fix these client rules: - A built `spec_id` that differs from the posted one, or a spec with no sentence, takes its sentence from Search: the client posts the built definition's `identity` as one `dataset_resubmit` identity entry, with the member's first part as `variable_text`, or `"dataset"` when no answer part names it, and checks the answer's `spec_id` equals the built one. The entry's `entity_groups` holds the spec's `resolved.entity_groups` for each role the built identity binds to the same entities as the spec's definition, so a window or facets narrowing keeps every group and a role the narrowing rebound or dropped loses its group. The entry leaves `entity_groups` out when it keeps no group, as for a resumed operation, whose spec the client does not hold. The server reads a role posted without its group as its members, so a narrowed spec of flows to the least developed countries would read "44 recipients" in place of "the 44 Least Developed Countries". - A dataset of several members puts the `part` column first, then each member's columns in member order, each column once. The `part` value on a member's rows is the member's `parts` joined by `"; "`, so a member that answers two folded parts reads `"health ODA disbursements; education ODA disbursements"`, or the member's sentence when `parts` is empty. - A choice names its part by index, by variable text, or by a word that one gap's options mention, and its option by index or label; a candidate is named by index. A label is matched among the options that mention the word the part was named by. With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. -- A choice raises `InvalidRequestError` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is out of range or matches no label or several. +- A choice raises `InvalidRequestError` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is out of range or matches no label or several. It raises the same when an entry it would post cannot be built: a part with no `variable_text`, or a part of a status the client does not know that has no `restatement`. A chosen option whose `data_query` holds other than one part raises `ContractError`. - Every pick of a candidate asks Search for the picked answer, and no client builds it locally. In a one-part answer the pick posts `dataset_resubmit`, without `raw_query`, with one identity entry: the candidate's identity and `entity_groups`, and the part's `variable_text`, `separate` and `operations` as below. The picked answer, its sentence with any "Assumed: …" clause, and its assumptions are Search's response. A choice of a no_data option in a one-part answer posts the option's `data_query` as the input. - In a several-part answer a choice posts `dataset_resubmit`, without `raw_query`, with one entry per part in part order. The chosen candidate posts an identity entry with its identity and `entity_groups`, and the chosen option its `data_query`'s one part as a parsed entry. A definite part posts an identity entry with its spec's identity and `entity_groups`. A candidates part left alone posts a `candidates` entry: its candidate set in the server's order, each with its identity and `entity_groups`, and its `ordering` and `truncated` echoed. The server cannot recompute that order, because it rests on the first answer's bind election and availability reads, and a parsed entry would cost an LLM bind. Any other part posts its `restatement` as a parsed entry, or a placeholder entry with its no_data `reason` or unsupported `code` when it has none. Every entry but a parsed one carries the part's `variable_text`, `separate` when true and `operations` when the part has any; `entity_groups` is left out when the spec has none. - Each identity a choice posts echoes its reading's assumptions as `assumptions`: the chosen candidate's entry carries its part's `reading_assumptions` under the candidate's `spec_id`, a definite part's entry carries the part's `assumptions`, and each candidate of a `candidates` entry carries its own `reading_assumptions` entry. Search then states the echoed items that still hold, so the picked answer states what that reading assumed. `[]` states none. An identity with no `assumptions` reads as a fresh request, so a client that holds no list for a reading, from a part that carries no `assumptions` or `reading_assumptions`, posts none. The identity entry that asks for a built sentence posts no `assumptions`, since it reads only the spec's own `rendered_sentence`. @@ -163,12 +163,12 @@ The records also fix these client rules: - A download asks the route that redirects to the signed URL: an artifact's `url`, or the file selector. A refused signed URL, or bytes that do not hash to the artifact's digest, ask the route once more, and a second failure raises `ServerError` with `download_failed` or `digest_mismatch`. - A declined or catalogue answer is not complete, and fetching it raises `DeclinedError`. - Fetching an answer with a gap raises `IncompleteAnswerError` before any request, unless the fetch is partial and some part has a reading. -- A fetch of an answer issues one `SearchWarning` when a definite part has an operation Search did not run, a departure, or a warning at severity `warn` or `degraded`, or the answer's `diagnostics.warnings` holds such a warning. An `info` warning issues nothing. A strict fetch raises the `SearchWarning` before any build, with the code of its one hint, or a null code when the readings differ from the question in several ways. -- A ref's version is found in this order: the snapshot route and the files route at the stored digest; the file selector, `GET /datasets/{id}/{content_version}/file` with the ref's rendering as the query; and a build of the ref's spec in the ref's rendering, which must answer the same `content_version`. A snapshot refusal other than `artifact_expired` ends the lookup, so `snapshot_not_found` raises `NotFoundError` with no further request. A files route or selector refusal of `artifact_expired`, `artifact_not_found` or `not_found` takes the next step, and a selector file of another digest is not the stored file. A rebuild that answers another version, or that raises `InvalidRequestError`, `NotFoundError` or `VersionUnavailableError`, ends in `VersionUnavailableError` with the first refusal's code, or `version_unavailable` when nothing refused. Its `newest_version` is the version the rebuild answered, or else the newest stored version, which `GET /datasets/{id}/versions?limit=1` lists alone, since the route lists versions newest first and needs no key; or null when that route lists none or refuses with `NotFoundError`. Any other refusal of the versions route raises. -- A build answers 200 with the manifest, or 202 with an operation the client polls at `/datasets/operations/{operation_id}`. Before each poll it waits the `Retry-After` of a 429 that refused the last poll, else the last operation resource's `retry_after_ms`, else the `Retry-After` of the response that carried that resource, else a backoff of 1, 2, 4 and then 8 seconds that advances only when it is used. -- A 429 poll spends no retry. Any other retryable refused poll spends one of the two retries, which a poll that answers restores, and a refusal that is not retryable raises. A poll that answers a failed operation whose error is retryable posts the same build once more and polls the operation it starts; a second failure, an error that is not retryable, and a resumed operation, whose build request the client does not hold, raise the operation's error. -- A build cut off by a retryable 504 is posted once more, and a second 504 raises. -- A retry waits `Retry-After` when the response carries it. A synthetic scenario that retries assumes the default of two retries. +- A fetch of an answer issues one `SearchWarning` when a definite part has an operation Search did not run, a departure, or a warning at severity `warn` or `degraded` with a `message`, or the answer's `diagnostics.warnings` holds such a warning. An `info` warning, and a warning with no `message`, issue nothing. Each way is one line a client shows: `Not done: ()` coded by the verb, the departure's `text` coded by its code, or `Note: ` coded by the warning's code, in part order with the diagnostics warnings last, and ways that show the same line count once, under the first one's code. A strict fetch raises the `SearchWarning` before any build, with the code of its one line, or a null code when there are several lines. A strict fetch raises it before the `frame` layout's several-member check. +- A ref's version is found in this order: the snapshot route and the files route at the stored digest; the file selector, `GET /datasets/{id}/{content_version}/file` with the ref's rendering as the query; and a build of the ref's spec in the ref's rendering, which must answer the same `content_version`. A snapshot refusal other than `artifact_expired` ends the lookup, so `snapshot_not_found` raises `NotFoundError` with no further request. A files route or selector refusal of `artifact_expired`, `artifact_not_found` or `not_found` takes the next step, and a selector file of another digest is not the stored file. A rebuild that answers another version, or that raises `InvalidRequestError`, `NotFoundError` or `VersionUnavailableError`, ends in `VersionUnavailableError` with the first refusal's code, or `version_unavailable` when nothing refused. Its `newest_version` is the version the rebuild answered, or else the newest stored version, which `GET /datasets/{id}/versions?limit=1` lists alone, as a `newest_version` step finds it, since the route lists versions newest first and needs no key; or null when that route lists none or refuses with `NotFoundError`. Any other refusal of the versions route raises. +- A build answers 200 with the manifest, or 202 with an operation the client polls at `/datasets/operations/{operation_id}`, the id of the operation it holds. A mint's build answers 202; a record whose mint answers 200 fits no mint step. Before each poll it waits the `Retry-After` of a 429 that refused the last poll, else the last operation resource's `retry_after_ms`, else the `Retry-After` of the response that carried that resource, else a backoff of 1, 2, 4 and then 8 seconds that advances only when it is used. +- A 429 poll spends no retry. Any other retryable refused poll spends one of the two retries, which a poll that answers restores, and a refusal that is not retryable raises. A poll that answers a failed operation whose error is retryable posts the same build once more and polls the operation it starts; a second failure, an error that is not retryable, and a resumed operation, whose build request the client does not hold, raise the operation's error. A refused poll whose code is `operation_failed` is a failed operation with that error. A 202 or resumed operation that already reads `failed` raises its error before any poll. +- Any other refusal is retried when it is retryable: as a problem document's `retryable` says, or the website proxy's `retry` of `retry_after_delay`, else when its status is 408, 429, 500, 502, 503 or 504. A client makes two retries by default, and the scenarios assume that default; a build cut off by a retryable 504 is posted once more only, and a second 504 raises. A refusal that is not retryable, or one past the retries, raises its error. +- A retry waits `Retry-After` when the response carries it. The scenarios hold no outcome for the waits before a retry, so a replay does not pin them. ## Recording @@ -179,7 +179,7 @@ uv sync --directory ../dfo-apis --extra eval --extra api --extra engine --extra uv run tools/capture_client_contract.py openapi --dfo-apis ../dfo-apis ``` -Its `record` command runs every scenario against a base URL, dev's Cloud Run URL by default, checks each live answer still has the shape its scenario names, derives the synthetic scenarios from the fresh records, and then runs the validator. It fails when the validator reports a problem or the binary bodies pass 5 MB. `--only` records the scenarios it names. `--offline` makes no request: each recorded scenario's steps run again over its own exchanges and rewrite its `expect`, and each synthetic scenario that records nothing live is derived again from its parent, so a change to the outcome rules or to `client-codes.json` reaches the records without a recording: +Its `record` command runs every scenario against a base URL, dev's Cloud Run URL by default, checks each live answer still has the shape its scenario names, derives the synthetic scenarios from the fresh records with no request, and then runs the validator. A recorded scenario holds only exchanges the server made, and the run refuses one that a canned exchange answered; the record names the commit the server's responses name. It fails when the validator reports a problem or the binary bodies pass 5 MB. `--only` records the scenarios it names. `--offline` makes no request: each recorded scenario's steps run again over its own exchanges and rewrite its `expect`, and each synthetic scenario is derived again from its parent, so a change to the outcome rules or to `client-codes.json` reaches the records without a recording: ```bash uv run tools/capture_client_contract.py record --offline --only answer-declined choose-refused-no-choice diff --git a/python/client-contract/src/dfo_client_contract/scenario.schema.json b/python/client-contract/src/dfo_client_contract/scenario.schema.json index 476973a..fade531 100644 --- a/python/client-contract/src/dfo_client_contract/scenario.schema.json +++ b/python/client-contract/src/dfo_client_contract/scenario.schema.json @@ -238,6 +238,9 @@ { "$ref": "#/$defs/fetch_ref_step" }, + { + "$ref": "#/$defs/newest_version_step" + }, { "$ref": "#/$defs/mint_step" }, @@ -385,6 +388,23 @@ } } }, + "newest_version_step": { + "description": "The newest stored version of a spec, the one the versions route lists first.", + "type": "object", + "additionalProperties": false, + "required": [ + "op", + "spec" + ], + "properties": { + "op": { + "const": "newest_version" + }, + "spec": { + "$ref": "#/$defs/spec" + } + } + }, "mint_step": { "description": "A mint of a spec, which starts its build and answers the operation; it takes a layout and no narrowing.", "type": "object", @@ -459,7 +479,7 @@ } }, "request": { - "description": "Exactly one of path, a path the client composes under the base URL; origin_path, a root-relative URL the server returned, resolved against the base URL's origin; or url, an absolute URL outside the API, such as a signed storage URL.", + "description": "Exactly one of path, a path the client composes under the base URL; origin_path, a root-relative URL the server returned, resolved against the base URL's origin; or url, an absolute URL outside the API, such as a signed storage URL. A POST names its body in json.", "type": "object", "additionalProperties": false, "required": [ @@ -482,6 +502,18 @@ ] } ], + "if": { + "properties": { + "method": { + "const": "POST" + } + } + }, + "then": { + "required": [ + "json" + ] + }, "properties": { "method": { "enum": [ @@ -601,6 +633,18 @@ } } }, + { + "type": "object", + "additionalProperties": false, + "required": [ + "newest_version" + ], + "properties": { + "newest_version": { + "$ref": "#/$defs/newest_version" + } + } + }, { "type": "object", "additionalProperties": false, @@ -809,6 +853,26 @@ } } }, + "newest_version": { + "description": "The newest stored version a newest_version step finds, or null when the spec has none.", + "type": "object", + "additionalProperties": false, + "required": [ + "content_version" + ], + "properties": { + "content_version": { + "oneOf": [ + { + "$ref": "#/$defs/content_version" + }, + { + "type": "null" + } + ] + } + } + }, "error": { "type": "object", "additionalProperties": false, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-place-beside-definite.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-beside-definite.json similarity index 57% rename from python/client-contract/src/dfo_client_contract/scenarios/choose-place-beside-definite.json rename to python/client-contract/src/dfo_client_contract/scenarios/choose-option-beside-definite.json index 461e6af..27168af 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-place-beside-definite.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-beside-definite.json @@ -1,21 +1,22 @@ { "format_version": 1, - "name": "choose-place-beside-definite", - "description": "Choosing \"Congo [DRC]\" on part 1 beside a definite part posts dataset_resubmit with the definite part's identity and entity_groups as an identity entry, and the chosen option's data_query part as a parsed entry. Both parts answer definite.", + "name": "choose-option-beside-definite", + "description": "Choosing option 0 on part 1, a no_data part whose direction the question leaves open, beside a definite part whose places are a named group posts dataset_resubmit with the definite part's identity, entity_groups and assumptions as an identity entry, and the chosen option's data_query part as a parsed entry. Part 0 answers definite again, and part 1 answers the debt read in the chosen direction.", "origin": { - "kind": "synthetic", - "derived_from": "search-two-parts-place-ambiguous", - "edit": "Part 0 becomes the definite part, entity groups included, of a live search for \"GDP of the least developed countries\", and the choice is recorded live." + "kind": "recorded", + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T09:25:52Z" }, "call": [ { "op": "search", - "question": "Kenya's GDP, and ODA disbursements from Germany to Congo" + "question": "GDP of sub-Saharan Africa, and debt of Kenya" }, { "op": "choose", "part": 1, - "option": "Congo [DRC]" + "option": 0 } ], "exchanges": [ @@ -27,7 +28,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "Kenya's GDP, and ODA disbursements from Germany to Congo" + "query": "GDP of sub-Saharan Africa, and debt of Kenya" } } }, @@ -40,25 +41,25 @@ "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "Kenya's GDP, and ODA disbursements from Germany to Congo", - "normalized_query": "Kenya's GDP, and ODA disbursements from Germany to Congo", + "raw_query": "GDP of sub-Saharan Africa, and debt of Kenya", + "normalized_query": "GDP of sub-Saharan Africa, and debt of Kenya", "extract_skipped": false }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "670f1650b70c4616805aa3dd54c4dae8", + "trace_id": "36b57c8d82ea4b938e42ca11105ac21c", "warnings": [], "timing_ms": { - "total": 1333, + "total": 4230, "by_step": { "coverage": 0, - "extract": 1329 + "extract": 875 } }, "llm_usage": { - "input_tokens": 2256, - "output_tokens": 207, - "cached_tokens": 861 + "input_tokens": 12972, + "output_tokens": 920, + "cached_tokens": 5719 }, "timed_out": false }, @@ -68,26 +69,30 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 2622, + "total": 2775, "by_step": { - "recall": 1, - "shape_arcs": 2, - "shape_probe": 0, - "shape_groups": 25, - "shape_labels": 6, - "shape_admission": 0, - "shape": 839, - "bind": 1261, - "materialise": 253, - "answer": 7, - "options": 261 + "recall": 0, + "shape_arcs": 3, + "shape_probe_coverage": 4, + "shape_probe": 298, + "shape_groups": 17, + "shape_labels": 4, + "shape_admission": 1, + "shape": 1305, + "bind": 1041, + "materialise": 182, + "answer": 5, + "options": 242 } }, "restatement": { "variable_text": "GDP", "entities": [ { - "text": "Least Developed Countries" + "text": "Sub-Saharan Africa" + }, + { + "text": "Kenya" } ], "sources": [], @@ -98,17 +103,17 @@ { "code": "group_read_as_members", "binding_ref": "where:", - "asked": "least developed countries", - "text": "You asked for least developed countries. This shows its members, each on its own." + "asked": "sub-Saharan Africa", + "text": "You asked for sub-Saharan Africa. This shows the countries in it, each on its own." } ], "assumptions": [], "status": "definite", "spec": { - "spec_id": "spec_e11cdfec28d9fac6551cfaa892be9558", + "spec_id": "spec_3c3d4e571162850b30db0321638f955b", "definition": { "schema_version": 1, - "spec_id": "spec_e11cdfec28d9fac6551cfaa892be9558", + "spec_id": "spec_3c3d4e571162850b30db0321638f955b", "identity": { "identity_version": "spec1", "shape": { @@ -147,54 +152,64 @@ ], "entities": { "observationAbout": [ - "country/AFG", "country/AGO", "country/BDI", "country/BEN", "country/BFA", - "country/BGD", + "country/BWA", "country/CAF", + "country/CIV", + "country/CMR", "country/COD", + "country/COG", "country/COM", + "country/CPV", "country/DJI", "country/ERI", "country/ETH", + "country/GAB", + "country/GHA", "country/GIN", "country/GMB", "country/GNB", - "country/HTI", - "country/KHM", - "country/KIR", - "country/LAO", + "country/GNQ", + "country/KEN", "country/LBR", "country/LSO", "country/MDG", "country/MLI", - "country/MMR", "country/MOZ", "country/MRT", + "country/MUS", "country/MWI", + "country/NAM", "country/NER", - "country/NPL", + "country/NGA", "country/RWA", - "country/SDN", "country/SEN", - "country/SLB", "country/SLE", "country/SOM", "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", "country/TCD", "country/TGO", - "country/TLS", - "country/TUV", "country/TZA", "country/UGA", - "country/YEM", - "country/ZMB" + "country/ZAF", + "country/ZMB", + "country/ZWE" ] }, "requested_window": { "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "USDollar" + } } } }, @@ -347,13 +362,6 @@ "binding": { "kind": "set", "values": [ - { - "ref": { - "ref": "country/AFG", - "label": "Afghanistan" - }, - "value_kind": "entity" - }, { "ref": { "ref": "country/AGO", @@ -384,8 +392,8 @@ }, { "ref": { - "ref": "country/BGD", - "label": "Bangladesh" + "ref": "country/BWA", + "label": "Botswana" }, "value_kind": "entity" }, @@ -396,10 +404,31 @@ }, "value_kind": "entity" }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, { "ref": { "ref": "country/COD", - "label": "Congo [DRC]" + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" }, "value_kind": "entity" }, @@ -410,6 +439,13 @@ }, "value_kind": "entity" }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, { "ref": { "ref": "country/DJI", @@ -433,50 +469,50 @@ }, { "ref": { - "ref": "country/GIN", - "label": "Guinea" + "ref": "country/GAB", + "label": "Gabon" }, "value_kind": "entity" }, { "ref": { - "ref": "country/GMB", - "label": "Gambia" + "ref": "country/GHA", + "label": "Ghana" }, "value_kind": "entity" }, { "ref": { - "ref": "country/GNB", - "label": "Guinea-Bissau" + "ref": "country/GIN", + "label": "Guinea" }, "value_kind": "entity" }, { "ref": { - "ref": "country/HTI", - "label": "Haiti" + "ref": "country/GMB", + "label": "The Gambia" }, "value_kind": "entity" }, { "ref": { - "ref": "country/KHM", - "label": "Cambodia" + "ref": "country/GNB", + "label": "Guinea-Bissau" }, "value_kind": "entity" }, { "ref": { - "ref": "country/KIR", - "label": "Kiribati" + "ref": "country/GNQ", + "label": "Equatorial Guinea" }, "value_kind": "entity" }, { "ref": { - "ref": "country/LAO", - "label": "Laos" + "ref": "country/KEN", + "label": "Kenya" }, "value_kind": "entity" }, @@ -508,13 +544,6 @@ }, "value_kind": "entity" }, - { - "ref": { - "ref": "country/MMR", - "label": "Myanmar" - }, - "value_kind": "entity" - }, { "ref": { "ref": "country/MOZ", @@ -531,50 +560,50 @@ }, { "ref": { - "ref": "country/MWI", - "label": "Malawi" + "ref": "country/MUS", + "label": "Mauritius" }, "value_kind": "entity" }, { "ref": { - "ref": "country/NER", - "label": "Niger" + "ref": "country/MWI", + "label": "Malawi" }, "value_kind": "entity" }, { "ref": { - "ref": "country/NPL", - "label": "Nepal" + "ref": "country/NAM", + "label": "Namibia" }, "value_kind": "entity" }, { "ref": { - "ref": "country/RWA", - "label": "Rwanda" + "ref": "country/NER", + "label": "Niger" }, "value_kind": "entity" }, { "ref": { - "ref": "country/SDN", - "label": "Sudan" + "ref": "country/NGA", + "label": "Nigeria" }, "value_kind": "entity" }, { "ref": { - "ref": "country/SEN", - "label": "Senegal" + "ref": "country/RWA", + "label": "Rwanda" }, "value_kind": "entity" }, { "ref": { - "ref": "country/SLB", - "label": "Solomon Islands" + "ref": "country/SEN", + "label": "Senegal" }, "value_kind": "entity" }, @@ -601,29 +630,36 @@ }, { "ref": { - "ref": "country/TCD", - "label": "Chad" + "ref": "country/STP", + "label": "São Tomé and Príncipe" }, "value_kind": "entity" }, { "ref": { - "ref": "country/TGO", - "label": "Togo" + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" }, "value_kind": "entity" }, { "ref": { - "ref": "country/TLS", - "label": "East Timor" + "ref": "country/TCD", + "label": "Chad" }, "value_kind": "entity" }, { "ref": { - "ref": "country/TUV", - "label": "Tuvalu" + "ref": "country/TGO", + "label": "Togo" }, "value_kind": "entity" }, @@ -643,8 +679,8 @@ }, { "ref": { - "ref": "country/YEM", - "label": "Yemen" + "ref": "country/ZAF", + "label": "South Africa" }, "value_kind": "entity" }, @@ -654,6 +690,13 @@ "label": "Zambia" }, "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" } ] }, @@ -687,7 +730,7 @@ ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 41, "member_count_exact": false, "served_count": 1, "data_date_range": { @@ -696,12 +739,6 @@ } }, "entities": [ - { - "ref": "country/AFG", - "label": "Afghanistan", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/AGO", "label": "Angola", @@ -727,8 +764,8 @@ "role": "observationAbout" }, { - "ref": "country/BGD", - "label": "Bangladesh", + "ref": "country/BWA", + "label": "Botswana", "entity_type": "Country", "role": "observationAbout" }, @@ -738,9 +775,27 @@ "entity_type": "Country", "role": "observationAbout" }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, { "ref": "country/COD", - "label": "Congo [DRC]", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", "entity_type": "Country", "role": "observationAbout" }, @@ -750,6 +805,12 @@ "entity_type": "Country", "role": "observationAbout" }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, { "ref": "country/DJI", "label": "Djibouti", @@ -769,44 +830,44 @@ "role": "observationAbout" }, { - "ref": "country/GIN", - "label": "Guinea", + "ref": "country/GAB", + "label": "Gabon", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/GMB", - "label": "Gambia", + "ref": "country/GHA", + "label": "Ghana", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/GNB", - "label": "Guinea-Bissau", + "ref": "country/GIN", + "label": "Guinea", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/HTI", - "label": "Haiti", + "ref": "country/GMB", + "label": "The Gambia", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/KHM", - "label": "Cambodia", + "ref": "country/GNB", + "label": "Guinea-Bissau", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/KIR", - "label": "Kiribati", + "ref": "country/GNQ", + "label": "Equatorial Guinea", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/LAO", - "label": "Laos", + "ref": "country/KEN", + "label": "Kenya", "entity_type": "Country", "role": "observationAbout" }, @@ -834,12 +895,6 @@ "entity_type": "Country", "role": "observationAbout" }, - { - "ref": "country/MMR", - "label": "Myanmar", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/MOZ", "label": "Mozambique", @@ -853,44 +908,44 @@ "role": "observationAbout" }, { - "ref": "country/MWI", - "label": "Malawi", + "ref": "country/MUS", + "label": "Mauritius", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/NER", - "label": "Niger", + "ref": "country/MWI", + "label": "Malawi", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/NPL", - "label": "Nepal", + "ref": "country/NAM", + "label": "Namibia", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/RWA", - "label": "Rwanda", + "ref": "country/NER", + "label": "Niger", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/SDN", - "label": "Sudan", + "ref": "country/NGA", + "label": "Nigeria", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/SEN", - "label": "Senegal", + "ref": "country/RWA", + "label": "Rwanda", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/SLB", - "label": "Solomon Islands", + "ref": "country/SEN", + "label": "Senegal", "entity_type": "Country", "role": "observationAbout" }, @@ -913,26 +968,32 @@ "role": "observationAbout" }, { - "ref": "country/TCD", - "label": "Chad", + "ref": "country/STP", + "label": "São Tomé and Príncipe", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/TGO", - "label": "Togo", + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/TLS", - "label": "East Timor", + "ref": "country/TCD", + "label": "Chad", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/TUV", - "label": "Tuvalu", + "ref": "country/TGO", + "label": "Togo", "entity_type": "Country", "role": "observationAbout" }, @@ -949,8 +1010,8 @@ "role": "observationAbout" }, { - "ref": "country/YEM", - "label": "Yemen", + "ref": "country/ZAF", + "label": "South Africa", "entity_type": "Country", "role": "observationAbout" }, @@ -959,23 +1020,30 @@ "label": "Zambia", "entity_type": "Country", "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" } ], "entity_groups": { "observationAbout": { - "label": "Least Developed Countries", - "group_id": "groups/UN.LDC" + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" } }, "coverage": { "kind": "exact", "has_data": true, - "observation_count": 2474, + "observation_count": 2859, "evidence": "facet_metadata", "dimensions": [ { "label": "countries", - "count": 44 + "count": 48 }, { "label": "observations", @@ -988,9 +1056,9 @@ ] }, "download": { - "rows": 2474, + "rows": 2859, "rows_exact": true, - "series": 44, + "series": 48, "window": { "start_year": 1960, "end_year": 2025 @@ -1015,7 +1083,7 @@ "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" }, "unit": { - "basis": "fallback", + "basis": "bound", "ref": "USDollar", "label": "USDollar", "currency": "USD" @@ -1783,13 +1851,22 @@ }, "value_kind": "enum_value" } + }, + { + "value": { + "ref": { + "ref": "XAF", + "label": "XAF" + }, + "value_kind": "enum_value" + } } ], "truncated": false, "source": "observed" } ], - "rendered_sentence": "GDP in the 44 Least Developed Countries, 1960 to 2025. Current US dollars · World Development Indicators.", + "rendered_sentence": "GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators.", "sentence_plan": [ { "kind": "slot", @@ -1853,7 +1930,7 @@ }, { "kind": "slot", - "text": "the 44 Least Developed Countries", + "text": "the 48 countries in Sub-Saharan Africa", "axis": "where", "segment": "heading", "binding_ref": "where:", @@ -1933,10 +2010,6 @@ ], "trace": { "resolved_entities": [ - { - "ref": "country/AFG", - "label": "Afghanistan" - }, { "ref": "country/AGO", "label": "Angola" @@ -1954,21 +2027,37 @@ "label": "Burkina Faso" }, { - "ref": "country/BGD", - "label": "Bangladesh" + "ref": "country/BWA", + "label": "Botswana" }, { "ref": "country/CAF", "label": "Central African Republic" }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, { "ref": "country/COD", - "label": "Congo [DRC]" + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" }, { "ref": "country/COM", "label": "Comoros" }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, { "ref": "country/DJI", "label": "Djibouti" @@ -1981,33 +2070,33 @@ "ref": "country/ETH", "label": "Ethiopia" }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, { "ref": "country/GIN", "label": "Guinea" }, { "ref": "country/GMB", - "label": "Gambia" + "label": "The Gambia" }, { "ref": "country/GNB", "label": "Guinea-Bissau" }, { - "ref": "country/HTI", - "label": "Haiti" - }, - { - "ref": "country/KHM", - "label": "Cambodia" - }, - { - "ref": "country/KIR", - "label": "Kiribati" + "ref": "country/GNQ", + "label": "Equatorial Guinea" }, { - "ref": "country/LAO", - "label": "Laos" + "ref": "country/KEN", + "label": "Kenya" }, { "ref": "country/LBR", @@ -2025,10 +2114,6 @@ "ref": "country/MLI", "label": "Mali" }, - { - "ref": "country/MMR", - "label": "Myanmar" - }, { "ref": "country/MOZ", "label": "Mozambique" @@ -2037,34 +2122,34 @@ "ref": "country/MRT", "label": "Mauritania" }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, { "ref": "country/MWI", "label": "Malawi" }, + { + "ref": "country/NAM", + "label": "Namibia" + }, { "ref": "country/NER", "label": "Niger" }, { - "ref": "country/NPL", - "label": "Nepal" + "ref": "country/NGA", + "label": "Nigeria" }, { "ref": "country/RWA", "label": "Rwanda" }, - { - "ref": "country/SDN", - "label": "Sudan" - }, { "ref": "country/SEN", "label": "Senegal" }, - { - "ref": "country/SLB", - "label": "Solomon Islands" - }, { "ref": "country/SLE", "label": "Sierra Leone" @@ -2078,20 +2163,24 @@ "label": "South Sudan" }, { - "ref": "country/TCD", - "label": "Chad" + "ref": "country/STP", + "label": "São Tomé and Príncipe" }, { - "ref": "country/TGO", - "label": "Togo" + "ref": "country/SWZ", + "label": "Swaziland" }, { - "ref": "country/TLS", - "label": "East Timor" + "ref": "country/SYC", + "label": "Seychelles" }, { - "ref": "country/TUV", - "label": "Tuvalu" + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" }, { "ref": "country/TZA", @@ -2102,12 +2191,16 @@ "label": "Uganda" }, { - "ref": "country/YEM", - "label": "Yemen" + "ref": "country/ZAF", + "label": "South Africa" }, { "ref": "country/ZMB", "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" } ], "resolved_sources": [ @@ -2190,10 +2283,6 @@ }, "binding_kind": "set", "refs": [ - { - "ref": "country/AFG", - "label": "Afghanistan" - }, { "ref": "country/AGO", "label": "Angola" @@ -2211,21 +2300,37 @@ "label": "Burkina Faso" }, { - "ref": "country/BGD", - "label": "Bangladesh" + "ref": "country/BWA", + "label": "Botswana" }, { "ref": "country/CAF", "label": "Central African Republic" }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, { "ref": "country/COD", - "label": "Congo [DRC]" + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" }, { "ref": "country/COM", "label": "Comoros" }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, { "ref": "country/DJI", "label": "Djibouti" @@ -2238,33 +2343,33 @@ "ref": "country/ETH", "label": "Ethiopia" }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, { "ref": "country/GIN", "label": "Guinea" }, { "ref": "country/GMB", - "label": "Gambia" + "label": "The Gambia" }, { "ref": "country/GNB", "label": "Guinea-Bissau" }, { - "ref": "country/HTI", - "label": "Haiti" + "ref": "country/GNQ", + "label": "Equatorial Guinea" }, { - "ref": "country/KHM", - "label": "Cambodia" - }, - { - "ref": "country/KIR", - "label": "Kiribati" - }, - { - "ref": "country/LAO", - "label": "Laos" + "ref": "country/KEN", + "label": "Kenya" }, { "ref": "country/LBR", @@ -2282,10 +2387,6 @@ "ref": "country/MLI", "label": "Mali" }, - { - "ref": "country/MMR", - "label": "Myanmar" - }, { "ref": "country/MOZ", "label": "Mozambique" @@ -2294,34 +2395,34 @@ "ref": "country/MRT", "label": "Mauritania" }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, { "ref": "country/MWI", "label": "Malawi" }, + { + "ref": "country/NAM", + "label": "Namibia" + }, { "ref": "country/NER", "label": "Niger" }, { - "ref": "country/NPL", - "label": "Nepal" + "ref": "country/NGA", + "label": "Nigeria" }, { "ref": "country/RWA", "label": "Rwanda" }, - { - "ref": "country/SDN", - "label": "Sudan" - }, { "ref": "country/SEN", "label": "Senegal" }, - { - "ref": "country/SLB", - "label": "Solomon Islands" - }, { "ref": "country/SLE", "label": "Sierra Leone" @@ -2335,20 +2436,24 @@ "label": "South Sudan" }, { - "ref": "country/TCD", - "label": "Chad" + "ref": "country/STP", + "label": "São Tomé and Príncipe" }, { - "ref": "country/TGO", - "label": "Togo" + "ref": "country/SWZ", + "label": "Swaziland" }, { - "ref": "country/TLS", - "label": "East Timor" + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" }, { - "ref": "country/TUV", - "label": "Tuvalu" + "ref": "country/TGO", + "label": "Togo" }, { "ref": "country/TZA", @@ -2359,12 +2464,16 @@ "label": "Uganda" }, { - "ref": "country/YEM", - "label": "Yemen" + "ref": "country/ZAF", + "label": "South Africa" }, { "ref": "country/ZMB", "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" } ], "provenance": "binder" @@ -2392,17 +2501,47 @@ "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, - "removed_stat_vars": [] + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAccommodationFoodServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSFinanceInsurance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSMiningQuarryingOilGasExtraction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSProfessionalScientificTechnicalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSWholesaleTrade_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826", + "dc/zz6gwv838v9w" + ] } }, "confidence": "high", "available_at_place": true, "equivalent_readings": [ { - "spec_id": "spec_9aed4e1ac845b3e88f8f4200131b78d4", + "spec_id": "spec_22cfb22f6e4a1cff1584eaf03285ce73", "definition": { "schema_version": 1, - "spec_id": "spec_9aed4e1ac845b3e88f8f4200131b78d4", + "spec_id": "spec_22cfb22f6e4a1cff1584eaf03285ce73", "identity": { "identity_version": "spec1", "shape": { @@ -2436,50 +2575,54 @@ ], "entities": { "observationAbout": [ - "country/AFG", "country/AGO", "country/BDI", "country/BEN", "country/BFA", - "country/BGD", + "country/BWA", "country/CAF", + "country/CIV", + "country/CMR", "country/COD", + "country/COG", "country/COM", + "country/CPV", "country/DJI", "country/ERI", "country/ETH", + "country/GAB", + "country/GHA", "country/GIN", "country/GMB", "country/GNB", - "country/HTI", - "country/KHM", - "country/KIR", - "country/LAO", + "country/GNQ", + "country/KEN", "country/LBR", "country/LSO", "country/MDG", "country/MLI", - "country/MMR", "country/MOZ", "country/MRT", + "country/MUS", "country/MWI", + "country/NAM", "country/NER", - "country/NPL", + "country/NGA", "country/RWA", - "country/SDN", "country/SEN", - "country/SLB", "country/SLE", "country/SOM", "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", "country/TCD", "country/TGO", - "country/TLS", - "country/TUV", "country/TZA", "country/UGA", - "country/YEM", - "country/ZMB" + "country/ZAF", + "country/ZMB", + "country/ZWE" ] }, "requested_window": { @@ -2629,15 +2772,8 @@ "values": [ { "ref": { - "ref": "country/AFG", - "label": "Afghanistan" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/AGO", - "label": "Angola" + "ref": "country/AGO", + "label": "Angola" }, "value_kind": "entity" }, @@ -2664,8 +2800,8 @@ }, { "ref": { - "ref": "country/BGD", - "label": "Bangladesh" + "ref": "country/BWA", + "label": "Botswana" }, "value_kind": "entity" }, @@ -2676,10 +2812,31 @@ }, "value_kind": "entity" }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, { "ref": { "ref": "country/COD", - "label": "Congo [DRC]" + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" }, "value_kind": "entity" }, @@ -2690,6 +2847,13 @@ }, "value_kind": "entity" }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, { "ref": { "ref": "country/DJI", @@ -2713,50 +2877,50 @@ }, { "ref": { - "ref": "country/GIN", - "label": "Guinea" + "ref": "country/GAB", + "label": "Gabon" }, "value_kind": "entity" }, { "ref": { - "ref": "country/GMB", - "label": "Gambia" + "ref": "country/GHA", + "label": "Ghana" }, "value_kind": "entity" }, { "ref": { - "ref": "country/GNB", - "label": "Guinea-Bissau" + "ref": "country/GIN", + "label": "Guinea" }, "value_kind": "entity" }, { "ref": { - "ref": "country/HTI", - "label": "Haiti" + "ref": "country/GMB", + "label": "The Gambia" }, "value_kind": "entity" }, { "ref": { - "ref": "country/KHM", - "label": "Cambodia" + "ref": "country/GNB", + "label": "Guinea-Bissau" }, "value_kind": "entity" }, { "ref": { - "ref": "country/KIR", - "label": "Kiribati" + "ref": "country/GNQ", + "label": "Equatorial Guinea" }, "value_kind": "entity" }, { "ref": { - "ref": "country/LAO", - "label": "Laos" + "ref": "country/KEN", + "label": "Kenya" }, "value_kind": "entity" }, @@ -2788,13 +2952,6 @@ }, "value_kind": "entity" }, - { - "ref": { - "ref": "country/MMR", - "label": "Myanmar" - }, - "value_kind": "entity" - }, { "ref": { "ref": "country/MOZ", @@ -2811,50 +2968,50 @@ }, { "ref": { - "ref": "country/MWI", - "label": "Malawi" + "ref": "country/MUS", + "label": "Mauritius" }, "value_kind": "entity" }, { "ref": { - "ref": "country/NER", - "label": "Niger" + "ref": "country/MWI", + "label": "Malawi" }, "value_kind": "entity" }, { "ref": { - "ref": "country/NPL", - "label": "Nepal" + "ref": "country/NAM", + "label": "Namibia" }, "value_kind": "entity" }, { "ref": { - "ref": "country/RWA", - "label": "Rwanda" + "ref": "country/NER", + "label": "Niger" }, "value_kind": "entity" }, { "ref": { - "ref": "country/SDN", - "label": "Sudan" + "ref": "country/NGA", + "label": "Nigeria" }, "value_kind": "entity" }, { "ref": { - "ref": "country/SEN", - "label": "Senegal" + "ref": "country/RWA", + "label": "Rwanda" }, "value_kind": "entity" }, { "ref": { - "ref": "country/SLB", - "label": "Solomon Islands" + "ref": "country/SEN", + "label": "Senegal" }, "value_kind": "entity" }, @@ -2881,29 +3038,36 @@ }, { "ref": { - "ref": "country/TCD", - "label": "Chad" + "ref": "country/STP", + "label": "São Tomé and Príncipe" }, "value_kind": "entity" }, { "ref": { - "ref": "country/TGO", - "label": "Togo" + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" }, "value_kind": "entity" }, { "ref": { - "ref": "country/TLS", - "label": "East Timor" + "ref": "country/TCD", + "label": "Chad" }, "value_kind": "entity" }, { "ref": { - "ref": "country/TUV", - "label": "Tuvalu" + "ref": "country/TGO", + "label": "Togo" }, "value_kind": "entity" }, @@ -2923,8 +3087,8 @@ }, { "ref": { - "ref": "country/YEM", - "label": "Yemen" + "ref": "country/ZAF", + "label": "South Africa" }, "value_kind": "entity" }, @@ -2934,6 +3098,13 @@ "label": "Zambia" }, "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" } ] }, @@ -2974,12 +3145,6 @@ } }, "entities": [ - { - "ref": "country/AFG", - "label": "Afghanistan", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/AGO", "label": "Angola", @@ -3005,8 +3170,8 @@ "role": "observationAbout" }, { - "ref": "country/BGD", - "label": "Bangladesh", + "ref": "country/BWA", + "label": "Botswana", "entity_type": "Country", "role": "observationAbout" }, @@ -3016,9 +3181,27 @@ "entity_type": "Country", "role": "observationAbout" }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, { "ref": "country/COD", - "label": "Congo [DRC]", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", "entity_type": "Country", "role": "observationAbout" }, @@ -3028,6 +3211,12 @@ "entity_type": "Country", "role": "observationAbout" }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, { "ref": "country/DJI", "label": "Djibouti", @@ -3047,44 +3236,44 @@ "role": "observationAbout" }, { - "ref": "country/GIN", - "label": "Guinea", + "ref": "country/GAB", + "label": "Gabon", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/GMB", - "label": "Gambia", + "ref": "country/GHA", + "label": "Ghana", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/GNB", - "label": "Guinea-Bissau", + "ref": "country/GIN", + "label": "Guinea", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/HTI", - "label": "Haiti", + "ref": "country/GMB", + "label": "The Gambia", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/KHM", - "label": "Cambodia", + "ref": "country/GNB", + "label": "Guinea-Bissau", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/KIR", - "label": "Kiribati", + "ref": "country/GNQ", + "label": "Equatorial Guinea", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/LAO", - "label": "Laos", + "ref": "country/KEN", + "label": "Kenya", "entity_type": "Country", "role": "observationAbout" }, @@ -3112,12 +3301,6 @@ "entity_type": "Country", "role": "observationAbout" }, - { - "ref": "country/MMR", - "label": "Myanmar", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/MOZ", "label": "Mozambique", @@ -3131,44 +3314,44 @@ "role": "observationAbout" }, { - "ref": "country/MWI", - "label": "Malawi", + "ref": "country/MUS", + "label": "Mauritius", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/NER", - "label": "Niger", + "ref": "country/MWI", + "label": "Malawi", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/NPL", - "label": "Nepal", + "ref": "country/NAM", + "label": "Namibia", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/RWA", - "label": "Rwanda", + "ref": "country/NER", + "label": "Niger", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/SDN", - "label": "Sudan", + "ref": "country/NGA", + "label": "Nigeria", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/SEN", - "label": "Senegal", + "ref": "country/RWA", + "label": "Rwanda", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/SLB", - "label": "Solomon Islands", + "ref": "country/SEN", + "label": "Senegal", "entity_type": "Country", "role": "observationAbout" }, @@ -3191,26 +3374,32 @@ "role": "observationAbout" }, { - "ref": "country/TCD", - "label": "Chad", + "ref": "country/STP", + "label": "São Tomé and Príncipe", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/TGO", - "label": "Togo", + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/TLS", - "label": "East Timor", + "ref": "country/TCD", + "label": "Chad", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/TUV", - "label": "Tuvalu", + "ref": "country/TGO", + "label": "Togo", "entity_type": "Country", "role": "observationAbout" }, @@ -3227,8 +3416,8 @@ "role": "observationAbout" }, { - "ref": "country/YEM", - "label": "Yemen", + "ref": "country/ZAF", + "label": "South Africa", "entity_type": "Country", "role": "observationAbout" }, @@ -3237,23 +3426,30 @@ "label": "Zambia", "entity_type": "Country", "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" } ], "entity_groups": { "observationAbout": { - "label": "Least Developed Countries", - "group_id": "groups/UN.LDC" + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" } }, "coverage": { "kind": "exact", "has_data": true, - "observation_count": 1746, + "observation_count": 2031, "evidence": "facet_metadata", "dimensions": [ { "label": "countries", - "count": 44 + "count": 48 }, { "label": "observations", @@ -3266,9 +3462,9 @@ ] }, "download": { - "rows": 1746, + "rows": 2031, "rows_exact": true, - "series": 44, + "series": 48, "window": { "start_year": 1980, "end_year": 2025 @@ -3374,10 +3570,6 @@ "facet_options": [], "trace": { "resolved_entities": [ - { - "ref": "country/AFG", - "label": "Afghanistan" - }, { "ref": "country/AGO", "label": "Angola" @@ -3395,21 +3587,37 @@ "label": "Burkina Faso" }, { - "ref": "country/BGD", - "label": "Bangladesh" + "ref": "country/BWA", + "label": "Botswana" }, { "ref": "country/CAF", "label": "Central African Republic" }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, { "ref": "country/COD", - "label": "Congo [DRC]" + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" }, { "ref": "country/COM", "label": "Comoros" }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, { "ref": "country/DJI", "label": "Djibouti" @@ -3422,33 +3630,33 @@ "ref": "country/ETH", "label": "Ethiopia" }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, { "ref": "country/GIN", "label": "Guinea" }, { "ref": "country/GMB", - "label": "Gambia" + "label": "The Gambia" }, { "ref": "country/GNB", "label": "Guinea-Bissau" }, { - "ref": "country/HTI", - "label": "Haiti" - }, - { - "ref": "country/KHM", - "label": "Cambodia" + "ref": "country/GNQ", + "label": "Equatorial Guinea" }, { - "ref": "country/KIR", - "label": "Kiribati" - }, - { - "ref": "country/LAO", - "label": "Laos" + "ref": "country/KEN", + "label": "Kenya" }, { "ref": "country/LBR", @@ -3466,10 +3674,6 @@ "ref": "country/MLI", "label": "Mali" }, - { - "ref": "country/MMR", - "label": "Myanmar" - }, { "ref": "country/MOZ", "label": "Mozambique" @@ -3478,34 +3682,34 @@ "ref": "country/MRT", "label": "Mauritania" }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, { "ref": "country/MWI", "label": "Malawi" }, + { + "ref": "country/NAM", + "label": "Namibia" + }, { "ref": "country/NER", "label": "Niger" }, { - "ref": "country/NPL", - "label": "Nepal" + "ref": "country/NGA", + "label": "Nigeria" }, { "ref": "country/RWA", "label": "Rwanda" }, - { - "ref": "country/SDN", - "label": "Sudan" - }, { "ref": "country/SEN", "label": "Senegal" }, - { - "ref": "country/SLB", - "label": "Solomon Islands" - }, { "ref": "country/SLE", "label": "Sierra Leone" @@ -3519,20 +3723,24 @@ "label": "South Sudan" }, { - "ref": "country/TCD", - "label": "Chad" + "ref": "country/STP", + "label": "São Tomé and Príncipe" }, { - "ref": "country/TGO", - "label": "Togo" + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" }, { - "ref": "country/TLS", - "label": "East Timor" + "ref": "country/TCD", + "label": "Chad" }, { - "ref": "country/TUV", - "label": "Tuvalu" + "ref": "country/TGO", + "label": "Togo" }, { "ref": "country/TZA", @@ -3543,12 +3751,16 @@ "label": "Uganda" }, { - "ref": "country/YEM", - "label": "Yemen" + "ref": "country/ZAF", + "label": "South Africa" }, { "ref": "country/ZMB", "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" } ], "resolved_sources": [ @@ -3623,10 +3835,6 @@ }, "binding_kind": "set", "refs": [ - { - "ref": "country/AFG", - "label": "Afghanistan" - }, { "ref": "country/AGO", "label": "Angola" @@ -3644,21 +3852,37 @@ "label": "Burkina Faso" }, { - "ref": "country/BGD", - "label": "Bangladesh" + "ref": "country/BWA", + "label": "Botswana" }, { "ref": "country/CAF", "label": "Central African Republic" }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, { "ref": "country/COD", - "label": "Congo [DRC]" + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" }, { "ref": "country/COM", "label": "Comoros" }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, { "ref": "country/DJI", "label": "Djibouti" @@ -3671,33 +3895,33 @@ "ref": "country/ETH", "label": "Ethiopia" }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, { "ref": "country/GIN", "label": "Guinea" }, { "ref": "country/GMB", - "label": "Gambia" + "label": "The Gambia" }, { "ref": "country/GNB", "label": "Guinea-Bissau" }, { - "ref": "country/HTI", - "label": "Haiti" + "ref": "country/GNQ", + "label": "Equatorial Guinea" }, { - "ref": "country/KHM", - "label": "Cambodia" - }, - { - "ref": "country/KIR", - "label": "Kiribati" - }, - { - "ref": "country/LAO", - "label": "Laos" + "ref": "country/KEN", + "label": "Kenya" }, { "ref": "country/LBR", @@ -3715,10 +3939,6 @@ "ref": "country/MLI", "label": "Mali" }, - { - "ref": "country/MMR", - "label": "Myanmar" - }, { "ref": "country/MOZ", "label": "Mozambique" @@ -3727,34 +3947,34 @@ "ref": "country/MRT", "label": "Mauritania" }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, { "ref": "country/MWI", "label": "Malawi" }, + { + "ref": "country/NAM", + "label": "Namibia" + }, { "ref": "country/NER", "label": "Niger" }, { - "ref": "country/NPL", - "label": "Nepal" + "ref": "country/NGA", + "label": "Nigeria" }, { "ref": "country/RWA", "label": "Rwanda" }, - { - "ref": "country/SDN", - "label": "Sudan" - }, { "ref": "country/SEN", "label": "Senegal" }, - { - "ref": "country/SLB", - "label": "Solomon Islands" - }, { "ref": "country/SLE", "label": "Sierra Leone" @@ -3768,20 +3988,24 @@ "label": "South Sudan" }, { - "ref": "country/TCD", - "label": "Chad" + "ref": "country/STP", + "label": "São Tomé and Príncipe" }, { - "ref": "country/TGO", - "label": "Togo" + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" }, { - "ref": "country/TLS", - "label": "East Timor" + "ref": "country/TCD", + "label": "Chad" }, { - "ref": "country/TUV", - "label": "Tuvalu" + "ref": "country/TGO", + "label": "Togo" }, { "ref": "country/TZA", @@ -3792,12 +4016,16 @@ "label": "Uganda" }, { - "ref": "country/YEM", - "label": "Yemen" + "ref": "country/ZAF", + "label": "South Africa" }, { "ref": "country/ZMB", "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" } ], "provenance": "binder" @@ -3825,7 +4053,37 @@ "capability_version": "cap_347a470e04c97eec", "default_reading": { "applied": true, - "removed_stat_vars": [] + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAccommodationFoodServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSFinanceInsurance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSMiningQuarryingOilGasExtraction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSProfessionalScientificTechnicalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSWholesaleTrade_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826", + "dc/zz6gwv838v9w" + ] } }, "confidence": "high", @@ -3849,7 +4107,7 @@ }, "definition": { "schema_version": 1, - "spec_id": "spec_d5b1250baf281e73b0c3f5599bb955d8", + "spec_id": "spec_df3e3c939162b3cfe113d2d78d4b4986", "identity": { "identity_version": "spec1", "shape": { @@ -3869,50 +4127,54 @@ ], "entities": { "observationAbout": [ - "country/AFG", "country/AGO", "country/BDI", "country/BEN", "country/BFA", - "country/BGD", + "country/BWA", "country/CAF", + "country/CIV", + "country/CMR", "country/COD", + "country/COG", "country/COM", + "country/CPV", "country/DJI", "country/ERI", "country/ETH", + "country/GAB", + "country/GHA", "country/GIN", "country/GMB", "country/GNB", - "country/HTI", - "country/KHM", - "country/KIR", - "country/LAO", + "country/GNQ", + "country/KEN", "country/LBR", "country/LSO", "country/MDG", "country/MLI", - "country/MMR", "country/MOZ", "country/MRT", + "country/MUS", "country/MWI", + "country/NAM", "country/NER", - "country/NPL", + "country/NGA", "country/RWA", - "country/SDN", "country/SEN", - "country/SLB", "country/SLE", "country/SOM", "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", "country/TCD", "country/TGO", - "country/TLS", - "country/TUV", "country/TZA", "country/UGA", - "country/YEM", - "country/ZMB" + "country/ZAF", + "country/ZMB", + "country/ZWE" ] }, "requested_window": { @@ -3926,116 +4188,74 @@ } }, { - "variable_text": "ODA disbursements", - "warnings": [], + "variable_text": "debt", + "warnings": [ + { + "code": "retrieval_score_weak", + "severity": "info", + "message": "the chosen reading's match to the query is weak; treat it with less confidence than a strong match." + } + ], "timing_ms": { - "total": 2, + "total": 2694, "by_step": { - "recall": 2 + "recall": 1, + "shape_arcs": 1, + "shape_probe_coverage": 4, + "shape_probe": 287, + "shape_groups": 2, + "shape_labels": 0, + "shape_admission": 0, + "shape": 1117, + "bind": 1576 } }, - "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "rendered_sentence": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", "sentence_plan": [ { "kind": "text", - "text": "\"", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "Congo", - "axis": "where", - "segment": "heading", - "role": "destination", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "text": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", "segment": "heading", "entity_refs": [], "states": [] } ], - "restatement": { - "variable_text": "ODA disbursements", - "entities": [ - { - "text": "Kenya", - "role_text": "to" - }, - { - "text": "Germany", - "role_text": "from" - }, - { - "text": "Congo", - "role_text": "to" - } - ], - "sources": [], - "operations": [] - }, "operations": [], "departures": [], "assumptions": [], "status": "no_data", "no_data": { - "reason": "entity_ambiguous", + "reason": "role_not_resolved", "category": "unresolved", - "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "message": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", "entity_terms": [ - "Congo" - ], - "ambiguous_entities": [ - { - "text": "Congo", - "candidates": [ - { - "ref": "country/COD", - "label": "Congo [DRC]", - "kind": "country" - }, - { - "ref": "country/COG", - "label": "Congo [Republic]", - "kind": "country" - } - ] - } + "sub-Saharan Africa", + "Kenya" ], + "ambiguous_entities": [], "source_terms": [], "ambiguous_sources": [], "unbound_qualifiers": [], "options": [ { "mentions": [ - "Congo" + "sub-Saharan Africa", + "Kenya" ], - "label": "Congo [DRC]", + "label": "sub-Saharan Africa to Kenya", "data_query": { "kind": "parsed", "parts": [ { - "variable_text": "ODA disbursements", + "variable_text": "debt", "entities": [ { - "text": "Kenya", - "role_text": "to", - "dcid": "country/KEN" - }, - { - "text": "Germany", - "role_text": "from", - "dcid": "country/DEU" + "text": "Sub-Saharan Africa", + "role_text": "from" }, { - "text": "Congo", - "role_text": "to", - "dcid": "country/COD" + "text": "Kenya", + "role_text": "to" } ], "sources": [], @@ -4046,29 +4266,23 @@ }, { "mentions": [ - "Congo" + "sub-Saharan Africa", + "Kenya" ], - "label": "Congo [Republic]", + "label": "Kenya to sub-Saharan Africa", "data_query": { "kind": "parsed", "parts": [ { - "variable_text": "ODA disbursements", + "variable_text": "debt", "entities": [ { - "text": "Kenya", - "role_text": "to", - "dcid": "country/KEN" - }, - { - "text": "Germany", - "role_text": "from", - "dcid": "country/DEU" + "text": "Sub-Saharan Africa", + "role_text": "to" }, { - "text": "Congo", - "role_text": "to", - "dcid": "country/COG" + "text": "Kenya", + "role_text": "from" } ], "sources": [], @@ -4081,30 +4295,206 @@ } } ], - "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "rendered_sentence": "Answered 1 of 2 parts. GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators. You asked for sub-Saharan Africa. This shows the countries in it, each on its own. Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", "sentence_plan": [ { "kind": "text", - "text": "\"", - "segment": "heading", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "Congo", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", "axis": "where", "segment": "heading", - "role": "destination", + "binding_ref": "where:", "entity_refs": [], - "states": [] + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "You asked for sub-Saharan Africa. This shows the countries in it, each on its own.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 }, { "kind": "text", - "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] + }, + { + "kind": "text", + "text": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 } ], "status": "mixed" @@ -4160,60 +4550,71 @@ ], "entities": { "observationAbout": [ - "country/AFG", "country/AGO", "country/BDI", "country/BEN", "country/BFA", - "country/BGD", + "country/BWA", "country/CAF", + "country/CIV", + "country/CMR", "country/COD", + "country/COG", "country/COM", + "country/CPV", "country/DJI", "country/ERI", "country/ETH", + "country/GAB", + "country/GHA", "country/GIN", "country/GMB", "country/GNB", - "country/HTI", - "country/KHM", - "country/KIR", - "country/LAO", + "country/GNQ", + "country/KEN", "country/LBR", "country/LSO", "country/MDG", "country/MLI", - "country/MMR", "country/MOZ", "country/MRT", + "country/MUS", "country/MWI", + "country/NAM", "country/NER", - "country/NPL", + "country/NGA", "country/RWA", - "country/SDN", "country/SEN", - "country/SLB", "country/SLE", "country/SOM", "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", "country/TCD", "country/TGO", - "country/TLS", - "country/TUV", "country/TZA", "country/UGA", - "country/YEM", - "country/ZMB" + "country/ZAF", + "country/ZMB", + "country/ZWE" ] }, "requested_window": { "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "USDollar" + } } }, "entity_groups": { "observationAbout": { - "label": "Least Developed Countries", - "group_id": "groups/UN.LDC" + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" } }, "assumptions": [], @@ -4222,22 +4623,15 @@ { "entry_kind": "parsed", "part": { - "variable_text": "ODA disbursements", + "variable_text": "debt", "entities": [ { - "text": "Kenya", - "role_text": "to", - "dcid": "country/KEN" - }, - { - "text": "Germany", - "role_text": "from", - "dcid": "country/DEU" + "text": "Sub-Saharan Africa", + "role_text": "from" }, { - "text": "Congo", - "role_text": "to", - "dcid": "country/COD" + "text": "Kenya", + "role_text": "to" } ], "sources": [], @@ -4261,18 +4655,18 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "6181bee2a8f84811bec4231e3fae4535", + "trace_id": "6bb21f75d7374cb1882111e02c35a590", "warnings": [], "timing_ms": { - "total": 3738, + "total": 2350, "by_step": { "coverage": 0 } }, "llm_usage": { - "input_tokens": 4244, - "output_tokens": 202, - "cached_tokens": 1518 + "input_tokens": 4539, + "output_tokens": 503, + "cached_tokens": 1544 }, "timed_out": false }, @@ -4282,19 +4676,19 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 3733, + "total": 1426, "by_step": { "validate": 0, "walk": 0, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 593, + "shape": 952, "bind": 0, "where_places": 0, - "materialise": 203, + "materialise": 213, "answer": 1, - "options": 2936 + "options": 260 } }, "operations": [], @@ -4302,16 +4696,16 @@ { "code": "group_read_as_members", "binding_ref": "where:", - "text": "This shows the 44 Least Developed Countries, each on its own." + "text": "This shows the 48 countries in Sub-Saharan Africa, each on its own." } ], "assumptions": [], "status": "definite", "spec": { - "spec_id": "spec_e11cdfec28d9fac6551cfaa892be9558", + "spec_id": "spec_3c3d4e571162850b30db0321638f955b", "definition": { "schema_version": 1, - "spec_id": "spec_e11cdfec28d9fac6551cfaa892be9558", + "spec_id": "spec_3c3d4e571162850b30db0321638f955b", "identity": { "identity_version": "spec1", "shape": { @@ -4350,54 +4744,64 @@ ], "entities": { "observationAbout": [ - "country/AFG", "country/AGO", "country/BDI", "country/BEN", "country/BFA", - "country/BGD", + "country/BWA", "country/CAF", + "country/CIV", + "country/CMR", "country/COD", + "country/COG", "country/COM", + "country/CPV", "country/DJI", "country/ERI", "country/ETH", + "country/GAB", + "country/GHA", "country/GIN", "country/GMB", "country/GNB", - "country/HTI", - "country/KHM", - "country/KIR", - "country/LAO", + "country/GNQ", + "country/KEN", "country/LBR", "country/LSO", "country/MDG", "country/MLI", - "country/MMR", "country/MOZ", "country/MRT", + "country/MUS", "country/MWI", + "country/NAM", "country/NER", - "country/NPL", + "country/NGA", "country/RWA", - "country/SDN", "country/SEN", - "country/SLB", "country/SLE", "country/SOM", "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", "country/TCD", "country/TGO", - "country/TLS", - "country/TUV", "country/TZA", "country/UGA", - "country/YEM", - "country/ZMB" + "country/ZAF", + "country/ZMB", + "country/ZWE" ] }, "requested_window": { "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "USDollar" + } } } }, @@ -4550,13 +4954,6 @@ "binding": { "kind": "set", "values": [ - { - "ref": { - "ref": "country/AFG", - "label": "Afghanistan" - }, - "value_kind": "entity" - }, { "ref": { "ref": "country/AGO", @@ -4587,8 +4984,8 @@ }, { "ref": { - "ref": "country/BGD", - "label": "Bangladesh" + "ref": "country/BWA", + "label": "Botswana" }, "value_kind": "entity" }, @@ -4599,6 +4996,20 @@ }, "value_kind": "entity" }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, { "ref": { "ref": "country/COD", @@ -4606,6 +5017,13 @@ }, "value_kind": "entity" }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, { "ref": { "ref": "country/COM", @@ -4613,6 +5031,13 @@ }, "value_kind": "entity" }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, { "ref": { "ref": "country/DJI", @@ -4636,50 +5061,50 @@ }, { "ref": { - "ref": "country/GIN", - "label": "Guinea" + "ref": "country/GAB", + "label": "Gabon" }, "value_kind": "entity" }, { "ref": { - "ref": "country/GMB", - "label": "The Gambia" + "ref": "country/GHA", + "label": "Ghana" }, "value_kind": "entity" }, { "ref": { - "ref": "country/GNB", - "label": "Guinea-Bissau" + "ref": "country/GIN", + "label": "Guinea" }, "value_kind": "entity" }, { "ref": { - "ref": "country/HTI", - "label": "Haiti" + "ref": "country/GMB", + "label": "The Gambia" }, "value_kind": "entity" }, { "ref": { - "ref": "country/KHM", - "label": "Cambodia" + "ref": "country/GNB", + "label": "Guinea-Bissau" }, "value_kind": "entity" }, { "ref": { - "ref": "country/KIR", - "label": "Kiribati" + "ref": "country/GNQ", + "label": "Equatorial Guinea" }, "value_kind": "entity" }, { "ref": { - "ref": "country/LAO", - "label": "Laos" + "ref": "country/KEN", + "label": "Kenya" }, "value_kind": "entity" }, @@ -4711,13 +5136,6 @@ }, "value_kind": "entity" }, - { - "ref": { - "ref": "country/MMR", - "label": "Myanmar [Burma]" - }, - "value_kind": "entity" - }, { "ref": { "ref": "country/MOZ", @@ -4734,50 +5152,50 @@ }, { "ref": { - "ref": "country/MWI", - "label": "Malawi" + "ref": "country/MUS", + "label": "Mauritius" }, "value_kind": "entity" }, { "ref": { - "ref": "country/NER", - "label": "Niger" + "ref": "country/MWI", + "label": "Malawi" }, "value_kind": "entity" }, { "ref": { - "ref": "country/NPL", - "label": "Nepal" + "ref": "country/NAM", + "label": "Namibia" }, "value_kind": "entity" }, { "ref": { - "ref": "country/RWA", - "label": "Rwanda" + "ref": "country/NER", + "label": "Niger" }, "value_kind": "entity" }, { "ref": { - "ref": "country/SDN", - "label": "Sudan" + "ref": "country/NGA", + "label": "Nigeria" }, "value_kind": "entity" }, { "ref": { - "ref": "country/SEN", - "label": "Senegal" + "ref": "country/RWA", + "label": "Rwanda" }, "value_kind": "entity" }, { "ref": { - "ref": "country/SLB", - "label": "Solomon Islands" + "ref": "country/SEN", + "label": "Senegal" }, "value_kind": "entity" }, @@ -4804,29 +5222,36 @@ }, { "ref": { - "ref": "country/TCD", - "label": "Chad" + "ref": "country/STP", + "label": "São Tomé and Príncipe" }, "value_kind": "entity" }, { "ref": { - "ref": "country/TGO", - "label": "Togo" + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" }, "value_kind": "entity" }, { "ref": { - "ref": "country/TLS", - "label": "Timor-Leste" + "ref": "country/TCD", + "label": "Chad" }, "value_kind": "entity" }, { "ref": { - "ref": "country/TUV", - "label": "Tuvalu" + "ref": "country/TGO", + "label": "Togo" }, "value_kind": "entity" }, @@ -4846,8 +5271,8 @@ }, { "ref": { - "ref": "country/YEM", - "label": "Yemen" + "ref": "country/ZAF", + "label": "South Africa" }, "value_kind": "entity" }, @@ -4857,6 +5282,13 @@ "label": "Zambia" }, "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" } ] }, @@ -4890,7 +5322,7 @@ ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 41, "member_count_exact": true, "served_count": 1, "data_date_range": { @@ -4899,12 +5331,6 @@ } }, "entities": [ - { - "ref": "country/AFG", - "label": "Afghanistan", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/AGO", "label": "Angola", @@ -4930,8 +5356,8 @@ "role": "observationAbout" }, { - "ref": "country/BGD", - "label": "Bangladesh", + "ref": "country/BWA", + "label": "Botswana", "entity_type": "Country", "role": "observationAbout" }, @@ -4941,18 +5367,42 @@ "entity_type": "Country", "role": "observationAbout" }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, { "ref": "country/COD", "label": "Democratic Republic of the Congo", "entity_type": "Country", "role": "observationAbout" }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, { "ref": "country/COM", "label": "Comoros", "entity_type": "Country", "role": "observationAbout" }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, { "ref": "country/DJI", "label": "Djibouti", @@ -4972,44 +5422,44 @@ "role": "observationAbout" }, { - "ref": "country/GIN", - "label": "Guinea", + "ref": "country/GAB", + "label": "Gabon", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/GMB", - "label": "The Gambia", + "ref": "country/GHA", + "label": "Ghana", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/GNB", - "label": "Guinea-Bissau", + "ref": "country/GIN", + "label": "Guinea", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/HTI", - "label": "Haiti", + "ref": "country/GMB", + "label": "The Gambia", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/KHM", - "label": "Cambodia", + "ref": "country/GNB", + "label": "Guinea-Bissau", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/KIR", - "label": "Kiribati", + "ref": "country/GNQ", + "label": "Equatorial Guinea", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/LAO", - "label": "Laos", + "ref": "country/KEN", + "label": "Kenya", "entity_type": "Country", "role": "observationAbout" }, @@ -5037,12 +5487,6 @@ "entity_type": "Country", "role": "observationAbout" }, - { - "ref": "country/MMR", - "label": "Myanmar [Burma]", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/MOZ", "label": "Mozambique", @@ -5056,44 +5500,44 @@ "role": "observationAbout" }, { - "ref": "country/MWI", - "label": "Malawi", + "ref": "country/MUS", + "label": "Mauritius", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/NER", - "label": "Niger", + "ref": "country/MWI", + "label": "Malawi", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/NPL", - "label": "Nepal", + "ref": "country/NAM", + "label": "Namibia", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/RWA", - "label": "Rwanda", + "ref": "country/NER", + "label": "Niger", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/SDN", - "label": "Sudan", + "ref": "country/NGA", + "label": "Nigeria", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/SEN", - "label": "Senegal", + "ref": "country/RWA", + "label": "Rwanda", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/SLB", - "label": "Solomon Islands", + "ref": "country/SEN", + "label": "Senegal", "entity_type": "Country", "role": "observationAbout" }, @@ -5116,26 +5560,32 @@ "role": "observationAbout" }, { - "ref": "country/TCD", - "label": "Chad", + "ref": "country/STP", + "label": "São Tomé and Príncipe", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/TGO", - "label": "Togo", + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/TLS", - "label": "Timor-Leste", + "ref": "country/TCD", + "label": "Chad", "entity_type": "Country", "role": "observationAbout" }, { - "ref": "country/TUV", - "label": "Tuvalu", + "ref": "country/TGO", + "label": "Togo", "entity_type": "Country", "role": "observationAbout" }, @@ -5152,8 +5602,8 @@ "role": "observationAbout" }, { - "ref": "country/YEM", - "label": "Yemen", + "ref": "country/ZAF", + "label": "South Africa", "entity_type": "Country", "role": "observationAbout" }, @@ -5162,23 +5612,30 @@ "label": "Zambia", "entity_type": "Country", "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" } ], "entity_groups": { "observationAbout": { - "label": "Least Developed Countries", - "group_id": "groups/UN.LDC" + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" } }, "coverage": { "kind": "exact", "has_data": true, - "observation_count": 2474, + "observation_count": 2859, "evidence": "facet_metadata", "dimensions": [ { "label": "countries", - "count": 44 + "count": 48 }, { "label": "observations", @@ -5191,9 +5648,9 @@ ] }, "download": { - "rows": 2474, + "rows": 2859, "rows_exact": true, - "series": 44, + "series": 48, "window": { "start_year": 1960, "end_year": 2025 @@ -5218,7 +5675,7 @@ "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" }, "unit": { - "basis": "fallback", + "basis": "bound", "ref": "USDollar", "label": "USDollar", "currency": "USD" @@ -5693,13 +6150,22 @@ }, "value_kind": "enum_value" } + }, + { + "value": { + "ref": { + "ref": "XAF", + "label": "XAF" + }, + "value_kind": "enum_value" + } } ], "truncated": false, "source": "observed" } ], - "rendered_sentence": "GDP in the 44 Least Developed Countries, 1960 to 2025. Current US dollars · World Development Indicators.", + "rendered_sentence": "GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators.", "sentence_plan": [ { "kind": "slot", @@ -5763,7 +6229,7 @@ }, { "kind": "slot", - "text": "the 44 Least Developed Countries", + "text": "the 48 countries in Sub-Saharan Africa", "axis": "where", "segment": "heading", "binding_ref": "where:", @@ -5843,10 +6309,6 @@ ], "trace": { "resolved_entities": [ - { - "ref": "country/AFG", - "label": "Afghanistan" - }, { "ref": "country/AGO", "label": "Angola" @@ -5864,21 +6326,37 @@ "label": "Burkina Faso" }, { - "ref": "country/BGD", - "label": "Bangladesh" + "ref": "country/BWA", + "label": "Botswana" }, { "ref": "country/CAF", "label": "Central African Republic" }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, { "ref": "country/COD", "label": "Democratic Republic of the Congo" }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, { "ref": "country/COM", "label": "Comoros" }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, { "ref": "country/DJI", "label": "Djibouti" @@ -5891,6 +6369,14 @@ "ref": "country/ETH", "label": "Ethiopia" }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, { "ref": "country/GIN", "label": "Guinea" @@ -5904,20 +6390,12 @@ "label": "Guinea-Bissau" }, { - "ref": "country/HTI", - "label": "Haiti" - }, - { - "ref": "country/KHM", - "label": "Cambodia" - }, - { - "ref": "country/KIR", - "label": "Kiribati" + "ref": "country/GNQ", + "label": "Equatorial Guinea" }, { - "ref": "country/LAO", - "label": "Laos" + "ref": "country/KEN", + "label": "Kenya" }, { "ref": "country/LBR", @@ -5935,10 +6413,6 @@ "ref": "country/MLI", "label": "Mali" }, - { - "ref": "country/MMR", - "label": "Myanmar [Burma]" - }, { "ref": "country/MOZ", "label": "Mozambique" @@ -5947,34 +6421,34 @@ "ref": "country/MRT", "label": "Mauritania" }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, { "ref": "country/MWI", "label": "Malawi" }, + { + "ref": "country/NAM", + "label": "Namibia" + }, { "ref": "country/NER", "label": "Niger" }, { - "ref": "country/NPL", - "label": "Nepal" + "ref": "country/NGA", + "label": "Nigeria" }, { "ref": "country/RWA", "label": "Rwanda" }, - { - "ref": "country/SDN", - "label": "Sudan" - }, { "ref": "country/SEN", "label": "Senegal" }, - { - "ref": "country/SLB", - "label": "Solomon Islands" - }, { "ref": "country/SLE", "label": "Sierra Leone" @@ -5988,20 +6462,24 @@ "label": "South Sudan" }, { - "ref": "country/TCD", - "label": "Chad" + "ref": "country/STP", + "label": "São Tomé and Príncipe" }, { - "ref": "country/TGO", - "label": "Togo" + "ref": "country/SWZ", + "label": "Swaziland" }, { - "ref": "country/TLS", - "label": "Timor-Leste" + "ref": "country/SYC", + "label": "Seychelles" }, { - "ref": "country/TUV", - "label": "Tuvalu" + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" }, { "ref": "country/TZA", @@ -6012,12 +6490,16 @@ "label": "Uganda" }, { - "ref": "country/YEM", - "label": "Yemen" + "ref": "country/ZAF", + "label": "South Africa" }, { "ref": "country/ZMB", "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" } ], "resolved_sources": [ @@ -6100,10 +6582,6 @@ }, "binding_kind": "set", "refs": [ - { - "ref": "country/AFG", - "label": "Afghanistan" - }, { "ref": "country/AGO", "label": "Angola" @@ -6121,21 +6599,37 @@ "label": "Burkina Faso" }, { - "ref": "country/BGD", - "label": "Bangladesh" + "ref": "country/BWA", + "label": "Botswana" }, { "ref": "country/CAF", "label": "Central African Republic" }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, { "ref": "country/COD", "label": "Democratic Republic of the Congo" }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, { "ref": "country/COM", "label": "Comoros" }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, { "ref": "country/DJI", "label": "Djibouti" @@ -6148,6 +6642,14 @@ "ref": "country/ETH", "label": "Ethiopia" }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, { "ref": "country/GIN", "label": "Guinea" @@ -6161,20 +6663,12 @@ "label": "Guinea-Bissau" }, { - "ref": "country/HTI", - "label": "Haiti" - }, - { - "ref": "country/KHM", - "label": "Cambodia" + "ref": "country/GNQ", + "label": "Equatorial Guinea" }, { - "ref": "country/KIR", - "label": "Kiribati" - }, - { - "ref": "country/LAO", - "label": "Laos" + "ref": "country/KEN", + "label": "Kenya" }, { "ref": "country/LBR", @@ -6192,10 +6686,6 @@ "ref": "country/MLI", "label": "Mali" }, - { - "ref": "country/MMR", - "label": "Myanmar [Burma]" - }, { "ref": "country/MOZ", "label": "Mozambique" @@ -6204,34 +6694,34 @@ "ref": "country/MRT", "label": "Mauritania" }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, { "ref": "country/MWI", "label": "Malawi" }, + { + "ref": "country/NAM", + "label": "Namibia" + }, { "ref": "country/NER", "label": "Niger" }, { - "ref": "country/NPL", - "label": "Nepal" + "ref": "country/NGA", + "label": "Nigeria" }, { "ref": "country/RWA", "label": "Rwanda" }, - { - "ref": "country/SDN", - "label": "Sudan" - }, { "ref": "country/SEN", "label": "Senegal" }, - { - "ref": "country/SLB", - "label": "Solomon Islands" - }, { "ref": "country/SLE", "label": "Sierra Leone" @@ -6245,20 +6735,24 @@ "label": "South Sudan" }, { - "ref": "country/TCD", - "label": "Chad" + "ref": "country/STP", + "label": "São Tomé and Príncipe" }, { - "ref": "country/TGO", - "label": "Togo" + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" }, { - "ref": "country/TLS", - "label": "Timor-Leste" + "ref": "country/TCD", + "label": "Chad" }, { - "ref": "country/TUV", - "label": "Tuvalu" + "ref": "country/TGO", + "label": "Togo" }, { "ref": "country/TZA", @@ -6269,12 +6763,16 @@ "label": "Uganda" }, { - "ref": "country/YEM", - "label": "Yemen" + "ref": "country/ZAF", + "label": "South Africa" }, { "ref": "country/ZMB", "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" } ], "provenance": "binder" @@ -6317,7 +6815,7 @@ }, "definition": { "schema_version": 1, - "spec_id": "spec_d5b1250baf281e73b0c3f5599bb955d8", + "spec_id": "spec_df3e3c939162b3cfe113d2d78d4b4986", "identity": { "identity_version": "spec1", "shape": { @@ -6337,50 +6835,54 @@ ], "entities": { "observationAbout": [ - "country/AFG", "country/AGO", "country/BDI", "country/BEN", "country/BFA", - "country/BGD", + "country/BWA", "country/CAF", + "country/CIV", + "country/CMR", "country/COD", + "country/COG", "country/COM", + "country/CPV", "country/DJI", "country/ERI", "country/ETH", + "country/GAB", + "country/GHA", "country/GIN", "country/GMB", "country/GNB", - "country/HTI", - "country/KHM", - "country/KIR", - "country/LAO", + "country/GNQ", + "country/KEN", "country/LBR", "country/LSO", "country/MDG", "country/MLI", - "country/MMR", "country/MOZ", "country/MRT", + "country/MUS", "country/MWI", + "country/NAM", "country/NER", - "country/NPL", + "country/NGA", "country/RWA", - "country/SDN", "country/SEN", - "country/SLB", "country/SLE", "country/SOM", "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", "country/TCD", "country/TGO", - "country/TLS", - "country/TUV", "country/TZA", "country/UGA", - "country/YEM", - "country/ZMB" + "country/ZAF", + "country/ZMB", + "country/ZWE" ] }, "requested_window": { @@ -6394,7 +6896,7 @@ } }, { - "variable_text": "ODA disbursements", + "variable_text": "debt", "warnings": [ { "code": "retrieval_score_weak", @@ -6408,3012 +6910,3426 @@ } ], "timing_ms": { - "total": 2095, + "total": 2327, "by_step": { - "recall": 1, + "recall": 0, "shape_arcs": 1, "shape_probe_coverage": 3, - "shape_probe": 182, - "shape_groups": 23, + "shape_probe": 218, + "shape_groups": 1, "shape_labels": 0, - "shape_admission": 0, - "shape": 1093, - "bind": 985, - "materialise": 7, - "answer": 6, - "options": 3 + "shape_admission": 1, + "shape": 817, + "bind": 1494, + "materialise": 5, + "answer": 11 } }, - "restatement": { - "variable_text": "ODA disbursements", - "entities": [ - { - "text": "Kenya", - "role_text": "to", - "dcid": "country/KEN" - }, - { - "text": "Germany", - "role_text": "from", - "dcid": "country/DEU" - }, - { - "text": "Congo", - "role_text": "to", - "dcid": "country/COD" - } - ], - "sources": [], - "operations": [] - }, - "operations": [], - "departures": [], - "assumptions": [], - "status": "definite", - "spec": { - "spec_id": "spec_4b8c1ba9efe879b10dc3fde2c24dc483", - "definition": { - "schema_version": 1, - "spec_id": "spec_4b8c1ba9efe879b10dc3fde2c24dc483", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "FinancialFlow", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" - }, - "slots": [ - { - "property": "dac2aAidType", - "binding": { - "state": "value", - "ref": "DAC2aAidType206" - } - }, - { - "property": "dacTypeOfFinance", - "binding": { - "state": "unbound" - } - }, - { - "property": "financialFlowType", - "binding": { - "state": "value", - "ref": "Disbursement" - } - }, - { - "property": "nettingBasis", - "binding": { - "state": "value", - "ref": "Gross" - } - } - ], - "entities": { - "destination": [ - "country/COD", - "country/KEN" - ], - "origin": [ - "country/DEU" - ] - }, - "requested_window": { - "kind": "all" - } - } + "rendered_sentence": "2 readings. Kenya's outstanding external debt owed to the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 1973 to 2024 · Current US dollars. Commitments of public or publicly guaranteed external debt (debt instrument), by creditor to Kenya from the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 2023 · Current US dollars.", + "sentence_plan": [ + { + "kind": "text", + "text": "2 readings.", + "segment": "heading", + "entity_refs": [], + "states": [] }, - "resolved": { - "shape": { - "shape_id": "financialflow_amount_measuredvalue_nominal_family_f096b1ba", - "label": "gross disbursements (official development assistance)", - "population_type": { - "ref": "FinancialFlow", - "label": "financial flow" - }, - "measured_property": { - "ref": "amount", - "label": "amount" - }, - "stat_type": { - "ref": "measuredValue", - "label": "measuredValue" - }, - "measurement_qualifier": { - "ref": "Nominal", - "label": "Nominal" - }, - "measurement_denominator_unresolved": false, - "slot_keys": [ - { - "axis": "how", - "property": { - "ref": "dac2aAidType", - "label": "DAC 2a aid type" - }, - "label": "aid type" - }, - { - "axis": "how", - "property": { - "ref": "dacTypeOfFinance", - "label": "DAC type of finance" - }, - "label": "DAC type of finance" - }, - { - "axis": "how", - "property": { - "ref": "financialFlowType", - "label": "financial flow type" - }, - "label": "financial flow type" - }, - { - "axis": "how", - "property": { - "ref": "nettingBasis", - "label": "netting basis" - }, - "label": "netting basis" - }, - { - "axis": "where", - "label": "place" - }, - { - "axis": "when", - "label": "time window" - }, - { - "axis": "source", - "label": "data source" - } - ], - "member_count": 1, - "member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", - "refine_supported": true, - "data_commons": [ - { - "id": "dfo", - "label": "Development Finance Observatory" - } - ] - }, - "slots": [ - { - "key": { - "axis": "how", - "property": { - "ref": "dac2aAidType", - "label": "DAC 2a aid type" - }, - "label": "aid type" - }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "DAC2aAidType206", - "label": "official development assistance" - }, - "value_kind": "enum_value" - } - }, - "summable": false - }, - { - "key": { - "axis": "how", - "property": { - "ref": "dacTypeOfFinance", - "label": "DAC type of finance" - }, - "label": "DAC type of finance" - }, - "binding": { - "kind": "unbound" - }, - "summable": false - }, - { - "key": { - "axis": "how", - "property": { - "ref": "financialFlowType", - "label": "financial flow type" - }, - "label": "financial flow type" - }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "Disbursement", - "label": "disbursement" - }, - "value_kind": "enum_value" - } - }, - "summable": false - }, - { - "key": { - "axis": "how", - "property": { - "ref": "nettingBasis", - "label": "netting basis" - }, - "label": "netting basis" - }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "Gross", - "label": "gross" - }, - "value_kind": "enum_value" - } - }, - "summable": false - }, - { - "key": { - "axis": "where", - "label": "place" - }, - "binding": { - "kind": "set", - "values": [ - { - "ref": { - "ref": "country/COD", - "label": "Democratic Republic of the Congo" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/KEN", - "label": "Kenya" - }, - "value_kind": "entity" - } - ] - }, - "summable": false - }, - { - "key": { - "axis": "when", - "label": "time window" - }, - "binding": { - "kind": "unbound" - }, - "summable": false - }, - { - "key": { - "axis": "source", - "label": "data source" - }, - "binding": { - "kind": "unbound" - }, - "summable": false - } - ], - "inapplicable_slots": [ - "dacTypeOfFinance", - "financialObligationType" - ], - "unresolved_slots": [], - "stat_vars": { - "member_count": 1, - "member_count_exact": true, - "served_count": 1, - "data_date_range": { - "start": "1960", - "end": "2024" - } - }, - "entities": [ - { - "ref": "country/COD", - "label": "Democratic Republic of the Congo", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/KEN", - "label": "Kenya", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "origin" - } - ], - "coverage": { - "kind": "exact", - "has_data": true, - "observation_count": 130, - "evidence": "facet_metadata", - "dimensions": [ - { - "label": "sources", - "count": 1 - }, - { - "label": "observations", - "count": 65 - }, - { - "label": "variables", - "count": 1 - } - ] - }, - "headline": { - "year": 2024, - "year_named": false, - "observations": 2, - "series": 2, - "role_counts": { - "financingProvider": 1, - "financingRecipient": 2 - }, - "recent_years": [ - { - "year": 2024, - "observations": 2, - "series": 2, - "role_counts": { - "financingProvider": 1, - "financingRecipient": 2 - } - }, - { - "year": 2023, - "observations": 2, - "series": 2, - "role_counts": { - "financingProvider": 1, - "financingRecipient": 2 - } - }, - { - "year": 2022, - "observations": 2, - "series": 2, - "role_counts": { - "financingProvider": 1, - "financingRecipient": 2 - } - } - ] - }, - "download": { - "rows": 130, - "rows_exact": true, - "series": 2, - "window": { - "start_year": 1960, - "end_year": 2024 - }, - "licence": { - "label": "OECD Terms and Conditions" - } - }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", - "facets": { - "provenance": { - "basis": "fallback", - "ref": "provenance/OECDDAC2A", - "label": "OECD DAC2A", - "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" - }, - "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" - }, - "documentation": "/api/graph/documentation/provenance/OECDDAC2A", - "account": "provider" - }, - "unit": { - "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" - } - }, - "slot_options": [ - { - "key": { - "axis": "how", - "property": { - "ref": "dac2aAidType", - "label": "DAC 2a aid type" - }, - "label": "aid type" - }, - "options": [ - { - "value": { - "ref": { - "ref": "DAC2aAidType218", - "label": "ODA loans and other long-term capital" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "DAC2aAidType206", - "member_count": 2, - "served_rows": 106, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "DAC2aAidType201", - "label": "ODA grant" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "DAC2aAidType206", - "member_count": 1, - "served_rows": 130, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "DAC2aAidType207", - "label": "free-standing technical co-operation" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 1, - "served_rows": 118, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "DAC2aAidType213", - "label": "developmental food aid" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 1, - "served_rows": 71, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "DAC2aAidType216", - "label": "humanitarian aid" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 1, - "served_rows": 58, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ - { - "axis": "provenance", - "options": [ - { - "value": { - "ref": { - "ref": "provenance/OECDDAC2A", - "label": "OECD DAC2A" - }, - "value_kind": "source" - } - } - ], - "truncated": false, - "source": "observed" - }, - { - "axis": "unit", - "options": [ - { - "value": { - "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" - }, - "value_kind": "enum_value" - } - } - ], - "truncated": false, - "source": "observed" - } - ], - "rendered_sentence": "Germany's gross disbursements to Democratic Republic of the Congo and Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", - "sentence_plan": [ - { - "kind": "slot", - "text": "Germany", - "segment": "heading", - "role": "origin", - "binding_ref": "origin:", - "entity_refs": [ - "country/DEU" - ], - "states": [ - "origin:" - ] - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "gross disbursements", - "axis": "what", - "segment": "heading", - "entity_refs": [], - "states": [ - "how:financialFlowType", - "how:nettingBasis", - "axis:populationType", - "axis:measuredProperty" - ] - }, - { - "kind": "text", - "text": " to ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "Democratic Republic of the Congo and Kenya", - "axis": "where", - "segment": "heading", - "role": "destination", - "binding_ref": "where:", - "entity_refs": [ - "country/COD", - "country/KEN" - ], - "states": [ - "where:" - ] - }, - { - "kind": "text", - "text": " for ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "official development assistance", - "axis": "how", - "segment": "heading", - "property_dcid": "dac2aAidType", - "binding_ref": "how:dac2aAidType", - "entity_refs": [], - "states": [ - "how:dac2aAidType" - ] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "dacTypeOfFinance", - "binding_ref": "how:dacTypeOfFinance", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "financialFlowType", - "binding_ref": "how:financialFlowType", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "nettingBasis", - "binding_ref": "how:nettingBasis", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": ", ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "1960 to 2024", - "axis": "when", - "segment": "heading", - "binding_ref": "when:", - "entity_refs": [], - "states": [ - "when:" - ] - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "OECD DAC2a", - "axis": "source", - "segment": "byline", - "entity_refs": [], - "states": [ - "source:" - ] - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [] - } - ], - "trace": { - "resolved_entities": [ - { - "ref": "country/COD", - "label": "Democratic Republic of the Congo" - }, - { - "ref": "country/KEN", - "label": "Kenya" - }, - { - "ref": "country/DEU", - "label": "Germany" - } - ], - "resolved_sources": [ - { - "ref": "provenance/OECDDAC2A", - "label": "OECD DAC2a", - "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" - }, - "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" - }, - "documentation": "/api/graph/documentation/provenance/OECDDAC2A" - } - ], - "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "dac2aAidType", - "label": "DAC 2a aid type" - }, - "label": "aid type" - }, - "binding_kind": "value", - "refs": [ - { - "ref": "DAC2aAidType206", - "label": "official development assistance" - } - ], - "provenance": "text_recognized" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "dacTypeOfFinance", - "label": "DAC type of finance" - }, - "label": "DAC type of finance" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "financialFlowType", - "label": "financial flow type" - }, - "label": "financial flow type" - }, - "binding_kind": "value", - "refs": [ - { - "ref": "Disbursement", - "label": "disbursement" - } - ], - "provenance": "text_recognized" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "nettingBasis", - "label": "netting basis" - }, - "label": "netting basis" - }, - "binding_kind": "value", - "refs": [ - { - "ref": "Gross", - "label": "gross" - } - ], - "provenance": "measure_elected" - }, - { - "key": { - "axis": "where", - "label": "place" - }, - "binding_kind": "set", - "refs": [ - { - "ref": "country/COD", - "label": "Democratic Republic of the Congo" - }, - { - "ref": "country/KEN", - "label": "Kenya" - } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "when", - "label": "time window" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, - { - "key": { - "axis": "source", - "label": "data source" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - } - ], - "query_qualifiers": [ - { - "text": "ODA", - "named": [ - { - "ref": "DAC2aAidType206", - "label": "official development assistance" - } - ], - "slot": "dac2aAidType", - "disposition": "bound", - "selected": [] - } - ], - "capability_version": "cap_347a470e04c97eec", - "default_reading": { - "applied": true, - "removed_stat_vars": [] - } - }, - "confidence": "high", - "available_at_place": true, - "alternative_measures": [ - { - "definition": { - "schema_version": 1, - "spec_id": "spec_9de5a8ccb2c8bd8f2ad793949b9c0222", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "FinancialFlow", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" - }, - "slots": [ - { - "property": "dac2aAidType", - "binding": { - "state": "value", - "ref": "DAC2aAidType206" - } - }, - { - "property": "dacTypeOfFinance", - "binding": { - "state": "unbound" - } - }, - { - "property": "financialFlowType", - "binding": { - "state": "value", - "ref": "Disbursement" - } - }, - { - "property": "nettingBasis", - "binding": { - "state": "value", - "ref": "Net" - } - } - ], - "entities": { - "destination": [ - "country/COD", - "country/KEN" - ], - "origin": [ - "country/DEU" - ] - }, - "requested_window": { - "kind": "all" - } - } - }, - "label": "net disbursements", - "axis": "what", - "measure_axis_values": [ - { - "axis": "populationType", - "value": { - "ref": "FinancialFlow", - "label": "financial flow" - } - }, - { - "axis": "measuredProperty", - "value": { - "ref": "amount", - "label": "amount" - } - }, - { - "axis": "measurementQualifier", - "value": { - "ref": "Nominal", - "label": "nominal" - } - }, - { - "axis": "financialFlowType", - "value": { - "ref": "Disbursement", - "label": "disbursement" - } - }, - { - "axis": "nettingBasis", - "value": { - "ref": "Net", - "label": "net" - } - } - ], - "served_rows": 130, - "served_rows_exact": true - } - ], - "measure_label": "gross disbursements", - "measure_label_axes": [ - "populationType", - "measuredProperty", - "measurementQualifier", - "financialFlowType", - "nettingBasis" - ], - "measure_axis_values": [ - { - "axis": "populationType", - "value": { - "ref": "FinancialFlow", - "label": "financial flow" - } - }, - { - "axis": "measuredProperty", - "value": { - "ref": "amount", - "label": "amount" - } - }, - { - "axis": "measurementQualifier", - "value": { - "ref": "Nominal", - "label": "nominal" - } - }, - { - "axis": "financialFlowType", - "value": { - "ref": "Disbursement", - "label": "disbursement" - } - }, - { - "axis": "nettingBasis", - "value": { - "ref": "Gross", - "label": "gross" - } - } - ], - "unit_conversion": { - "currencies": [ - { - "code": "AED", - "noun": "UAE dirhams", - "current_years": { - "start_year": 1997, - "end_year": 2021 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 2023, - "base_year_max": 2023 - }, - { - "code": "AFN", - "noun": "Afghan afghanis", - "current_years": { - "start_year": 2002, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 2002, - "base_year_max": 2025 - }, - { - "code": "ALL", - "noun": "Albanian leks", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "AMD", - "noun": "Armenian drams", - "current_years": { - "start_year": 1992, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1992, - "base_year_max": 2025 - }, - { - "code": "AOA", - "noun": "Angolan kwanzas", - "current_years": { - "start_year": 1991, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1991, - "base_year_max": 2025 - }, - { - "code": "ARS", - "noun": "Argentine pesos", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "AUD", - "noun": "Australian dollars", - "current_years": { - "start_year": 1960, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1960, - "base_year_max": 2025 - }, - { - "code": "AWG", - "noun": "Aruban florins", - "current_years": { - "start_year": 1995, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1995, - "base_year_max": 2025 - }, - { - "code": "AZN", - "noun": "Azerbaijani manats", - "current_years": { - "start_year": 2014, - "end_year": 2019 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 2023, - "base_year_max": 2023 - }, - { - "code": "BAM", - "noun": "Bosnia-Herzegovina convertible marks", - "current_years": { - "start_year": 1996, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1996, - "base_year_max": 2025 - }, - { - "code": "BBD", - "noun": "Barbadian dollars", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "BDT", - "noun": "Bangladeshi taka", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "BHD", - "noun": "Bahraini dinars", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "BIF", - "noun": "Burundian francs", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "BND", - "noun": "Brunei dollars", - "current_years": { - "start_year": 1985, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1985, - "base_year_max": 2025 - }, - { - "code": "BOB", - "noun": "Bolivian bolivianos", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "BRL", - "noun": "Brazilian reais", - "current_years": { - "start_year": 1986, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1986, - "base_year_max": 2025 - }, - { - "code": "BSD", - "noun": "Bahamian dollars", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "BTN", - "noun": "Bhutanese ngultrums", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "BWP", - "noun": "Botswana pula", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "BYN", - "noun": "Belarusian rubles", - "current_years": { - "start_year": 1992, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1992, - "base_year_max": 2025 - }, - { - "code": "BZD", - "noun": "Belize dollars", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "CAD", - "noun": "Canadian dollars", - "current_years": { - "start_year": 1960, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1960, - "base_year_max": 2025 - }, - { - "code": "CDF", - "noun": "Congolese francs", - "current_years": { - "start_year": 1991, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1991, - "base_year_max": 2025 - }, - { - "code": "CHF", - "noun": "Swiss francs", - "current_years": { - "start_year": 1960, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1960, - "base_year_max": 2025 - }, - { - "code": "CLP", - "noun": "Chilean pesos", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "CNY", - "noun": "Chinese yuan", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "COP", - "noun": "Colombian pesos", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "CRC", - "noun": "Costa Rican colones", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "CVE", - "noun": "Cape Verdean escudos", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "CZK", - "noun": "Czech korunas", - "current_years": { - "start_year": 1998, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1998, - "base_year_max": 2025 - }, - { - "code": "DJF", - "noun": "Djiboutian francs", - "current_years": { - "start_year": 1990, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1990, - "base_year_max": 2025 - }, - { - "code": "DKK", - "noun": "Danish kroner", - "current_years": { - "start_year": 1960, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1960, - "base_year_max": 2025 - }, - { - "code": "DOP", - "noun": "Dominican pesos", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "DZD", - "noun": "Algerian dinars", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "EGP", - "noun": "Egyptian pounds", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "ERN", - "noun": "Eritrean nakfas", - "current_years": { - "start_year": 1992, - "end_year": 2019 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1992, - "base_year_max": 2019 - }, - { - "code": "ETB", - "noun": "Ethiopian birr", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "EUR", - "noun": "euros", - "current_years": { - "start_year": 1973, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1973, - "base_year_max": 2025 - }, - { - "code": "FJD", - "noun": "Fijian dollars", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "GBP", - "noun": "British pounds", - "current_years": { - "start_year": 1960, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1960, - "base_year_max": 2025 - }, - { - "code": "GEL", - "noun": "Georgian lari", - "current_years": { - "start_year": 1994, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1994, - "base_year_max": 2025 - }, - { - "code": "GHS", - "noun": "Ghanaian cedis", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "GMD", - "noun": "Gambian dalasis", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "GNF", - "noun": "Guinean francs", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "GTQ", - "noun": "Guatemalan quetzales", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "GYD", - "noun": "Guyanese dollars", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "HKD", - "noun": "Hong Kong dollars", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "HNL", - "noun": "Honduran lempiras", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "outstanding external debt", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " owed to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Bank International Debt Statistics (IDS)", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "1973 to 2024", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Commitments of public or publicly guaranteed external debt (debt instrument), by creditor", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " from ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Bank International Debt Statistics (IDS)", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2023", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "debt", + "entities": [ + { + "text": "Sub-Saharan Africa", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "candidates", + "candidates": { + "ordering": "intent_rank", + "max_candidates": 6, + "specs": [ + { + "spec_id": "spec_db19b572801b0e2db437bf4722826ef1", + "definition": { + "schema_version": 1, + "spec_id": "spec_db19b572801b0e2db437bf4722826ef1", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialPosition", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + "slots": [ + { + "property": "financialPositionType", + "binding": { + "state": "unbound" + } + }, + { + "property": "financingResource", + "binding": { + "state": "unbound" + } + }, + { + "property": "guaranteeStatus", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsConcessionality", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsCreditorType", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsDebtorType", + "binding": { + "state": "unbound" + } + }, + { + "property": "includesIMFCredit", + "binding": { + "state": "unbound" + } + }, + { + "property": "interestRateVariability", + "binding": { + "state": "unbound" + } + }, + { + "property": "maturityBand", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "HTG", - "noun": "Haitian gourdes", - "current_years": { - "start_year": 1980, - "end_year": 2024 + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialposition_amount_measuredvalue_nominal_by_role", + "label": "Outstanding external debt, by creditor", + "population_type": { + "ref": "FinancialPosition", + "label": "financial position" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + "measured_property": { + "ref": "amount", + "label": "amount" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "HUF", - "noun": "Hungarian forints", - "current_years": { - "start_year": 2003, - "end_year": 2024 + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" }, - "base_year_min": 2003, - "base_year_max": 2025 + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "financialPositionType", + "label": "financial position type" + }, + "label": "financial position type" + }, + { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + { + "axis": "how", + "property": { + "ref": "interestRateVariability", + "label": "interest rate variability" + }, + "label": "interest rate variability" + }, + { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 85, + "member_digest": "59b8172b4da7c06ded4825c4f3f96a3b90414a056cb5c6447595c6be1748066b", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] }, - { - "code": "IDR", - "noun": "Indonesian rupiahs", - "current_years": { - "start_year": 1980, - "end_year": 2024 + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialPositionType", + "label": "financial position type" + }, + "label": "financial position type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding": { + "kind": "unbound" + }, + "summable": false }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "ILS", - "noun": "Israeli new shekels", - "current_years": { - "start_year": 1997, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false }, - "base_year_min": 1997, - "base_year_max": 2025 - }, - { - "code": "INR", - "noun": "Indian rupees", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding": { + "kind": "unbound" + }, + "summable": false }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "interestRateVariability", + "label": "interest rate variability" + }, + "label": "interest rate variability" + }, + "binding": { + "kind": "unbound" + }, + "summable": false }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "IQD", - "noun": "Iraqi dinars", - "current_years": { - "start_year": 2000, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "binding": { + "kind": "unbound" + }, + "summable": false }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "binding": { + "kind": "unbound" + }, + "summable": false }, - "base_year_min": 2000, - "base_year_max": 2025 - }, - { - "code": "IRR", - "noun": "Iranian rials", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "binding": { + "kind": "unbound" + }, + "summable": false }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "ISK", - "noun": "Icelandic krónur", - "current_years": { - "start_year": 1997, - "end_year": 2024 + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "guaranteeStatus", + "idsDebtorType", + "idsCreditorType", + "financingResource", + "interestRateVariability", + "idsConcessionality", + "includesIMFCredit", + "maturityBand" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1973", + "end": "2024" }, - "base_year_min": 1997, - "base_year_max": 2025 + "source_codes": [ + { + "provenance": "provenance/WorldBankInternationalDebtStatistics", + "code": "DT.DOD.DECT.CD" + } + ] }, - { - "code": "JMD", - "noun": "Jamaican dollars", - "current_years": { - "start_year": 1980, - "end_year": 2024 + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "JOD", - "noun": "Jordanian dinars", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "JPY", - "noun": "Japanese yen", - "current_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1960, - "base_year_max": 2025 - }, - { - "code": "KES", - "noun": "Kenyan shillings", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "KGS", - "noun": "Kyrgyz soms", - "current_years": { - "start_year": 1992, - "end_year": 2024 + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1992, - "base_year_max": 2025 - }, - { - "code": "KHR", - "noun": "Cambodian riels", - "current_years": { - "start_year": 1986, - "end_year": 2024 + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1986, - "base_year_max": 2025 - }, - { - "code": "KMF", - "noun": "Comorian francs", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "KRW", - "noun": "South Korean won", - "current_years": { - "start_year": 1987, - "end_year": 2024 + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1987, - "base_year_max": 2025 - }, - { - "code": "KWD", - "noun": "Kuwaiti dinars", - "current_years": { - "start_year": 1995, - "end_year": 2024 + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1995, - "base_year_max": 2024 - }, - { - "code": "KZT", - "noun": "Kazakh tenge", - "current_years": { - "start_year": 2013, - "end_year": 2024 + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 2013, - "base_year_max": 2024 - }, - { - "code": "LAK", - "noun": "Lao kip", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "LBP", - "noun": "Lebanese pounds", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "LKR", - "noun": "Sri Lankan rupees", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2024 - }, - { - "code": "LSL", - "noun": "Lesotho maloti", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "LYD", - "noun": "Libyan dinars", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MAD", - "noun": "Moroccan dirhams", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MDL", - "noun": "Moldovan lei", - "current_years": { - "start_year": 1992, - "end_year": 2024 + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1992, - "base_year_max": 2025 - }, - { - "code": "MGA", - "noun": "Malagasy ariary", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MKD", - "noun": "Macedonian denars", - "current_years": { - "start_year": 1992, - "end_year": 2024 + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1992, - "base_year_max": 2025 - }, - { - "code": "MMK", - "noun": "Myanmar kyats", - "current_years": { - "start_year": 1998, - "end_year": 2024 + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1998, - "base_year_max": 2025 - }, - { - "code": "MNT", - "noun": "Mongolian tugriks", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MOP", - "noun": "Macanese patacas", - "current_years": { - "start_year": 2001, - "end_year": 2024 + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 2001, - "base_year_max": 2025 - }, - { - "code": "MRU", - "noun": "Mauritanian ouguiyas", - "current_years": { - "start_year": 1990, - "end_year": 2024 + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1990, - "base_year_max": 2025 - }, - { - "code": "MUR", - "noun": "Mauritian rupees", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "origin" + } + ], + "entity_groups": { + "origin": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } }, - { - "code": "MVR", - "noun": "Maldivian rufiyaa", - "current_years": { - "start_year": 1980, - "end_year": 2024 + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 13, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 11 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 }, - "constant_years": { - "start_year": 1960, + "recent_years": [ + { + "year": 2024, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 0, + "series": 0, + "role_counts": {} + } + ] + }, + "download": { + "rows": 13, + "rows_exact": true, + "series": 2, + "window": { + "start_year": 1973, "end_year": 2024 }, - "base_year_min": 1980, - "base_year_max": 2025 + "licence": { + "label": "Creative Commons Attribution License" + } }, - { - "code": "MWK", - "noun": "Malawian kwachas", - "current_years": { - "start_year": 1980, - "end_year": 2024 + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialPositionType", + "label": "financial position type" + }, + "label": "financial position type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "AmountOutstanding", + "label": "amount outstanding" + }, + "value_kind": "enum_value" + }, + "served_rows": 13, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "options": [ + { + "value": { + "ref": { + "ref": "PublicOrPubliclyGuaranteed", + "label": "public or publicly guaranteed" + }, + "value_kind": "enum_value" + }, + "served_rows": 13, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MXN", - "noun": "Mexican pesos", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSDebtorTypeGG", + "label": "general government (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 2, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSDebtorTypePS", + "label": "public sector (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 13, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSDebtorTypeOPS", + "label": "other public sector (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 11, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSCreditorTypePRVT", + "label": "private creditors (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 2, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypeBLAT", + "label": "bilateral (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 11, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypeOFFT", + "label": "official creditors (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 11, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypePCBK", + "label": "commercial banks (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 2, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "options": [ + { + "value": { + "ref": { + "ref": "DebtInstrument", + "label": "debt instrument" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Loan", + "label": "loan" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SDRAllocation", + "label": "SDR allocation" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MYR", - "noun": "Malaysian ringgits", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "interestRateVariability", + "label": "interest rate variability" + }, + "label": "interest rate variability" + }, + "options": [ + { + "value": { + "ref": { + "ref": "VariableInterestRate", + "label": "variable interest rate" + }, + "value_kind": "enum_value" + }, + "served_rows": 2, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSConcessional", + "label": "concessional (IDS concessionality)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "IDSNonConcessional", + "label": "non-concessional (IDS concessionality)" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MZN", - "noun": "Mozambican meticais", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "options": [ + { + "value": { + "ref": { + "ref": "WithoutIMFCredit", + "label": "without IMF credit" + }, + "value_kind": "enum_value" + }, + "served_rows": 13, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "options": [ + { + "value": { + "ref": { + "ref": "LongTermMaturity", + "label": "long-term maturity" + }, + "value_kind": "enum_value" + }, + "served_rows": 26, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "NAD", - "noun": "Namibian dollars", - "current_years": { - "start_year": 1989, - "end_year": 2024 + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Kenya's outstanding external debt owed to the 48 countries in Sub-Saharan Africa, 1973 to 2024. Current US dollars · World Bank International Debt Statistics (IDS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] }, - "base_year_min": 1989, - "base_year_max": 2025 - }, - { - "code": "NGN", - "noun": "Nigerian naira", - "current_years": { - "start_year": 1990, - "end_year": 2024 + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "kind": "slot", + "text": "outstanding external debt", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialPositionType", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " owed to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "states": [ + "origin:" + ] }, - "base_year_min": 1990, - "base_year_max": 2025 - }, - { - "code": "NIO", - "noun": "Nicaraguan córdobas", - "current_years": { - "start_year": 1987, - "end_year": 2024 + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financingResource", + "binding_ref": "how:financingResource", + "entity_refs": [], + "states": [] }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "guaranteeStatus", + "binding_ref": "how:guaranteeStatus", + "entity_refs": [], + "states": [] }, - "base_year_min": 1987, - "base_year_max": 2025 - }, - { - "code": "NOK", - "noun": "Norwegian kroner", - "current_years": { - "start_year": 1960, - "end_year": 2024 + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsConcessionality", + "binding_ref": "how:idsConcessionality", + "entity_refs": [], + "states": [] }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsCreditorType", + "binding_ref": "how:idsCreditorType", + "entity_refs": [], + "states": [] }, - "base_year_min": 1960, - "base_year_max": 2025 - }, - { - "code": "NPR", - "noun": "Nepalese rupees", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsDebtorType", + "binding_ref": "how:idsDebtorType", + "entity_refs": [], + "states": [] }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "includesIMFCredit", + "binding_ref": "how:includesIMFCredit", + "entity_refs": [], + "states": [] }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "NZD", - "noun": "New Zealand dollars", - "current_years": { - "start_year": 1961, - "end_year": 2024 + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "interestRateVariability", + "binding_ref": "how:interestRateVariability", + "entity_refs": [], + "states": [] }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "maturityBand", + "binding_ref": "how:maturityBand", + "entity_refs": [], + "states": [] }, - "base_year_min": 1961, - "base_year_max": 2025 - }, - { - "code": "OMR", - "noun": "Omani rials", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialPositionType", + "binding_ref": "how:financialPositionType", + "entity_refs": [], + "states": [] }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "PEN", - "noun": "Peruvian soles", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "kind": "slot", + "text": "1973 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "distinguishes": true }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "PGK", - "noun": "Papua New Guinean kina", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "PHP", - "noun": "Philippine pesos", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "kind": "slot", + "text": "World Bank International Debt Statistics (IDS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] }, - "base_year_min": 1980, - "base_year_max": 2025 + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialPositionType", + "label": "financial position type" + }, + "label": "financial position type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "interestRateVariability", + "label": "interest rate variability" + }, + "label": "interest rate variability" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } }, - { - "code": "PKR", - "noun": "Pakistani rupees", - "current_years": { - "start_year": 1980, - "end_year": 2024 + "confidence": "low", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [], + "open_axis_facts": [ + { + "property": "financialPositionType", + "varies": false, + "value": { + "ref": "AmountOutstanding", + "label": "amount outstanding" + }, + "distinct_count": 1, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "AmountOutstanding", + "label": "amount outstanding" + }, + "count": 1 + } + ] + } + ] + } + }, + { + "spec_id": "spec_6eb3e2b7e6bc64c3f0ae0ac0d41c9b3c", + "definition": { + "schema_version": 1, + "spec_id": "spec_6eb3e2b7e6bc64c3f0ae0ac0d41c9b3c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialObligation", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + "slots": [ + { + "property": "financialObligationType", + "binding": { + "state": "value", + "ref": "Commitment" + } + }, + { + "property": "financingResource", + "binding": { + "state": "value", + "ref": "DebtInstrument" + } + }, + { + "property": "guaranteeStatus", + "binding": { + "state": "value", + "ref": "PublicOrPubliclyGuaranteed" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "PLN", - "noun": "Polish zlotys", - "current_years": { - "start_year": 1998, - "end_year": 2024 + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialobligation_amount_measuredvalue_nominal_by_role", + "label": "Commitments of public or publicly guaranteed external debt (debt instrument), by creditor", + "population_type": { + "ref": "FinancialObligation", + "label": "financial obligation" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + "measured_property": { + "ref": "amount", + "label": "amount" }, - "base_year_min": 1998, - "base_year_max": 2025 - }, - { - "code": "PYG", - "noun": "Paraguayan guaranís", - "current_years": { - "start_year": 1980, - "end_year": 2024 + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" }, - "base_year_min": 1980, - "base_year_max": 2025 + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "financialObligationType", + "label": "financial obligation type" + }, + "label": "financial obligation type" + }, + { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "9c8389fcc18b49e94e1286c629ec5260fce8837ba425bc60c6f31d333d34a73c", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] }, - { - "code": "QAR", - "noun": "Qatari riyals", - "current_years": { - "start_year": 1985, - "end_year": 1990 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialObligationType", + "label": "financial obligation type" + }, + "label": "financial obligation type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Commitment", + "label": "commitment" + }, + "value_kind": "enum_value" + } + }, + "summable": false }, - "base_year_min": 2023, - "base_year_max": 2023 - }, - { - "code": "RON", - "noun": "Romanian lei", - "current_years": { - "start_year": 2013, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "DebtInstrument", + "label": "debt instrument" + }, + "value_kind": "enum_value" + } + }, + "summable": false }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "PublicOrPubliclyGuaranteed", + "label": "public or publicly guaranteed" + }, + "value_kind": "enum_value" + } + }, + "summable": false }, - "base_year_min": 2013, - "base_year_max": 2025 - }, - { - "code": "RSD", - "noun": "Serbian dinars", - "current_years": { - "start_year": 1997, - "end_year": 2024 + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false }, - "base_year_min": 1997, - "base_year_max": 2025 + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2023", + "end": "2023" + }, + "source_codes": [ + { + "provenance": "provenance/WorldBankInternationalDebtStatistics", + "code": "DT.COM.DPPG.CD", + "exact": true + } + ] }, - { - "code": "RUB", - "noun": "Russian rubles", - "current_years": { - "start_year": 2010, - "end_year": 2020 + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 2010, - "base_year_max": 2020 - }, - { - "code": "RWF", - "noun": "Rwandan francs", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "SAR", - "noun": "Saudi riyals", - "current_years": { - "start_year": 2000, - "end_year": 2023 + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 2000, - "base_year_max": 2023 - }, - { - "code": "SBD", - "noun": "Solomon Islands dollars", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "SCR", - "noun": "Seychellois rupees", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "SDG", - "noun": "Sudanese pounds", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "SEK", - "noun": "Swedish kronor", - "current_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1960, - "base_year_max": 2025 - }, - { - "code": "SGD", - "noun": "Singapore dollars", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "SLE", - "noun": "Sierra Leonean leones", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "SRD", - "noun": "Surinamese dollars", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "SSP", - "noun": "South Sudanese pounds", - "current_years": { - "start_year": 2011, - "end_year": 2024 + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 2011, - "base_year_max": 2025 - }, - { - "code": "STN", - "noun": "São Tomé and Príncipe dobras", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "SYP", - "noun": "Syrian pounds", - "current_years": { - "start_year": 1980, - "end_year": 2010 + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2010 - }, - { - "code": "SZL", - "noun": "Swazi emalangeni", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "THB", - "noun": "Thai baht", - "current_years": { - "start_year": 2006, - "end_year": 2016 + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 2018, - "base_year_max": 2024 - }, - { - "code": "TJS", - "noun": "Tajikistani somonis", - "current_years": { - "start_year": 1992, - "end_year": 2024 + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1992, - "base_year_max": 2025 - }, - { - "code": "TMT", - "noun": "Turkmenistani manat", - "current_years": { - "start_year": 1992, - "end_year": 2024 + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1992, - "base_year_max": 2025 - }, - { - "code": "TND", - "noun": "Tunisian dinars", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "TOP", - "noun": "Tongan paʻanga", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "TRY", - "noun": "Turkish lira", - "current_years": { - "start_year": 1990, - "end_year": 2024 + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1990, - "base_year_max": 2025 - }, - { - "code": "TTD", - "noun": "Trinidad and Tobago dollars", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "TWD", - "noun": "New Taiwan dollars", - "current_years": { - "start_year": 2006, - "end_year": 2016 + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 2023, - "base_year_max": 2025 - }, - { - "code": "TZS", - "noun": "Tanzanian shillings", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "UAH", - "noun": "Ukrainian hryvnias", - "current_years": { - "start_year": 1991, - "end_year": 2024 + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "origin" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "origin" }, - "base_year_min": 1991, - "base_year_max": 2025 + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "origin" + } + ], + "entity_groups": { + "origin": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } }, - { - "code": "UGX", - "noun": "Ugandan shillings", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 1, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 1 + }, + { + "label": "variables", + "count": 1 + } + ] }, - { - "code": "USD", - "noun": "US dollars", - "current_years": { - "start_year": 1960, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + "headline": { + "year": 2023, + "year_named": false, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 }, - "base_year_min": 1960, - "base_year_max": 2025 + "recent_years": [ + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 0, + "series": 0, + "role_counts": {} + }, + { + "year": 2021, + "observations": 0, + "series": 0, + "role_counts": {} + } + ] }, - { - "code": "UYU", - "noun": "Uruguayan pesos", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + "download": { + "rows": 1, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2023, + "end_year": 2023 }, - "base_year_min": 1980, - "base_year_max": 2025 + "licence": { + "label": "Creative Commons Attribution License" + } }, - { - "code": "UZS", - "noun": "Uzbekistani soms", - "current_years": { - "start_year": 1992, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1992, - "base_year_max": 2025 + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } }, - { - "code": "VES", - "noun": "Venezuelan bolívares", - "current_years": { - "start_year": 2017, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialObligationType", + "label": "financial obligation type" + }, + "label": "financial obligation type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Commitment", + "label": "commitment" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, - "base_year_min": 2017, - "base_year_max": 2025 - }, - { - "code": "VND", - "noun": "Vietnamese dong", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "options": [ + { + "value": { + "ref": { + "ref": "DebtInstrument", + "label": "debt instrument" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "options": [ + { + "value": { + "ref": { + "ref": "PublicOrPubliclyGuaranteed", + "label": "public or publicly guaranteed" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "VUV", - "noun": "Vanuatu vatu", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Commitments of public or publicly guaranteed external debt (debt instrument), by creditor to Kenya from the 48 countries in Sub-Saharan Africa in 2023. Current US dollars · World Bank International Debt Statistics (IDS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Commitments of public or publicly guaranteed external debt (debt instrument), by creditor", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialObligationType", + "how:financingResource", + "how:guaranteeStatus" + ], + "distinguishes": true }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "WST", - "noun": "Samoan tala", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "kind": "text", + "text": " from ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "states": [ + "origin:" + ] }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "XAF", - "noun": "Central African CFA francs", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialObligationType", + "binding_ref": "how:financialObligationType", + "entity_refs": [], + "states": [] }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financingResource", + "binding_ref": "how:financingResource", + "entity_refs": [], + "states": [] }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "XCD", - "noun": "East Caribbean dollars", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "guaranteeStatus", + "binding_ref": "how:guaranteeStatus", + "entity_refs": [], + "states": [] }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "XOF", - "noun": "West African CFA francs", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "kind": "slot", + "text": "in 2023", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "distinguishes": true }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "YER", - "noun": "Yemeni rials", - "current_years": { - "start_year": 2014, - "end_year": 2024 + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] }, - "base_year_min": 2014, - "base_year_max": 2025 - }, - { - "code": "ZAR", - "noun": "South African rand", - "current_years": { - "start_year": 1980, - "end_year": 2024 + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 + { + "kind": "slot", + "text": "World Bank International Debt Statistics (IDS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] }, - "base_year_min": 1980, - "base_year_max": 2025 + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialObligationType", + "label": "financial obligation type" + }, + "label": "financial obligation type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Commitment", + "label": "commitment" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "DebtInstrument", + "label": "debt instrument" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "PublicOrPubliclyGuaranteed", + "label": "public or publicly guaranteed" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } }, - { - "code": "ZMW", - "noun": "Zambian kwachas", - "current_years": { - "start_year": 1980, - "end_year": 2024 - }, - "constant_years": { - "start_year": 1960, - "end_year": 2024 - }, - "base_year_min": 1980, - "base_year_max": 2025 - } - ], - "default_base_year": 2024, - "role_currencies": { - "origin": "EUR" + "confidence": "low", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] } } - } + ], + "truncated": false + }, + "reading_assumptions": { + "spec_db19b572801b0e2db437bf4722826ef1": [], + "spec_6eb3e2b7e6bc64c3f0ae0ac0d41c9b3c": [] } } ], - "rendered_sentence": "GDP in the 44 Least Developed Countries, 1960 to 2025. Current US dollars · World Development Indicators. This shows the 44 Least Developed Countries, each on its own. Germany's gross disbursements to Democratic Republic of the Congo and Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", + "rendered_sentence": "Answered 1 of 2 parts. GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators. This shows the 48 countries in Sub-Saharan Africa, each on its own. Debt has 2 readings. Kenya's outstanding external debt owed to the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 1973 to 2024 · Current US dollars. Commitments of public or publicly guaranteed external debt (debt instrument), by creditor to Kenya from the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 2023 · Current US dollars.", "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, { "kind": "slot", "text": "GDP", @@ -9482,7 +10398,7 @@ }, { "kind": "slot", - "text": "the 44 Least Developed Countries", + "text": "the 48 countries in Sub-Saharan Africa", "axis": "where", "segment": "heading", "binding_ref": "where:", @@ -9578,7 +10494,7 @@ }, { "kind": "text", - "text": "This shows the 44 Least Developed Countries, each on its own.", + "text": "This shows the 48 countries in Sub-Saharan Africa, each on its own.", "segment": "departure", "entity_refs": [], "states": [], @@ -9593,16 +10509,35 @@ }, { "kind": "slot", - "text": "Germany", + "text": "Debt", + "axis": "what", "segment": "heading", - "role": "origin", - "binding_ref": "origin:", - "entity_refs": [ - "country/DEU" - ], - "states": [ - "origin:" - ], + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " has 2 readings.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [], "part_index": 1 }, { @@ -9622,115 +10557,139 @@ "part_index": 1 }, { - "kind": "slot", - "text": "gross disbursements", - "axis": "what", + "kind": "text", + "text": "outstanding external debt", "segment": "heading", "entity_refs": [], - "states": [ - "how:financialFlowType", - "how:nettingBasis", - "axis:populationType", - "axis:measuredProperty" - ], + "states": [], "part_index": 1 }, { "kind": "text", - "text": " to ", + "text": " owed to ", "segment": "heading", "entity_refs": [], "states": [], "part_index": 1 }, { - "kind": "slot", - "text": "Democratic Republic of the Congo and Kenya", - "axis": "where", + "kind": "text", + "text": "the 48 countries in Sub-Saharan Africa", "segment": "heading", - "role": "destination", - "binding_ref": "where:", - "entity_refs": [ - "country/COD", - "country/KEN" - ], - "states": [ - "where:" - ], + "entity_refs": [], + "states": [], "part_index": 1 }, { "kind": "text", - "text": " for ", + "text": ".", "segment": "heading", "entity_refs": [], "states": [], "part_index": 1 }, { - "kind": "slot", - "text": "official development assistance", - "axis": "how", + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "World Bank International Debt Statistics (IDS)", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "1973 to 2024", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", "segment": "heading", - "property_dcid": "dac2aAidType", - "binding_ref": "how:dac2aAidType", "entity_refs": [], - "states": [ - "how:dac2aAidType" - ], + "states": [], "part_index": 1 }, { - "kind": "slot", - "text": "", - "axis": "how", + "kind": "text", + "text": "Commitments of public or publicly guaranteed external debt (debt instrument), by creditor", "segment": "heading", - "property_dcid": "dacTypeOfFinance", - "binding_ref": "how:dacTypeOfFinance", "entity_refs": [], "states": [], "part_index": 1 }, { - "kind": "slot", - "text": "", - "axis": "how", + "kind": "text", + "text": " to ", "segment": "heading", - "property_dcid": "financialFlowType", - "binding_ref": "how:financialFlowType", "entity_refs": [], "states": [], "part_index": 1 }, { - "kind": "slot", - "text": "", - "axis": "how", + "kind": "text", + "text": "Kenya", "segment": "heading", - "property_dcid": "nettingBasis", - "binding_ref": "how:nettingBasis", "entity_refs": [], "states": [], "part_index": 1 }, { "kind": "text", - "text": ", ", + "text": " from ", "segment": "heading", "entity_refs": [], "states": [], "part_index": 1 }, { - "kind": "slot", - "text": "1960 to 2024", - "axis": "when", + "kind": "text", + "text": "the 48 countries in Sub-Saharan Africa", "segment": "heading", - "binding_ref": "when:", "entity_refs": [], - "states": [ - "when:" - ], + "states": [], "part_index": 1 }, { @@ -9750,16 +10709,11 @@ "part_index": 1 }, { - "kind": "slot", - "text": "Current US dollars", - "axis": "unit", + "kind": "text", + "text": "World Bank International Debt Statistics (IDS)", "segment": "byline", - "binding_ref": "unit:", "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ], + "states": [], "part_index": 1 }, { @@ -9771,14 +10725,27 @@ "part_index": 1 }, { - "kind": "slot", - "text": "OECD DAC2a", - "axis": "source", + "kind": "text", + "text": "2023", "segment": "byline", "entity_refs": [], - "states": [ - "source:" - ], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [], "part_index": 1 }, { @@ -9790,7 +10757,7 @@ "part_index": 1 } ], - "status": "definite" + "status": "mixed" } } } @@ -9800,10 +10767,10 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence": "Answered 1 of 2 parts. GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators. You asked for sub-Saharan Africa. This shows the countries in it, each on its own. Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", "complete": false, "specs": [ - "spec_e11cdfec28d9fac6551cfaa892be9558" + "spec_3c3d4e571162850b30db0321638f955b" ], "gaps": [ { @@ -9817,14 +10784,19 @@ { "answer": { "kind": "resolution", - "status": "definite", - "sentence": "GDP in the 44 Least Developed Countries, 1960 to 2025. Current US dollars · World Development Indicators. This shows the 44 Least Developed Countries, each on its own. Germany's gross disbursements to Democratic Republic of the Congo and Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", - "complete": true, + "status": "mixed", + "sentence": "Answered 1 of 2 parts. GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators. This shows the 48 countries in Sub-Saharan Africa, each on its own. Debt has 2 readings. Kenya's outstanding external debt owed to the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 1973 to 2024 · Current US dollars. Commitments of public or publicly guaranteed external debt (debt instrument), by creditor to Kenya from the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 2023 · Current US dollars.", + "complete": false, "specs": [ - "spec_e11cdfec28d9fac6551cfaa892be9558", - "spec_4b8c1ba9efe879b10dc3fde2c24dc483" + "spec_3c3d4e571162850b30db0321638f955b" ], - "gaps": [] + "gaps": [ + { + "part": 1, + "kind": "choice", + "options": 2 + } + ] } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json index 07eb593..906bbec 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json @@ -1,7 +1,7 @@ { "format_version": 1, "name": "fetch-null-member", - "description": "A member that admits null may be left out or served as null; a client reads both as null, and neither changes the outcome. The recording and this record carry the two forms of the status column's distinct.", + "description": "An optional member that admits null may be left out or served as null; a client reads both as null, and neither changes the outcome. The recording and this record carry the two forms of the status column's distinct.", "origin": { "kind": "synthetic", "derived_from": "answer-definite-fetch", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json index fc66dd8..2334584 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json @@ -1,11 +1,11 @@ { "format_version": 1, "name": "fetch-ref-expired-not-reproducible", - "description": "When the stored version has expired and the build is refused, the client asks the versions route for the newest version alone with limit=1, since the route lists versions newest first, and raises VersionUnavailableError with the snapshot's artifact_expired code and that version as the newest.", + "description": "When the stored version has expired and the build is refused, the client asks the versions route for the newest version alone with limit=1, and raises VersionUnavailableError with the snapshot's artifact_expired code and that version as the newest.", "origin": { "kind": "synthetic", - "derived_from": "fetch-ref", - "edit": "The snapshot refuses 410 artifact_expired and the rebuild 422 member_not_resolvable; the versions route is recorded live." + "derived_from": "fetch-ref-newest-version", + "edit": "A fetch of a ref to the listed version, its unreached artifact digest all zeros, whose snapshot refuses 410 artifact_expired and whose rebuild refuses 422 member_not_resolvable, comes before the parent's versions exchange." }, "call": [ { @@ -14,9 +14,7 @@ "format_version": 1, "members": [ { - "parts": [ - "basic health care ODA disbursements" - ], + "parts": [], "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", "spec": { "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", @@ -24,64 +22,64 @@ "schema_version": 1, "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", "identity": { + "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "stat_type": "measuredValue", "population_type": "FinancialFlow", "measured_property": "amount", + "stat_type": "measuredValue", "measurement_qualifier": "Nominal" }, "slots": [ { + "property": "crsCooperationModality", "binding": { "state": "unbound" - }, - "property": "crsCooperationModality" + } }, { + "property": "crsPurpose", "binding": { - "ref": "CRSPurposeCode12220", - "state": "value" - }, - "property": "crsPurpose" + "state": "value", + "ref": "CRSPurposeCode12220" + } }, { + "property": "crsTypeOfFinance", "binding": { "state": "unbound" - }, - "property": "crsTypeOfFinance" + } }, { + "property": "crsTypeOfFlow", "binding": { - "ref": "CRSTypeOfFlow10", - "state": "value" - }, - "property": "crsTypeOfFlow" + "state": "value", + "ref": "CRSTypeOfFlow10" + } }, { + "property": "financialFlowType", "binding": { - "ref": "Disbursement", - "state": "value" - }, - "property": "financialFlowType" + "state": "value", + "ref": "Disbursement" + } }, { + "property": "nettingBasis", "binding": { - "ref": "Gross", - "state": "value" - }, - "property": "nettingBasis" + "state": "value", + "ref": "Gross" + } } ], "entities": { - "origin": [ - "country/DEU" - ], "destination": [ "country/NGA" + ], + "origin": [ + "country/DEU" ] }, - "identity_version": "spec1", "requested_window": { "kind": "all" } @@ -90,7 +88,7 @@ }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", "artifact": { - "digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "digest": "sha256:0000000000000000000000000000000000000000000000000000000000000000", "rendering": { "format": "parquet", "bundle": false @@ -137,64 +135,64 @@ "schema_version": 1, "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", "identity": { + "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "stat_type": "measuredValue", "population_type": "FinancialFlow", "measured_property": "amount", + "stat_type": "measuredValue", "measurement_qualifier": "Nominal" }, "slots": [ { + "property": "crsCooperationModality", "binding": { "state": "unbound" - }, - "property": "crsCooperationModality" + } }, { + "property": "crsPurpose", "binding": { - "ref": "CRSPurposeCode12220", - "state": "value" - }, - "property": "crsPurpose" + "state": "value", + "ref": "CRSPurposeCode12220" + } }, { + "property": "crsTypeOfFinance", "binding": { "state": "unbound" - }, - "property": "crsTypeOfFinance" + } }, { + "property": "crsTypeOfFlow", "binding": { - "ref": "CRSTypeOfFlow10", - "state": "value" - }, - "property": "crsTypeOfFlow" + "state": "value", + "ref": "CRSTypeOfFlow10" + } }, { + "property": "financialFlowType", "binding": { - "ref": "Disbursement", - "state": "value" - }, - "property": "financialFlowType" + "state": "value", + "ref": "Disbursement" + } }, { + "property": "nettingBasis", "binding": { - "ref": "Gross", - "state": "value" - }, - "property": "nettingBasis" + "state": "value", + "ref": "Gross" + } } ], "entities": { - "origin": [ - "country/DEU" - ], "destination": [ "country/NGA" + ], + "origin": [ + "country/DEU" ] }, - "identity_version": "spec1", "requested_window": { "kind": "all" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-newest-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-newest-version.json new file mode 100644 index 0000000..390f885 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-newest-version.json @@ -0,0 +1,122 @@ +{ + "format_version": 1, + "name": "fetch-ref-newest-version", + "description": "The newest stored version of a spec is the one the versions route lists first, so the client asks for it alone with limit=1. The route needs no key.", + "origin": { + "kind": "recorded", + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T09:31:38Z" + }, + "call": [ + { + "op": "newest_version", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "GET", + "path": "/datasets/spec_774d6c001a6250aa67ca676ab067895e/versions?limit=1" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "versions": [ + { + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "base_content_version": null, + "rendering": "plain", + "groupby": null + } + ], + "next_cursor": null, + "complete": true + } + } + } + ], + "expect": [ + { + "newest_version": { + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756" + } + } + ] +} diff --git a/tools/README.md b/tools/README.md index f41446e..1937eb4 100644 --- a/tools/README.md +++ b/tools/README.md @@ -38,13 +38,13 @@ uv run tools/validate_provenance_docs_vectors.py uv run tools/validate_descriptions_vectors.py ``` -`validate_client_contract.py` validates the client contract under `python/client-contract/src/dfo_client_contract/` against its schemas, then checks what they cannot express: every `strict-fields.json` pointer resolves in `served/openapi.json` and stays required and non-nullable, or keeps its enum values; `actions.json` holds one row, in code order, for each active refusal code in `registries/codes.json` that reaches a problem document or a no_data reason, with a gap kind exactly for the no_data reasons; `client-codes.json` lists each code a client raises itself once, in code order, none of them a code in `actions.json` or the registry, each with a class a scenario names; each recorded scenario's requests match a served route and its JSON bodies validate against that route's schemas, a required member that admits null allowed to be absent; each scenario's `expect` equals the outcomes its steps reach over its exchanges, with refusals' error classes and gap kinds from `actions.json` and each error the client raises itself carrying its code and class from `client-codes.json`, each build posts the `input.scope` its step's narrowing derives over the spec's bound roles, and each Search request posts the input its steps derive; every absolute URL a record holds has the redacted query; and each `DatasetRef` example gets the verdict it states. It does not import `dfo_client_contract`, whose `tests/test_rules.py` replays the rule vectors. Also a PEP 723 script: +`validate_client_contract.py` validates the client contract under `python/client-contract/src/dfo_client_contract/` against its schemas, then checks what they cannot express: every `strict-fields.json` pointer resolves in `served/openapi.json` and stays required and non-nullable, or keeps its enum values; `actions.json` holds one row, in code order, for each active refusal code in `registries/codes.json` that reaches a problem document or a no_data reason, with a gap kind exactly for the no_data reasons; `client-codes.json` lists each code a client raises itself once, in code order, none of them a code in `actions.json` or the registry, each with a class a scenario names; `served/openapi.json` holds the Search, Datasets, Graph and Presentation surfaces and nothing outside them but the platform's `/codes` route; each recorded scenario's requests match a served route and its JSON bodies validate against that route's schemas, where a required member stays required when it admits null; every problem document in a scenario, synthetic ones and failed operations' errors included, carries an active code registered at its status; each scenario's `expect` equals the outcomes its steps reach over its exchanges, with refusals' error classes and gap kinds from `actions.json`, each error the client raises itself carrying its code and class from `client-codes.json`, and a repeated refused request counted a retry only where the retry rules allow one; each POST carries its body, each build posts the body its spec, narrowing and layout give, each Search request posts the input its steps derive, each poll names the operation the client holds, and each signed download is the URL its redirect names; every absolute URL a record holds has the redacted query; and each `DatasetRef` example gets the verdict it states. It does not import `dfo_client_contract`, whose `tests/test_rules.py` replays the rule vectors. Also a PEP 723 script: ```bash uv run tools/validate_client_contract.py ``` -`capture_client_contract.py` refreshes the client contract from dfo-apis. `openapi --dfo-apis PATH` builds the composed app in that checkout's environment, in process, and writes `served/openapi.json` and `served/SOURCE.json`, refusing a checkout with uncommitted changes or untracked files and an environment out of step with its `uv.lock`; `record` runs the contract's scenarios against a base URL, dev by default, writes the records with every absolute URL's query redacted and a local app's signed URLs written as storage URLs, derives the synthetic ones and validates the result, and `record --offline` derives the outcomes again from the records with no request. It imports its outcome rules from `validate_client_contract.py`. `python/client-contract/README.md` has the recipe. A PEP 723 script; its tests run without network or pyarrow: +`capture_client_contract.py` refreshes the client contract from dfo-apis. `openapi --dfo-apis PATH` builds the composed app in that checkout's environment, in process, and writes `served/openapi.json` and `served/SOURCE.json`, refusing a checkout with uncommitted changes or untracked files and an environment out of step with its `uv.lock`; `record` runs the contract's scenarios against a base URL, dev by default, writes the records with every absolute URL's query redacted and a local app's signed URLs written as storage URLs, derives the synthetic ones and validates the result, and `record --offline` derives the outcomes again from the records with no request. A recorded scenario holds only exchanges the server made: `record` refuses a recorded scenario that a canned exchange answered, and a synthetic derivation makes no request. Nothing in a record marks an exchange as canned, so `validate_client_contract.py` cannot check this rule and the capture enforces it. It imports its outcome rules from `validate_client_contract.py`. `python/client-contract/README.md` has the recipe. A PEP 723 script; its tests run without network or pyarrow: ```bash uv run tools/capture_client_contract.py record diff --git a/tools/capture_client_contract.py b/tools/capture_client_contract.py index e8bf4dc..4fbf36f 100644 --- a/tools/capture_client_contract.py +++ b/tools/capture_client_contract.py @@ -29,7 +29,8 @@ scenario is named for and refuses to write one that does not. With `--offline` no request is made: each recorded scenario's steps run again over its own exchanges and rewrite its `expect`, and each synthetic scenario -that records nothing live is derived again from its parent. Synthetic +is derived again from its parent. A synthetic derivation makes no request +in either mode. Synthetic scenarios are derived from the recorded records after them, so a recording refreshes both, and a synthetic record names its parent's body files rather than copies. Every absolute URL a record keeps, a signed download or a @@ -63,7 +64,7 @@ import urllib.error import urllib.request from collections.abc import Callable, Mapping, Sequence -from dataclasses import dataclass, field +from dataclasses import dataclass, field, replace from datetime import UTC, datetime from pathlib import Path from typing import Any, Protocol @@ -73,6 +74,7 @@ FILE_EXPIRED, FILE_GONE, NO_VERSIONS, + POLL_PATH, REBUILD_REFUSED, VERSION_UNAVAILABLE, Answer, @@ -82,6 +84,7 @@ answer_gaps, answer_members, answer_outcome, + build_body, choice_for, choice_input, data_warning, @@ -100,6 +103,7 @@ search_warns, selector_path, sentence_entry, + surface_problems, versions_path, ) from validate_client_contract import main as validate_main @@ -114,7 +118,6 @@ RENDERING = {"format": "parquet", "bundle": False} # The response headers a client reads, and so the ones a record keeps. KEPT_HEADERS = ("content-type", "location", "retry-after") -POLL_PATH = "/datasets/operations/{operation_id}" def dump_json(document: Any) -> str: @@ -227,7 +230,13 @@ def capture_openapi(checkout: Path) -> tuple[dict[str, Any], str]: ) if result.returncode != 0: raise SystemExit(f"the capture failed in {checkout}:\n{result.stderr}") - return json.loads(out.read_text(encoding="utf-8")), commit + document = json.loads(out.read_text(encoding="utf-8")) + if problems := surface_problems(document): + raise SystemExit( + "the captured document is not the deployed composition:\n" + + "\n".join(problems) + ) + return document, commit def write_served( @@ -340,17 +349,17 @@ def _is_json(content_type: str) -> bool: class Recorder: """Sends requests the way a client does and keeps each exchange. - `canned` exchanges are served in order, before the network, to the - requests that match them; `edit` rewrites each live JSON response body.""" + `canned` exchanges answer the first requests, in order, before the + network; a request that is not the next canned one ends the run.""" name: str base_url: str transport: Transport canned: list[dict[str, Any]] = field(default_factory=list) - edit: Callable[[Any], Any] | None = None exchanges: list[dict[str, Any]] = field(default_factory=list) bodies: dict[str, bytes] = field(default_factory=dict) commits: set[str] = field(default_factory=set) + canned_served: int = 0 def api(self, method: str, path: str, json_body: Any = None) -> Response: """A request to `path` under the base URL.""" @@ -381,9 +390,15 @@ def _send( request: dict[str, Any] = {"method": method, **target} if json_body is not None: request["json"] = json_body - if self.canned and self.canned[0]["request"] == request: + if self.canned: + if self.canned[0]["request"] != request: + raise SystemExit( + f"{self.name}: {method} {url} is not the canned request " + f"{json.dumps(self.canned[0]['request'])[:300]}" + ) exchange = self.canned.pop(0) self.exchanges.append(exchange) + self.canned_served += 1 return _canned_response(exchange["response"]) headers = {} if bare else {"user-agent": "dfo-client-contract-recorder/1"} @@ -396,9 +411,6 @@ def _send( ) if not bare and "x-dfo-commit" in response.headers: self.commits.add(response.headers["x-dfo-commit"]) - if self.edit is not None and _is_json(response.headers.get("content-type", "")): - edited = json.dumps(self.edit(response.json())).encode() - response = Response(response.status, response.headers, edited) self.exchanges.append({"request": request, "response": self._keep(response)}) return response @@ -727,6 +739,17 @@ def run() -> dict[str, Any]: self._step({"op": "fetch", "ref": ref}, run) + def newest_version(self, spec: Spec) -> str | None: + """The newest stored version of `spec`, from the versions route.""" + found: list[str | None] = [] + + def run() -> dict[str, Any]: + found.append(self._newest(spec.spec_id)) + return {"newest_version": {"content_version": found[0]}} + + self._step({"op": "newest_version", "spec": spec.step()}, run) + return found[0] if found else None + def mint(self, spec: Spec, *, layout: str | None = None) -> str: operation: list[str] = [] @@ -1004,14 +1027,8 @@ def _operation_outcome(resource: dict[str, Any]) -> dict[str, Any]: def _build_body( spec: Spec, scope: dict[str, Any] | None, rendering: Mapping[str, Any] ) -> dict[str, Any]: - input_: dict[str, Any] = { - "kind": "spec_id", - "spec_id": spec.spec_id, - "definition": spec.definition, - } - if scope: - input_["scope"] = scope - return {"schema_version": 1, "input": input_, "options": dict(rendering)} + held = {"spec_id": spec.spec_id, "definition": spec.definition} + return build_body(held, scope, rendering) # --- scenarios -------------------------------------------------------------- @@ -1033,6 +1050,9 @@ def _build_body( TWO_CANDIDATES = "GNI of Germany and tax revenue of Kenya from 2015 to 2022" CANDIDATES_BESIDE_UNRESTATED = "GNI of Germany and debt of Kenya from 2015 to 2022" GROUP_DEFINITE = "GDP of the least developed countries" +# A definite part whose places are a named group, beside a part whose +# direction the question leaves open, which offers one option per direction. +GROUP_BESIDE_OPTIONS = "GDP of sub-Saharan Africa, and debt of Kenya" GROUPED_FLOW = "Germany's ODA to the least developed countries" CANDIDATES_BESIDE_ASSUMED = "GNI of Germany and aid flows to Kenya" # Two specs just above the 100,000-row sync budget, one for the mint and one @@ -1387,6 +1407,32 @@ def _choose_candidate_echoes_assumptions(s: Session, ctx: Context) -> None: ) +def _choose_option_beside_definite(s: Session, ctx: Context) -> None: + answer = s.search(GROUP_BESIDE_OPTIONS) + require(_statuses(answer) == ["definite", "no_data"], "definite, no_data") + require( + bool(answer.parts[0]["spec"]["resolved"].get("entity_groups")), + "the definite part names an entity group", + ) + require( + bool(answer.parts[1]["no_data"].get("options")), "the no_data part has options" + ) + chosen = s.choose(answer, 0, part=1) + require( + chosen is not None + and _statuses(chosen)[0] == "definite" + and _statuses(chosen)[1] in ("definite", "candidates"), + "part 0 stays definite and part 1 answers in the chosen direction", + ) + + +def _fetch_ref_newest_version(s: Session, ctx: Context) -> None: + (member,) = ctx.definite_ref()["members"] + spec = ctx.definite_spec(DEFINITE) + newest = s.newest_version(spec) + require(newest == member["content_version"], "the stored version is the newest") + + def _resubmit_placeholder(s: Session, ctx: Context) -> None: answer = s.search(CANDIDATES_BESIDE_UNRESTATED) require(_statuses(answer) == ["candidates", "no_data"], "candidates, no_data") @@ -1598,6 +1644,21 @@ def _resubmit_placeholder(s: Session, ctx: Context) -> None: "its ordering and truncated echoed. Part 1 answers candidates again in the same order.", _resubmit_candidates_sibling, ), + Recorded( + "choose-option-beside-definite", + "Choosing option 0 on part 1, a no_data part whose direction the question leaves " + "open, beside a definite part whose places are a named group posts dataset_resubmit " + "with the definite part's identity, entity_groups and assumptions as an identity " + "entry, and the chosen option's data_query part as a parsed entry. Part 0 answers " + "definite again, and part 1 answers the debt read in the chosen direction.", + _choose_option_beside_definite, + ), + Recorded( + "fetch-ref-newest-version", + "The newest stored version of a spec is the one the versions route lists first, so " + "the client asks for it alone with limit=1. The route needs no key.", + _fetch_ref_newest_version, + ), Recorded( "choose-candidate-echoes-assumptions", "Choosing candidate 0 on part 0 beside a definite part that states assumptions posts " @@ -1675,15 +1736,14 @@ class Derived: @dataclass(frozen=True) class Synthetic: - """A scenario derived from a recorded one. A `live` derivation records - some of its exchanges against the base URL.""" + """A scenario derived from a recorded one, with no request: its + derivation runs over a context whose transport refuses every request.""" name: str derived_from: str edit: str description: str derive: Callable[[dict[str, Any], Context], Derived] - live: bool = False def _same(parent: dict[str, Any], exchanges: list[dict[str, Any]]) -> Derived: @@ -1949,25 +2009,42 @@ def _expired_newer(parent: dict[str, Any], ctx: Context) -> Derived: ) +# The digest a ref names for a file the lookup never reaches. +UNREACHED_DIGEST = "sha256:" + "0" * 64 + + def _expired_not_reproducible(parent: dict[str, Any], ctx: Context) -> Derived: - """The parent's ref, its snapshot expired and its rebuild refused; the - versions route is recorded live.""" - ref = copy.deepcopy(parent["call"][0]["ref"]) - (member,) = ref["members"] - spec = Spec(member["spec"]["spec_id"], member["spec"]["definition"]) - body = _build_body(spec, None, member["artifact"]["rendering"]) + """A ref to the version the parent lists as newest, whose snapshot + refuses 410 artifact_expired and whose rebuild refuses 422 + member_not_resolvable, then the parent's versions exchange.""" + (step,) = parent["call"] + (outcome,) = parent["expect"] + version = outcome["newest_version"]["content_version"] + require(version is not None, "the parent lists a stored version") + spec = step["spec"] + ref = { + "format_version": 1, + "members": [ + { + "parts": [], + "sentence": spec["sentence"], + "spec": {"spec_id": spec["spec_id"], "definition": spec["definition"]}, + "content_version": version, + "artifact": {"digest": UNREACHED_DIGEST, "rendering": dict(RENDERING)}, + } + ], + } + body = _build_body(_step_spec(spec), None, RENDERING) canned = [ _snapshot_expired(ref), _refusal( {"method": "POST", "path": "/datasets", "json": body}, 422, _NOT_RESOLVABLE ), + *copy.deepcopy(parent["exchanges"]), ] session = ctx.session("synthetic", canned=canned) session.fetch_ref(ref) - require( - session.expect[-1].get("error", {}).get("class") == VERSION_UNAVAILABLE, - "the lookup raises VersionUnavailableError", - ) + require(not session.recorder.canned, "the lookup makes every exchange") return Derived(session.call, session.recorder.exchanges, session.expect) @@ -2113,8 +2190,8 @@ def _choice( *, edit: BodyEdit | None = None, ) -> Callable[[dict[str, Any], Context], Derived]: - """The parent's search, its answer body changed by `edit`, then a choice. - A choice that posts is recorded live; one that refuses makes no request.""" + """The parent's search, its answer body changed by `edit`, then a choice + that refuses and makes no request.""" def derive(parent: dict[str, Any], ctx: Context) -> Derived: canned = copy.deepcopy(parent["exchanges"][:1]) @@ -2129,17 +2206,6 @@ def derive(parent: dict[str, Any], ctx: Context) -> Derived: return derive -def _definite_beside(body: Any, ctx: Context) -> Any: - """Part 0 becomes the definite part a live search for GROUP_DEFINITE - answers.""" - body = copy.deepcopy(body) - (part,) = copy.deepcopy(ctx.definite_answer(GROUP_DEFINITE).parts) - require(bool(part["spec"]["resolved"].get("entity_groups")), "a group part") - body["parts"][0] = part - body["status"] = "mixed" - return body - - def _without_options(body: Any, ctx: Context) -> Any: """Each no_data part's options go, as from a build that serves none.""" body = copy.deepcopy(body) @@ -2408,14 +2474,15 @@ def _strict_info_notice(parent: dict[str, Any], ctx: Context) -> Derived: ), Synthetic( "fetch-ref-expired-not-reproducible", - "fetch-ref", - "The snapshot refuses 410 artifact_expired and the rebuild 422 member_not_resolvable; the versions route is recorded live.", + "fetch-ref-newest-version", + "A fetch of a ref to the listed version, its unreached artifact digest all zeros, " + "whose snapshot refuses 410 artifact_expired and whose rebuild refuses 422 " + "member_not_resolvable, comes before the parent's versions exchange.", "When the stored version has expired and the build is refused, the client asks the " - "versions route for the newest version alone with limit=1, since the route lists " - "versions newest first, and raises VersionUnavailableError with the snapshot's " - "artifact_expired code and that version as the newest.", + "versions route for the newest version alone with limit=1, and raises " + "VersionUnavailableError with the snapshot's artifact_expired code and that version " + "as the newest.", _expired_not_reproducible, - live=True, ), Synthetic( "fetch-ref-expired-file-selector", @@ -2480,7 +2547,8 @@ def _strict_info_notice(parent: dict[str, Any], ctx: Context) -> Derived: "fetch-null-member", "answer-definite-fetch", "The manifest's status column distinct flips between left out and served as null.", - "A member that admits null may be left out or served as null; a client reads both as " + "An optional member that admits null may be left out or served as null; a client " + "reads both as " "null, and neither changes the outcome. The recording and this record carry the two " "forms of the status column's distinct.", _null_member, @@ -2493,17 +2561,6 @@ def _strict_info_notice(parent: dict[str, Any], ctx: Context) -> Derived: "response, before any download.", _renamed_strict_field, ), - Synthetic( - "choose-place-beside-definite", - "search-two-parts-place-ambiguous", - f"Part 0 becomes the definite part, entity groups included, of a live search for " - f'"{GROUP_DEFINITE}", and the choice is recorded live.', - 'Choosing "Congo [DRC]" on part 1 beside a definite part posts dataset_resubmit with the ' - "definite part's identity and entity_groups as an identity entry, and the chosen " - "option's data_query part as a parsed entry. Both parts answer definite.", - _choice("Congo [DRC]", 1, edit=_definite_beside), - live=True, - ), Synthetic( "answer-timed-out", "answer-mixed-fetch-raises", @@ -2677,6 +2734,11 @@ def record_recorded(definition: Recorded, ctx: Context, directory: Path) -> None recorded_at = _now() session = ctx.session(definition.name) definition.run(session, ctx) + if session.recorder.canned_served: + raise SystemExit( + f"{definition.name}: a recorded scenario holds only exchanges the server made, " + f"and {session.recorder.canned_served} were canned" + ) commits = session.recorder.commits if len(commits) != 1 or not re.fullmatch(r"[0-9a-f]{40}", next(iter(commits))): raise SystemExit( @@ -2699,7 +2761,7 @@ def record_recorded(definition: Recorded, ctx: Context, directory: Path) -> None def record_synthetic(definition: Synthetic, ctx: Context, directory: Path) -> None: parent_path = directory / f"{definition.derived_from}.json" parent = json.loads(parent_path.read_text(encoding="utf-8")) - derived = definition.derive(parent, ctx) + derived = definition.derive(parent, replace(ctx, transport=_offline)) origin = { "kind": "synthetic", "derived_from": definition.derived_from, @@ -2779,7 +2841,7 @@ def __call__( def _offline(method: str, url: str, **_: Any) -> Response: - raise SystemExit(f"--offline makes no request, and a scenario sent {method} {url}") + raise SystemExit(f"this derivation makes no request, and it sent {method} {url}") def drive(session: Session, call: Sequence[dict[str, Any]]) -> None: @@ -2805,6 +2867,8 @@ def drive(session: Session, call: Sequence[dict[str, Any]]) -> None: ) case {"op": "fetch", "ref": ref}: session.fetch_ref(ref) + case {"op": "newest_version", "spec": spec}: + session.newest_version(_step_spec(spec)) case {"op": "fetch"}: if answer is None: raise ValueError("a fetch of an answer follows no answer") @@ -2864,9 +2928,6 @@ def run_record(args: argparse.Namespace) -> int: if unknown: raise SystemExit(f"no scenario is named {sorted(unknown)}") chosen = set(args.only or names) - live = sorted(d.name for d in SYNTHETIC if d.live and d.name in chosen) - if args.offline and live: - raise SystemExit(f"--offline derives no live scenario, and {live} are live") ctx = Context( args.base_url, _offline if args.offline else urllib_transport, diff --git a/tools/tests/test_capture_client_contract.py b/tools/tests/test_capture_client_contract.py index 901b980..a55163f 100644 --- a/tools/tests/test_capture_client_contract.py +++ b/tools/tests/test_capture_client_contract.py @@ -61,9 +61,6 @@ def _without_shapes(expect: list[dict[str, Any]]) -> list[dict[str, Any]]: return expect -_LIVE = sorted(d.name for d in capture.SYNTHETIC if d.live) - - def test_every_record_has_a_definition_and_every_definition_a_record() -> None: for kind, definitions in ( ("recorded", capture.RECORDED), @@ -72,7 +69,7 @@ def test_every_record_has_a_definition_and_every_definition_a_record() -> None: assert sorted(d.name for d in definitions) == _records(kind) -@pytest.mark.parametrize("name", [*_records("recorded"), *_LIVE]) +@pytest.mark.parametrize("name", _records("recorded")) def test_the_recorder_reproduces_each_record_from_its_steps(name: str) -> None: record = _load(name) served = capture.Served(record, SCENARIOS) @@ -183,7 +180,7 @@ def test_a_record_whose_signed_url_names_the_local_host_is_refused( capture._refuse_local_host(record, base_url) -@pytest.mark.parametrize("name", [n for n in _records("synthetic") if n not in _LIVE]) +@pytest.mark.parametrize("name", _records("synthetic")) def test_each_derived_record_follows_from_its_parent(name: str) -> None: record = _load(name) definition = next(d for d in capture.SYNTHETIC if d.name == name) @@ -213,9 +210,56 @@ def test_an_offline_rederivation_rewrites_only_the_expect(tmp_path: Path) -> Non assert fresh == (SCENARIOS / f"{name}.json").read_text(encoding="utf-8") -def test_an_offline_run_refuses_a_live_scenario() -> None: - with pytest.raises(SystemExit, match="derives no live scenario"): - capture.main(["record", "--offline", "--only", _LIVE[0]]) +def test_a_recorder_refuses_a_request_that_is_not_the_next_canned_one() -> None: + def transport(method: str, url: str, **kwargs: Any) -> Any: + raise AssertionError(f"{method} {url} reached the network") + + canned = [ + { + "request": {"method": "GET", "path": "/datasets/a"}, + "response": {"status": 200}, + } + ] + recorder = capture.Recorder("s", capture.DEV_BASE_URL, transport, canned=canned) + with pytest.raises(SystemExit, match="is not the canned request"): + recorder.api("GET", "/datasets/b") + + +def test_a_recorded_scenario_answered_by_a_canned_exchange_is_refused( + tmp_path: Path, +) -> None: + canned = { + "request": {"method": "GET", "path": "/datasets/a"}, + "response": {"status": 200, "json": {}}, + } + + def run(s: Any, ctx: Any) -> None: + s.recorder.canned = [canned] + s.recorder.api("GET", "/datasets/a") + + def transport(method: str, url: str, **kwargs: Any) -> Any: + raise AssertionError(f"{method} {url} reached the network") + + definition = capture.Recorded("s", "None.", run) + ctx = capture.Context(capture.DEV_BASE_URL, transport, ACTIONS, CLIENT_CODES) + with pytest.raises(SystemExit, match="1 were canned"): + capture.record_recorded(definition, ctx, tmp_path) + assert list(tmp_path.iterdir()) == [] + + +def test_a_synthetic_derivation_makes_no_request(tmp_path: Path) -> None: + (tmp_path / "parent.json").write_text(json.dumps({"exchanges": []})) + + def derive(parent: dict[str, Any], ctx: Any) -> Any: + ctx.session("synthetic").search("anything") + + def transport(method: str, url: str, **kwargs: Any) -> Any: + raise AssertionError(f"{method} {url} reached the network") + + definition = capture.Synthetic("s", "parent", "None.", "None.", derive) + ctx = capture.Context(capture.DEV_BASE_URL, transport, ACTIONS, CLIENT_CODES) + with pytest.raises(SystemExit, match="makes no request"): + capture.record_synthetic(definition, ctx, tmp_path) def test_a_renamed_strict_field_ends_the_call_at_the_build() -> None: diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index f98564e..bc4d868 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -194,6 +194,60 @@ def _last_response(change: Callable[[Any], None]) -> Callable[[Any], None]: return lambda doc: change(doc["exchanges"][-1]["response"]) +_RETRY_503 = "scenarios/search-retry-after-503.json" + + +def _repeat(index: int, times: int) -> Callable[[Any], None]: + """Exchange `index` answers `times` more times before the next one.""" + + def change(doc: Any) -> None: + exchange = doc["exchanges"][index] + for _ in range(times): + doc["exchanges"].insert(index, copy.deepcopy(exchange)) + + return change + + +def _refused_400(doc: Any) -> None: + """The first search is refused 400 request_invalid, then answered.""" + doc["exchanges"][0]["response"]["json"].update( + type="/codes/request_invalid", + title="Bad Request", + status=400, + code="request_invalid", + retryable=False, + ) + doc["exchanges"][0]["response"]["status"] = 400 + + +def _swap_builds(doc: Any) -> None: + """The two builds post each other's input.""" + first, second = doc["exchanges"][1]["request"], doc["exchanges"][4]["request"] + first["json"]["input"], second["json"]["input"] = ( + second["json"]["input"], + first["json"]["input"], + ) + + +def _poll_other_operation(doc: Any) -> None: + for exchange in doc["exchanges"]: + if exchange["request"].get("path", "").startswith("/datasets/operations/"): + exchange["request"]["path"] = "/datasets/operations/op_" + "f" * 64 + + +def _made_up_code(doc: Any) -> None: + doc["exchanges"][0]["response"]["json"]["code"] = "made_up_code" + doc["expect"][0]["error"]["code"] = "made_up_code" + + +def _drop_paths(prefix: str) -> Callable[[Any], None]: + def change(doc: Any) -> None: + for path in [p for p in doc["paths"] if p.startswith(prefix)]: + del doc["paths"][path] + + return change + + def _versions_forbidden(response: Any) -> None: """The versions route refuses 403 publish_not_permitted.""" response.update( @@ -292,7 +346,7 @@ def _versions_forbidden(response: Any) -> None: ), ( _FETCH, - lambda doc: doc["exchanges"][1]["request"].update(method="POST"), + lambda doc: doc["exchanges"][1]["request"].update(method="POST", json={}), "serves no POST", ), ( @@ -469,7 +523,7 @@ def _versions_forbidden(response: Any) -> None: "where the rules post", ), ( - "scenarios/choose-place-beside-definite.json", + "scenarios/choose-option-beside-definite.json", _posted(0, lambda entry: entry.update(entry_kind="parsed")), "where the rules post", ), @@ -709,7 +763,7 @@ def _versions_forbidden(response: Any) -> None: ( "scenarios/fetch-spec-strict-warning.json", _set_body(0, lambda body: body["warnings"][0].update(severity="info")), - "the steps make a GET origin the record lacks", + "the steps make a GET /api/datasets/", ), ( "scenarios/fetch-spec-digest-mismatch.json", @@ -726,7 +780,7 @@ def _versions_forbidden(response: Any) -> None: ( "scenarios/fetch-spec-resubmit-other-spec.json", _resubmit_answers_built, - "the steps make a GET origin the record lacks", + "the steps make a GET /api/datasets/", ), ( "scenarios/fetch-frame-several-readings.json", @@ -771,6 +825,76 @@ def _versions_forbidden(response: Any) -> None: "where the steps make a GET", ), (_NOT_REPRODUCIBLE, _last_response(_versions_forbidden), "step 0 expects"), + (_RETRY_503, _repeat(0, 2), "the steps never make exchanges"), + ( + _RETRY_503, + _set_body(0, lambda body: body.update(retryable=False)), + "the steps never make exchanges", + ), + (_RETRY_503, _refused_400, "the steps never make exchanges"), + ( + "scenarios/fetch-retry-after-504.json", + _repeat(1, 1), + "the steps never make exchanges", + ), + ( + "scenarios/answer-candidates-choose-fetch.json", + lambda doc: doc["exchanges"][1]["request"].pop("json"), + "scenarios/answer-candidates-choose-fetch.json: schema", + ), + ( + _REBOUND, + lambda doc: doc["exchanges"][0]["request"].pop("json"), + "scenarios/fetch-spec-entity-rebound.json: schema", + ), + ( + "scenarios/answer-several-readings-folded.json", + _swap_builds, + "where the rules post", + ), + ( + "scenarios/mint-async-build.json", + _poll_other_operation, + "where the steps make a GET /datasets/operations/op_", + ), + ( + "scenarios/fetch-spec-known-sentence.json", + lambda doc: doc["exchanges"][2]["request"].update( + url="https://storage.googleapis.com/other-bucket/other-object" + "?X-Goog-Signature=redacted" + ), + "where the steps make a GET https://storage.googleapis.com/", + ), + ( + "scenarios/fetch-spec-known-sentence.json", + lambda doc: doc["exchanges"][1]["response"]["headers"].pop("location"), + "names no location", + ), + ( + "scenarios/fetch-spec-member-not-resolvable.json", + _made_up_code, + "problem code 'made_up_code' is not in the registry", + ), + ( + "scenarios/mint-async-build.json", + lambda doc: doc["exchanges"][0]["response"].update(status=200), + "a mint step's build answers 200; a mint expects an operation", + ), + ( + "served/openapi.json", + _drop_paths("/api/graph/"), + "no route under /api/graph", + ), + ( + "served/openapi.json", + lambda doc: doc["paths"].update({"/api/skills": {}}), + "/api/skills is under no deployed surface", + ), + ( + "scenarios/fetch-ref-newest-version.json", + _set_outcome(0, lambda o: o["newest_version"].update(content_version=None)), + "step 0 expects", + ), ( "scenarios/mint-async-build.json", _set_step(0, window=[2020, 2023]), @@ -882,6 +1006,21 @@ def _versions_forbidden(response: Any) -> None: "picked-sentence-not-taken-from-the-response", "versions-without-limit", "versions-forbidden-raises", + "retry-past-the-budget", + "retry-of-a-refusal-not-retryable", + "retry-of-a-400", + "build-504-retried-twice", + "pick-posted-without-a-body", + "build-posted-without-a-body", + "builds-in-another-order", + "poll-of-another-operation", + "signed-url-not-the-redirect", + "redirect-without-location", + "synthetic-problem-code-unregistered", + "mint-answering-200", + "served-document-without-graph", + "served-document-with-skills", + "newest-version-not-the-listed-one", "mint-step-narrowed", ], ) diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index 4cc523d..d7f64fe 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -13,7 +13,9 @@ Checks that every packaged schema is valid draft 2020-12 and that every document validates against its schema, then what the schemas cannot express: -- `served/SOURCE.json` names a 40-character dfo-apis commit. +- `served/SOURCE.json` names a 40-character dfo-apis commit, and + `served/openapi.json` holds routes under each of SURFACE_PREFIXES and none + outside them and PLATFORM_PREFIXES. - Every `strict-fields.json` pointer resolves in `served/openapi.json` and names each property once. A required entry's property stays in its schema's `required` list and admits no null; an enum entry's property admits every @@ -35,8 +37,9 @@ parent names. In a recorded scenario each API request matches a route and method in `served/openapi.json`, its JSON body validates against the route's request schema, each JSON response body validates against the - route's schema for its status, and a problem document's `code` is an active - code registered with that status. + route's schema for its status, a required member included when it admits + null. In every scenario a problem document's `code`, a failed operation's + error included, is an active code registered with its status. - Each error a scenario expects, other than a `SearchWarning` or `DataWarning`, carries a refusal's code from its exchanges, a failed operation's included, or a client code of its class. @@ -50,7 +53,11 @@ record holds posts the input the steps derive: the question, a choice's data_query or dataset_resubmit entries, or a member's identity with the entity groups of the roles its build left bound as they were, and each - build posts the options its layout gives. Every + build posts the body `build_body` gives for the spec the step builds, its + narrowing and its layout. A POST carries its body, a refused request + repeated is a retry only as `may_retry` allows, each poll names the + operation the client holds, and each signed download is the `location` the + files route answered. Every absolute URL a record holds, a `url` request or a `location` header, has the query `X-Goog-Signature=redacted`. - Each ref example's file name matches its `name` and gets the verdict it @@ -60,9 +67,7 @@ - Each rule file under `rules/` validates against `rules.schema.json`, names the rule its file name names, and names each vector once. -A recorded body is checked with one allowance: a required member whose schema -admits null may be absent, because the server leaves null members out of the -bodies it serves. It does not import `dfo_client_contract`, whose tests replay +It does not import `dfo_client_contract`, whose tests replay the rule vectors. `tools/capture_client_contract.py` imports the outcome rules from here, so the records are written by the code that checks them. """ @@ -210,6 +215,34 @@ def _allowed_values(openapi: dict[str, Any], schema: Any) -> set[str]: return values +# The route prefixes of the surfaces the deployed composition mounts, and of +# the platform routes beside them. The served document holds these and only +# these. +SURFACE_PREFIXES = ("/api/search", "/api/datasets", "/api/graph", "/api/presentation") +PLATFORM_PREFIXES = ("/codes",) + + +def surface_problems(openapi: Mapping[str, Any]) -> list[str]: + """A surface of SURFACE_PREFIXES the document lacks, and a path under no + surface or platform prefix.""" + + def under(path: str, prefix: str) -> bool: + return path == prefix or path.startswith(prefix + "/") + + paths = list(openapi.get("paths", {})) + problems = [ + f"served/openapi.json: no route under {prefix}, so its surface is not mounted" + for prefix in SURFACE_PREFIXES + if not any(under(path, prefix) for path in paths) + ] + problems.extend( + f"served/openapi.json: {path} is under no deployed surface" + for path in paths + if not any(under(path, p) for p in (*SURFACE_PREFIXES, *PLATFORM_PREFIXES)) + ) + return problems + + def _check_source(source: Any) -> list[str]: if not isinstance(source, dict): return ["served/SOURCE.json: not an object"] @@ -578,6 +611,23 @@ def _check_problem_code( _PROXY_RETRY = "retry_after_delay" # The retries a client makes by default after a retryable refusal. MAX_RETRIES = 2 +# A build cut off by a retryable 504 is posted once more only. +MAX_BUILD_TIMEOUT_RETRIES = 1 + + +def may_retry( + request: Mapping[str, Any], response: Mapping[str, Any], used: int +) -> bool: + """Whether a client sends `request` again after `response`, having retried + it `used` times: the response is a retryable refusal and the retries stay + within MAX_RETRIES, or within MAX_BUILD_TIMEOUT_RETRIES for a build cut + off by a 504.""" + status = response["status"] + if status < 400 or not retryable(status, response.get("json")): + return False + build = request["method"] == "POST" and request.get("path") == "/datasets" + limit = MAX_BUILD_TIMEOUT_RETRIES if build and status == 504 else MAX_RETRIES + return used < limit def gap_kinds(actions: Mapping[str, Mapping[str, Any]]) -> dict[str, str]: @@ -1179,7 +1229,8 @@ class _UnfitError(Exception): _SEARCH = ("POST", "/search/resolve") _BUILD = ("POST", "/datasets") -_POLL = ("GET", "/datasets/operations/") +# The path a client polls an operation at, under the base URL. +POLL_PATH = "/datasets/operations/{operation_id}" _MANIFEST = {"$ref": "#/components/schemas/Manifest"} _OPERATION = {"$ref": "#/components/schemas/OperationResource"} # The bare Parquet rendering a fetch asks for, by layout. @@ -1239,6 +1290,24 @@ def versions_path(spec_id: str) -> str: return f"/datasets/{spec_id}/versions?limit=1" +def build_body( + spec: Mapping[str, Any], + scope: Mapping[str, Any] | None, + rendering: Mapping[str, Any], +) -> dict[str, Any]: + """The body a client posts to build `spec`, a step's `spec` or a ref's: + its spec_id and unmodified definition, `scope` when it narrows anything, + and `rendering` as the options.""" + input_: dict[str, Any] = { + "kind": "spec_id", + "spec_id": spec["spec_id"], + "definition": spec["definition"], + } + if scope: + input_["scope"] = dict(scope) + return {"schema_version": 1, "input": input_, "options": dict(rendering)} + + def pick_artifact( manifest: Mapping[str, Any], rendering: Mapping[str, Any] ) -> dict[str, Any] | None: @@ -1468,35 +1537,34 @@ def kinds(self) -> dict[str, str]: # -- exchanges -- - def call(self, method: str, target: str, *, retries: bool = True) -> dict[str, Any]: - """The exchange a client acts on for its next request: with `retries`, - the last of a run that repeats one request, each refusal before it a - retry. `target` is a path under the base URL, a path prefix ending in - `/`, `origin` for a root-relative URL or `url` for an absolute one.""" + def call( + self, method: str, target: str, *, kind: str = "path", retries: bool = True + ) -> dict[str, Any]: + """The exchange a client acts on for its next request, whose `kind`, + `path`, `origin_path` or `url`, is exactly `target`. With `retries`, + a refusal followed by the same request is retried as `may_retry` + allows, and the last exchange of the run is the one acted on.""" if self.cursor >= len(self.exchanges): raise _UnfitError(f"the steps make a {method} {target} the record lacks") exchange = self.exchanges[self.cursor] request = exchange["request"] - actual = request.get("path") or ( - "origin" if "origin_path" in request else "url" - ) - fits = request["method"] == method and ( - actual == target or (target.endswith("/") and actual.startswith(target)) - ) - if not fits: + if request["method"] != method or request.get(kind) != target: + actual = request.get("path") or request.get("origin_path") or request["url"] raise _UnfitError( f"exchange {self.cursor} is {request['method']} {actual}, where the " f"steps make a {method} {target}" ) self.cursor += 1 + used = 0 while ( retries - and exchange["response"]["status"] >= 400 and self.cursor < len(self.exchanges) and self.exchanges[self.cursor]["request"] == request + and may_retry(request, exchange["response"], used) ): exchange = self.exchanges[self.cursor] self.cursor += 1 + used += 1 return exchange def acted_on(self, exchange: dict[str, Any], schema: Any = None) -> Any: @@ -1531,18 +1599,18 @@ def body(self, response: dict[str, Any]) -> bytes: def download(self, target: str, digest: str, *, origin: bool) -> None: """A file through the route that redirects to its signed URL: an artifact's root-relative `url` when `origin`, else a path under the - base URL. A refused signed URL, or bytes that do not hash to `digest`, - ask the route once more, and a second failure raises.""" + base URL. The client fetches the URL the route's `location` names. A + refused signed URL, or bytes that do not hash to `digest`, ask the + route once more, and a second failure raises.""" failure = ClientError("download_failed") for _ in range(2): - exchange = self.call("GET", "origin" if origin else target) - asked = exchange["request"].get("origin_path", target) - if asked != target: - raise _UnfitError( - f"the record asks {asked}, where the rules ask {target}" - ) + kind = "origin_path" if origin else "path" + exchange = self.call("GET", target, kind=kind) self.acted_on(exchange) - signed = self.call("GET", "url", retries=False)["response"] + location = exchange["response"].get("headers", {}).get("location") + if not isinstance(location, str): + raise _UnfitError(f"the redirect from {target} names no location") + signed = self.call("GET", location, kind="url", retries=False)["response"] if signed["status"] >= 400: failure = ClientError("download_failed") continue @@ -1552,11 +1620,10 @@ def download(self, target: str, digest: str, *, origin: bool) -> None: raise failure def resolve(self, posts: dict[str, Any]) -> Answer: - """A Search request whose recorded body, when it has one, posts the - input `posts`.""" + """A Search request whose recorded body posts the input `posts`.""" exchange = self.call(*_SEARCH) sent = exchange["request"].get("json") - if sent is not None and sent.get("input") != posts: + if not isinstance(sent, dict) or sent.get("input") != posts: raise _UnfitError( f"exchange {self.cursor - 1} posts {json.dumps(sent.get('input'))[:300]}" f", where the rules post {json.dumps(posts)[:300]}" @@ -1566,34 +1633,33 @@ def resolve(self, posts: dict[str, Any]) -> Answer: # -- builds -- def posted_build( - self, rendering: dict[str, Any], scope: dict[str, Any] | None + self, + spec: Mapping[str, Any], + rendering: dict[str, Any], + scope: dict[str, Any] | None, ) -> dict[str, Any]: - """A build request whose recorded body, when it has one, posts - `rendering` as its options and `scope` as its input's scope.""" + """A build request whose recorded body is the one `build_body` gives + for `spec`, `scope` and `rendering`.""" exchange = self.call(*_BUILD) sent = exchange["request"].get("json") - if sent is None: - return exchange - if sent.get("options") != rendering: - raise _UnfitError( - f"exchange {self.cursor - 1} posts options {sent.get('options')}, " - f"where the rules post {rendering}" - ) - if "input" in sent and sent["input"].get("scope") != scope: + posts = build_body(spec, scope, rendering) + if sent != posts: raise _UnfitError( - f"exchange {self.cursor - 1} posts scope " - f"{json.dumps(sent['input'].get('scope'))}, where the rules post " - f"{json.dumps(scope)}" + f"exchange {self.cursor - 1} posts {json.dumps(sent)[:300]}, " + f"where the rules post {json.dumps(posts)[:300]}" ) return exchange def build( - self, rendering: dict[str, Any], scope: dict[str, Any] | None = None + self, + spec: Mapping[str, Any], + rendering: dict[str, Any], + scope: dict[str, Any] | None = None, ) -> dict[str, Any]: - """A build of the latest version, posting `rendering` as its options - and `scope` as its input's scope: the manifest it answers, through a - long build when it answers 202.""" - exchange = self.posted_build(rendering, scope) + """A build of `spec`'s latest version, posting `rendering` as its + options and `scope` as its input's scope: the manifest it answers, + through a long build when it answers 202.""" + exchange = self.posted_build(spec, rendering, scope) if exchange["response"]["status"] != 202: return self.acted_on(exchange) resource = self.acted_on(exchange, _OPERATION) @@ -1612,7 +1678,8 @@ def long_build( self.long_builds.append(build.entry) while build.result is None: build.next_wait() - response = self.call(*_POLL, retries=False)["response"] + path = POLL_PATH.format(operation_id=build.entry["operation_id"]) + response = self.call("GET", path, retries=False)["response"] body = response.get("json") if response["status"] < 400: self.strict(_OPERATION, body) @@ -1643,7 +1710,7 @@ def fetched( strict: bool, ) -> dict[str, Any]: """One member: the build, then the member's files.""" - return self.member(parts, spec, self.build(rendering), rendering, strict) + return self.member(parts, spec, self.build(spec, rendering), rendering, strict) def member( self, @@ -1721,7 +1788,7 @@ def stored_version(self, member: dict[str, Any]) -> dict[str, Any]: return stored try: - manifest = self.build(rendering) + manifest = self.build(spec, rendering) except ClientError as error: if error.error_class(self.client_codes) not in REBUILD_REFUSED: raise @@ -1859,7 +1926,7 @@ def _fetch(self, step: dict[str, Any]) -> dict[str, Any]: def _fetch_spec(self, step: dict[str, Any]) -> dict[str, Any]: rendering = rendering_for(step.get("layout")) - manifest = self.build(rendering, posted_scope(step)) + manifest = self.build(step["spec"], rendering, posted_scope(step)) strict = step.get("strict", False) member = self.member([], step["spec"], manifest, rendering, strict) return {"dataset": dataset_summary([member], [])} @@ -1870,9 +1937,11 @@ def _fetch_ref(self, step: dict[str, Any]) -> dict[str, Any]: def _mint(self, step: dict[str, Any]) -> dict[str, Any]: rendering = rendering_for(step.get("layout")) - exchange = self.posted_build(rendering, None) + exchange = self.posted_build(step["spec"], rendering, None) if exchange["response"]["status"] == 200: - raise _UnfitError("a mint step's build answers an operation") + raise _UnfitError( + "a mint step's build answers 200; a mint expects an operation" + ) resource = self.acted_on(exchange, _OPERATION) headers = exchange["response"].get("headers", {}) self.minted = _Minted( @@ -1881,13 +1950,18 @@ def _mint(self, step: dict[str, Any]) -> dict[str, Any]: return _operation_outcome(resource) def _operation(self, step: dict[str, Any]) -> dict[str, Any]: - exchange = self.call("GET", f"/datasets/operations/{step['operation_id']}") + exchange = self.call("GET", POLL_PATH.format(operation_id=step["operation_id"])) resource = self.acted_on(exchange, _OPERATION) headers = exchange["response"].get("headers", {}) rendering = rendering_for(step.get("layout")) self.minted = _Minted(resource, headers, None, None, rendering) return _operation_outcome(resource) + def _newest_version(self, step: dict[str, Any]) -> dict[str, Any]: + return { + "newest_version": {"content_version": self.newest(step["spec"]["spec_id"])} + } + def _result(self, step: dict[str, Any]) -> dict[str, Any]: if self.minted is None: raise _UnfitError("result follows no mint or operation") @@ -2128,17 +2202,29 @@ def _check_scenarios( problems.extend(_check_body_files(file_name, record, parent, directory)) recorded = parent or record base_path = urlsplit(recorded["origin"]["base_url"]).path.rstrip("/") - if origin["kind"] == "recorded": - for index, exchange in enumerate(record["exchanges"]): + for index, exchange in enumerate(record["exchanges"]): + label = f"scenarios/{file_name}: exchange {index}" + if origin["kind"] == "recorded": problems.extend( - _check_exchange( - f"scenarios/{file_name}: exchange {index}", - exchange, - base_path, - routes, - registry, - ) + _check_exchange(label, exchange, base_path, routes, registry) ) + elif "json" in exchange["response"]: + problems.extend( + _check_problem_code(label, exchange["response"], registry) + ) + for resource in _failed_operations(record): + error = resource.get("error") + status = error.get("status") if isinstance(error, dict) else None + problems.extend( + _check_problem_code( + f"scenarios/{file_name}: failed operation", + { + "status": status if isinstance(status, int) else 500, + "json": error, + }, + registry, + ) + ) try: derived = expected_outcomes( record, @@ -2326,6 +2412,7 @@ def validate() -> list[str]: openapi = _load(PACKAGE_DIR / "served" / "openapi.json") registry = _load(REGISTRY_PATH) problems = _check_source(_load(PACKAGE_DIR / "served" / "SOURCE.json")) + problems.extend(surface_problems(openapi)) strict = _load(PACKAGE_DIR / "strict-fields.json") errors = _schema_problems( From 3b696918c9ea8780f8d6a33a4a627003b406bbfc Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Wed, 21 Oct 2026 12:16:06 +0200 Subject: [PATCH 19/39] feat(client-contract): pin retries, downloads, warnings and refusal shapes Outcomes gain retry_waits, the seconds before each retry, and warnings, the codes API responses issued. A retry waits Retry-After, else 0.5 s doubling to 8 s, and a record that ends with retries left is unfit. The files route follows the ordinary retry rules; a failed signed fetch gets one more round, and a second network failure raises as itself. A relative Location resolves against the files route. New tables: proxy-codes.json for the website proxy's error codes and warning-codes.json for the warnings a client issues itself, each with its schema. client-codes.json rows state retryable, and key_empty joins them. The validator compares the whole Search body, checks that recorded commits match served/SOURCE.json, refuses any absolute URL off the storage host, and reads facets: {} and entities: {} as no narrowing. New scenarios pin a signed URL refused twice, a relative Location, a failed operation with no error, an unreadable versions page, a 504 carrying Retry-After, a Sunset-only warning, a part status that is not a string, a definition naming another spec_id, an option without a data_query, a Search response with no JSON body, and an empty narrowing. Steps no longer take timeout; the README states the clients' timeouts. 79 scenarios, 31 recorded and 48 synthetic. --- python/client-contract/CHANGELOG.md | 10 +- python/client-contract/README.md | 45 +- .../src/dfo_client_contract/__init__.py | 11 +- .../src/dfo_client_contract/client-codes.json | 26 +- .../client-codes.schema.json | 12 + .../src/dfo_client_contract/contract.py | 20 + .../src/dfo_client_contract/proxy-codes.json | 15 + .../proxy-codes.schema.json | 49 + .../src/dfo_client_contract/rules/README.md | 6 +- .../rules/credentials-file.json | 9 + .../dfo_client_contract/rules/key-lookup.json | 19 + .../rules/rules.schema.json | 6 +- .../dfo_client_contract/scenario.schema.json | 72 +- .../answer-definition-spec-id-mismatch.json | 3685 +++++++++++++++++ .../answer-part-status-not-a-string.json | 3609 ++++++++++++++++ .../choose-option-without-data-query.json | 244 ++ .../fetch-ref-signed-url-refused-twice.json | 865 ++++ .../scenarios/fetch-retry-after-504.json | 7 +- .../scenarios/fetch-spec-504-retry-after.json | 1033 +++++ .../scenarios/fetch-spec-504-twice.json | 5 +- .../scenarios/fetch-spec-empty-narrowing.json | 929 +++++ .../fetch-spec-relative-location.json | 927 +++++ .../newest-version-unreadable-page.json | 122 + .../operation-failed-without-error.json | 90 + .../scenarios/search-no-json-body.json | 45 + .../scenarios/search-proxy-rate-limited.json | 3 + .../scenarios/search-proxy-unavailable.json | 6 +- .../scenarios/search-retry-after-503.json | 3 + .../scenarios/search-sunset-warning.json | 501 +++ .../dfo_client_contract/warning-codes.json | 30 + .../warning-codes.schema.json | 50 + python/client-contract/tests/test_contract.py | 13 + python/client-contract/tests/test_rules.py | 4 +- tools/README.md | 4 +- tools/capture_client_contract.py | 480 ++- tools/tests/test_capture_client_contract.py | 18 +- tools/tests/test_validate_client_contract.py | 273 +- tools/validate_client_contract.py | 559 ++- 38 files changed, 13582 insertions(+), 223 deletions(-) create mode 100644 python/client-contract/src/dfo_client_contract/proxy-codes.json create mode 100644 python/client-contract/src/dfo_client_contract/proxy-codes.schema.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-part-status-not-a-string.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-option-without-data-query.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused-twice.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-retry-after.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-empty-narrowing.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-relative-location.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/search-no-json-body.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/search-sunset-warning.json create mode 100644 python/client-contract/src/dfo_client_contract/warning-codes.json create mode 100644 python/client-contract/src/dfo_client_contract/warning-codes.schema.json diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index 0a052ec..2fad949 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -11,11 +11,13 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be - `strict-fields.json` and its schema: 25 members that stay required and non-nullable, and the answer kinds, part statuses and operation statuses the clients branch on. - `actions.json` and its schema: the caller's next step for each of the 101 active refusal codes on `problem_details` or `no_data_reason`, with the gap kind of each no_data reason. - The status fallback for a refusal whose code has no row: 400 and 422 to `InvalidRequestError`, 401 to `AuthenticationError`, 403 to `PermissionDeniedError`, 404 and 410 to `NotFoundError`, 408 to `DfoTimeoutError`, 429 to `RateLimitError`, and any other 4xx or 5xx to `InvalidRequestError` or `ServerError`. -- `scenario.schema.json`, the scenario record, and 68 scenarios: 31 recorded against the composed dfo-apis app at `635943e03`, and 37 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 2,105,201 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, an identity resubmit answering another spec, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, a failed operation posted again, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route. -- `client-codes.json` and its schema: the 16 codes a client sets on the errors it raises itself, each with its error class and condition, disjoint from `actions.json` and `registries/codes.json`, and the `client_codes()` and `client_codes_schema()` accessors. Every scenario error the client raises itself carries its code, and `refusal_without_code` names a refusal whose body carries no code. +- `scenario.schema.json`, the scenario record, and 79 scenarios: 31 recorded against the composed dfo-apis app at `635943e03`, and 48 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 2,105,201 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a cut-off build retried after its Retry-After, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, a signed URL refused on both rounds, a relative files-route Location, an identity resubmit answering another spec, a part whose status is not a string, a Search spec whose definition names another spec_id, a Search response with no JSON body, an option with no data_query, empty entities and facets, a Sunset header issued once, an unreadable versions page, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, a failed operation posted again, a failed operation with no error, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route. +- `client-codes.json` and its schema: the 17 codes a client sets on the errors it raises itself, each with its error class, retryable flag and condition, disjoint from `actions.json` and `registries/codes.json`, and the `client_codes()` and `client_codes_schema()` accessors. Every scenario error the client raises itself carries its code, and `refusal_without_code` names a refusal whose body carries no code. +- `proxy-codes.json` and its schema, the website proxy's `rate_limited` and `transient_unavailable` codes with their statuses, and `warning-codes.json` and its schema, the 5 codes a client sets on the warnings it issues itself, with the `proxy_codes()` and `warning_codes()` accessors. +- Scenario outcomes give `retry_waits`, the waits before each retry, and `warnings`, the warning codes a step's responses issued. Scenario steps take no `timeout`. - `dataset-ref.schema.json`, the frozen `DatasetRef` format, with accepted and rejected examples. - `tools/capture_client_contract.py`, which captures `served/openapi.json` from a dfo-apis checkout in process and records the scenarios against a base URL, dev by default, or with `record --offline` derives their outcomes again from the records with no request. A local app's signed URLs are written as the storage URLs a deployment signs. -- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, checks `client-codes.json` against them, and checks each scenario's `expect` against the outcomes its exchanges, `actions.json` and `client-codes.json` give, each Search request against the input its steps derive, a sentence lookup's `entity_groups` included, each build's `input.scope` against the narrowing its step names over the spec's bound roles, each build's options against its layout, and each download against its artifact's digest. The outcomes include each long build's operation id, poll waits and resubmissions, and a `VersionUnavailableError`'s newest version. -- The client rules and their vectors: the credentials path and file format, the key lookup order, the key format check, and the cache directory and layout. +- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, checks `client-codes.json` against them, and checks each scenario's `expect` against the outcomes its exchanges, `actions.json` and `client-codes.json` give, each Search request against the input its steps derive, a sentence lookup's `entity_groups` included, each build's `input.scope` against the narrowing its step names over the spec's bound roles, each build's options against its layout, each Search request's whole body, each download against its artifact's digest, each recorded scenario's commit against `served/SOURCE.json`, each proxy refusal's code against `proxy-codes.json`, and each absolute URL against the storage host. A record that ends a run of retries while a retry remains does not fit. The outcomes include each long build's operation id, poll waits and resubmissions, and a `VersionUnavailableError`'s newest version. +- The client rules and their vectors: the credentials path and file format, the key lookup order, with an empty `api_key` refused as `key_empty` and an empty profile key as `profile_without_key`, the key format check, and the cache directory and layout. [unreleased]: https://github.com/DevelopmentFinanceObservatory/spec-kit/commits/main/python diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 78c0bba..5421fca 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -42,6 +42,10 @@ uv run ty check src/dfo_client_contract | `actions.schema.json` | The shape of `actions.json` | | `client-codes.json` | The code, class and condition of each error a client raises itself | | `client-codes.schema.json` | The shape of `client-codes.json` | +| `proxy-codes.json` | The code and status of each refusal the website proxy answers itself | +| `proxy-codes.schema.json` | The shape of `proxy-codes.json` | +| `warning-codes.json` | The code, class and condition of each warning a client issues itself | +| `warning-codes.schema.json` | The shape of `warning-codes.json` | | `scenario.schema.json` | One scenario record | | `scenarios/` | The scenario records, and the binary response bodies they name | | `dataset-ref.schema.json` | The frozen `DatasetRef` format | @@ -55,6 +59,8 @@ uv run ty check src/dfo_client_contract | `strict_fields()` | `strict-fields.json`, parsed | | `actions()` | `actions.json`, parsed | | `client_codes()` | `client-codes.json`, parsed | +| `proxy_codes()` | `proxy-codes.json`, parsed | +| `warning_codes()` | `warning-codes.json`, parsed | | `scenarios()` | Every scenario record; raises `RuntimeError` when none load | | `ref_examples()` | Every `DatasetRef` example; raises `RuntimeError` when none | | `rule(name)` | The vector file for one of `RULES` | @@ -63,13 +69,13 @@ uv run ty check src/dfo_client_contract ## Served document -`served/openapi.json` is `app.openapi()` of the composed dfo-apis app as deployed, with the Search, Datasets, Graph and Presentation surfaces mounted. `served/SOURCE.json` names the commit it came from as `{format_version, repository, commit, captured_from}`. It names the closed runtime models, `Manifest`, `ArtifactEntryModel`, every Search part model and `ProblemDetails` among them, which the per-surface schema routes leave open. Both clients generate wire types from it and parse tolerantly regardless of its `additionalProperties: false`: an unknown member or enum value passes through. +`served/openapi.json` is `app.openapi()` of the composed dfo-apis app as deployed, with the Search, Datasets, Graph and Presentation surfaces mounted and the platform's `/codes/{code}` route beside them, and no other route. `served/SOURCE.json` names the commit it came from as `{format_version, repository, commit, captured_from}`. It names the closed runtime models, `Manifest`, `ArtifactEntryModel`, every Search part model and `ProblemDetails` among them, which the per-surface schema routes leave open. Both clients generate wire types from it and parse tolerantly regardless of its `additionalProperties: false`: an unknown member or enum value passes through. ## Strict fields `strict-fields.json` lists the members a client cannot act without. Each pointer names one property of one component schema, `/components/schemas//properties/`. A `required` entry stays in its schema's `required` list and admits no null, so a client raises `ContractError` when one is missing or null. An `enums` entry keeps every listed value, the values a client branches on: the answer kinds, the part statuses and the operation statuses. A client still accepts a value no entry lists. -The answer's `kind` and each part's `status` are the discriminators of their unions in the served document. A search response with no `kind` raises `ContractError`, as a part with no `status` does, although the served document gives `kind` a default and leaves it out of `required`. A part `status` a client does not know raises nothing and makes the part an `unknown` gap. An answer `kind` a client does not know raises `ContractError`, because the client cannot read the answer. +The answer's `kind` and each part's `status` are the discriminators of their unions in the served document. A search response with no `kind` raises `ContractError`, as a part with no `status` does, although the served document gives `kind` a default and leaves it out of `required`. A part `status` a client does not know raises nothing and makes the part an `unknown` gap. An answer `kind` a client does not know raises `ContractError`, because the client cannot read the answer. A Search response body that is not an object, a part whose `status` is not a string, at pointer `/parts//status`, and a definite or candidate spec whose `definition.spec_id` differs from its `spec_id` raise `ContractError` `contract_violation`, in a Search response as in a ref; `answer-part-status-not-a-string` and `answer-definition-spec-id-mismatch` pin the last two. The required members are each part's `status` and its payload (`spec`, `candidates`, `no_data`, `unsupported`), `Resolution.parts`, `CandidateSet.specs`, `NoData.reason`, `Unsupported.code`, `Spec.spec_id` and `definition`, `SpecDefinition.spec_id`, the manifest's `definition`, `definition.spec_id`, `content_version` and `artifacts`, each artifact's `artifact_digest`, `rendering` and `url`, and the operation resource's `operation`, `operation_id` and `status`. The operation's `poll` is nullable in the served document, so a client builds the poll path from `operation_id`. @@ -91,7 +97,7 @@ The required members are each part's `status` and its payload (`spec`, `candidat | `report` | `ServerError` | Reports the trace id, after the client's retries | | `upgrade` | `ContractError` | Upgrades the client | -A code that maps to `no_data_reason` also carries `gap_kind`, the kind of gap a no_data part with that reason becomes: `choice`, `no_data`, `not_understood` or `unsupported`. `choose` goes with `choice` and only with it. `choose` and `ask_data_question` name a next step inside an answer, so a code that also reaches a problem document takes another action. The website proxy's own `{error, retry, detail}` body carries its code in `error`. `capability_unavailable` is a well-formed request for a format, reshape or conversion class the deployment does not enable, answered 501; its action is `fix_request`, since the caller asks for another one, and `fetch-spec-capability-unavailable` pins it. +A code that maps to `no_data_reason` also carries `gap_kind`, the kind of gap a no_data part with that reason becomes: `choice`, `no_data`, `not_understood` or `unsupported`. `choose` goes with `choice` and only with it. `choose` and `ask_data_question` name a next step inside an answer, so a code that also reaches a problem document takes another action. The website proxy's own `{error, retry, detail}` body carries its code in `error`. `proxy-codes.json` lists those codes with their status, `rate_limited` at 429 and `transient_unavailable` at 502, and the validator refuses a proxy body whose `error` it does not list at that status. No proxy code has a row here, so a client raises a proxy refusal with the class its status maps to. `capability_unavailable` is a well-formed request for a format, reshape or conversion class the deployment does not enable, answered 501; its action is `fix_request`, since the caller asks for another one, and `fetch-spec-capability-unavailable` pins it. A client maps a refusal whose code has no row, or that carries no code, on its HTTP status: @@ -106,13 +112,13 @@ A client maps a refusal whose code has no row, or that carries no code, on its H | any other 4xx | `InvalidRequestError` | | any other 5xx | `ServerError` | -A 408 is a timeout the caller retries, and a 410 names a resource that is gone, so the caller stops as it does on a 404. A no_data reason with no row becomes a `no_data` gap. +A 408 is a timeout the caller retries, and a 410 names a resource that is gone, so the caller stops as it does on a 404. A client reads a refusal's body, a problem document or the proxy's own, when its content type is `application/problem+json` or `application/json`; a body of any other type reads as no body, so the refusal carries no code. A no_data reason with no row becomes a `no_data` gap. An answer's gaps follow from its parts. A candidates part is a `choice` gap, its options the candidates. A no_data part is a gap of its reason's `gap_kind`, its options the no_data `options`, and of kind `timed_out` instead when the answer's `diagnostics.timed_out` is true. An unsupported part is an `unsupported` gap. A part whose status a client does not know is an `unknown` gap. ## Client codes -`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, and a one-line `condition`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps the server's code: the problem document's `code`, or the website proxy's `error`. A refusal whose body carries neither raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`; no other row does. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. The list holds no warning, since a warning carries the server's code. A `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and a null code when they differ in several ways. A `DataWarning` carries the manifest warning's code. +`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, `retryable`, and a one-line `condition`. `retryable` is the flag both clients generate onto the error: `deadline_exceeded`, `download_failed` and `network_error` are retryable, `digest_mismatch` and the rest are not, and `refusal_without_code` is retryable as its status is, which its row gives as `by_status`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps the server's code: the problem document's `code`, or the website proxy's `error`. A refusal whose body carries neither raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`; no other row does. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. The list holds no warning. `warning-codes.json` lists, sorted by code, each code a client sets on a warning it issues itself, with its class and condition: `route_deprecated`, a `DfoDeprecationWarning`, for a `Deprecation` or `Sunset` header; `server_warning`, a `DfoWarning`, for an `x-dfo-warning` header; and `key_checksum_mismatch`, `key_not_base62` and `key_unknown_prefix`, each a `DfoWarning`, for a key that fails the key-format rule with that reason. Both clients generate their warning codes from it and issue no other. No warning code is a code in another table or in `registries/codes.json`. A `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and a null code when they differ in several ways. A `DataWarning` carries the manifest warning's code. ## Scenarios @@ -132,9 +138,9 @@ A step that acts on an earlier result follows one: `choose` follows `search` or An exchange's request names its target in one of three ways. `path` is a path the client composes under the base URL, such as `/search/resolve`. `origin_path` is a root-relative URL the server returned, such as an artifact's `url`, which resolves against the base URL's origin and never against its path. `url` is an absolute URL outside the API, such as the signed storage URL a files route redirects to, which the client fetches with a bare request carrying no client header and no key. `json` holds the request body members that must match; a recorded scenario lists every member the client sent. The response gives `status`, the `headers` a client reads, and a `json` body or a `body_file`, a binary body in `scenarios/`. A scenario's own body files are named `.` and `-.`; a synthetic scenario may instead name a body file its parent names. -A `newest_version` outcome gives the `content_version` the step found, or null. An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a warning's code, which for a `SearchWarning` may be null, or for any other error the client raises itself its code in `client-codes.json`. A `VersionUnavailableError` also gives `newest_version`, the version the lookup found, or null. A dataset or error outcome of a step that made a long build gives `long_builds`, one entry per build the server ran on, in order: the `operation_id` the client polled last, the `poll_waits` in seconds before each poll, and the number of `resubmissions`. +A `newest_version` outcome gives the `content_version` the step found, or null. An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a warning's code, which for a `SearchWarning` may be null, or for any other error the client raises itself its code in `client-codes.json`. A `VersionUnavailableError` also gives `newest_version`, the version the lookup found, or null. A dataset or error outcome of a step that made a long build gives `long_builds`, one entry per build the server ran on, in order: the `operation_id` the client polled last, the `poll_waits` in seconds before each poll, and the number of `resubmissions`. Any outcome of a step that retried a refused request gives `retry_waits`, the seconds before each retry in order, and any outcome of a step whose API responses issued warnings gives `warnings`, their codes from `warning-codes.json` in order. -Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry where the retry rules allow one, except on a poll, where the long-build rules count retries, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, each POST carries its body, each build posts the body the rules give for the spec it builds, so the builds' order and spec_ids are checked, each Search request posts the input the rules give: the question, a choice's input, or a member's identity, each poll names the operation the client holds, and each signed download is the URL the files route's `location` names. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. +Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry where the retry rules allow one, except on a poll, where the long-build rules count retries, and a record that ends a run of retries while the rules allow another does not fit, since the client makes it, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, each POST carries its body, each build posts the body the rules give for the spec it builds, so the builds' order and spec_ids are checked, each Search request posts the whole body `{"schema_version": 1, "input": ...}` with the input the rules give: the question, a choice's input, or a member's identity, each poll names the operation the client holds, each signed download is the URL the files route's `location` names, each retry waits the wait the retry rules give, and each response's warning headers issue the warnings the warning rules give. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. A recorded scenario's request and response bodies validate against their route's schemas in `served/openapi.json`. A required member stays required when its schema admits null: the body carries it, as null or a value. A member the schema leaves optional may be absent or null, and a client reads both as null. @@ -143,32 +149,37 @@ A client replays a scenario by serving the exchanges in order: - A request matches the next exchange on its method and target, and on each listed `json` member, compared as parsed JSON values. - A request with no exchange left, or one that matches none, fails the scenario, and so does an exchange the call never makes. - `path` resolves against the base URL the replay gives the client, and `origin_path` against that base URL's origin, so a replay can run under any base URL form. -- Sleeps are not replayed: the replay injects the client's clock and sleep, and each wait the client asks for advances the clock at once. The waits before polls are the outcome's `poll_waits`. -- Every absolute URL a record holds, a `url` request or a `location` header, keeps its scheme, host and path, and its query reads `X-Goog-Signature=redacted`, whatever signed it. +- Sleeps are not replayed: the replay injects the client's clock and sleep, and each wait the client asks for advances the clock at once. The waits before polls are the outcome's `poll_waits`, and the waits before retries its `retry_waits`. +- A replay runs each scenario as a fresh process, so no warning has been issued when it starts. +- Every absolute URL a record holds, a `url` request or a `location` header, is a signed URL on `https://storage.googleapis.com` with its path kept and its query `X-Goog-Signature=redacted`, whatever signed it; a `location` may also name a route under the base URL. The validator compares hostnames and refuses any other host, a local app's under any name or port included. The records also fix these client rules: - A fetch builds each distinct `spec_id` once, in part order, and finishes one member (build, the sentence when the client lacks it, files, download) before the next. -- A fetch of a spec posts its narrowing as the build's `input.scope`, and posts no `scope` when it narrows nothing. A mint takes a layout and no narrowing, so it posts no `scope`. `window` posts `{"kind": "range", "start_year", "end_year"}` for a pair of years, or `{"kind": "all"}` or `{"kind": "latest"}`, and `facets` posts each axis as `{"ref": ...}`. The server's `scope.entities` replaces the spec's whole entity binding, so `entities` posts a whole map: the roles the spec's `definition.identity.entities` binds, with each role the caller names replaced by its refs and each role the caller binds to null dropped. Naming `origin` alone on a spec bound to `origin` and `destination` keeps `destination`. A fetch that names no role posts no `entities`. +- A fetch of a spec posts its narrowing as the build's `input.scope`, and posts no `scope` when it narrows nothing. A mint takes a layout and no narrowing, so it posts no `scope`. `window` posts `{"kind": "range", "start_year", "end_year"}` for a pair of years, or `{"kind": "all"}` or `{"kind": "latest"}`, and `facets` posts each axis as `{"ref": ...}`, and `facets: {}` names no axis and posts no `facets`. The server's `scope.entities` replaces the spec's whole entity binding, so `entities` posts a whole map: the roles the spec's `definition.identity.entities` binds, with each role the caller names replaced by its refs and each role the caller binds to null dropped. Naming `origin` alone on a spec bound to `origin` and `destination` keeps `destination`. A fetch that names no role, `entities: {}` included, posts no `entities`, so a fetch whose narrowing is all empty posts no `scope`; `fetch-spec-empty-narrowing` pins it. - A built `spec_id` that differs from the posted one, or a spec with no sentence, takes its sentence from Search: the client posts the built definition's `identity` as one `dataset_resubmit` identity entry, with the member's first part as `variable_text`, or `"dataset"` when no answer part names it, and checks the answer's `spec_id` equals the built one. The entry's `entity_groups` holds the spec's `resolved.entity_groups` for each role the built identity binds to the same entities as the spec's definition, so a window or facets narrowing keeps every group and a role the narrowing rebound or dropped loses its group. The entry leaves `entity_groups` out when it keeps no group, as for a resumed operation, whose spec the client does not hold. The server reads a role posted without its group as its members, so a narrowed spec of flows to the least developed countries would read "44 recipients" in place of "the 44 Least Developed Countries". - A dataset of several members puts the `part` column first, then each member's columns in member order, each column once. The `part` value on a member's rows is the member's `parts` joined by `"; "`, so a member that answers two folded parts reads `"health ODA disbursements; education ODA disbursements"`, or the member's sentence when `parts` is empty. - A choice names its part by index, by variable text, or by a word that one gap's options mention, and its option by index or label; a candidate is named by index. A label is matched among the options that mention the word the part was named by. With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. -- A choice raises `InvalidRequestError` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is out of range or matches no label or several. It raises the same when an entry it would post cannot be built: a part with no `variable_text`, or a part of a status the client does not know that has no `restatement`. A chosen option whose `data_query` holds other than one part raises `ContractError`. +- A choice raises `InvalidRequestError` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is out of range or matches no label or several. It raises the same when an entry it would post cannot be built: a part with no `variable_text`, or a part of a status the client does not know that has no `restatement`. A chosen option whose `data_query` holds other than one part raises `ContractError`, and so does a chosen option with no `data_query`, in a one-part answer as in a several-part one, before any request. - Every pick of a candidate asks Search for the picked answer, and no client builds it locally. In a one-part answer the pick posts `dataset_resubmit`, without `raw_query`, with one identity entry: the candidate's identity and `entity_groups`, and the part's `variable_text`, `separate` and `operations` as below. The picked answer, its sentence with any "Assumed: …" clause, and its assumptions are Search's response. A choice of a no_data option in a one-part answer posts the option's `data_query` as the input. - In a several-part answer a choice posts `dataset_resubmit`, without `raw_query`, with one entry per part in part order. The chosen candidate posts an identity entry with its identity and `entity_groups`, and the chosen option its `data_query`'s one part as a parsed entry. A definite part posts an identity entry with its spec's identity and `entity_groups`. A candidates part left alone posts a `candidates` entry: its candidate set in the server's order, each with its identity and `entity_groups`, and its `ordering` and `truncated` echoed. The server cannot recompute that order, because it rests on the first answer's bind election and availability reads, and a parsed entry would cost an LLM bind. Any other part posts its `restatement` as a parsed entry, or a placeholder entry with its no_data `reason` or unsupported `code` when it has none. Every entry but a parsed one carries the part's `variable_text`, `separate` when true and `operations` when the part has any; `entity_groups` is left out when the spec has none. - Each identity a choice posts echoes its reading's assumptions as `assumptions`: the chosen candidate's entry carries its part's `reading_assumptions` under the candidate's `spec_id`, a definite part's entry carries the part's `assumptions`, and each candidate of a `candidates` entry carries its own `reading_assumptions` entry. Search then states the echoed items that still hold, so the picked answer states what that reading assumed. `[]` states none. An identity with no `assumptions` reads as a fresh request, so a client that holds no list for a reading, from a part that carries no `assumptions` or `reading_assumptions`, posts none. The identity entry that asks for a built sentence posts no `assumptions`, since it reads only the spec's own `rendered_sentence`. - A strict fetch raises the manifest's first warning above `info` severity as a `DataWarning` with that warning's code, before the sentence lookup and the download. - An identity resubmit whose answer is not one definite part of the built `spec_id`, with a sentence, raises `ContractError`. - The `frame` layout posts `{"format": "parquet", "bundle": false, "layout": "frame"}` as the build's `options` and downloads the artifact whose rendering's `layout` is `frame`; the `long` layout posts `{"format": "parquet", "bundle": false}` and downloads the bare Parquet artifact with any other layout. A fetch of an answer with several members in the `frame` layout raises `InvalidRequestError` before any build. -- A download asks the route that redirects to the signed URL: an artifact's `url`, or the file selector. A refused signed URL, or bytes that do not hash to the artifact's digest, ask the route once more, and a second failure raises `ServerError` with `download_failed` or `digest_mismatch`. +- A download asks the route that redirects to the signed URL, an artifact's `url` or the file selector, and fetches the URL its `location` names once. The route ask is an API request and follows the retry rules below, so a retryable refusal is retried within the budget and any other refusal, `artifact_expired` among them, raises at once. A failed fetch gets exactly one more round: a refused fetch or bytes that do not hash to the artifact's digest ask the route again, under the same retry rules, and fetch again, with no wait between rounds. A second failure raises `ServerError` with `download_failed`, or `digest_mismatch` when the bytes are wrong. A network error or timeout on the fetch is retryable, so it starts the second round too, and when the second round fails the same way the client raises that failure as itself, `network_error` or `deadline_exceeded`. The replay holds no network failure, so no scenario pins that case. +- A relative `location` resolves against the files route's URL, and the client fetches it on the API's origin as an `origin_path` request. A `location`, or a manifest artifact's `url`, on an origin other than the API's or `https://storage.googleapis.com` raises `ContractError` `contract_violation` before any fetch. A fetch on the storage host is bare and carries no API key. `fetch-spec-relative-location` pins the relative case. - A declined or catalogue answer is not complete, and fetching it raises `DeclinedError`. - Fetching an answer with a gap raises `IncompleteAnswerError` before any request, unless the fetch is partial and some part has a reading. - A fetch of an answer issues one `SearchWarning` when a definite part has an operation Search did not run, a departure, or a warning at severity `warn` or `degraded` with a `message`, or the answer's `diagnostics.warnings` holds such a warning. An `info` warning, and a warning with no `message`, issue nothing. Each way is one line a client shows: `Not done: ()` coded by the verb, the departure's `text` coded by its code, or `Note: ` coded by the warning's code, in part order with the diagnostics warnings last, and ways that show the same line count once, under the first one's code. A strict fetch raises the `SearchWarning` before any build, with the code of its one line, or a null code when there are several lines. A strict fetch raises it before the `frame` layout's several-member check. -- A ref's version is found in this order: the snapshot route and the files route at the stored digest; the file selector, `GET /datasets/{id}/{content_version}/file` with the ref's rendering as the query; and a build of the ref's spec in the ref's rendering, which must answer the same `content_version`. A snapshot refusal other than `artifact_expired` ends the lookup, so `snapshot_not_found` raises `NotFoundError` with no further request. A files route or selector refusal of `artifact_expired`, `artifact_not_found` or `not_found` takes the next step, and a selector file of another digest is not the stored file. A rebuild that answers another version, or that raises `InvalidRequestError`, `NotFoundError` or `VersionUnavailableError`, ends in `VersionUnavailableError` with the first refusal's code, or `version_unavailable` when nothing refused. Its `newest_version` is the version the rebuild answered, or else the newest stored version, which `GET /datasets/{id}/versions?limit=1` lists alone, as a `newest_version` step finds it, since the route lists versions newest first and needs no key; or null when that route lists none or refuses with `NotFoundError`. Any other refusal of the versions route raises. +- A ref's version is found in this order: the snapshot route and the files route at the stored digest; the file selector, `GET /datasets/{id}/{content_version}/file` with the ref's rendering as the query; and a build of the ref's spec in the ref's rendering, which must answer the same `content_version`. A snapshot refusal other than `artifact_expired` ends the lookup, so `snapshot_not_found` raises `NotFoundError` with no further request. A files route or selector refusal of `artifact_expired`, `artifact_not_found` or `not_found` takes the next step, and a selector file of another digest is not the stored file. A rebuild that answers another version, or that raises `InvalidRequestError`, `NotFoundError` or `VersionUnavailableError`, ends in `VersionUnavailableError` with the first refusal's code, or `version_unavailable` when nothing refused. Its `newest_version` is the version the rebuild answered, or else the newest stored version, which `GET /datasets/{id}/versions?limit=1` lists alone, as a `newest_version` step finds it, since the route lists versions newest first and needs no key; or null when that route lists none or refuses with `NotFoundError`. Any other refusal of the versions route raises, and a page whose `versions` is not a list of versions each with a `content_version` raises `ContractError` `contract_violation`, which `newest-version-unreadable-page` pins. - A build answers 200 with the manifest, or 202 with an operation the client polls at `/datasets/operations/{operation_id}`, the id of the operation it holds. A mint's build answers 202; a record whose mint answers 200 fits no mint step. Before each poll it waits the `Retry-After` of a 429 that refused the last poll, else the last operation resource's `retry_after_ms`, else the `Retry-After` of the response that carried that resource, else a backoff of 1, 2, 4 and then 8 seconds that advances only when it is used. -- A 429 poll spends no retry. Any other retryable refused poll spends one of the two retries, which a poll that answers restores, and a refusal that is not retryable raises. A poll that answers a failed operation whose error is retryable posts the same build once more and polls the operation it starts; a second failure, an error that is not retryable, and a resumed operation, whose build request the client does not hold, raise the operation's error. A refused poll whose code is `operation_failed` is a failed operation with that error. A 202 or resumed operation that already reads `failed` raises its error before any poll. +- A 429 poll spends no retry. Any other retryable refused poll spends one of the two retries, which a poll that answers restores, and a refusal that is not retryable raises. A poll that answers a failed operation whose error is retryable posts the same build once more and polls the operation it starts; a second failure, an error that is not retryable, and a resumed operation, whose build request the client does not hold, raise the operation's error. A refused poll whose code is `operation_failed` is a failed operation with that error. A failed operation whose resource carries no `error` raises `ServerError` with `operation_failed`, retryable by status 500 as a refusal without a document is, which `operation-failed-without-error` pins. A 202 or resumed operation that already reads `failed` raises its error before any poll. - Any other refusal is retried when it is retryable: as a problem document's `retryable` says, or the website proxy's `retry` of `retry_after_delay`, else when its status is 408, 429, 500, 502, 503 or 504. A client makes two retries by default, and the scenarios assume that default; a build cut off by a retryable 504 is posted once more only, and a second 504 raises. A refusal that is not retryable, or one past the retries, raises its error. -- A retry waits `Retry-After` when the response carries it. The scenarios hold no outcome for the waits before a retry, so a replay does not pin them. +- Each retry waits the refusal's `Retry-After` when it carries one, and otherwise the client's backoff for that attempt: 0.5 seconds before the first retry, doubling to at most 8. The build's 504 cut-off retry follows the same rule. `retry_waits` pins these waits, and `fetch-spec-504-retry-after` pins a cut-off that carries `Retry-After`. +- A 2xx response of a JSON route with no JSON body raises `ContractError` `unexpected_response`; `search-no-json-body` pins it for Search. +- A `Deprecation` or `Sunset` header on an API response, either alone, issues `route_deprecated` once per process per distinct pair of their values, and an `x-dfo-warning` header issues `server_warning` once per process per message. A signed fetch's headers issue nothing. `search-sunset-warning` pins a Sunset header alone, issued once over two responses that carry the same value. +- Timeouts follow the clients' design and are not replayed, since the replay advances the clock only by the waits the client asks for: the client's `timeout`, 30 s by default, bounds one request attempt; `search(timeout=60)` bounds the whole search, each attempt reading until that deadline, and None means no limit; `fetch(timeout=1800)` bounds the whole fetch, each download getting the time left on the fetch's deadline; a synchronous build POST, and mint's POST, read for up to 150 s within any outer deadline; `result(timeout=1800)` bounds the wait, and None means no limit. A poll attempt that hangs past the per-attempt timeout spends a retry, and a deadline that passes during a body read raises `DfoTimeoutError` `deadline_exceeded`. In TypeScript an infinite remaining time arms no timer, and a finite one above 2^31-1 ms is clamped. No scenario step takes a timeout. ## Recording @@ -185,13 +196,13 @@ Its `record` command runs every scenario against a base URL, dev's Cloud Run URL uv run tools/capture_client_contract.py record --offline --only answer-declined choose-refused-no-choice ``` -Each record names the commit in the responses' `x-dfo-commit` header, and the run refuses responses that name none or several. To record against a local app, run the composed app, with the same four surfaces mounted, from the checkout the document came from, with `DFO_BUILD_COMMIT` set to that checkout's commit, then pass its base URL: +Each record names the commit in the responses' `x-dfo-commit` header, and the run refuses responses that name none or several. Every recorded scenario's `origin.dfo_commit` equals `served/SOURCE.json`'s `commit`, and the validator refuses one that differs, so the records and the served document describe one server. To record against a local app, run the composed app, with the same four surfaces mounted, from the checkout the document came from, with `DFO_BUILD_COMMIT` set to that checkout's commit, then pass its base URL: ```bash uv run tools/capture_client_contract.py record --base-url http://127.0.0.1:8083/api ``` -A record's `origin.base_url` is the base URL the run was given, a local app's included. A local app's signed URL, which its launcher serves at `/__e2e__/blob/{bucket}/{object}` on the API's origin, is written as `https://storage.googleapis.com/{bucket}/{object}` with its query redacted, as a deployment signs it, because a production download is cross-origin and the client sends no key there; the run refuses a record whose signed URL or `location` header still names the base URL's host. A server answers a version it has built inline, so `mint-async-build` and `operation-resume` each need a spec just above the 100,000-row sync budget that the server has not built: the DAC2a recipient flows from 2018 to 2024 for the mint, and from 2017 to 2024 for the resumed operation. A local recording therefore starts on a fresh datasets database with `DATASETS_SYNC_BUDGET_ROWS=100000`. `--scenarios-dir` writes records outside the package, unvalidated. +A record's `origin.base_url` is the base URL the run was given, a local app's included. A local app's signed URL, which its launcher serves at `/__e2e__/blob/{bucket}/{object}` on the API's origin, is written as `https://storage.googleapis.com/{bucket}/{object}` with its query redacted, as a deployment signs it, because a production download is cross-origin and the client sends no key there; the run, like the validator, refuses a record holding any absolute URL other than such a storage URL, or a `location` under the base URL, so a local app's host under another name or port is refused too. A server answers a version it has built inline, so `mint-async-build` and `operation-resume` each need a spec just above the 100,000-row sync budget that the server has not built: the DAC2a recipient flows from 2018 to 2024 for the mint, and from 2017 to 2024 for the resumed operation. A local recording therefore starts on a fresh datasets database with `DATASETS_SYNC_BUDGET_ROWS=100000`. `--scenarios-dir` writes records outside the package, unvalidated. ## DatasetRef diff --git a/python/client-contract/src/dfo_client_contract/__init__.py b/python/client-contract/src/dfo_client_contract/__init__.py index b4aa34d..2e31e8b 100644 --- a/python/client-contract/src/dfo_client_contract/__init__.py +++ b/python/client-contract/src/dfo_client_contract/__init__.py @@ -2,7 +2,8 @@ Ships, as package data, what the DFO Python and TypeScript clients generate from and replay: the served OpenAPI document, the strict fields, the caller -action for each refusal code, the code of each error a client raises itself, +action for each refusal code, the code of each error and warning a client +raises or issues itself, the website proxy's refusal codes, the scenario and DatasetRef formats with their records, and the client rules with their vectors. Every accessor reads the installed files through `importlib.resources`. @@ -17,6 +18,8 @@ contract_dir, dataset_ref_schema, openapi, + proxy_codes, + proxy_codes_schema, ref_examples, rule, rules_schema, @@ -25,6 +28,8 @@ served_source, strict_fields, strict_fields_schema, + warning_codes, + warning_codes_schema, ) __all__ = [ @@ -36,6 +41,8 @@ "contract_dir", "dataset_ref_schema", "openapi", + "proxy_codes", + "proxy_codes_schema", "ref_examples", "rule", "rules_schema", @@ -44,4 +51,6 @@ "served_source", "strict_fields", "strict_fields_schema", + "warning_codes", + "warning_codes_schema", ] diff --git a/python/client-contract/src/dfo_client_contract/client-codes.json b/python/client-contract/src/dfo_client_contract/client-codes.json index 1a02e36..f1bedd5 100644 --- a/python/client-contract/src/dfo_client_contract/client-codes.json +++ b/python/client-contract/src/dfo_client_contract/client-codes.json @@ -4,81 +4,103 @@ { "code": "answer_declined", "class": "DeclinedError", + "retryable": false, "condition": "Fetching an answer Search declined or answered with the catalogue." }, { "code": "answer_incomplete", "class": "IncompleteAnswerError", + "retryable": false, "condition": "Fetching an answer with a part that has no reading, when the fetch is not partial or no part has a reading." }, { "code": "choice_invalid", "class": "InvalidRequestError", + "retryable": false, "condition": "A choice whose part or option names no gap, several gaps or no option, or a choice that cannot post back a part." }, { "code": "contract_violation", "class": "ContractError", + "retryable": false, "condition": "A response lacks a member the client acts on, or holds one that contradicts the request." }, { "code": "credentials_file_invalid", "class": "AuthenticationError", + "retryable": false, "condition": "The credentials file breaks the credentials-file rule." }, { "code": "deadline_exceeded", "class": "DfoTimeoutError", + "retryable": true, "condition": "The call's deadline passed before it finished." }, { "code": "digest_mismatch", "class": "ServerError", - "condition": "A downloaded file does not hash to the digest its manifest names." + "retryable": false, + "condition": "A downloaded file does not hash to the digest its manifest names, after the files route was asked once more." }, { "code": "download_failed", "class": "ServerError", - "condition": "A signed storage URL answered a status other than 2xx." + "retryable": true, + "condition": "The signed URL a files route names refused, or its fetch failed, after the route was asked once more." }, { "code": "invalid_argument", "class": "InvalidRequestError", + "retryable": false, "condition": "A call's arguments break a rule the client checks before any request." }, + { + "code": "key_empty", + "class": "AuthenticationError", + "retryable": false, + "condition": "The api_key argument is an empty string." + }, { "code": "network_error", "class": "NetworkError", + "retryable": true, "condition": "The connection failed before a response arrived." }, { "code": "offline", "class": "NetworkError", + "retryable": false, "condition": "DFO_OFFLINE=1 is set, and the call needs the server." }, { "code": "profile_not_found", "class": "AuthenticationError", + "retryable": false, "condition": "DFO_PROFILE names a profile the credentials file lacks." }, { "code": "profile_without_key", "class": "AuthenticationError", + "retryable": false, "condition": "The chosen profile in the credentials file has no key." }, { "code": "refusal_without_code", "class": "by_status", + "retryable": "by_status", "condition": "A refusal whose body carries no code: neither a problem document nor the website proxy's own body." }, { "code": "unexpected_response", "class": "ContractError", + "retryable": false, "condition": "A response of a status or form the call does not act on: a redirect it does not follow, a body that is not JSON, or a status the route does not answer." }, { "code": "version_unavailable", "class": "VersionUnavailableError", + "retryable": false, "condition": "A stored version can no longer be fetched, and no refusal names why." } ] diff --git a/python/client-contract/src/dfo_client_contract/client-codes.schema.json b/python/client-contract/src/dfo_client_contract/client-codes.schema.json index 32249a6..ab0f20b 100644 --- a/python/client-contract/src/dfo_client_contract/client-codes.schema.json +++ b/python/client-contract/src/dfo_client_contract/client-codes.schema.json @@ -22,6 +22,7 @@ "required": [ "code", "class", + "retryable", "condition" ], "properties": { @@ -34,6 +35,17 @@ "type": "string", "pattern": "^([A-Z][A-Za-z]*|by_status)$" }, + "retryable": { + "description": "Whether the error is one a caller may retry, which both clients set as the error's retryable flag; by_status for the error whose class its status maps to, retryable as that status is.", + "oneOf": [ + { + "type": "boolean" + }, + { + "const": "by_status" + } + ] + }, "condition": { "description": "The condition, in one line.", "type": "string", diff --git a/python/client-contract/src/dfo_client_contract/contract.py b/python/client-contract/src/dfo_client_contract/contract.py index b200c7e..9503495 100644 --- a/python/client-contract/src/dfo_client_contract/contract.py +++ b/python/client-contract/src/dfo_client_contract/contract.py @@ -79,6 +79,26 @@ def client_codes_schema() -> dict[str, Any]: return _load("client-codes.schema.json") +def proxy_codes() -> dict[str, Any]: + """`proxy-codes.json`: the codes of the website proxy's own refusals.""" + return _load("proxy-codes.json") + + +def proxy_codes_schema() -> dict[str, Any]: + """`proxy-codes.schema.json`: the shape of `proxy-codes.json`.""" + return _load("proxy-codes.schema.json") + + +def warning_codes() -> dict[str, Any]: + """`warning-codes.json`: the code of each warning a client issues itself.""" + return _load("warning-codes.json") + + +def warning_codes_schema() -> dict[str, Any]: + """`warning-codes.schema.json`: the shape of `warning-codes.json`.""" + return _load("warning-codes.schema.json") + + def scenario_schema() -> dict[str, Any]: """`scenario.schema.json`: the shape of one scenario record.""" return _load("scenario.schema.json") diff --git a/python/client-contract/src/dfo_client_contract/proxy-codes.json b/python/client-contract/src/dfo_client_contract/proxy-codes.json new file mode 100644 index 0000000..abba574 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/proxy-codes.json @@ -0,0 +1,15 @@ +{ + "format_version": 1, + "codes": [ + { + "code": "rate_limited", + "status": 429, + "condition": "The website proxy's rate limit for the caller's address is spent; the response carries Retry-After." + }, + { + "code": "transient_unavailable", + "status": 502, + "condition": "The website proxy could not reach the API behind it." + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/proxy-codes.schema.json b/python/client-contract/src/dfo_client_contract/proxy-codes.schema.json new file mode 100644 index 0000000..6cec2dd --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/proxy-codes.schema.json @@ -0,0 +1,49 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/python/client-contract/src/dfo_client_contract/proxy-codes.schema.json", + "title": "Proxy codes", + "description": "Each code the website proxy's own {error, retry, detail} body carries in error, with the HTTP status it answers and the condition, sorted by code. A client raises such a refusal with the error's code and the class its status maps to.", + "type": "object", + "additionalProperties": false, + "required": [ + "format_version", + "codes" + ], + "properties": { + "format_version": { + "const": 1 + }, + "codes": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "code", + "status", + "condition" + ], + "properties": { + "code": { + "type": "string", + "pattern": "^[a-z][a-z0-9]*(_[a-z0-9]+)*$" + }, + "status": { + "type": "integer", + "minimum": 400, + "maximum": 599 + }, + "condition": { + "description": "The condition, in one line.", + "type": "string", + "minLength": 1, + "not": { + "pattern": "\\n" + } + } + } + } + } + } +} diff --git a/python/client-contract/src/dfo_client_contract/rules/README.md b/python/client-contract/src/dfo_client_contract/rules/README.md index f70b359..cfd440a 100644 --- a/python/client-contract/src/dfo_client_contract/rules/README.md +++ b/python/client-contract/src/dfo_client_contract/rules/README.md @@ -26,19 +26,19 @@ A name is one or more of `A-Z`, `a-z`, `0-9`, `_` and `-`. A value holds no `"`, A client resolves its key when it is built, and again after a 401. The first source found wins: -1. the `api_key` argument: a key, or `false` to force anonymous use; +1. the `api_key` argument: a key, or `false` to force anonymous use; an empty string raises `key_empty`; 1. `DFO_API_KEY`; 1. the credentials file at the credentials path, profile `$DFO_PROFILE`, else `default`; 1. inside Colab, a notebook secret named `DFO_API_KEY`; 1. otherwise, anonymous. -A missing file goes on to the next source, and so does a missing `default` profile. A file that fails to parse raises `credentials_file_invalid`, a profile named by `DFO_PROFILE` that the file lacks raises `profile_not_found`, and a chosen profile with no `key` raises `profile_without_key`. The file is read only when no earlier source wins. The argument may also be a callable or a key object, called or unwrapped when the client resolves the key; vectors pass strings, and the Colab source has none. +A missing file goes on to the next source, and so does a missing `default` profile. A file that fails to parse raises `credentials_file_invalid`, a profile named by `DFO_PROFILE` that the file lacks raises `profile_not_found`, and a chosen profile with no `key`, or an empty one, raises `profile_without_key`. The file is read only when no earlier source wins. The argument may also be a callable or a key object, called or unwrapped when the client resolves the key; vectors pass strings, and the Colab source has none. ## Key format (`key-format`) A secret key is `dfo_k_`, then a base62 body, then a 6-character checksum; `dfo_p_` marks a browser-safe key. Base62 is `0-9A-Za-z` in that order. The checksum is the CRC32 (ISO-HDLC, as zlib computes it) of the body's ASCII bytes, written in base62 and left-padded with `0` to six characters. Issued keys have a 32-character body, 44 characters in all, but the check ignores length: the last six characters after the prefix are the checksum and the rest is the body. -The check runs in order and reports the first failure: `unknown_prefix` when the key starts with neither prefix, `not_base62` when a character after the prefix is outside base62, and `checksum_mismatch` when the body is empty or its checksum differs. A failure warns and the client sends the key anyway, so a change of key format forces no upgrade. +The check runs in order and reports the first failure: `unknown_prefix` when the key starts with neither prefix, `not_base62` when a character after the prefix is outside base62, and `checksum_mismatch` when the body is empty or its checksum differs. A failure warns with the code `key_` from `warning-codes.json`, such as `key_checksum_mismatch`, and the client sends the key anyway, so a change of key format forces no upgrade. ## Cache directory (`cache-dir`) diff --git a/python/client-contract/src/dfo_client_contract/rules/credentials-file.json b/python/client-contract/src/dfo_client_contract/rules/credentials-file.json index 8cdad68..8dc296f 100644 --- a/python/client-contract/src/dfo_client_contract/rules/credentials-file.json +++ b/python/client-contract/src/dfo_client_contract/rules/credentials-file.json @@ -117,6 +117,15 @@ "reason": "invalid_line", "line": 2 } + }, + { + "name": "empty-value-parses", + "text": "[default]\nkey = \"\"\n", + "profiles": { + "default": { + "key": "" + } + } } ] } diff --git a/python/client-contract/src/dfo_client_contract/rules/key-lookup.json b/python/client-contract/src/dfo_client_contract/rules/key-lookup.json index 2f5d4c0..2b8d1e5 100644 --- a/python/client-contract/src/dfo_client_contract/rules/key-lookup.json +++ b/python/client-contract/src/dfo_client_contract/rules/key-lookup.json @@ -105,6 +105,25 @@ "file": "key = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\"\n", "source": "environment", "key": "dfo_k_environment" + }, + { + "name": "empty-argument-raises", + "api_key": "", + "env": { + "DFO_API_KEY": "dfo_k_environment" + }, + "file": "[default]\nkey = \"dfo_k_4f8Kq2ZtR7mWx1NcB9vLp3YhD6sGa0Ue2wanxe\"\n", + "error": { + "reason": "key_empty" + } + }, + { + "name": "empty-profile-key-raises", + "env": {}, + "file": "[default]\nkey = \"\"\n", + "error": { + "reason": "profile_without_key" + } } ] } diff --git a/python/client-contract/src/dfo_client_contract/rules/rules.schema.json b/python/client-contract/src/dfo_client_contract/rules/rules.schema.json index e6e956c..9a33072 100644 --- a/python/client-contract/src/dfo_client_contract/rules/rules.schema.json +++ b/python/client-contract/src/dfo_client_contract/rules/rules.schema.json @@ -309,11 +309,10 @@ "$ref": "#/$defs/name" }, "api_key": { - "description": "The api_key argument: a key string, or false to force anonymous use. Absent when the caller passes none.", + "description": "The api_key argument: a key string, the empty string a client refuses, or false to force anonymous use. Absent when the caller passes none.", "oneOf": [ { - "type": "string", - "minLength": 1 + "type": "string" }, { "const": false @@ -353,6 +352,7 @@ "properties": { "reason": { "enum": [ + "key_empty", "profile_not_found", "profile_without_key", "credentials_file_invalid" diff --git a/python/client-contract/src/dfo_client_contract/scenario.schema.json b/python/client-contract/src/dfo_client_contract/scenario.schema.json index fade531..e455121 100644 --- a/python/client-contract/src/dfo_client_contract/scenario.schema.json +++ b/python/client-contract/src/dfo_client_contract/scenario.schema.json @@ -266,10 +266,6 @@ "question": { "type": "string", "minLength": 1 - }, - "timeout": { - "type": "number", - "exclusiveMinimum": 0 } } }, @@ -330,10 +326,6 @@ }, "strict": { "type": "boolean" - }, - "timeout": { - "type": "number", - "exclusiveMinimum": 0 } } }, @@ -358,10 +350,6 @@ "strict": { "type": "boolean" }, - "timeout": { - "type": "number", - "exclusiveMinimum": 0 - }, "window": true, "entities": true, "facets": true @@ -381,10 +369,6 @@ }, "ref": { "$ref": "dataset-ref.schema.json" - }, - "timeout": { - "type": "number", - "exclusiveMinimum": 0 } } }, @@ -455,10 +439,6 @@ "properties": { "op": { "const": "result" - }, - "timeout": { - "type": "number", - "exclusiveMinimum": 0 } } }, @@ -719,6 +699,12 @@ } } } + }, + "retry_waits": { + "$ref": "#/$defs/retry_waits" + }, + "warnings": { + "$ref": "#/$defs/warnings" } } }, @@ -829,6 +815,12 @@ }, "long_builds": { "$ref": "#/$defs/long_builds" + }, + "retry_waits": { + "$ref": "#/$defs/retry_waits" + }, + "warnings": { + "$ref": "#/$defs/warnings" } } }, @@ -850,6 +842,12 @@ "done", "failed" ] + }, + "retry_waits": { + "$ref": "#/$defs/retry_waits" + }, + "warnings": { + "$ref": "#/$defs/warnings" } } }, @@ -870,6 +868,12 @@ "type": "null" } ] + }, + "retry_waits": { + "$ref": "#/$defs/retry_waits" + }, + "warnings": { + "$ref": "#/$defs/warnings" } } }, @@ -920,6 +924,12 @@ }, "long_builds": { "$ref": "#/$defs/long_builds" + }, + "retry_waits": { + "$ref": "#/$defs/retry_waits" + }, + "warnings": { + "$ref": "#/$defs/warnings" } }, "if": { @@ -974,6 +984,28 @@ } } } + }, + "retry_waits": { + "description": "The seconds a step waited before each retry of a refused request, in order: the refusal's Retry-After, else a backoff that doubles from 0.5 to 8 seconds. Given only when the step retried.", + "type": "array", + "minItems": 1, + "items": { + "type": "number", + "minimum": 0 + } + }, + "warnings": { + "description": "The codes, from warning-codes.json and in order, of the warnings the step's API responses issued. Given only when they issued any.", + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/name_code" + } + }, + "name_code": { + "type": "string", + "pattern": "^[a-z][a-z0-9]*(_[a-z0-9]+)*$", + "$ref": "#/$defs/one_line" } } } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json new file mode 100644 index 0000000..0d47b11 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json @@ -0,0 +1,3685 @@ +{ + "format_version": 1, + "name": "answer-definition-spec-id-mismatch", + "description": "A Search spec whose definition.spec_id differs from its spec_id raises ContractError contract_violation, in a Search response as in a ref.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-definite-fetch", + "edit": "Part 0's spec definition names spec_id spec_00000000000000000000000000000000, and the fetch goes." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Nigeria for basic health care" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Nigeria for basic health care" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Nigeria for basic health care", + "normalized_query": "ODA disbursements from Germany to Nigeria for basic health care", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", + "warnings": [], + "timing_ms": { + "total": 4556, + "by_step": { + "coverage": 0, + "extract": 889 + } + }, + "llm_usage": { + "input_tokens": 6116, + "output_tokens": 408, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "basic health care ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 3505, + "by_step": { + "recall": 628, + "shape_arcs": 1, + "shape_probe_coverage": 5, + "shape_probe": 477, + "shape_groups": 22, + "shape_labels": 1, + "shape_admission": 1, + "shape": 1283, + "bind": 1188, + "materialise": 11, + "answer": 381, + "options": 14 + } + }, + "restatement": { + "variable_text": "basic health care ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Nigeria", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_00000000000000000000000000000000", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal", + "label": "gross disbursements (basic health care, official development assistance, standard grant)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 21, + "member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "financialObligationType" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 5, + "member_count_exact": true, + "served_count": 21, + "data_date_range": { + "start": "1995", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 30, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 15 + }, + { + "label": "variables", + "count": 5 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 3, + "series": 3, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2024, + "observations": 3, + "series": 3, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + } + ] + }, + "download": { + "rows": 30, + "rows_exact": true, + "series": 5, + "window": { + "start_year": 1995, + "end_year": 2024 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 88, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 30, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 7, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1606, + "served_rows": 1, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 6, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 7, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 7, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 1, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 1600, + "served_rows": 1, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFinance", + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Nigeria", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/NGA" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "basic health care", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1995 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "measure_elected" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/NGA", + "label": "Nigeria" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [ + { + "text": "basic health care", + "named": [ + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + } + ], + "slot": "crsPurpose", + "disposition": "bound", + "selected": [] + }, + { + "text": "ODA", + "named": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "slot": "crsTypeOfFlow", + "disposition": "bound", + "selected": [] + } + ], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "high", + "available_at_place": true, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_80b92ca1ba1114b426eb5e79b84361d4", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 30, + "served_rows_exact": true + }, + { + "definition": { + "schema_version": 1, + "spec_id": "spec_c394f9108db2100f1c8e4532d8d1c804", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialObligation", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialObligationType", + "binding": { + "state": "value", + "ref": "Commitment" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "commitments", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialObligation", + "label": "financial obligation" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialObligationType", + "value": { + "ref": "Commitment", + "label": "commitment" + } + } + ], + "served_rows": 24, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "open_axis_facts": [ + { + "property": "crsTypeOfFinance", + "varies": false, + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "distinct_count": 1, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "count": 5 + } + ] + }, + { + "property": "crsCooperationModality", + "varies": true, + "distinct_count": 4, + "undeclared_count": 1, + "values": [ + { + "value": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "count": 1 + } + ] + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1995, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 2023, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1995, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "NGN", + "origin": "EUR" + } + } + } + } + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFinance", + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Nigeria", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/NGA" + ], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "basic health care", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1995 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "status": "definite" + } + } + } + ], + "expect": [ + { + "error": { + "class": "ContractError", + "code": "contract_violation" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-part-status-not-a-string.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-part-status-not-a-string.json new file mode 100644 index 0000000..788437b --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-part-status-not-a-string.json @@ -0,0 +1,3609 @@ +{ + "format_version": 1, + "name": "answer-part-status-not-a-string", + "description": "A part whose status is not a string raises ContractError contract_violation at /parts/1/status, where an unknown string status is an unknown gap.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-mixed-fetch-raises", + "edit": "Part 1's status becomes the number 7, and the fetch goes." + }, + "call": [ + { + "op": "search", + "question": "debt service of Kenya and the price of tea in Kenya" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "debt service of Kenya and the price of tea in Kenya" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "debt service of Kenya and the price of tea in Kenya", + "normalized_query": "debt service of Kenya and the price of tea in Kenya", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "d0fa88511b064cc6966082b296cd6ea8", + "warnings": [], + "timing_ms": { + "total": 4688, + "by_step": { + "coverage": 0, + "extract": 928 + } + }, + "llm_usage": { + "input_tokens": 5885, + "output_tokens": 606, + "cached_tokens": 860 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "debt service", + "warnings": [], + "timing_ms": { + "total": 3547, + "by_step": { + "recall": 312, + "shape_arcs": 2, + "shape_probe_coverage": 2, + "shape_probe": 192, + "shape_groups": 2, + "shape_labels": 6, + "shape_admission": 0, + "shape": 912, + "bind": 1643, + "materialise": 3, + "answer": 462, + "options": 215 + } + }, + "restatement": { + "variable_text": "debt service", + "entities": [ + { + "text": "Kenya" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [ + { + "kind": "open_role", + "binding_ref": "origin:", + "text": "every creditor", + "refs": [] + } + ], + "status": "definite", + "spec": { + "spec_id": "spec_78d04fefc3b3f1ef71acd622957e4995", + "definition": { + "schema_version": 1, + "spec_id": "spec_78d04fefc3b3f1ef71acd622957e4995", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "ServicingPayment" + } + }, + { + "property": "financingResource", + "binding": { + "state": "unbound" + } + }, + { + "property": "guaranteeStatus", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsConcessionality", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsCreditorType", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsDebtorType", + "binding": { + "state": "unbound" + } + }, + { + "property": "includesIMFCredit", + "binding": { + "state": "unbound" + } + }, + { + "property": "maturityBand", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal_by_role", + "label": "Debt service on external debt", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 65, + "member_digest": "b66541c53125ee32113e51b4f52a3a428043b5506e15f96277f37b89547fc1c4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "ServicingPayment", + "label": "servicing payment" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "financingResource", + "guaranteeStatus", + "idsDebtorType", + "idsCreditorType", + "idsConcessionality", + "includesIMFCredit", + "maturityBand" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1970", + "end": "2024" + }, + "source_codes": [ + { + "provenance": "provenance/WorldBankInternationalDebtStatistics", + "code": "DT.TDS.DECT.CD" + } + ] + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 55, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 55 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 1, + "series": 1, + "role_counts": { + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2024, + "observations": 1, + "series": 1, + "role_counts": { + "financingRecipient": 1 + } + }, + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 1, + "series": 1, + "role_counts": { + "financingRecipient": 1 + } + } + ] + }, + "download": { + "rows": 55, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 1970, + "end_year": 2024 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "ServicingPayment", + "label": "servicing payment" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "options": [ + { + "value": { + "ref": { + "ref": "PublicOrPubliclyGuaranteed", + "label": "public or publicly guaranteed" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "NotPubliclyGuaranteed", + "label": "not publicly guaranteed" + }, + "value_kind": "enum_value" + }, + "served_rows": 56, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSDebtorTypePS", + "label": "public sector (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSDebtorTypeGG", + "label": "general government (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSDebtorTypeOPS", + "label": "other public sector (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSDebtorTypePrivateSector", + "label": "private sector (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 56, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSCreditorTypePROP", + "label": "other private creditors (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 46, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypePBND", + "label": "bondholders (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 31, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypePRVT", + "label": "private creditors (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypeOFFT", + "label": "official creditors (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 55, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypeMLAT", + "label": "multilateral (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSConcessional", + "label": "concessional (IDS concessionality)" + }, + "value_kind": "enum_value" + }, + "served_rows": 118, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "options": [ + { + "value": { + "ref": { + "ref": "WithoutIMFCredit", + "label": "without IMF credit" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "options": [ + { + "value": { + "ref": { + "ref": "LongTermMaturity", + "label": "long-term maturity" + }, + "value_kind": "enum_value" + }, + "served_rows": 63, + "served_rows_exact": false + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Estimated", + "label": "estimated" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "external debt service", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ] + }, + { + "kind": "text", + "text": " owed to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "all creditors", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [], + "states": [ + "origin:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financingResource", + "binding_ref": "how:financingResource", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "guaranteeStatus", + "binding_ref": "how:guaranteeStatus", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsConcessionality", + "binding_ref": "how:idsConcessionality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsCreditorType", + "binding_ref": "how:idsCreditorType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsDebtorType", + "binding_ref": "how:idsDebtorType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "includesIMFCredit", + "binding_ref": "how:includesIMFCredit", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "maturityBand", + "binding_ref": "how:maturityBand", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1970 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Bank International Debt Statistics (IDS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "resolved_sources": [ + { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "ServicingPayment", + "label": "servicing payment" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1985, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1992, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1994, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1981, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1981, + "base_year_max": 2025 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1989, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1987, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1980, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "KES" + } + } + } + } + }, + { + "variable_text": "price of tea", + "warnings": [], + "timing_ms": { + "total": 502, + "by_step": { + "recall": 307, + "shape_arcs": 1, + "shape_probe": 190, + "shape_groups": 1, + "shape_labels": 0, + "shape_admission": 0, + "shape": 195 + } + }, + "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", + "sentence_plan": [ + { + "kind": "text", + "text": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "operations": [], + "departures": [], + "assumptions": [], + "status": 7, + "no_data": { + "reason": "variable_not_resolved", + "category": "unresolved", + "message": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", + "entity_terms": [], + "ambiguous_entities": [], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [] + } + } + ], + "rendered_sentence": "Answered 1 of 2 parts. Kenya's external debt service owed to all creditors, 1970 to 2024. Current US dollars · World Bank International Debt Statistics (IDS). Assumed: every creditor. No match for price of tea. Try a different wording or a related indicator.", + "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "external debt service", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " owed to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "all creditors", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [], + "states": [ + "origin:" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financingResource", + "binding_ref": "how:financingResource", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "guaranteeStatus", + "binding_ref": "how:guaranteeStatus", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsConcessionality", + "binding_ref": "how:idsConcessionality", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsCreditorType", + "binding_ref": "how:idsCreditorType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsDebtorType", + "binding_ref": "how:idsDebtorType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "includesIMFCredit", + "binding_ref": "how:includesIMFCredit", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "maturityBand", + "binding_ref": "how:maturityBand", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "1970 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "World Bank International Debt Statistics (IDS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Assumed: ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "every creditor", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "No match for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "price of tea", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ". Try a different wording or a related indicator.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + } + ], + "status": "mixed" + } + } + } + ], + "expect": [ + { + "error": { + "class": "ContractError", + "code": "contract_violation" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-option-without-data-query.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-without-data-query.json new file mode 100644 index 0000000..ac4f30a --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-without-data-query.json @@ -0,0 +1,244 @@ +{ + "format_version": 1, + "name": "choose-option-without-data-query", + "description": "Choosing an option with no data_query in a one-part answer raises ContractError contract_violation with no request, as in a several-part answer.", + "origin": { + "kind": "synthetic", + "derived_from": "choose-place-one-part", + "edit": "The no_data part's first option loses its data_query." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + }, + { + "op": "choose", + "option": "Congo [DRC]" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Congo", + "normalized_query": "ODA disbursements from Germany to Congo", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "9c755dc7ffaf4568afe68d812e56d8fa", + "warnings": [], + "timing_ms": { + "total": 1084, + "by_step": { + "coverage": 0, + "extract": 1082 + } + }, + "llm_usage": { + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 0, + "by_step": { + "recall": 0 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]" + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + ] + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "no_data" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "no_data", + "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 2 + } + ] + } + }, + { + "error": { + "class": "ContractError", + "code": "contract_violation" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused-twice.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused-twice.json new file mode 100644 index 0000000..bb60be9 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused-twice.json @@ -0,0 +1,865 @@ +{ + "format_version": 1, + "name": "fetch-ref-signed-url-refused-twice", + "description": "A download asks the files route once and fetches the signed URL once, then asks the route once more and fetches again, with no wait; a second refused fetch raises ServerError download_failed.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-ref", + "edit": "The signed download answers 403, and so does the one the files route names when asked again." + }, + "call": [ + { + "op": "fetch", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [ + "basic health care ODA disbursements" + ], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + } + }, + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "artifact": { + "digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "rendering": { + "format": "parquet", + "bundle": false + } + } + } + ] + } + } + ], + "exchanges": [ + { + "request": { + "method": "GET", + "path": "/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + }, + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "prepared_at": "2026-10-21T08:57:19Z", + "coverage": { + "rows": 30, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 27 + } + ], + "window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1995 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1995 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 7 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 15 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9785, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:19.589654+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + }, + { + "artifact_digest": "sha256:ac65501b1aef56a9caaadf063eb0390e8d816198384081e2c1645b04816693b8", + "rendering": { + "format": "frame" + }, + "bytes": 4764, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:19.589654+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:ac65501b1aef56a9caaadf063eb0390e8d816198384081e2c1645b04816693b8" + }, + { + "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", + "rendering": { + "statistics": "series" + }, + "bytes": 5981, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:19.589654+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" + } + ], + "series_count": 5, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 5 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 27 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "stat_var", + "columns": "time_period", + "state": "available", + "width": 28, + "cells": 140 + }, + { + "index": "time_period", + "columns": "stat_var", + "state": "available", + "width": 6, + "cells": 162 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:19.589587Z" + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + }, + "response": { + "status": 403, + "headers": { + "content-type": "application/xml" + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + }, + "response": { + "status": 403, + "headers": { + "content-type": "application/xml" + } + } + } + ], + "expect": [ + { + "error": { + "class": "ServerError", + "code": "download_failed" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json index 2aee0f0..740e4d6 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json @@ -1,7 +1,7 @@ { "format_version": 1, "name": "fetch-retry-after-504", - "description": "A synchronous build cut off at the server's limit answers a retryable 504 timeout; the client builds once more and reaches the same dataset.", + "description": "A synchronous build cut off at the server's limit answers a retryable 504 timeout; the client waits the first backoff, 0.5 seconds, builds once more and reaches the same dataset.", "origin": { "kind": "synthetic", "derived_from": "answer-definite-fetch", @@ -4630,7 +4630,10 @@ } ], "missing": [], - "search_warning": false + "search_warning": false, + "retry_waits": [ + 0.5 + ] } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-retry-after.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-retry-after.json new file mode 100644 index 0000000..3052299 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-retry-after.json @@ -0,0 +1,1033 @@ +{ + "format_version": 1, + "name": "fetch-spec-504-retry-after", + "description": "A build cut off by a 504 that carries Retry-After is posted once more after the Retry-After seconds, not the backoff, and reaches the same dataset.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "A 504 timeout with retryable true and Retry-After 5 answers the build." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 504, + "headers": { + "content-type": "application/problem+json", + "retry-after": "5" + }, + "json": { + "type": "/codes/timeout", + "title": "Gateway Timeout", + "status": 504, + "detail": "The build passed its 120 s limit.", + "code": "timeout", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": true + } + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "prepared_at": "2026-10-21T08:57:50Z", + "coverage": { + "rows": 4, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 4 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "head", + "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal, which hold none at the observation period the other members serve in the requested years." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9541, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:50.451120+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + { + "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", + "rendering": { + "statistics": "series" + }, + "bytes": 5741, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:50.451120+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" + } + ], + "series_count": 1, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 4 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:50.451687Z" + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "fetch-spec-known-sentence.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 4, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "crsCooperationModality", + "crsCooperationModality_label", + "crsPurpose", + "crsPurpose_label", + "crsTypeOfFinance", + "crsTypeOfFinance_label", + "crsTypeOfFlow", + "crsTypeOfFlow_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + ], + "missing": [], + "retry_waits": [ + 5.0 + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-twice.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-twice.json index 9b6bb66..9653e39 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-twice.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-twice.json @@ -295,7 +295,10 @@ { "error": { "class": "ServerError", - "code": "timeout" + "code": "timeout", + "retry_waits": [ + 0.5 + ] } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-empty-narrowing.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-empty-narrowing.json new file mode 100644 index 0000000..b91fc2a --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-empty-narrowing.json @@ -0,0 +1,929 @@ +{ + "format_version": 1, + "name": "fetch-spec-empty-narrowing", + "description": "An empty entities or facets map narrows nothing, so the build posts no scope, as a fetch that names neither does.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "The fetch names entities {} and facets {}." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + }, + "entities": {}, + "facets": {} + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "prepared_at": "2026-10-21T08:57:50Z", + "coverage": { + "rows": 4, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 4 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "head", + "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal, which hold none at the observation period the other members serve in the requested years." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9541, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:50.451120+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + { + "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", + "rendering": { + "statistics": "series" + }, + "bytes": 5741, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:50.451120+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" + } + ], + "series_count": 1, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 4 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:50.451687Z" + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "fetch-spec-known-sentence.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 4, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "crsCooperationModality", + "crsCooperationModality_label", + "crsPurpose", + "crsPurpose_label", + "crsTypeOfFinance", + "crsTypeOfFinance_label", + "crsTypeOfFlow", + "crsTypeOfFlow_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + ], + "missing": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-relative-location.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-relative-location.json new file mode 100644 index 0000000..ffb1bb6 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-relative-location.json @@ -0,0 +1,927 @@ +{ + "format_version": 1, + "name": "fetch-spec-relative-location", + "description": "A relative Location resolves against the files route's URL, not the base URL's origin, and the client fetches the file there, on the API's origin, reaching the same dataset.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "The files route's Location becomes the relative URL 'bytes', and the file comes from the path it resolves to." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "prepared_at": "2026-10-21T08:57:50Z", + "coverage": { + "rows": 4, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 4 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "head", + "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal, which hold none at the observation period the other members serve in the requested years." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9541, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:50.451120+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + { + "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", + "rendering": { + "statistics": "series" + }, + "bytes": 5741, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:50.451120+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" + } + ], + "series_count": 1, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 4 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:50.451687Z" + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + "response": { + "status": 302, + "headers": { + "location": "bytes" + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/bytes" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "fetch-spec-known-sentence.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 4, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "crsCooperationModality", + "crsCooperationModality_label", + "crsPurpose", + "crsPurpose_label", + "crsTypeOfFinance", + "crsTypeOfFinance_label", + "crsTypeOfFlow", + "crsTypeOfFlow_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + ], + "missing": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json b/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json new file mode 100644 index 0000000..95d6791 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json @@ -0,0 +1,122 @@ +{ + "format_version": 1, + "name": "newest-version-unreadable-page", + "description": "A versions page with no versions list raises ContractError contract_violation, since only a NotFoundError reads as no stored version.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-ref-newest-version", + "edit": "The versions page names its versions list items." + }, + "call": [ + { + "op": "newest_version", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "GET", + "path": "/datasets/spec_774d6c001a6250aa67ca676ab067895e/versions?limit=1" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "next_cursor": null, + "complete": true, + "items": [ + { + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "base_content_version": null, + "rendering": "plain", + "groupby": null + } + ] + } + } + } + ], + "expect": [ + { + "error": { + "class": "ContractError", + "code": "contract_violation" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json b/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json new file mode 100644 index 0000000..5893a9d --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json @@ -0,0 +1,90 @@ +{ + "format_version": 1, + "name": "operation-failed-without-error", + "description": "A failed operation whose resource carries no error raises ServerError with the code operation_failed; a resumed operation holds no build request, so nothing is posted again.", + "origin": { + "kind": "synthetic", + "derived_from": "operation-resume", + "edit": "The resumed operation's first poll answers it failed with no error member." + }, + "call": [ + { + "op": "operation", + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + }, + { + "op": "result" + } + ], + "exchanges": [ + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "status": "pending", + "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 123015 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "status": "failed", + "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "retry_after_ms": 1500 + } + } + } + } + ], + "expect": [ + { + "operation": { + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "status": "pending" + } + }, + { + "error": { + "class": "ServerError", + "code": "operation_failed", + "long_builds": [ + { + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "poll_waits": [ + 1.5 + ], + "resubmissions": 0 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-no-json-body.json b/python/client-contract/src/dfo_client_contract/scenarios/search-no-json-body.json new file mode 100644 index 0000000..d121b47 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-no-json-body.json @@ -0,0 +1,45 @@ +{ + "format_version": 1, + "name": "search-no-json-body", + "description": "A 2xx Search response with no JSON body raises ContractError unexpected_response.", + "origin": { + "kind": "synthetic", + "derived_from": "search-place-ambiguous", + "edit": "The search answers 200 with an empty text/html body." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "text/html; charset=utf-8" + } + } + } + ], + "expect": [ + { + "error": { + "class": "ContractError", + "code": "unexpected_response" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json index 5f17161..31f2357 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json @@ -274,6 +274,9 @@ "kind": "choice", "options": 2 } + ], + "retry_waits": [ + 2.0 ] } } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json index af2d05b..e56c3a9 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json @@ -91,7 +91,11 @@ { "error": { "class": "ServerError", - "code": "transient_unavailable" + "code": "transient_unavailable", + "retry_waits": [ + 0.5, + 1.0 + ] } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json b/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json index 3255290..1e330ac 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json @@ -279,6 +279,9 @@ "kind": "choice", "options": 2 } + ], + "retry_waits": [ + 1.0 ] } } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-sunset-warning.json b/python/client-contract/src/dfo_client_contract/scenarios/search-sunset-warning.json new file mode 100644 index 0000000..91b7086 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-sunset-warning.json @@ -0,0 +1,501 @@ +{ + "format_version": 1, + "name": "search-sunset-warning", + "description": "A Sunset header alone issues the route_deprecated warning, once per process per distinct value, so the second search, whose response carries the same value, warns nothing.", + "origin": { + "kind": "synthetic", + "derived_from": "search-place-ambiguous", + "edit": "The search is made twice, and each response carries Sunset 'Sat, 01 May 2027 00:00:00 GMT' with no Deprecation header." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + }, + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "sunset": "Sat, 01 May 2027 00:00:00 GMT" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Congo", + "normalized_query": "ODA disbursements from Germany to Congo", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "warnings": [], + "timing_ms": { + "total": 1788, + "by_step": { + "coverage": 0, + "extract": 1353 + } + }, + "llm_usage": { + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 434, + "by_step": { + "recall": 434 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + ] + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "no_data" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "sunset": "Sat, 01 May 2027 00:00:00 GMT" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Congo", + "normalized_query": "ODA disbursements from Germany to Congo", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "warnings": [], + "timing_ms": { + "total": 1788, + "by_step": { + "coverage": 0, + "extract": 1353 + } + }, + "llm_usage": { + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 434, + "by_step": { + "recall": 434 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + ] + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "no_data" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "no_data", + "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 2 + } + ], + "warnings": [ + "route_deprecated" + ] + } + }, + { + "answer": { + "kind": "resolution", + "status": "no_data", + "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 2 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/warning-codes.json b/python/client-contract/src/dfo_client_contract/warning-codes.json new file mode 100644 index 0000000..337e2a7 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/warning-codes.json @@ -0,0 +1,30 @@ +{ + "format_version": 1, + "codes": [ + { + "code": "key_checksum_mismatch", + "class": "DfoWarning", + "condition": "The resolved key's body is empty or its checksum differs, by the key-format rule; the client sends it anyway." + }, + { + "code": "key_not_base62", + "class": "DfoWarning", + "condition": "A character of the resolved key after its prefix is outside base62, by the key-format rule; the client sends it anyway." + }, + { + "code": "key_unknown_prefix", + "class": "DfoWarning", + "condition": "The resolved key starts with neither dfo_k_ nor dfo_p_, by the key-format rule; the client sends it anyway." + }, + { + "code": "route_deprecated", + "class": "DfoDeprecationWarning", + "condition": "An API response carries a Deprecation or Sunset header, once per process per distinct pair of their values." + }, + { + "code": "server_warning", + "class": "DfoWarning", + "condition": "An API response carries an x-dfo-warning header, once per process per message." + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/warning-codes.schema.json b/python/client-contract/src/dfo_client_contract/warning-codes.schema.json new file mode 100644 index 0000000..4427722 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/warning-codes.schema.json @@ -0,0 +1,50 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/python/client-contract/src/dfo_client_contract/warning-codes.schema.json", + "title": "Warning codes", + "description": "Each code a client sets on a warning it issues itself, with the warning class and the condition, sorted by code. A SearchWarning or DataWarning carries the server's code, so neither is listed.", + "type": "object", + "additionalProperties": false, + "required": [ + "format_version", + "codes" + ], + "properties": { + "format_version": { + "const": 1 + }, + "codes": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "code", + "class", + "condition" + ], + "properties": { + "code": { + "type": "string", + "pattern": "^[a-z][a-z0-9]*(_[a-z0-9]+)*$" + }, + "class": { + "enum": [ + "DfoWarning", + "DfoDeprecationWarning" + ] + }, + "condition": { + "description": "The condition, in one line.", + "type": "string", + "minLength": 1, + "not": { + "pattern": "\\n" + } + } + } + } + } + } +} diff --git a/python/client-contract/tests/test_contract.py b/python/client-contract/tests/test_contract.py index c99da8e..e3cb21c 100644 --- a/python/client-contract/tests/test_contract.py +++ b/python/client-contract/tests/test_contract.py @@ -51,3 +51,16 @@ def test_client_codes_are_disjoint_from_the_refusal_codes() -> None: assert client == sorted(set(client)) assert not refusals & set(client) assert dfo_client_contract.client_codes_schema()["title"] == "Client codes" + + +def test_client_code_tables_are_disjoint() -> None: + tables = { + "client": dfo_client_contract.client_codes(), + "proxy": dfo_client_contract.proxy_codes(), + "warning": dfo_client_contract.warning_codes(), + "actions": dfo_client_contract.actions(), + } + codes = [row["code"] for table in tables.values() for row in table["codes"]] + assert len(codes) == len(set(codes)) + assert dfo_client_contract.proxy_codes_schema()["title"] == "Proxy codes" + assert dfo_client_contract.warning_codes_schema()["title"] == "Warning codes" diff --git a/python/client-contract/tests/test_rules.py b/python/client-contract/tests/test_rules.py index 73a1086..79e438d 100644 --- a/python/client-contract/tests/test_rules.py +++ b/python/client-contract/tests/test_rules.py @@ -100,6 +100,8 @@ def look_up_key(vector: dict[str, Any]) -> tuple[str, str | None]: api_key = vector.get("api_key") if api_key is False: return "anonymous", None + if api_key == "": + raise RuleError("key_empty") if api_key is not None: return "argument", api_key if from_env := _set(env, "DFO_API_KEY"): @@ -116,7 +118,7 @@ def look_up_key(vector: dict[str, Any]) -> tuple[str, str | None]: if named: raise RuleError("profile_not_found") return "anonymous", None - if "key" not in profile: + if not profile.get("key"): raise RuleError("profile_without_key") return "credentials_file", profile["key"] diff --git a/tools/README.md b/tools/README.md index 1937eb4..9b795ea 100644 --- a/tools/README.md +++ b/tools/README.md @@ -38,13 +38,13 @@ uv run tools/validate_provenance_docs_vectors.py uv run tools/validate_descriptions_vectors.py ``` -`validate_client_contract.py` validates the client contract under `python/client-contract/src/dfo_client_contract/` against its schemas, then checks what they cannot express: every `strict-fields.json` pointer resolves in `served/openapi.json` and stays required and non-nullable, or keeps its enum values; `actions.json` holds one row, in code order, for each active refusal code in `registries/codes.json` that reaches a problem document or a no_data reason, with a gap kind exactly for the no_data reasons; `client-codes.json` lists each code a client raises itself once, in code order, none of them a code in `actions.json` or the registry, each with a class a scenario names; `served/openapi.json` holds the Search, Datasets, Graph and Presentation surfaces and nothing outside them but the platform's `/codes` route; each recorded scenario's requests match a served route and its JSON bodies validate against that route's schemas, where a required member stays required when it admits null; every problem document in a scenario, synthetic ones and failed operations' errors included, carries an active code registered at its status; each scenario's `expect` equals the outcomes its steps reach over its exchanges, with refusals' error classes and gap kinds from `actions.json`, each error the client raises itself carrying its code and class from `client-codes.json`, and a repeated refused request counted a retry only where the retry rules allow one; each POST carries its body, each build posts the body its spec, narrowing and layout give, each Search request posts the input its steps derive, each poll names the operation the client holds, and each signed download is the URL its redirect names; every absolute URL a record holds has the redacted query; and each `DatasetRef` example gets the verdict it states. It does not import `dfo_client_contract`, whose `tests/test_rules.py` replays the rule vectors. Also a PEP 723 script: +`validate_client_contract.py` validates the client contract under `python/client-contract/src/dfo_client_contract/` against its schemas, then checks what they cannot express: every `strict-fields.json` pointer resolves in `served/openapi.json` and stays required and non-nullable, or keeps its enum values; `actions.json` holds one row, in code order, for each active refusal code in `registries/codes.json` that reaches a problem document or a no_data reason, with a gap kind exactly for the no_data reasons; `client-codes.json` lists each code a client raises itself once, in code order, none of them a code in `actions.json` or the registry, each with a class a scenario names and a retryable flag; `proxy-codes.json` and `warning-codes.json` list their codes once, in code order, apart from every other table, and the warning codes are those the client rules issue; `served/openapi.json` holds the Search, Datasets, Graph and Presentation surfaces and nothing outside them but the platform's `/codes` route; each recorded scenario's requests match a served route and its JSON bodies validate against that route's schemas, where a required member stays required when it admits null; every problem document in a scenario, synthetic ones and failed operations' errors included, carries an active code registered at its status, and every website proxy body a code `proxy-codes.json` lists at its status; each recorded scenario names `served/SOURCE.json`'s commit; each scenario's `expect` equals the outcomes its steps reach over its exchanges, with refusals' error classes and gap kinds from `actions.json`, each error the client raises itself carrying its code and class from `client-codes.json`, a repeated refused request counted a retry only where the retry rules allow one, a record that stops retrying while a retry remains refused, and the waits before retries and the warnings response headers issue derived; each POST carries its body, each build posts the body its spec, narrowing and layout give, each Search request posts the whole body its steps derive, each poll names the operation the client holds, and each signed download is the URL its redirect names; every absolute URL a record holds is a signed URL on the storage host with the redacted query, or a `location` under the base URL; and each `DatasetRef` example gets the verdict it states. It does not import `dfo_client_contract`, whose `tests/test_rules.py` replays the rule vectors. Also a PEP 723 script: ```bash uv run tools/validate_client_contract.py ``` -`capture_client_contract.py` refreshes the client contract from dfo-apis. `openapi --dfo-apis PATH` builds the composed app in that checkout's environment, in process, and writes `served/openapi.json` and `served/SOURCE.json`, refusing a checkout with uncommitted changes or untracked files and an environment out of step with its `uv.lock`; `record` runs the contract's scenarios against a base URL, dev by default, writes the records with every absolute URL's query redacted and a local app's signed URLs written as storage URLs, derives the synthetic ones and validates the result, and `record --offline` derives the outcomes again from the records with no request. A recorded scenario holds only exchanges the server made: `record` refuses a recorded scenario that a canned exchange answered, and a synthetic derivation makes no request. Nothing in a record marks an exchange as canned, so `validate_client_contract.py` cannot check this rule and the capture enforces it. It imports its outcome rules from `validate_client_contract.py`. `python/client-contract/README.md` has the recipe. A PEP 723 script; its tests run without network or pyarrow: +`capture_client_contract.py` refreshes the client contract from dfo-apis. `openapi --dfo-apis PATH` builds the composed app in that checkout's environment, in process, and writes `served/openapi.json` and `served/SOURCE.json`, refusing a checkout with uncommitted changes or untracked files and an environment out of step with its `uv.lock`; `record` runs the contract's scenarios against a base URL, dev by default, writes the records with every absolute URL's query redacted and a local app's signed URLs written as storage URLs, refusing a record that still names any other host, derives the synthetic ones and validates the result, and `record --offline` derives the outcomes again from the records with no request. A recorded scenario holds only exchanges the server made: `record` refuses a recorded scenario that a canned exchange answered, and a synthetic derivation makes no request. Nothing in a record marks an exchange as canned, so `validate_client_contract.py` cannot check this rule and the capture enforces it. It imports its outcome rules from `validate_client_contract.py`. `python/client-contract/README.md` has the recipe. A PEP 723 script; its tests run without network or pyarrow: ```bash uv run tools/capture_client_contract.py record diff --git a/tools/capture_client_contract.py b/tools/capture_client_contract.py index 4fbf36f..d404ef2 100644 --- a/tools/capture_client_contract.py +++ b/tools/capture_client_contract.py @@ -36,7 +36,8 @@ than copies. Every absolute URL a record keeps, a signed download or a `location` header, keeps its path, and its query becomes `X-Goog-Signature=redacted`, and a local app's blob URL becomes the storage -URL a deployment signs, so no signed URL names the base URL's host. The +URL a deployment signs; a record holding any other absolute URL, outside a +`location` under the base URL, is refused. The long builds need two specs the server has not built, so a local recording starts on a fresh datasets database. `--scenarios-dir` writes outside the package, unvalidated. The run ends by validating the whole contract with @@ -68,7 +69,7 @@ from datetime import UTC, datetime from pathlib import Path from typing import Any, Protocol -from urllib.parse import quote, unquote, urlsplit, urlunsplit +from urllib.parse import quote, unquote, urljoin, urlsplit, urlunsplit from validate_client_contract import ( FILE_EXPIRED, @@ -76,10 +77,12 @@ NO_VERSIONS, POLL_PATH, REBUILD_REFUSED, + STORAGE_ORIGIN, VERSION_UNAVAILABLE, Answer, ClientError, LongBuild, + absolute_url_problems, answer_from_body, answer_gaps, answer_members, @@ -90,21 +93,30 @@ data_warning, dataset_summary, digest_of, + download_target, + failed_operation, gap_kinds, + header_warnings, held_spec, + may_retry, + newest_listed, owns_body_file, part_label, pick_artifact, posted_scope, + problem_body, refusal_error, rendering_for, resubmitted_sentence, + retry_wait, + search_body, search_warning_code, search_warns, selector_path, sentence_entry, surface_problems, versions_path, + with_step_notes, ) from validate_client_contract import main as validate_main @@ -117,7 +129,14 @@ # The rendering both clients ask for: bare long Parquet. RENDERING = {"format": "parquet", "bundle": False} # The response headers a client reads, and so the ones a record keeps. -KEPT_HEADERS = ("content-type", "location", "retry-after") +KEPT_HEADERS = ( + "content-type", + "location", + "retry-after", + "deprecation", + "sunset", + "x-dfo-warning", +) def dump_json(document: Any) -> str: @@ -314,7 +333,6 @@ def _lower(items: Any) -> dict[str, str]: # `/__e2e__/blob/{bucket}/{object}` on the API's own origin. A record states # such a URL as the storage URL a deployment signs for the same object. LOCAL_BLOB_PREFIX = "/__e2e__/blob/" -STORAGE_ORIGIN = "https://storage.googleapis.com" def redact_external_url(url: str) -> str: @@ -360,6 +378,8 @@ class Recorder: bodies: dict[str, bytes] = field(default_factory=dict) commits: set[str] = field(default_factory=set) canned_served: int = 0 + warned: set[tuple[str, ...]] = field(default_factory=set) + warnings: list[str] = field(default_factory=list) def api(self, method: str, path: str, json_body: Any = None) -> Response: """A request to `path` under the base URL.""" @@ -399,7 +419,7 @@ def _send( exchange = self.canned.pop(0) self.exchanges.append(exchange) self.canned_served += 1 - return _canned_response(exchange["response"]) + return self._warned(_canned_response(exchange["response"]), bare=bare) headers = {} if bare else {"user-agent": "dfo-client-contract-recorder/1"} body = None @@ -412,6 +432,12 @@ def _send( if not bare and "x-dfo-commit" in response.headers: self.commits.add(response.headers["x-dfo-commit"]) self.exchanges.append({"request": request, "response": self._keep(response)}) + return self._warned(response, bare=bare) + + def _warned(self, response: Response, *, bare: bool) -> Response: + """Notes the warnings an API response's headers issue.""" + if not bare: + self.warnings.extend(header_warnings(response.headers, self.warned)) return response def _keep(self, response: Response) -> dict[str, Any]: @@ -604,6 +630,7 @@ class Session: expect: list[dict[str, Any]] = field(default_factory=list) minted: Minted | None = None long_builds: list[dict[str, Any]] = field(default_factory=list) + retry_waits: list[float] = field(default_factory=list) @property def gap_kinds(self) -> dict[str, str]: @@ -611,23 +638,50 @@ def gap_kinds(self) -> dict[str, str]: def _step(self, step: dict[str, Any], run: Callable[[], dict[str, Any]]) -> None: self.call.append(step) - self.long_builds = [] + self.long_builds, self.retry_waits = [], [] + self.recorder.warnings = [] try: outcome = run() except ClientError as error: outcome = error.outcome(self.client_codes) - if self.long_builds: - (value,) = outcome.values() - value["long_builds"] = self.long_builds - self.expect.append(outcome) + self.expect.append( + with_step_notes( + outcome, + long_builds=self.long_builds, + retry_waits=self.retry_waits, + warnings=self.recorder.warnings, + ) + ) def _answered(self, answer: Answer) -> dict[str, Any]: return answer_outcome(answer, self.gap_kinds) - def _resolve(self, input_: dict[str, Any]) -> Answer: - response = self.recorder.api( - "POST", "/search/resolve", {"schema_version": 1, "input": input_} + def _retried( + self, request: dict[str, Any], send: Callable[[], Response] + ) -> Response: + """Sends `request` through `send`, and again after each refusal + `may_retry` allows, waiting `retry_wait` before each retry.""" + response = send() + used = 0 + while may_retry(request, _read(response), used): + wait = retry_wait(response.headers, used) + self.retry_waits.append(wait) + self.sleep(wait) + response = send() + used += 1 + return response + + def _api(self, method: str, path: str, json_body: Any = None) -> Response: + """A request under the base URL, retried as a client retries it.""" + request: dict[str, Any] = {"method": method, "path": path} + if json_body is not None: + request["json"] = json_body + return self._retried( + request, lambda: self.recorder.api(method, path, json_body) ) + + def _resolve(self, input_: dict[str, Any]) -> Answer: + response = self._api("POST", "/search/resolve", search_body(input_)) return answer_from_body(self._acted(response)) def search(self, question: str) -> Answer: @@ -756,7 +810,7 @@ def mint(self, spec: Spec, *, layout: str | None = None) -> str: def run() -> dict[str, Any]: rendering = rendering_for(layout) body = _build_body(spec, None, rendering) - response = self.recorder.api("POST", "/datasets", body) + response = self._api("POST", "/datasets", body) resource = self._acted(response) require( response.status == 202, f"the build answered {response.status}, not 202" @@ -778,7 +832,7 @@ def resume(self, operation_id: str, *, layout: str | None = None) -> None: def run() -> dict[str, Any]: path = POLL_PATH.format(operation_id=operation_id) - response = self.recorder.api("GET", path) + response = self._api("GET", path) resource = self._acted(response) self.minted = Minted( resource, response.headers, None, None, rendering_for(layout) @@ -819,7 +873,7 @@ def build( def _built(self, body: dict[str, Any]) -> dict[str, Any]: """The manifest a build answers, through a long build on a 202.""" - response = self.recorder.api("POST", "/datasets", body) + response = self._api("POST", "/datasets", body) reply = self._acted(response) if response.status != 202: return reply @@ -868,18 +922,39 @@ def _identity_sentence( def _download(self, target: str, digest: str, *, origin: bool = True) -> bytes: """A file through the route that redirects to it: an artifact's - root-relative url, or a path under the base URL. A refused signed URL - or bytes of another digest ask the route once more.""" + root-relative url, or a path under the base URL. The redirect's + location is fetched once, where `download_target` places it; a local + app's blob URL on the API's origin stands for the storage URL a + deployment signs. A refused fetch or bytes of another digest ask the + route once more.""" + base_url = self.recorder.base_url + if origin: + route_url = _origin(base_url) + target + request = {"method": "GET", "origin_path": target} + else: + route_url = base_url.rstrip("/") + target + request = {"method": "GET", "path": target} failure = ClientError("download_failed") for _ in range(2): - files = ( - self.recorder.origin("GET", target) - if origin - else self.recorder.api("GET", target) + files = self._retried( + request, + lambda: ( + self.recorder.origin("GET", target) + if origin + else self.recorder.api("GET", target) + ), ) self._raise_problem(files) require(files.status == 302, f"the files route answered {files.status}") - data = self.recorder.external(files.headers["location"]) + location = files.headers["location"] + kind, at = download_target(base_url, route_url, location) + if kind == "origin_path" and at.startswith(LOCAL_BLOB_PREFIX): + kind = "url" + data = ( + self.recorder.external(urljoin(route_url, location)) + if kind == "url" + else self.recorder.origin("GET", at) + ) if data.status >= 400: failure = ClientError("download_failed") continue @@ -905,9 +980,9 @@ def _wait( self.sleep(build.next_wait()) path = POLL_PATH.format(operation_id=build.entry["operation_id"]) response = self.recorder.api("GET", path) - if build.polled(response.status, response.headers, _json(response)): - again = self.recorder.api("POST", "/datasets", request) - build.reposted(again.status, again.headers, _json(again)) + if build.polled(response.status, response.headers, _answered(response)): + again = self._api("POST", "/datasets", request) + build.reposted(again.status, again.headers, _answered(again)) return build.result # -- stored versions -- @@ -922,9 +997,7 @@ def _stored(self, member: dict[str, Any]) -> Member: refusal: ClientError | None = None manifest = None try: - manifest = self._acted( - self.recorder.api("GET", f"/datasets/{spec_id}/{version}") - ) + manifest = self._acted(self._api("GET", f"/datasets/{spec_id}/{version}")) except ClientError as error: if error.code != FILE_EXPIRED: raise @@ -994,29 +1067,46 @@ def _stored_file( def _newest(self, spec_id: str) -> str | None: try: - body = self._acted(self.recorder.api("GET", versions_path(spec_id))) + body = self._acted(self._api("GET", versions_path(spec_id))) except ClientError as error: if error.error_class(self.client_codes) in NO_VERSIONS: return None raise - versions = body.get("versions") if isinstance(body, dict) else None - first = versions[0] if isinstance(versions, list) and versions else None - newest = first.get("content_version") if isinstance(first, dict) else None - return newest if isinstance(newest, str) else None + return newest_listed(body) def _acted(self, response: Response) -> Any: + """The JSON body of a success; a refusal raises its error, and a + success without a JSON body raises ContractError + `unexpected_response`.""" self._raise_problem(response) - return response.json() + return _answered(response) def _raise_problem(self, response: Response) -> None: if response.status < 400: return - raise refusal_error(response.status, _json(response), self.actions) + raise refusal_error( + response.status, problem_body(_read(response)), self.actions + ) + +def _read(response: Response) -> dict[str, Any]: + """A response as a record holds it: its status, headers, and its JSON + body when it has one.""" + read: dict[str, Any] = {"status": response.status, "headers": response.headers} + if response.body and _is_json(response.headers.get("content-type", "")): + read["json"] = response.json() + return read -def _json(response: Response) -> Any: - """A response's JSON body, or None for an empty one.""" - return response.json() if response.body else None + +def _answered(response: Response) -> Any: + """A success's JSON body, which a success without one lacks, raising + ContractError `unexpected_response`, or a refusal's problem body.""" + read = _read(response) + if response.status >= 400: + return problem_body(read) + if "json" not in read: + raise ClientError("unexpected_response") + return read["json"] def _operation_outcome(resource: dict[str, Any]) -> dict[str, Any]: @@ -1752,6 +1842,28 @@ def _same(parent: dict[str, Any], exchanges: list[dict[str, Any]]) -> Derived: ) +def _waited(outcome: dict[str, Any], *refusals: dict[str, Any]) -> dict[str, Any]: + """`outcome` with the waits before the retries that follow `refusals`, + the refused exchanges of one request in order.""" + waits = [ + retry_wait(refused["response"].get("headers", {}), attempt) + for attempt, refused in enumerate(refusals) + ] + return with_step_notes(outcome, long_builds=(), retry_waits=waits, warnings=()) + + +def _refused_first( + parent: dict[str, Any], index: int, refused: dict[str, Any] +) -> Derived: + """The parent with `refused` answering exchange `index` first, and the + retry's wait in the outcome of the last step, which makes it.""" + exchanges = copy.deepcopy(parent["exchanges"]) + exchanges.insert(index, refused) + expect = copy.deepcopy(parent["expect"]) + expect[-1] = _waited(expect[-1], refused) + return Derived(copy.deepcopy(parent["call"]), exchanges, expect) + + def _retry_after_503(parent: dict[str, Any], ctx: Context) -> Derived: first = parent["exchanges"][0] problem = _problem( @@ -1762,7 +1874,7 @@ def _retry_after_503(parent: dict[str, Any], ctx: Context) -> Derived: retryable=True, ) refused = _refusal(first["request"], 503, problem, {"retry-after": "1"}) - return _same(parent, [refused, *copy.deepcopy(parent["exchanges"])]) + return _refused_first(parent, 0, refused) def _proxy_429(parent: dict[str, Any], ctx: Context) -> Derived: @@ -1770,7 +1882,7 @@ def _proxy_429(parent: dict[str, Any], ctx: Context) -> Derived: refused = _refusal( first["request"], 429, dict(_PROXY_RATE_LIMITED), {"retry-after": "2"} ) - return _same(parent, [refused, *copy.deepcopy(parent["exchanges"])]) + return _refused_first(parent, 0, refused) def _proxy_502(parent: dict[str, Any], ctx: Context) -> Derived: @@ -1781,7 +1893,9 @@ def _proxy_502(parent: dict[str, Any], ctx: Context) -> Derived: error = refusal_error(502, _PROXY_UNAVAILABLE, ctx.actions).outcome( ctx.client_codes ) - return Derived(copy.deepcopy(parent["call"]), refused, [error]) + return Derived( + copy.deepcopy(parent["call"]), refused, [_waited(error, *refused[:2])] + ) def _build_index(parent: dict[str, Any]) -> int: @@ -1831,11 +1945,17 @@ def _build_index(parent: dict[str, Any]) -> int: NEWER_VERSION = "cv_" + "1" * 32 -def _retry_after_504(parent: dict[str, Any], ctx: Context) -> Derived: - exchanges = copy.deepcopy(parent["exchanges"]) - index = _build_index(parent) - exchanges.insert(index, _refusal(exchanges[index]["request"], 504, _TIMEOUT)) - return _same(parent, exchanges) +def _retry_after_504( + headers: Mapping[str, str] | None = None, +) -> Callable[[dict[str, Any], Context], Derived]: + """A 504 timeout, carrying `headers`, answers the parent's first build.""" + + def derive(parent: dict[str, Any], ctx: Context) -> Derived: + index = _build_index(parent) + build = parent["exchanges"][index]["request"] + return _refused_first(parent, index, _refusal(build, 504, _TIMEOUT, headers)) + + return derive def _ends_at_build( @@ -1864,7 +1984,7 @@ def _cut_off_twice( ) -> tuple[list[dict[str, Any]], dict[str, Any]]: refused = _refusal(build["request"], 504, _TIMEOUT) error = refusal_error(504, _TIMEOUT, ctx.actions).outcome(ctx.client_codes) - return [refused, copy.deepcopy(refused)], error + return [refused, copy.deepcopy(refused)], _waited(error, refused) def _not_resolvable( @@ -2362,6 +2482,154 @@ def _strict_info_notice(parent: dict[str, Any], ctx: Context) -> Derived: return Derived(call, exchanges, copy.deepcopy(parent["expect"])) +def _signed_url_refused_twice(parent: dict[str, Any], ctx: Context) -> Derived: + """Both signed fetches refuse 403, the second after the files route was + asked again.""" + exchanges = copy.deepcopy(parent["exchanges"]) + index = next(i for i, e in enumerate(exchanges) if "url" in e["request"]) + files, signed = exchanges[index - 1], exchanges[index] + signed["response"] = {"status": 403, "headers": {"content-type": "application/xml"}} + return Derived( + copy.deepcopy(parent["call"]), + [*exchanges[: index + 1], copy.deepcopy(files), copy.deepcopy(signed)], + [*copy.deepcopy(parent["expect"][:-1]), ctx.raised("download_failed")], + ) + + +# The relative Location a files route answers in `fetch-spec-relative-location`, +# which names a path beside the route's own. +RELATIVE_LOCATION = "bytes" + + +def _relative_location(parent: dict[str, Any], ctx: Context) -> Derived: + """The files route answers RELATIVE_LOCATION, and the file comes from the + path it resolves to against the route's URL, on the API's origin.""" + exchanges = copy.deepcopy(parent["exchanges"]) + index = next(i for i, e in enumerate(exchanges) if "url" in e["request"]) + files, signed = exchanges[index - 1], exchanges[index] + route = files["request"]["origin_path"] + files["response"]["headers"]["location"] = RELATIVE_LOCATION + resolved = urlsplit(urljoin(f"https://api.invalid{route}", RELATIVE_LOCATION)) + signed["request"] = {"method": "GET", "origin_path": resolved.path} + return _same(parent, exchanges) + + +def _failed_without_error(parent: dict[str, Any], ctx: Context) -> Derived: + """The resumed operation's first poll answers it failed with no error.""" + resume, poll = copy.deepcopy(parent["exchanges"][:2]) + operation = poll["response"]["json"]["operation"] + operation["status"] = "failed" + operation.pop("progress", None) + poll["response"]["json"] = {"operation": operation} + error, _ = failed_operation(poll["response"]["json"], ctx.actions) + (build,) = parent["expect"][1]["dataset"]["long_builds"] + entry = {**build, "poll_waits": build["poll_waits"][:1], "resubmissions": 0} + outcome = with_step_notes( + error.outcome(ctx.client_codes), + long_builds=[entry], + retry_waits=(), + warnings=(), + ) + return Derived( + copy.deepcopy(parent["call"]), + [resume, poll], + [copy.deepcopy(parent["expect"][0]), outcome], + ) + + +def _versions_renamed(parent: dict[str, Any], ctx: Context) -> Derived: + exchanges = copy.deepcopy(parent["exchanges"]) + body = exchanges[0]["response"]["json"] + body["items"] = body.pop("versions") + return Derived( + copy.deepcopy(parent["call"]), exchanges, [ctx.raised("contract_violation")] + ) + + +# The Sunset header `search-sunset-warning`'s responses carry, with no +# Deprecation header beside it. +SUNSET = "Sat, 01 May 2027 00:00:00 GMT" + + +def _sunset_twice(parent: dict[str, Any], ctx: Context) -> Derived: + """The parent's search made twice, each response carrying SUNSET: the + first warns, and the second, with the same value, does not.""" + exchange = copy.deepcopy(parent["exchanges"][0]) + exchange["response"]["headers"]["sunset"] = SUNSET + (step,) = parent["call"] + (outcome,) = parent["expect"] + warned = with_step_notes( + copy.deepcopy(outcome), + long_builds=(), + retry_waits=(), + warnings=header_warnings(exchange["response"]["headers"], set()), + ) + return Derived( + [copy.deepcopy(step), copy.deepcopy(step)], + [exchange, copy.deepcopy(exchange)], + [warned, copy.deepcopy(outcome)], + ) + + +def _search_ends( + change: Callable[[dict[str, Any]], None], code: str +) -> Callable[[dict[str, Any], Context], Derived]: + """The parent's search alone, its response changed by `change`, ending + in the client error `code`.""" + + def derive(parent: dict[str, Any], ctx: Context) -> Derived: + exchange = copy.deepcopy(parent["exchanges"][0]) + change(exchange["response"]) + return Derived( + copy.deepcopy(parent["call"][:1]), [exchange], [ctx.raised(code)] + ) + + return derive + + +def _status_a_number(response: dict[str, Any]) -> None: + response["json"]["parts"][1]["status"] = 7 + + +def _definition_spec_id_differs(response: dict[str, Any]) -> None: + response["json"]["parts"][0]["spec"]["definition"]["spec_id"] = UNKNOWN_SPEC_ID + + +# The spec_id a Search spec's definition names in +# `answer-definition-spec-id-mismatch`, one no build answered. +UNKNOWN_SPEC_ID = "spec_" + "0" * 32 + + +def _without_json(response: dict[str, Any]) -> None: + del response["json"] + response["headers"] = {"content-type": "text/html; charset=utf-8"} + + +def _without_data_query(body: Any, ctx: Context) -> Any: + """The first option of the one no_data part loses its data_query.""" + body = copy.deepcopy(body) + del body["parts"][0]["no_data"]["options"][0]["data_query"] + return body + + +def _choice_without_data_query(parent: dict[str, Any], ctx: Context) -> Derived: + derived = _choice(parent["call"][1]["option"], edit=_without_data_query)( + parent, ctx + ) + require( + derived.expect[-1] == ctx.raised("contract_violation"), + "the choice raises ContractError", + ) + return derived + + +def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: + """The fetch names `entities: {}` and `facets: {}`, which narrow nothing.""" + derived = _same(parent, copy.deepcopy(parent["exchanges"])) + derived.call[0].update(entities={}, facets={}) + return derived + + SYNTHETIC = ( Synthetic( "search-retry-after-503", @@ -2394,8 +2662,17 @@ def _strict_info_notice(parent: dict[str, Any], ctx: Context) -> Derived: "answer-definite-fetch", "A 504 timeout with retryable true answers the first build.", "A synchronous build cut off at the server's limit answers a retryable 504 timeout; the " - "client builds once more and reaches the same dataset.", - _retry_after_504, + "client waits the first backoff, 0.5 seconds, builds once more and reaches the same " + "dataset.", + _retry_after_504(), + ), + Synthetic( + "fetch-spec-504-retry-after", + "fetch-spec-known-sentence", + "A 504 timeout with retryable true and Retry-After 5 answers the build.", + "A build cut off by a 504 that carries Retry-After is posted once more after the " + "Retry-After seconds, not the backoff, and reaches the same dataset.", + _retry_after_504({"retry-after": "5"}), ), Synthetic( "fetch-spec-504-twice", @@ -2526,6 +2803,91 @@ def _strict_info_notice(parent: dict[str, Any], ctx: Context) -> Derived: "for a fresh redirect and downloads from that, reaching the same dataset.", _signed_url_refused, ), + Synthetic( + "fetch-ref-signed-url-refused-twice", + "fetch-ref", + "The signed download answers 403, and so does the one the files route names when asked again.", + "A download asks the files route once and fetches the signed URL once, then asks the " + "route once more and fetches again, with no wait; a second refused fetch raises " + "ServerError download_failed.", + _signed_url_refused_twice, + ), + Synthetic( + "fetch-spec-relative-location", + "fetch-spec-known-sentence", + f"The files route's Location becomes the relative URL {RELATIVE_LOCATION!r}, and the " + "file comes from the path it resolves to.", + "A relative Location resolves against the files route's URL, not the base URL's " + "origin, and the client fetches the file there, on the API's origin, reaching the " + "same dataset.", + _relative_location, + ), + Synthetic( + "operation-failed-without-error", + "operation-resume", + "The resumed operation's first poll answers it failed with no error member.", + "A failed operation whose resource carries no error raises ServerError with the code " + "operation_failed; a resumed operation holds no build request, so nothing is posted " + "again.", + _failed_without_error, + ), + Synthetic( + "newest-version-unreadable-page", + "fetch-ref-newest-version", + "The versions page names its versions list items.", + "A versions page with no versions list raises ContractError contract_violation, " + "since only a NotFoundError reads as no stored version.", + _versions_renamed, + ), + Synthetic( + "search-sunset-warning", + "search-place-ambiguous", + f"The search is made twice, and each response carries Sunset {SUNSET!r} with no " + "Deprecation header.", + "A Sunset header alone issues the route_deprecated warning, once per process per " + "distinct value, so the second search, whose response carries the same value, " + "warns nothing.", + _sunset_twice, + ), + Synthetic( + "answer-part-status-not-a-string", + "answer-mixed-fetch-raises", + "Part 1's status becomes the number 7, and the fetch goes.", + "A part whose status is not a string raises ContractError contract_violation at " + "/parts/1/status, where an unknown string status is an unknown gap.", + _search_ends(_status_a_number, "contract_violation"), + ), + Synthetic( + "answer-definition-spec-id-mismatch", + "answer-definite-fetch", + f"Part 0's spec definition names spec_id {UNKNOWN_SPEC_ID}, and the fetch goes.", + "A Search spec whose definition.spec_id differs from its spec_id raises ContractError " + "contract_violation, in a Search response as in a ref.", + _search_ends(_definition_spec_id_differs, "contract_violation"), + ), + Synthetic( + "search-no-json-body", + "search-place-ambiguous", + "The search answers 200 with an empty text/html body.", + "A 2xx Search response with no JSON body raises ContractError unexpected_response.", + _search_ends(_without_json, "unexpected_response"), + ), + Synthetic( + "choose-option-without-data-query", + "choose-place-one-part", + "The no_data part's first option loses its data_query.", + "Choosing an option with no data_query in a one-part answer raises ContractError " + "contract_violation with no request, as in a several-part answer.", + _choice_without_data_query, + ), + Synthetic( + "fetch-spec-empty-narrowing", + "fetch-spec-known-sentence", + "The fetch names entities {} and facets {}.", + "An empty entities or facets map narrows nothing, so the build posts no scope, as a " + "fetch that names neither does.", + _empty_narrowing, + ), Synthetic( "answer-unknown-part-status", "answer-mixed-fetch-raises", @@ -2718,16 +3080,12 @@ def write_record( def _refuse_local_host(record: dict[str, Any], base_url: str) -> None: - """Refuses a record whose signed download or `location` header names the - base URL's host: a client fetches those cross-origin, without its key.""" - local = urlsplit(base_url).netloc - for exchange in record["exchanges"]: - urls = [ - exchange["request"].get("url"), - exchange["response"].get("headers", {}).get("location"), - ] - if any(url and urlsplit(url).netloc == local for url in urls): - raise SystemExit(f"{record['name']}: a signed URL still names {local}") + """Refuses a record holding an absolute URL other than a redacted signed + URL on the storage host, or a `location` under `base_url`, as + `absolute_url_problems` finds them: a local app's host, under any name + or port, is one no deployed client can fetch.""" + if problems := absolute_url_problems(record, base_url): + raise SystemExit("\n".join(problems)) def record_recorded(definition: Recorded, ctx: Context, directory: Path) -> None: @@ -2768,7 +3126,7 @@ def record_synthetic(definition: Synthetic, ctx: Context, directory: Path) -> No "edit": definition.edit, } record = _record(definition.name, definition.description, origin, derived) - _refuse_local_host(record, ctx.base_url) + _refuse_local_host(record, parent["origin"]["base_url"]) write_record(directory, record, derived.bodies) diff --git a/tools/tests/test_capture_client_contract.py b/tools/tests/test_capture_client_contract.py index a55163f..44fffdb 100644 --- a/tools/tests/test_capture_client_contract.py +++ b/tools/tests/test_capture_client_contract.py @@ -159,10 +159,24 @@ def test_every_absolute_url_loses_its_query(url: str, expected: str) -> None: ("location", "refused"), [ ("http://127.0.0.1:19493/__e2e__/blob/b/o?X-Goog-Signature=redacted", True), + ("http://localhost:19493/b/o?X-Goog-Signature=redacted", True), + ("http://127.0.0.1:4443/b/o?X-Goog-Signature=redacted", True), + ("http://127.0.0.1/b/o?X-Goog-Signature=redacted", True), + ("http://storage.googleapis.com/b/o?X-Goog-Signature=redacted", True), ("https://storage.googleapis.com/b/o?X-Goog-Signature=redacted", False), + ("http://127.0.0.1:19493/api/datasets/operations/op_1", False), ("/api/datasets/operations/op_1", False), ], - ids=["local-signed-url", "storage-url", "root-relative"], + ids=[ + "local-signed-url", + "localhost-alias", + "other-port", + "no-port", + "storage-over-http", + "storage-url", + "api-route-under-the-base-url", + "root-relative", + ], ) def test_a_record_whose_signed_url_names_the_local_host_is_refused( location: str, refused: bool @@ -174,7 +188,7 @@ def test_a_record_whose_signed_url_names_the_local_host_is_refused( record = {"name": "s", "exchanges": [exchange]} base_url = "http://127.0.0.1:19493/api" if refused: - with pytest.raises(SystemExit, match=r"still names 127\.0\.0\.1:19493"): + with pytest.raises(SystemExit, match="where a record's absolute URL names"): capture._refuse_local_host(record, base_url) else: capture._refuse_local_host(record, base_url) diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index bc4d868..7c7da46 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -172,7 +172,8 @@ def change(doc: Any) -> None: def _resubmit_answers_built(doc: Any) -> None: """Search answers the identity resubmit with the built spec_id.""" built = doc["exchanges"][0]["response"]["json"]["definition"]["spec_id"] - doc["exchanges"][1]["response"]["json"]["parts"][0]["spec"]["spec_id"] = built + spec = doc["exchanges"][1]["response"]["json"]["parts"][0]["spec"] + spec["spec_id"] = spec["definition"]["spec_id"] = built def _posted_entities(change: Callable[[Any], None]) -> Callable[[Any], None]: @@ -265,6 +266,65 @@ def _versions_forbidden(response: Any) -> None: ) +def _keep_exchanges(count: int) -> Callable[[Any], None]: + return lambda doc: doc.update(exchanges=doc["exchanges"][:count]) + + +def _never_retried(doc: Any) -> None: + """The 503 ends the record, and the search raises it unretried.""" + doc["exchanges"] = doc["exchanges"][:1] + doc["expect"] = [{"error": {"class": "ServerError", "code": "service_unavailable"}}] + + +def _proxy_code(code: str) -> Callable[[Any], None]: + def change(doc: Any) -> None: + for exchange in doc["exchanges"]: + exchange["response"]["json"]["error"] = code + doc["expect"][0]["error"]["code"] = code + + return change + + +def _search_posts(change: Callable[[Any], None]) -> Callable[[Any], None]: + return lambda doc: change(doc["exchanges"][0]["request"]["json"]) + + +def _redirect_to(url: str) -> Callable[[Any], None]: + """fetch-spec-known-sentence's files route names `url`, and the client + fetches it.""" + + def change(doc: Any) -> None: + doc["exchanges"][1]["response"]["headers"]["location"] = url + doc["exchanges"][2]["request"]["url"] = url + + return change + + +def _posted_scope(scope: Any) -> Callable[[Any], None]: + return lambda doc: doc["exchanges"][0]["request"]["json"]["input"].update( + scope=scope + ) + + +def _without_data_query(doc: Any) -> None: + del doc["exchanges"][0]["response"]["json"]["parts"][0]["no_data"]["options"][0][ + "data_query" + ] + + +def _second_fetch_served(doc: Any) -> None: + """The second signed fetch serves the stored file.""" + doc["exchanges"][-1]["response"] = { + "status": 200, + "headers": {"content-type": "application/vnd.apache.parquet"}, + "body_file": "fetch-ref.parquet", + } + + +_SUNSET = "scenarios/search-sunset-warning.json" +_FOREIGN = "https://downloads.example.com/b/o?X-Goog-Signature=redacted" + + @pytest.mark.parametrize( ("target", "change", "expected"), [ @@ -655,7 +715,12 @@ def _versions_forbidden(response: Any) -> None: ( "client-codes.json", _add_action( - {"code": "spec_not_found", "class": "NotFoundError", "condition": "x"} + { + "code": "spec_not_found", + "class": "NotFoundError", + "retryable": False, + "condition": "x", + } ), "'spec_not_found' is also a code in actions.json", ), @@ -665,6 +730,7 @@ def _versions_forbidden(response: Any) -> None: { "code": "alternates_unevaluated", "class": "ServerError", + "retryable": False, "condition": "x", } ), @@ -900,6 +966,176 @@ def _versions_forbidden(response: Any) -> None: _set_step(0, window=[2020, 2023]), "scenarios/mint-async-build.json: schema: call/0", ), + ( + "scenarios/search-proxy-unavailable.json", + _keep_exchanges(2), + "is a retryable refusal with retries left", + ), + (_RETRY_503, _never_retried, "is a retryable refusal with retries left"), + ( + _SEARCH, + _search_posts(lambda body: body.update(response_options=None)), + "where the rules post", + ), + ( + _SEARCH, + _search_posts(lambda body: body.pop("schema_version")), + "where the rules post", + ), + ( + "scenarios/mint-async-build.json", + _set_step(1, timeout=0.001), + "scenarios/mint-async-build.json: schema: call/1", + ), + ( + "scenarios/search-proxy-unavailable.json", + _proxy_code("made_up_code"), + "proxy code 'made_up_code' is not a code proxy-codes.json lists", + ), + ( + "scenarios/search-proxy-unavailable.json", + _proxy_code("rate_limited"), + "lists with status 502", + ), + ( + "proxy-codes.json", + _add_action({"code": "spec_not_found", "status": 404, "condition": "x"}), + "'spec_not_found' is also a code in registries/codes.json", + ), + ( + "warning-codes.json", + _drop_action("route_deprecated"), + "no row for 'route_deprecated'", + ), + ( + "warning-codes.json", + _add_action( + {"code": "key_too_long", "class": "DfoWarning", "condition": "x"} + ), + "'key_too_long' is a warning no rule issues", + ), + ( + "warning-codes.json", + _add_action({"code": "offline", "class": "DfoWarning", "condition": "x"}), + "'offline' is also a code in client-codes.json", + ), + ( + "scenarios/fetch-ref.json", + lambda doc: doc["exchanges"][1]["response"]["headers"].update( + location="http://localhost:19493/b/o?X-Goog-Signature=redacted" + ), + "names localhost:19493, where a record's absolute URL names", + ), + ( + "scenarios/fetch-ref.json", + lambda doc: doc["exchanges"][2]["request"].update( + url="http://127.0.0.1:4443/b/o?X-Goog-Signature=redacted" + ), + "names 127.0.0.1:4443, where a record's absolute URL names", + ), + (_FETCH, _redirect_to(_FOREIGN), "names downloads.example.com"), + (_FETCH, _redirect_to(_FOREIGN), "the steps never make exchanges 2 to 2"), + ( + "scenarios/fetch-spec-relative-location.json", + lambda doc: doc["exchanges"][2]["request"].update(origin_path="/bytes"), + "where the steps make a GET /api/datasets/", + ), + ( + "scenarios/fetch-spec-empty-narrowing.json", + _posted_scope({"facets": {}}), + "where the rules post", + ), + ( + "scenarios/fetch-spec-empty-narrowing.json", + _posted_scope({"entities": {}}), + "where the rules post", + ), + ( + _SEARCH, + lambda doc: doc["exchanges"][0]["response"].pop("json"), + "step 0 expects", + ), + ( + _SEARCH, + lambda doc: doc["origin"].update(dfo_commit="f" * 40), + "is not served/SOURCE.json's commit", + ), + ( + "scenarios/fetch-ref-signed-url-refused-twice.json", + _second_fetch_served, + "step 0 expects", + ), + ( + "scenarios/operation-failed-without-error.json", + _error_code(1, "refusal_without_code"), + "step 1 expects", + ), + ( + "client-codes.json", + _set_action("offline", retryable=None), + "'retryable' is a required property", + ), + ( + "client-codes.json", + _set_action("offline", retryable="by_status"), + "'offline' takes its retryable flag by_status", + ), + ( + "scenarios/newest-version-unreadable-page.json", + lambda doc: doc["expect"].__setitem__( + 0, {"newest_version": {"content_version": None}} + ), + "step 0 expects", + ), + ( + _RETRY_503, + _set_outcome(0, lambda o: o["answer"].update(retry_waits=[0.5])), + "step 0 expects", + ), + ( + "scenarios/fetch-spec-504-retry-after.json", + _set_outcome(0, lambda o: o["dataset"].update(retry_waits=[0.5])), + "step 0 expects", + ), + ( + _SUNSET, + _set_outcome(0, lambda o: o["answer"].pop("warnings")), + "step 0 expects", + ), + ( + _SUNSET, + _set_outcome( + 1, lambda o: o["answer"].update(warnings=["route_deprecated"]) + ), + "step 1 expects", + ), + ( + "scenarios/answer-unknown-part-status.json", + _set_body(0, lambda body: body["parts"][1].update(status=7)), + "the step follows no answer", + ), + ( + "scenarios/answer-definite-fetch.json", + _set_body( + 0, + lambda body: body["parts"][0]["spec"]["definition"].update( + spec_id="spec_" + "0" * 32 + ), + ), + "the step follows no answer", + ), + ( + "scenarios/choose-place-one-part.json", + _without_data_query, + "the steps never make exchanges 1 to 1", + ), + ( + "scenarios/fetch-spec-member-not-resolvable.json", + lambda doc: doc["exchanges"][0]["response"]["headers"].update( + {"content-type": "text/html"} + ), + "step 0 expects", + ), ], ids=[ "strict-pointer-unresolved", @@ -1022,6 +1258,39 @@ def _versions_forbidden(response: Any) -> None: "served-document-with-skills", "newest-version-not-the-listed-one", "mint-step-narrowed", + "retry-short-of-the-budget", + "retryable-refusal-never-retried", + "search-posts-an-extra-member", + "search-without-schema-version", + "step-timeout", + "proxy-code-unlisted", + "proxy-code-wrong-status", + "proxy-code-is-a-registry-code", + "warning-code-missing", + "warning-code-no-rule-issues", + "warning-code-is-a-client-code", + "location-localhost-alias", + "signed-url-other-port", + "location-foreign-origin-recorded", + "location-foreign-origin-raises", + "relative-location-against-the-origin", + "empty-facets-posts-scope", + "empty-entities-posts-scope", + "search-200-without-body", + "dfo-commit-not-the-served-commit", + "second-signed-fetch-served", + "failed-operation-without-error-uncoded", + "client-code-without-retryable", + "client-code-retryable-by-status", + "unreadable-versions-page-reads-as-none", + "retry-waits-backoff-over-retry-after", + "build-retry-waits-backoff-over-retry-after", + "sunset-warning-missing", + "sunset-warning-repeated", + "part-status-not-a-string", + "definition-spec-id-mismatch", + "one-part-option-without-data-query", + "refusal-in-another-content-type", ], ) def test_a_broken_contract_is_reported( diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index d7f64fe..2c8f473 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -29,7 +29,12 @@ - `client-codes.json` lists codes in order, each once, none of them a code in `actions.json` or `registries/codes.json`. Each row's class is one a scenario's error may name, other than a warning's, and only - `refusal_without_code` takes the class its status maps to. + `refusal_without_code` takes the class its status maps to, and its + retryable flag `by_status`. +- `proxy-codes.json` and `warning-codes.json` list codes in order, each once, + none of them a code another table or `registries/codes.json` holds, and the + warning codes are those the client rules issue: `route_deprecated`, + `server_warning`, and one `key_` per key-format reason. - Each scenario's file name matches its `name`, names are unique, `expect` holds one outcome per step, a step that acts on an earlier result follows one, a synthetic scenario derives from a recorded one, and every body file @@ -38,8 +43,10 @@ method in `served/openapi.json`, its JSON body validates against the route's request schema, each JSON response body validates against the route's schema for its status, a required member included when it admits - null. In every scenario a problem document's `code`, a failed operation's - error included, is an active code registered with its status. + null, and its `origin.dfo_commit` is `served/SOURCE.json`'s commit. In + every scenario a problem document's `code`, a failed operation's error + included, is an active code registered with its status, and the website + proxy's `error` a code `proxy-codes.json` lists with its status. - Each error a scenario expects, other than a `SearchWarning` or `DataWarning`, carries a refusal's code from its exchanges, a failed operation's included, or a client code of its class. @@ -54,12 +61,16 @@ data_query or dataset_resubmit entries, or a member's identity with the entity groups of the roles its build left bound as they were, and each build posts the body `build_body` gives for the spec the step builds, its - narrowing and its layout. A POST carries its body, a refused request - repeated is a retry only as `may_retry` allows, each poll names the - operation the client holds, and each signed download is the `location` the - files route answered. Every - absolute URL a record holds, a `url` request or a `location` header, has - the query `X-Goog-Signature=redacted`. + narrowing and its layout, and each Search request the whole body + `search_body` gives. A POST carries its body, a refused request repeated is + a retry only as `may_retry` allows, a record that ends a run of retries + while `may_retry` holds does not fit, each poll names the operation the + client holds, and each signed download is where `download_target` places + the `location` the files route answered. The outcomes give the waits + before retries and the warnings response headers issue. Every absolute URL + a record holds, a `url` request or a `location` header, is a signed URL on + the storage host with the query `X-Goog-Signature=redacted`, or a + `location` under the base URL. - Each ref example's file name matches its `name` and gets the verdict it states: from `dataset-ref.schema.json`, then from the rules that each member's definition carries its own `spec_id` and that members hold @@ -82,7 +93,7 @@ from dataclasses import dataclass, field from pathlib import Path from typing import Any -from urllib.parse import urlsplit +from urllib.parse import urljoin, urlsplit, urlunsplit import jsonschema from referencing import Registry, Resource @@ -141,6 +152,8 @@ def _contract_validators() -> dict[str, jsonschema.Draft202012Validator]: "strict-fields.schema.json", "actions.schema.json", "client-codes.schema.json", + "proxy-codes.schema.json", + "warning-codes.schema.json", "scenario.schema.json", "dataset-ref.schema.json", "rules/rules.schema.json", @@ -411,9 +424,74 @@ def _check_client_codes( f"client-codes.json: {by_status} take the class {BY_STATUS}, where " f"{REFUSAL_WITHOUT_CODE!r} alone does" ) + problems.extend( + f"client-codes.json: {row['code']!r} takes its retryable flag " + f"{BY_STATUS} exactly when it takes its class {BY_STATUS}" + for row in document["codes"] + if (row["retryable"] == BY_STATUS) != (row["class"] == BY_STATUS) + ) + return problems + + +def _sorted_once(label: str, codes: Sequence[str]) -> list[str]: + problems = [ + f"{label}: code {code!r} is listed twice" + for code in sorted({c for c in codes if codes.count(c) > 1}) + ] + if list(codes) != sorted(codes): + problems.append(f"{label}: codes are not sorted") + return problems + + +def _check_other_codes( + label: str, codes: Sequence[str], taken: Mapping[str, set[str]] +) -> list[str]: + """A code table's codes are sorted, listed once, and none is a code + another table or the registry holds.""" + problems = _sorted_once(label, codes) + for source, others in taken.items(): + problems.extend( + f"{label}: {code!r} is also a code in {source}" + for code in sorted(set(codes) & others) + ) + return problems + + +def _check_proxy_codes( + document: dict[str, Any], taken: Mapping[str, set[str]] +) -> list[str]: + codes = [row["code"] for row in document["codes"]] + return _check_other_codes("proxy-codes.json", codes, taken) + + +def _check_warning_codes( + document: dict[str, Any], + taken: Mapping[str, set[str]], + key_reasons: Sequence[str], +) -> list[str]: + """As `_check_other_codes`, and the codes are those a client's rules + issue: each header warning, and one `key_` warning per + key-format reason.""" + codes = [row["code"] for row in document["codes"]] + problems = _check_other_codes("warning-codes.json", codes, taken) + wanted = {ROUTE_DEPRECATED, SERVER_WARNING, *(f"key_{r}" for r in key_reasons)} + problems.extend( + f"warning-codes.json: no row for {code!r}, a warning a client issues" + for code in sorted(wanted - set(codes)) + ) + problems.extend( + f"warning-codes.json: {code!r} is a warning no rule issues" + for code in sorted(set(codes) - wanted) + ) return problems +def key_format_reasons(rules_schema: Mapping[str, Any]) -> list[str]: + """The reasons the key-format rule warns with.""" + vectors = rules_schema["$defs"]["key_format"]["properties"]["vectors"] + return vectors["items"]["properties"]["reason"]["enum"] + + # --- scenarios -------------------------------------------------------------- @@ -502,6 +580,7 @@ def _check_exchange( base_path: str, routes: _Routes, registry: dict[str, Any], + proxy_codes: Mapping[str, Mapping[str, Any]], ) -> list[str]: request, response = exchange["request"], exchange["response"] if "url" in request: @@ -543,15 +622,33 @@ def _check_exchange( f"{label}: response body: {problem}" for problem in routes.validate(pointer, response["json"]) ) - problems.extend(_check_problem_code(label, response, registry)) + problems.extend(_check_problem_code(label, response, registry, proxy_codes)) return problems def _check_problem_code( - label: str, response: dict[str, Any], registry: dict[str, Any] + label: str, + response: dict[str, Any], + registry: dict[str, Any], + proxy_codes: Mapping[str, Mapping[str, Any]], ) -> list[str]: - body = response["json"] - if response["status"] < 400 or not isinstance(body, dict) or "code" not in body: + """A refusal's code: a problem document's is an active registry code + registered with its status, and the website proxy's `error` is a code + `proxy-codes.json` lists with its status.""" + body = response.get("json") + if response["status"] < 400 or not isinstance(body, dict): + return [] + if "code" not in body: + if "error" not in body: + return [] + row = proxy_codes.get(body["error"]) + if row is None or row["status"] != response["status"]: + return [ + ( + f"{label}: proxy code {body['error']!r} is not a code " + f"proxy-codes.json lists with status {response['status']}" + ) + ] return [] for entry in registry["entries"]: if entry["code"] != body["code"]: @@ -623,13 +720,26 @@ def may_retry( within MAX_RETRIES, or within MAX_BUILD_TIMEOUT_RETRIES for a build cut off by a 504.""" status = response["status"] - if status < 400 or not retryable(status, response.get("json")): + if status < 400 or not retryable(status, problem_body(response)): return False build = request["method"] == "POST" and request.get("path") == "/datasets" limit = MAX_BUILD_TIMEOUT_RETRIES if build and status == 504 else MAX_RETRIES return used < limit +# The content types a client reads a refusal's body as a problem document, or +# the website proxy's own body, in. +PROBLEM_MEDIA = ("application/problem+json", "application/json") + + +def problem_body(response: Mapping[str, Any]) -> Any: + """A refusal's JSON body when its content type is one of PROBLEM_MEDIA, + else None: a body in any other type reads as no body.""" + content_type = response.get("headers", {}).get("content-type", "") + media = content_type.split(";", maxsplit=1)[0].strip().lower() + return response.get("json") if media in PROBLEM_MEDIA else None + + def gap_kinds(actions: Mapping[str, Mapping[str, Any]]) -> dict[str, str]: """The gap kind of each no_data reason in actions.json, keyed by code.""" return {code: row["gap_kind"] for code, row in actions.items() if "gap_kind" in row} @@ -676,6 +786,46 @@ def retry_after(headers: Mapping[str, str]) -> float | None: return wait if wait >= 0 else None +RETRY_BACKOFF_FIRST = 0.5 +RETRY_BACKOFF_CAP = 8.0 + + +def retry_wait(headers: Mapping[str, str], attempt: int) -> float: + """The wait before retry `attempt` (from 0) of a refused request: the + refusal's `Retry-After`, else a backoff that doubles from 0.5 to 8 + seconds.""" + wait = retry_after(headers) + if wait is not None: + return wait + return min(RETRY_BACKOFF_FIRST * 2**attempt, RETRY_BACKOFF_CAP) + + +# The headers a client warns on, and the warning-codes.json code of each. +DEPRECATION_HEADERS = ("deprecation", "sunset") +ROUTE_DEPRECATED = "route_deprecated" +SERVER_WARNING_HEADER = "x-dfo-warning" +SERVER_WARNING = "server_warning" + + +def header_warnings( + headers: Mapping[str, str], seen: set[tuple[str, ...]] +) -> list[str]: + """The warnings an API response's headers issue, as warning-codes.json + codes, each once per process: a `Deprecation` or `Sunset` header once per + distinct pair of their values, either alone included, and `x-dfo-warning` + once per message. `seen` holds the warnings the process has issued.""" + issued = [] + marks = tuple(headers.get(name, "") for name in DEPRECATION_HEADERS) + if any(marks) and (key := (ROUTE_DEPRECATED, *marks)) not in seen: + seen.add(key) + issued.append(ROUTE_DEPRECATED) + message = headers.get(SERVER_WARNING_HEADER) + if message and (key := (SERVER_WARNING, message)) not in seen: + seen.add(key) + issued.append(SERVER_WARNING) + return issued + + POLL_BACKOFF_FIRST = 1.0 POLL_BACKOFF_CAP = 8.0 @@ -811,13 +961,32 @@ class Answer: status: str | None -def answer_from_body(body: dict[str, Any]) -> Answer: - """The answer a search response holds; a kind no client knows raises +def answer_from_body(body: Any) -> Answer: + """The answer a search response holds. A body that is not an object, a + kind no client knows, a part whose `status` is not a string, and a spec + whose `definition.spec_id` differs from its `spec_id` raise ContractError.""" - if body.get("kind") not in ANSWER_KINDS: + if not isinstance(body, dict) or body.get("kind") not in ANSWER_KINDS: + raise ClientError("contract_violation") + parts = body.get("parts", []) + if not isinstance(parts, list) or not all(_readable(part) for part in parts): raise ClientError("contract_violation") - return Answer( - body, body.get("parts", []), body.get("rendered_sentence"), body.get("status") + return Answer(body, parts, body.get("rendered_sentence"), body.get("status")) + + +def _readable(part: Any) -> bool: + """Whether a part has a string `status`, and each spec it holds names + its own spec_id in its definition.""" + if not isinstance(part, dict) or not isinstance(part.get("status"), str): + return False + specs = [part.get("spec")] if part["status"] == "definite" else [] + if part["status"] == "candidates": + specs = (part.get("candidates") or {}).get("specs") or [] + return all( + not isinstance(spec, dict) + or not isinstance(spec.get("definition"), dict) + or spec["definition"].get("spec_id") == spec.get("spec_id") + for spec in specs ) @@ -909,7 +1078,7 @@ def choice_input(answer: Answer, choice: Choice) -> dict[str, Any]: per part, in part order, so a picked candidate in a one-part answer posts its identity as the one entry, and Search answers the picked reading.""" if len(answer.parts) == 1 and choice.option is not None: - return choice.option["data_query"] + return _data_query(choice.option) entries = [ resubmit_entry(part, choice if index == choice.part else None) for index, part in enumerate(answer.parts) @@ -934,7 +1103,7 @@ def resubmit_entry(part: dict[str, Any], choice: Choice | None) -> dict[str, Any **_identity(candidate, reading_echo(part, candidate)), ) if choice is not None and choice.option is not None: - parts = choice.option["data_query"].get("parts") + parts = _data_query(choice.option).get("parts") if not isinstance(parts, list) or len(parts) != 1: raise ClientError("contract_violation") return {"entry_kind": "parsed", "part": parts[0]} @@ -959,6 +1128,15 @@ def resubmit_entry(part: dict[str, Any], choice: Choice | None) -> dict[str, Any return _restated_entry(part) +def _data_query(option: Mapping[str, Any]) -> dict[str, Any]: + """A no_data option's `data_query`; an option without one raises + ContractError, in a one-part answer as in a several-part one.""" + query = option.get("data_query") + if not isinstance(query, dict): + raise ClientError("contract_violation") + return query + + def reading_echo(part: Mapping[str, Any], spec: Mapping[str, Any]) -> Any: """The assumptions a resubmitted reading of `part` echoes: a definite part's `assumptions`, or a candidates part's `reading_assumptions` under @@ -1263,7 +1441,8 @@ def posted_scope(step: Mapping[str, Any]) -> dict[str, Any] | None: `scope.entities` replaces the spec's whole entity binding, so the client posts the spec's bound roles with each role the step names replaced, and a role named with null dropped. A step that names no - role posts no `entities`.""" + role, or no facet, posts no `entities` or `facets`, so `{}` narrows + nothing.""" scope: dict[str, Any] = {} window = step.get("window") if isinstance(window, list): @@ -1279,7 +1458,7 @@ def posted_scope(step: Mapping[str, Any]) -> dict[str, Any] | None: else: bound[role] = list(refs) scope["entities"] = bound - if (facets := step.get("facets")) is not None: + if facets := step.get("facets"): scope["facets"] = {name: {"ref": ref} for name, ref in facets.items()} return scope or None @@ -1290,6 +1469,24 @@ def versions_path(spec_id: str) -> str: return f"/datasets/{spec_id}/versions?limit=1" +def search_body(input_: Mapping[str, Any]) -> dict[str, Any]: + """The whole body a client posts to Search for `input_`.""" + return {"schema_version": 1, "input": input_} + + +def newest_listed(body: Any) -> str | None: + """The newest version a versions page lists, its first, or None when it + lists none. A body whose `versions` is not a list of versions, each with + a `content_version`, raises ContractError.""" + versions = body.get("versions") if isinstance(body, dict) else None + if not isinstance(versions, list) or not all( + isinstance(v, dict) and isinstance(v.get("content_version"), str) + for v in versions + ): + raise ClientError("contract_violation") + return versions[0]["content_version"] if versions else None + + def build_body( spec: Mapping[str, Any], scope: Mapping[str, Any] | None, @@ -1343,6 +1540,28 @@ def selector_path( return f"/datasets/{spec_id}/{content_version}/file?{query}" +# The storage host a signed download names, the only host outside the API a +# client fetches from, and the query every signed URL in a record carries. +STORAGE_ORIGIN = "https://storage.googleapis.com" +REDACTED_QUERY = "X-Goog-Signature=redacted" + + +def download_target(base_url: str, route_url: str, location: str) -> tuple[str, str]: + """Where a client fetches the file a files route's `location` names, + as `(kind, target)`: a URL on the storage host as `url`, fetched bare; + or a URL on the API's origin, a relative one resolved against + `route_url`, as the `origin_path` it reaches. A URL on any other origin + raises ContractError.""" + resolved = urlsplit(urljoin(route_url, location)) + origin = f"{resolved.scheme}://{resolved.netloc}" + if origin == STORAGE_ORIGIN: + return "url", location + base = urlsplit(base_url) + if origin != f"{base.scheme}://{base.netloc}": + raise ClientError("contract_violation") + return "origin_path", urlunsplit(("", "", resolved.path, resolved.query, "")) + + def data_warning(manifest: Mapping[str, Any]) -> ClientError | None: """The DataWarning a strict fetch raises for a manifest: its first warning above `info` severity, with that warning's code; None when it has none.""" @@ -1407,9 +1626,15 @@ def failed_operation( resource: Mapping[str, Any], actions: Mapping[str, Mapping[str, Any]] ) -> tuple[ClientError, bool]: """A failed operation's error, the refusal its problem document states at - that document's status or else 500, and whether it is retryable.""" + that document's status or else 500, and whether it is retryable. A + failed operation with no document raises `operation_failed`.""" problem = resource.get("error") - status = problem.get("status") if isinstance(problem, dict) else None + if not isinstance(problem, dict): + error = ClientError( + OPERATION_FAILED, error=error_class(500, OPERATION_FAILED, actions) + ) + return error, retryable(500, None) + status = problem.get("status") status = status if isinstance(status, int) else 500 return refusal_error(status, problem, actions), retryable(status, problem) @@ -1521,7 +1746,7 @@ class _Replay: exchanges: list[dict[str, Any]] routes: _Routes - base_path: str + base_url: str members: Mapping[str, Sequence[str]] actions: Mapping[str, Mapping[str, Any]] client_codes: Mapping[str, Mapping[str, Any]] @@ -1530,11 +1755,18 @@ class _Replay: answer: Answer | None = None minted: _Minted | None = None long_builds: list[dict[str, Any]] = field(default_factory=list) + retry_waits: list[float] = field(default_factory=list) + warnings: list[str] = field(default_factory=list) + warned: set[tuple[str, ...]] = field(default_factory=set) @property def kinds(self) -> dict[str, str]: return gap_kinds(self.actions) + @property + def base_path(self) -> str: + return urlsplit(self.base_url).path.rstrip("/") + # -- exchanges -- def call( @@ -1543,7 +1775,10 @@ def call( """The exchange a client acts on for its next request, whose `kind`, `path`, `origin_path` or `url`, is exactly `target`. With `retries`, a refusal followed by the same request is retried as `may_retry` - allows, and the last exchange of the run is the one acted on.""" + allows, each retry after the wait `retry_wait` gives, and the last + exchange of the run is the one acted on; a run that ends while + `may_retry` still holds lacks a retry the client makes. Each API + response issues the warnings its headers carry.""" if self.cursor >= len(self.exchanges): raise _UnfitError(f"the steps make a {method} {target} the record lacks") exchange = self.exchanges[self.cursor] @@ -1555,6 +1790,7 @@ def call( f"steps make a {method} {target}" ) self.cursor += 1 + self.took(exchange) used = 0 while ( retries @@ -1562,26 +1798,58 @@ def call( and self.exchanges[self.cursor]["request"] == request and may_retry(request, exchange["response"], used) ): + headers = exchange["response"].get("headers", {}) + self.retry_waits.append(retry_wait(headers, used)) exchange = self.exchanges[self.cursor] self.cursor += 1 + self.took(exchange) used += 1 + if retries and may_retry(request, exchange["response"], used): + raise _UnfitError( + f"exchange {self.cursor - 1} is a retryable refusal with retries " + f"left, and the record holds no retry of {method} {target}" + ) return exchange + def took(self, exchange: dict[str, Any]) -> None: + """Notes the warnings an API response's headers issue.""" + if "url" not in exchange["request"]: + headers = exchange["response"].get("headers", {}) + self.warnings.extend(header_warnings(headers, self.warned)) + def acted_on(self, exchange: dict[str, Any], schema: Any = None) -> Any: """The JSON body a client acts on, read through `schema` or else its - route's schema for its status. A refusal raises its error, and a body - without a strict member raises ContractError.""" + route's schema for its status. A refusal raises its error, a success + of a JSON route without a JSON body raises ContractError + `unexpected_response`, and a body without a strict member raises + ContractError.""" response = exchange["response"] body = response.get("json") if response["status"] >= 400: - raise refusal_error(response["status"], body, self.actions) + raise refusal_error( + response["status"], problem_body(response), self.actions + ) if schema is None: schema = self.routes.response_schema( self.base_path, exchange["request"], response["status"] ) + if schema is not None and "json" not in response: + raise ClientError("unexpected_response") self.strict(schema, body) return body + def answered(self, response: Mapping[str, Any], schema: Any) -> Any: + """The body of a response the long-build rules read: a refusal's + problem body, or a success's JSON body read through `schema`, which a + success without one lacks, raising ContractError + `unexpected_response`.""" + if response["status"] >= 400: + return problem_body(response) + if "json" not in response: + raise ClientError("unexpected_response") + self.strict(schema, response["json"]) + return response["json"] + def strict(self, schema: Any, body: Any) -> None: if strict_gaps(self.routes.openapi, self.members, schema, body): raise ClientError("contract_violation") @@ -1599,10 +1867,17 @@ def body(self, response: dict[str, Any]) -> bytes: def download(self, target: str, digest: str, *, origin: bool) -> None: """A file through the route that redirects to its signed URL: an artifact's root-relative `url` when `origin`, else a path under the - base URL. The client fetches the URL the route's `location` names. A - refused signed URL, or bytes that do not hash to `digest`, ask the - route once more, and a second failure raises.""" + base URL. The client fetches once the URL the route's `location` + names, as `download_target` places it. A refused fetch, or bytes that + do not hash to `digest`, ask the route once more, and a second + failure raises.""" failure = ClientError("download_failed") + base = urlsplit(self.base_url) + route_url = ( + f"{base.scheme}://{base.netloc}{target}" + if origin + else f"{self.base_url.rstrip('/')}{target}" + ) for _ in range(2): kind = "origin_path" if origin else "path" exchange = self.call("GET", target, kind=kind) @@ -1610,7 +1885,8 @@ def download(self, target: str, digest: str, *, origin: bool) -> None: location = exchange["response"].get("headers", {}).get("location") if not isinstance(location, str): raise _UnfitError(f"the redirect from {target} names no location") - signed = self.call("GET", location, kind="url", retries=False)["response"] + fetched, at = download_target(self.base_url, route_url, location) + signed = self.call("GET", at, kind=fetched, retries=False)["response"] if signed["status"] >= 400: failure = ClientError("download_failed") continue @@ -1620,15 +1896,21 @@ def download(self, target: str, digest: str, *, origin: bool) -> None: raise failure def resolve(self, posts: dict[str, Any]) -> Answer: - """A Search request whose recorded body posts the input `posts`.""" - exchange = self.call(*_SEARCH) + """A Search request whose recorded body is the one `search_body` gives + for the input `posts`.""" + exchange = self.posted(_SEARCH, search_body(posts)) + return answer_from_body(self.acted_on(exchange)) + + def posted(self, route: tuple[str, str], posts: dict[str, Any]) -> dict[str, Any]: + """A request to `route` whose recorded body is `posts`, whole.""" + exchange = self.call(*route) sent = exchange["request"].get("json") - if not isinstance(sent, dict) or sent.get("input") != posts: + if sent != posts: raise _UnfitError( - f"exchange {self.cursor - 1} posts {json.dumps(sent.get('input'))[:300]}" - f", where the rules post {json.dumps(posts)[:300]}" + f"exchange {self.cursor - 1} posts {json.dumps(sent)[:300]}, " + f"where the rules post {json.dumps(posts)[:300]}" ) - return answer_from_body(self.acted_on(exchange)) + return exchange # -- builds -- @@ -1640,15 +1922,7 @@ def posted_build( ) -> dict[str, Any]: """A build request whose recorded body is the one `build_body` gives for `spec`, `scope` and `rendering`.""" - exchange = self.call(*_BUILD) - sent = exchange["request"].get("json") - posts = build_body(spec, scope, rendering) - if sent != posts: - raise _UnfitError( - f"exchange {self.cursor - 1} posts {json.dumps(sent)[:300]}, " - f"where the rules post {json.dumps(posts)[:300]}" - ) - return exchange + return self.posted(_BUILD, build_body(spec, scope, rendering)) def build( self, @@ -1680,21 +1954,16 @@ def long_build( build.next_wait() path = POLL_PATH.format(operation_id=build.entry["operation_id"]) response = self.call("GET", path, retries=False)["response"] - body = response.get("json") - if response["status"] < 400: - self.strict(_OPERATION, body) + body = self.answered(response, _OPERATION) if not build.polled(response["status"], response.get("headers", {}), body): continue again = self.call(*_BUILD) if again["request"] != request: raise _UnfitError("the build posted again posts another request") reply = again["response"] - if reply["status"] < 400: - self.strict( - _OPERATION if reply["status"] == 202 else _MANIFEST, - reply.get("json"), - ) - build.reposted(reply["status"], reply.get("headers", {}), reply.get("json")) + schema = _OPERATION if reply["status"] == 202 else _MANIFEST + body = self.answered(reply, schema) + build.reposted(reply["status"], reply.get("headers", {}), body) self.strict(_MANIFEST, build.result) return build.result @@ -1843,24 +2112,25 @@ def stored_file( def newest(self, spec_id: str) -> str | None: """The newest stored version, the one the versions route lists first, - or None when it lists none or refuses the spec as unknown.""" + or None when it lists none or refuses the spec as unknown; a page + that lists no versions in the form `newest_listed` reads raises.""" try: body = self.acted_on(self.call("GET", versions_path(spec_id))) except ClientError as error: if error.error_class(self.client_codes) in NO_VERSIONS: return None raise - versions = body.get("versions") if isinstance(body, dict) else None - first = versions[0] if isinstance(versions, list) and versions else None - newest = first.get("content_version") if isinstance(first, dict) else None - return newest if isinstance(newest, str) else None + return newest_listed(body) # -- steps -- def step(self, step: dict[str, Any]) -> dict[str, Any]: - """The outcome `step` reaches. A step that made a long build names - each in `long_builds`, whatever its outcome.""" - self.long_builds = [] + """The outcome `step` reaches. Whatever the outcome, a step that made + a long build names each in `long_builds`, a step that retried a + refused request gives the waits before its retries in + `retry_waits`, and a step whose responses issued warnings gives their + codes in `warnings`.""" + self.long_builds, self.retry_waits, self.warnings = [], [], [] op = step["op"] if op == "fetch": op = ( @@ -1872,10 +2142,12 @@ def step(self, step: dict[str, Any]) -> dict[str, Any]: if op in {"search", "choose"}: self.answer = None outcome = ended.outcome(self.client_codes) - if self.long_builds: - (value,) = outcome.values() - value["long_builds"] = self.long_builds - return outcome + return with_step_notes( + outcome, + long_builds=self.long_builds, + retry_waits=self.retry_waits, + warnings=self.warnings, + ) def _answered(self) -> Answer: if self.answer is None: @@ -1976,11 +2248,31 @@ def _operation_outcome(resource: dict[str, Any]) -> dict[str, Any]: return {"operation": {k: operation[k] for k in ("operation_id", "status")}} +def with_step_notes( + outcome: dict[str, Any], + *, + long_builds: Sequence[dict[str, Any]], + retry_waits: Sequence[float], + warnings: Sequence[str], +) -> dict[str, Any]: + """`outcome` with the step's `long_builds`, `retry_waits` and `warnings`, + each given only when it holds any.""" + (value,) = outcome.values() + for name, notes in ( + ("long_builds", long_builds), + ("retry_waits", retry_waits), + ("warnings", warnings), + ): + if notes: + value[name] = list(notes) + return outcome + + def expected_outcomes( record: dict[str, Any], *, routes: _Routes, - base_path: str, + base_url: str, strict: dict[str, Any], actions: Mapping[str, Mapping[str, Any]], client_codes: Mapping[str, Mapping[str, Any]], @@ -1999,7 +2291,7 @@ def expected_outcomes( replay = _Replay( record["exchanges"], routes, - base_path, + base_url, _strict_members(strict), actions, client_codes, @@ -2025,23 +2317,45 @@ def owns_body_file(name: str, body_file: str) -> bool: ) -_REDACTED_QUERY = "X-Goog-Signature=redacted" - - -def _check_redaction(label: str, exchange: dict[str, Any]) -> list[str]: - """An absolute URL a record holds, a `url` request or a `location` - header, keeps no query but the redacted signature.""" - urls = [ - exchange["request"].get("url"), - exchange["response"].get("headers", {}).get("location"), - ] - return [ - f"{label}: {url.split('?', 1)[0]} keeps a query other than {_REDACTED_QUERY}" - for url in urls - if isinstance(url, str) - and urlsplit(url).netloc - and urlsplit(url).query != _REDACTED_QUERY - ] +def _under(url: str, base_url: str) -> bool: + """Whether `url` names a route under `base_url`: the same scheme, host + and port, and a path under the base URL's path.""" + parts, base = urlsplit(url), urlsplit(base_url) + root = base.path.rstrip("/") + return (parts.scheme, parts.hostname, parts.port) == ( + base.scheme, + base.hostname, + base.port, + ) and (parts.path == root or parts.path.startswith(root + "/")) + + +def absolute_url_problems(record: Mapping[str, Any], base_url: str) -> list[str]: + """Each absolute URL a record holds, a `url` request or a `location` + header, that is not a signed URL on the storage host, over https and + with the redacted query; a `location` may also name a route under + `base_url`. A local app's host, or any other, is refused by name.""" + storage = urlsplit(STORAGE_ORIGIN) + problems = [] + for index, exchange in enumerate(record["exchanges"]): + label = f"scenarios/{record['name']}.json: exchange {index}" + location = exchange["response"].get("headers", {}).get("location") + for url, api in ((exchange["request"].get("url"), False), (location, True)): + if not isinstance(url, str) or not urlsplit(url).netloc: + continue + parts = urlsplit(url) + if api and _under(url, base_url): + continue + if (parts.scheme, parts.netloc) != (storage.scheme, storage.netloc): + problems.append( + f"{label}: {url.split('?', 1)[0]} names {parts.netloc}, where " + f"a record's absolute URL names {STORAGE_ORIGIN}" + ) + elif parts.query != REDACTED_QUERY: + problems.append( + f"{label}: {url.split('?', 1)[0]} keeps a query other than " + f"{REDACTED_QUERY}" + ) + return problems def _check_body_files( @@ -2151,6 +2465,8 @@ def _check_scenarios( strict: dict[str, Any], actions: Mapping[str, Mapping[str, Any]], client_codes: Mapping[str, Mapping[str, Any]], + proxy_codes: Mapping[str, Mapping[str, Any]], + served_commit: str | None, ) -> list[str]: directory = PACKAGE_DIR / "scenarios" paths = sorted(directory.glob("*.json")) @@ -2176,10 +2492,6 @@ def _check_scenarios( records[name] = record problems.extend(_check_steps(path.name, record)) problems.extend(_check_client_errors(path.name, record, client_codes)) - for index, exchange in enumerate(record["exchanges"]): - problems.extend( - _check_redaction(f"scenarios/{path.name}: exchange {index}", exchange) - ) named_files: set[str] = set() for name, record in records.items(): @@ -2201,16 +2513,27 @@ def _check_scenarios( ) problems.extend(_check_body_files(file_name, record, parent, directory)) recorded = parent or record - base_path = urlsplit(recorded["origin"]["base_url"]).path.rstrip("/") + base_url = recorded["origin"]["base_url"] + base_path = urlsplit(base_url).path.rstrip("/") + if origin["kind"] == "recorded" and origin["dfo_commit"] != served_commit: + problems.append( + f"scenarios/{file_name}: dfo_commit {origin['dfo_commit']} is not " + f"served/SOURCE.json's commit {served_commit}" + ) + problems.extend(absolute_url_problems(record, base_url)) for index, exchange in enumerate(record["exchanges"]): label = f"scenarios/{file_name}: exchange {index}" if origin["kind"] == "recorded": problems.extend( - _check_exchange(label, exchange, base_path, routes, registry) + _check_exchange( + label, exchange, base_path, routes, registry, proxy_codes + ) ) - elif "json" in exchange["response"]: + else: problems.extend( - _check_problem_code(label, exchange["response"], registry) + _check_problem_code( + label, exchange["response"], registry, proxy_codes + ) ) for resource in _failed_operations(record): error = resource.get("error") @@ -2223,13 +2546,14 @@ def _check_scenarios( "json": error, }, registry, + proxy_codes, ) ) try: derived = expected_outcomes( record, routes=routes, - base_path=base_path, + base_url=base_url, strict=strict, actions=actions, client_codes=client_codes, @@ -2265,7 +2589,13 @@ def _check_client_errors( refusal_code(e["response"].get("json")) for e in record["exchanges"] if e["response"]["status"] >= 400 - } | {refusal_code(body.get("error")) for body in _failed_operations(record)} + } | { + refusal_code(body["error"]) + if isinstance(body.get("error"), dict) + # A failed operation with no document raises operation_failed. + else OPERATION_FAILED + for body in _failed_operations(record) + } problems = [] for index, outcome in enumerate(record["expect"]): error = outcome.get("error") @@ -2411,7 +2741,8 @@ def validate() -> list[str]: validators = _contract_validators() openapi = _load(PACKAGE_DIR / "served" / "openapi.json") registry = _load(REGISTRY_PATH) - problems = _check_source(_load(PACKAGE_DIR / "served" / "SOURCE.json")) + source = _load(PACKAGE_DIR / "served" / "SOURCE.json") + problems = _check_source(source) problems.extend(surface_problems(openapi)) strict = _load(PACKAGE_DIR / "strict-fields.json") @@ -2439,6 +2770,30 @@ def validate() -> list[str]: ) client_rows = [] if errors else client_codes["codes"] + taken = { + "registries/codes.json": {entry["code"] for entry in registry["entries"]}, + "actions.json": {row["code"] for row in actions["codes"]}, + "client-codes.json": {row["code"] for row in client_rows}, + } + proxy_codes = _load(PACKAGE_DIR / "proxy-codes.json") + errors = _schema_problems( + "proxy-codes.json", validators["proxy-codes.schema.json"], proxy_codes + ) + problems.extend(errors or _check_proxy_codes(proxy_codes, taken)) + proxy_rows = [] if errors else proxy_codes["codes"] + warning_codes = _load(PACKAGE_DIR / "warning-codes.json") + errors = _schema_problems( + "warning-codes.json", validators["warning-codes.schema.json"], warning_codes + ) + problems.extend( + errors + or _check_warning_codes( + warning_codes, + {**taken, "proxy-codes.json": {row["code"] for row in proxy_rows}}, + key_format_reasons(validators["rules/rules.schema.json"].schema), + ) + ) + problems.extend( _check_scenarios( validators["scenario.schema.json"], @@ -2447,6 +2802,8 @@ def validate() -> list[str]: strict=strict, actions={row["code"]: row for row in actions["codes"]}, client_codes={row["code"]: row for row in client_rows}, + proxy_codes={row["code"]: row for row in proxy_rows}, + served_commit=source.get("commit") if isinstance(source, dict) else None, ) ) problems.extend(_check_refs(validators["dataset-ref.schema.json"])) From d2ca886cf4f85ea32d59cd053a0862917aac34d2 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Wed, 21 Oct 2026 14:02:08 +0200 Subject: [PATCH 20/39] fix(client-contract): check only what a client reads, and pin the refusal and choice rules A manifest artifact's url must sit on the API's origin, relative or absolute; any other origin, the storage host's included, raises contract_violation before any request. Only a files route's Location may sit on the storage host. The strict check walks down from the body's root through strict members alone, so a spec nested where no rule reads it raises nothing. Spec.resolved, SpecDefinition.identity and DefinitionModel.identity join strict-fields.json, which now holds 28 required pointers. A resolution with empty parts raises contract_violation at /parts. A build's POST shares the two retries, and after a 504 cut-off it is posted once more only: 504 then 503 raises the 503. A refused poll changes no pacing, and a non-retryable one raises at once. A problem document without a code keeps its retryable and trace_id. A 401 resolves the key again. request() refuses a path that is not a path on the base URL. A one-part option whose data_query holds other than one part raises ContractError in a one-part answer too, and the validator derives it. 22 new synthetic scenarios pin these rules, the header warnings, the separate and operations echo, the unsupported placeholder and three choice_invalid cases. 101 scenarios, 31 recorded and 70 synthetic. --- python/client-contract/CHANGELOG.md | 6 +- python/client-contract/README.md | 27 +- .../scenarios/answer-empty-parts.json | 104 + .../answer-nested-specs-unchecked.json | 4418 +++++++ .../answer-spec-without-identity.json | 3622 ++++++ .../answer-spec-without-resolved.json | 402 + ...choose-echoes-separate-and-operations.json | 10817 ++++++++++++++++ .../choose-option-two-part-query.json | 283 + .../choose-posts-unsupported-placeholder.json | 6615 ++++++++++ ...se-refused-part-without-variable-text.json | 4529 +++++++ .../choose-refused-shared-label.json | 266 + .../choose-refused-unknown-status.json | 4520 +++++++ .../scenarios/fetch-spec-503-then-504.json | 1135 ++ .../scenarios/fetch-spec-504-then-503.json | 305 + .../fetch-spec-foreign-artifact-url.json | 865 ++ .../fetch-spec-manifest-without-identity.json | 800 ++ .../scenarios/fetch-spec-poll-not-found.json | 203 + .../scenarios/fetch-spec-poll-refused.json | 1277 ++ .../fetch-spec-same-origin-artifact-url.json | 927 ++ .../fetch-spec-storage-artifact-url.json | 865 ++ .../scenarios/search-body-not-an-object.json | 248 + .../search-refused-without-code.json | 53 + .../scenarios/search-server-warning.json | 752 ++ .../scenarios/search-unauthorized.json | 45 + .../dfo_client_contract/strict-fields.json | 9 + tools/capture_client_contract.py | 545 +- tools/tests/test_validate_client_contract.py | 272 + tools/validate_client_contract.py | 175 +- 28 files changed, 44002 insertions(+), 83 deletions(-) create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-nested-specs-unchecked.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-echoes-separate-and-operations.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-option-two-part-query.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-posts-unsupported-placeholder.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-refused-part-without-variable-text.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-label.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-status.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-503-then-504.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-then-503.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-foreign-artifact-url.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-same-origin-artifact-url.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/search-refused-without-code.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/search-server-warning.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/search-unauthorized.json diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index 2fad949..a2a9b4f 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -8,16 +8,16 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be - Package scaffolding (uv, ruff, ty, pytest). - `served/openapi.json`, the composed dfo-apis app's OpenAPI document, and `served/SOURCE.json`, naming dfo-apis commit `635943e03a297f686ca5af32f6d027181d1971d4`. -- `strict-fields.json` and its schema: 25 members that stay required and non-nullable, and the answer kinds, part statuses and operation statuses the clients branch on. +- `strict-fields.json` and its schema: 28 members that stay required and non-nullable, each one a client reads, and the answer kinds, part statuses and operation statuses the clients branch on. - `actions.json` and its schema: the caller's next step for each of the 101 active refusal codes on `problem_details` or `no_data_reason`, with the gap kind of each no_data reason. - The status fallback for a refusal whose code has no row: 400 and 422 to `InvalidRequestError`, 401 to `AuthenticationError`, 403 to `PermissionDeniedError`, 404 and 410 to `NotFoundError`, 408 to `DfoTimeoutError`, 429 to `RateLimitError`, and any other 4xx or 5xx to `InvalidRequestError` or `ServerError`. -- `scenario.schema.json`, the scenario record, and 79 scenarios: 31 recorded against the composed dfo-apis app at `635943e03`, and 48 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 2,105,201 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a cut-off build retried after its Retry-After, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, a signed URL refused on both rounds, a relative files-route Location, an identity resubmit answering another spec, a part whose status is not a string, a Search spec whose definition names another spec_id, a Search response with no JSON body, an option with no data_query, empty entities and facets, a Sunset header issued once, an unreadable versions page, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, a failed operation posted again, a failed operation with no error, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route. +- `scenario.schema.json`, the scenario record, and 101 scenarios: 31 recorded against the composed dfo-apis app at `635943e03`, and 70 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 2,105,201 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, a part without variable_text, an unknown status without a restatement, a shared label, a one-part option whose data_query holds two parts, the separate and operations echo, an unsupported part's placeholder, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a cut-off build retried after its Retry-After, a build refused 504 then 503 and one refused 503 then 504, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, a signed URL refused on both rounds, a relative files-route Location, an artifact url on a foreign origin, on the storage host and absolute on the API's origin, a manifest definition without identity, a Search spec without identity or resolved, nested specs no rule reads, an empty parts list, a Search body that is not an object, a codeless 503 problem document that is not retryable, a 401, an identity resubmit answering another spec, a part whose status is not a string, a Search spec whose definition names another spec_id, a Search response with no JSON body, an option with no data_query, empty entities and facets, a Sunset header issued once, `x-dfo-warning` messages and a Deprecation and Sunset pair, an unreadable versions page, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, 503 polls retried within the budget an answered poll restores, a 404 poll that raises, a failed operation posted again, a failed operation with no error, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route. - `client-codes.json` and its schema: the 17 codes a client sets on the errors it raises itself, each with its error class, retryable flag and condition, disjoint from `actions.json` and `registries/codes.json`, and the `client_codes()` and `client_codes_schema()` accessors. Every scenario error the client raises itself carries its code, and `refusal_without_code` names a refusal whose body carries no code. - `proxy-codes.json` and its schema, the website proxy's `rate_limited` and `transient_unavailable` codes with their statuses, and `warning-codes.json` and its schema, the 5 codes a client sets on the warnings it issues itself, with the `proxy_codes()` and `warning_codes()` accessors. - Scenario outcomes give `retry_waits`, the waits before each retry, and `warnings`, the warning codes a step's responses issued. Scenario steps take no `timeout`. - `dataset-ref.schema.json`, the frozen `DatasetRef` format, with accepted and rejected examples. - `tools/capture_client_contract.py`, which captures `served/openapi.json` from a dfo-apis checkout in process and records the scenarios against a base URL, dev by default, or with `record --offline` derives their outcomes again from the records with no request. A local app's signed URLs are written as the storage URLs a deployment signs. -- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, checks `client-codes.json` against them, and checks each scenario's `expect` against the outcomes its exchanges, `actions.json` and `client-codes.json` give, each Search request against the input its steps derive, a sentence lookup's `entity_groups` included, each build's `input.scope` against the narrowing its step names over the spec's bound roles, each build's options against its layout, each Search request's whole body, each download against its artifact's digest, each recorded scenario's commit against `served/SOURCE.json`, each proxy refusal's code against `proxy-codes.json`, and each absolute URL against the storage host. A record that ends a run of retries while a retry remains does not fit. The outcomes include each long build's operation id, poll waits and resubmissions, and a `VersionUnavailableError`'s newest version. +- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, checks `client-codes.json` against them and against the reasons the key-lookup rule raises, and checks each scenario's `expect` against the outcomes its exchanges, `actions.json` and `client-codes.json` give, each Search request against the input its steps derive, a sentence lookup's `entity_groups` included, each build's `input.scope` against the narrowing its step names over the spec's bound roles, each build's options against its layout, each Search request's whole body, each download against its artifact's digest, each recorded scenario's commit against `served/SOURCE.json`, each proxy refusal's code against `proxy-codes.json`, and each absolute URL against the storage host. A record that ends a run of retries while a retry remains does not fit. The outcomes include each long build's operation id, poll waits and resubmissions, and a `VersionUnavailableError`'s newest version. - The client rules and their vectors: the credentials path and file format, the key lookup order, with an empty `api_key` refused as `key_empty` and an empty profile key as `profile_without_key`, the key format check, and the cache directory and layout. [unreleased]: https://github.com/DevelopmentFinanceObservatory/spec-kit/commits/main/python diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 5421fca..2c720fe 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -73,11 +73,11 @@ uv run ty check src/dfo_client_contract ## Strict fields -`strict-fields.json` lists the members a client cannot act without. Each pointer names one property of one component schema, `/components/schemas//properties/`. A `required` entry stays in its schema's `required` list and admits no null, so a client raises `ContractError` when one is missing or null. An `enums` entry keeps every listed value, the values a client branches on: the answer kinds, the part statuses and the operation statuses. A client still accepts a value no entry lists. +`strict-fields.json` lists the members a client cannot act without. Each pointer names one property of one component schema, `/components/schemas//properties/`. A `required` entry stays in its schema's `required` list and admits no null, so a client raises `ContractError` when one is missing or null. Every entry is a member some client rule acts on, and a client checks a body only along them: from the body's root it goes down through strict members alone, so a member no client reads goes unchecked, however deep. A spec nested where no rule reads it, in `resolved.alternative_measures`, `resolved.equivalent_readings` or `resolved.related_measures`, or in `no_data.flagged_match` or `no_data.nearest_real`, may lack `resolved` or `identity` and raises nothing, which `answer-nested-specs-unchecked` pins. An `enums` entry keeps every listed value, the values a client branches on: the answer kinds, the part statuses and the operation statuses. A client still accepts a value no entry lists. -The answer's `kind` and each part's `status` are the discriminators of their unions in the served document. A search response with no `kind` raises `ContractError`, as a part with no `status` does, although the served document gives `kind` a default and leaves it out of `required`. A part `status` a client does not know raises nothing and makes the part an `unknown` gap. An answer `kind` a client does not know raises `ContractError`, because the client cannot read the answer. A Search response body that is not an object, a part whose `status` is not a string, at pointer `/parts//status`, and a definite or candidate spec whose `definition.spec_id` differs from its `spec_id` raise `ContractError` `contract_violation`, in a Search response as in a ref; `answer-part-status-not-a-string` and `answer-definition-spec-id-mismatch` pin the last two. +The answer's `kind` and each part's `status` are the discriminators of their unions in the served document. A search response with no `kind` raises `ContractError`, as a part with no `status` does, although the served document gives `kind` a default and leaves it out of `required`. A part `status` a client does not know raises nothing and makes the part an `unknown` gap. An answer `kind` a client does not know raises `ContractError`, because the client cannot read the answer. A Search response body that is not an object, a `resolution` answer whose `parts` is empty, at pointer `/parts`, since the served schema gives it at least one item, a part whose `status` is not a string, at pointer `/parts//status`, and a definite or candidate spec whose `definition.spec_id` differs from its `spec_id` raise `ContractError` `contract_violation`, in a Search response as in a ref; `search-body-not-an-object`, `answer-empty-parts`, `answer-part-status-not-a-string` and `answer-definition-spec-id-mismatch` pin the four. -The required members are each part's `status` and its payload (`spec`, `candidates`, `no_data`, `unsupported`), `Resolution.parts`, `CandidateSet.specs`, `NoData.reason`, `Unsupported.code`, `Spec.spec_id` and `definition`, `SpecDefinition.spec_id`, the manifest's `definition`, `definition.spec_id`, `content_version` and `artifacts`, each artifact's `artifact_digest`, `rendering` and `url`, and the operation resource's `operation`, `operation_id` and `status`. The operation's `poll` is nullable in the served document, so a client builds the poll path from `operation_id`. +The required members are each part's `status` and its payload (`spec`, `candidates`, `no_data`, `unsupported`), `Resolution.parts`, `CandidateSet.specs`, `NoData.reason`, `Unsupported.code`, `Spec.spec_id`, `definition` and `resolved`, `SpecDefinition.spec_id` and `identity`, the manifest's `definition`, `definition.spec_id` and `definition.identity`, `content_version` and `artifacts`, each artifact's `artifact_digest`, `rendering` and `url`, and the operation resource's `operation`, `operation_id` and `status`. The operation's `poll` is nullable in the served document, so a client builds the poll path from `operation_id`. A client posts a spec's `identity` back to Search and reads its `resolved.entity_groups`, so a Search spec without `resolved`, or a definition, a Search spec's or a manifest's, without `identity` raises `ContractError` `contract_violation`; `answer-spec-without-resolved`, `answer-spec-without-identity` and `fetch-spec-manifest-without-identity` pin them. ## Actions @@ -118,7 +118,7 @@ An answer's gaps follow from its parts. A candidates part is a `choice` gap, its ## Client codes -`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, `retryable`, and a one-line `condition`. `retryable` is the flag both clients generate onto the error: `deadline_exceeded`, `download_failed` and `network_error` are retryable, `digest_mismatch` and the rest are not, and `refusal_without_code` is retryable as its status is, which its row gives as `by_status`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps the server's code: the problem document's `code`, or the website proxy's `error`. A refusal whose body carries neither raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`; no other row does. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. The list holds no warning. `warning-codes.json` lists, sorted by code, each code a client sets on a warning it issues itself, with its class and condition: `route_deprecated`, a `DfoDeprecationWarning`, for a `Deprecation` or `Sunset` header; `server_warning`, a `DfoWarning`, for an `x-dfo-warning` header; and `key_checksum_mismatch`, `key_not_base62` and `key_unknown_prefix`, each a `DfoWarning`, for a key that fails the key-format rule with that reason. Both clients generate their warning codes from it and issue no other. No warning code is a code in another table or in `registries/codes.json`. A `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and a null code when they differ in several ways. A `DataWarning` carries the manifest warning's code. +`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, `retryable`, and a one-line `condition`. `retryable` is the flag both clients generate onto the error: `deadline_exceeded`, `download_failed` and `network_error` are retryable, `digest_mismatch` and the rest are not, and `refusal_without_code` is retryable as its status is, which its row gives as `by_status`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps the server's code: the problem document's `code`, or the website proxy's `error`. A refusal whose body carries neither raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`; no other row does. A problem document without a code still gives the error its `retryable` and `trace_id`, so a 503 whose body says `retryable: false` raises at once, which `search-refused-without-code` pins. Every refusal's trace id is the body's `trace_id`, else the `x-dfo-trace-id` header; no outcome carries it, so no scenario pins it. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. Each reason the key-lookup rule raises, `key_empty`, `profile_not_found`, `profile_without_key` and `credentials_file_invalid`, is a row of class `AuthenticationError`. The list holds no warning. `warning-codes.json` lists, sorted by code, each code a client sets on a warning it issues itself, with its class and condition: `route_deprecated`, a `DfoDeprecationWarning`, for a `Deprecation` or `Sunset` header; `server_warning`, a `DfoWarning`, for an `x-dfo-warning` header; and `key_checksum_mismatch`, `key_not_base62` and `key_unknown_prefix`, each a `DfoWarning`, for a key that fails the key-format rule with that reason. Both clients generate their warning codes from it and issue no other. No warning code is a code in another table or in `registries/codes.json`. A `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and a null code when they differ in several ways. A `DataWarning` carries the manifest warning's code. ## Scenarios @@ -136,11 +136,11 @@ A scenario is one client-level call, the HTTP exchanges it makes, and the outcom A step that acts on an earlier result follows one: `choose` follows `search` or `choose`, a `fetch` with no target follows `search`, `choose` or another `fetch` with no target and acts on the last answer, and `result` follows `mint` or `operation`. A `fetch` of an answer or a spec, `mint` and `operation` take a `layout`, `long` by default or `frame`, and a `fetch` of an answer or a spec takes `strict`. A `spec` in a step holds `spec_id`, the server's unmodified `definition`, the `sentence` when the client knows it, and the server's `resolved.entity_groups` as `entity_groups` when it names any. -An exchange's request names its target in one of three ways. `path` is a path the client composes under the base URL, such as `/search/resolve`. `origin_path` is a root-relative URL the server returned, such as an artifact's `url`, which resolves against the base URL's origin and never against its path. `url` is an absolute URL outside the API, such as the signed storage URL a files route redirects to, which the client fetches with a bare request carrying no client header and no key. `json` holds the request body members that must match; a recorded scenario lists every member the client sent. The response gives `status`, the `headers` a client reads, and a `json` body or a `body_file`, a binary body in `scenarios/`. A scenario's own body files are named `.` and `-.`; a synthetic scenario may instead name a body file its parent names. +An exchange's request names its target in one of three ways. `path` is a path the client composes under the base URL, such as `/search/resolve`. `origin_path` is a root-relative URL the server returned, such as an artifact's `url`, or the path and query of an absolute one on the API's origin, which resolves against the base URL's origin and never against its path. `url` is an absolute URL outside the API, such as the signed storage URL a files route redirects to, which the client fetches with a bare request carrying no client header and no key. `json` holds the request body members that must match; a recorded scenario lists every member the client sent. The response gives `status`, the `headers` a client reads, and a `json` body or a `body_file`, a binary body in `scenarios/`. A scenario's own body files are named `.` and `-.`; a synthetic scenario may instead name a body file its parent names. A `newest_version` outcome gives the `content_version` the step found, or null. An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a warning's code, which for a `SearchWarning` may be null, or for any other error the client raises itself its code in `client-codes.json`. A `VersionUnavailableError` also gives `newest_version`, the version the lookup found, or null. A dataset or error outcome of a step that made a long build gives `long_builds`, one entry per build the server ran on, in order: the `operation_id` the client polled last, the `poll_waits` in seconds before each poll, and the number of `resubmissions`. Any outcome of a step that retried a refused request gives `retry_waits`, the seconds before each retry in order, and any outcome of a step whose API responses issued warnings gives `warnings`, their codes from `warning-codes.json` in order. -Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry where the retry rules allow one, except on a poll, where the long-build rules count retries, and a record that ends a run of retries while the rules allow another does not fit, since the client makes it, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, each POST carries its body, each build posts the body the rules give for the spec it builds, so the builds' order and spec_ids are checked, each Search request posts the whole body `{"schema_version": 1, "input": ...}` with the input the rules give: the question, a choice's input, or a member's identity, each poll names the operation the client holds, each signed download is the URL the files route's `location` names, each retry waits the wait the retry rules give, and each response's warning headers issue the warnings the warning rules give. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. +Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry where the retry rules allow one, except on a poll, where the long-build rules count retries, and a record that ends a run of retries while the rules allow another does not fit, since the client makes it, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, each POST carries its body, each build posts the body the rules give for the spec it builds, so the builds' order and spec_ids are checked, each Search request posts the whole body `{"schema_version": 1, "input": ...}` with the input the rules give: the question, a choice's input, or a member's identity, each poll names the operation the client holds, each files route is the one the artifact's `url` names, each signed download is the URL the files route's `location` names, each retry waits the wait the retry rules give, and each response's warning headers issue the warnings the warning rules give. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. A recorded scenario's request and response bodies validate against their route's schemas in `served/openapi.json`. A required member stays required when its schema admits null: the body carries it, as null or a value. A member the schema leaves optional may be absent or null, and a client reads both as null. @@ -160,25 +160,28 @@ The records also fix these client rules: - A built `spec_id` that differs from the posted one, or a spec with no sentence, takes its sentence from Search: the client posts the built definition's `identity` as one `dataset_resubmit` identity entry, with the member's first part as `variable_text`, or `"dataset"` when no answer part names it, and checks the answer's `spec_id` equals the built one. The entry's `entity_groups` holds the spec's `resolved.entity_groups` for each role the built identity binds to the same entities as the spec's definition, so a window or facets narrowing keeps every group and a role the narrowing rebound or dropped loses its group. The entry leaves `entity_groups` out when it keeps no group, as for a resumed operation, whose spec the client does not hold. The server reads a role posted without its group as its members, so a narrowed spec of flows to the least developed countries would read "44 recipients" in place of "the 44 Least Developed Countries". - A dataset of several members puts the `part` column first, then each member's columns in member order, each column once. The `part` value on a member's rows is the member's `parts` joined by `"; "`, so a member that answers two folded parts reads `"health ODA disbursements; education ODA disbursements"`, or the member's sentence when `parts` is empty. - A choice names its part by index, by variable text, or by a word that one gap's options mention, and its option by index or label; a candidate is named by index. A label is matched among the options that mention the word the part was named by. With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. -- A choice raises `InvalidRequestError` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is out of range or matches no label or several. It raises the same when an entry it would post cannot be built: a part with no `variable_text`, or a part of a status the client does not know that has no `restatement`. A chosen option whose `data_query` holds other than one part raises `ContractError`, and so does a chosen option with no `data_query`, in a one-part answer as in a several-part one, before any request. +- A choice raises `InvalidRequestError` `choice_invalid` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is out of range or matches no label or several. It raises the same when an entry it would post cannot be built: a part with no `variable_text`, or a part of a status the client does not know that has no `restatement`. A chosen option whose `data_query` holds other than one part raises `ContractError`, and so does a chosen option with no `data_query`, in a one-part answer as in a several-part one, before any request. `choose-refused-shared-label`, `choose-refused-part-without-variable-text`, `choose-refused-unknown-status`, `choose-option-two-part-query` and `choose-option-without-data-query` pin these. - Every pick of a candidate asks Search for the picked answer, and no client builds it locally. In a one-part answer the pick posts `dataset_resubmit`, without `raw_query`, with one identity entry: the candidate's identity and `entity_groups`, and the part's `variable_text`, `separate` and `operations` as below. The picked answer, its sentence with any "Assumed: …" clause, and its assumptions are Search's response. A choice of a no_data option in a one-part answer posts the option's `data_query` as the input. -- In a several-part answer a choice posts `dataset_resubmit`, without `raw_query`, with one entry per part in part order. The chosen candidate posts an identity entry with its identity and `entity_groups`, and the chosen option its `data_query`'s one part as a parsed entry. A definite part posts an identity entry with its spec's identity and `entity_groups`. A candidates part left alone posts a `candidates` entry: its candidate set in the server's order, each with its identity and `entity_groups`, and its `ordering` and `truncated` echoed. The server cannot recompute that order, because it rests on the first answer's bind election and availability reads, and a parsed entry would cost an LLM bind. Any other part posts its `restatement` as a parsed entry, or a placeholder entry with its no_data `reason` or unsupported `code` when it has none. Every entry but a parsed one carries the part's `variable_text`, `separate` when true and `operations` when the part has any; `entity_groups` is left out when the spec has none. +- In a several-part answer a choice posts `dataset_resubmit`, without `raw_query`, with one entry per part in part order. The chosen candidate posts an identity entry with its identity and `entity_groups`, and the chosen option its `data_query`'s one part as a parsed entry. A definite part posts an identity entry with its spec's identity and `entity_groups`. A candidates part left alone posts a `candidates` entry: its candidate set in the server's order, each with its identity and `entity_groups`, and its `ordering` and `truncated` echoed. The server cannot recompute that order, because it rests on the first answer's bind election and availability reads, and a parsed entry would cost an LLM bind. Any other part posts its `restatement` as a parsed entry, or a placeholder entry with its no_data `reason` or unsupported `code` when it has none. Every entry but a parsed one carries the part's `variable_text`, `separate` when true and `operations` when the part has any; `entity_groups` is left out when the spec has none. `choose-echoes-separate-and-operations` pins the echo on a definite part's entry, and `choose-posts-unsupported-placeholder` an unsupported part's placeholder. - Each identity a choice posts echoes its reading's assumptions as `assumptions`: the chosen candidate's entry carries its part's `reading_assumptions` under the candidate's `spec_id`, a definite part's entry carries the part's `assumptions`, and each candidate of a `candidates` entry carries its own `reading_assumptions` entry. Search then states the echoed items that still hold, so the picked answer states what that reading assumed. `[]` states none. An identity with no `assumptions` reads as a fresh request, so a client that holds no list for a reading, from a part that carries no `assumptions` or `reading_assumptions`, posts none. The identity entry that asks for a built sentence posts no `assumptions`, since it reads only the spec's own `rendered_sentence`. - A strict fetch raises the manifest's first warning above `info` severity as a `DataWarning` with that warning's code, before the sentence lookup and the download. - An identity resubmit whose answer is not one definite part of the built `spec_id`, with a sentence, raises `ContractError`. - The `frame` layout posts `{"format": "parquet", "bundle": false, "layout": "frame"}` as the build's `options` and downloads the artifact whose rendering's `layout` is `frame`; the `long` layout posts `{"format": "parquet", "bundle": false}` and downloads the bare Parquet artifact with any other layout. A fetch of an answer with several members in the `frame` layout raises `InvalidRequestError` before any build. - A download asks the route that redirects to the signed URL, an artifact's `url` or the file selector, and fetches the URL its `location` names once. The route ask is an API request and follows the retry rules below, so a retryable refusal is retried within the budget and any other refusal, `artifact_expired` among them, raises at once. A failed fetch gets exactly one more round: a refused fetch or bytes that do not hash to the artifact's digest ask the route again, under the same retry rules, and fetch again, with no wait between rounds. A second failure raises `ServerError` with `download_failed`, or `digest_mismatch` when the bytes are wrong. A network error or timeout on the fetch is retryable, so it starts the second round too, and when the second round fails the same way the client raises that failure as itself, `network_error` or `deadline_exceeded`. The replay holds no network failure, so no scenario pins that case. -- A relative `location` resolves against the files route's URL, and the client fetches it on the API's origin as an `origin_path` request. A `location`, or a manifest artifact's `url`, on an origin other than the API's or `https://storage.googleapis.com` raises `ContractError` `contract_violation` before any fetch. A fetch on the storage host is bare and carries no API key. `fetch-spec-relative-location` pins the relative case. +- A manifest artifact's `url` names its files route on the API's origin: a root-relative `url` resolves against the base URL's origin, and an absolute one on that origin is asked as its path and query, so both make the same `origin_path` request, which `fetch-spec-same-origin-artifact-url` pins. An artifact `url` on any other origin, the storage host's included, raises `ContractError` `contract_violation` before the sentence lookup and any request for the file, which `fetch-spec-foreign-artifact-url` and `fetch-spec-storage-artifact-url` pin. +- A relative `location` resolves against the files route's URL, and the client fetches it on the API's origin as an `origin_path` request. A `location` on an origin other than the API's or `https://storage.googleapis.com` raises `ContractError` `contract_violation` before any fetch. A fetch on the storage host is bare and carries no API key. `fetch-spec-relative-location` pins the relative case. - A declined or catalogue answer is not complete, and fetching it raises `DeclinedError`. - Fetching an answer with a gap raises `IncompleteAnswerError` before any request, unless the fetch is partial and some part has a reading. - A fetch of an answer issues one `SearchWarning` when a definite part has an operation Search did not run, a departure, or a warning at severity `warn` or `degraded` with a `message`, or the answer's `diagnostics.warnings` holds such a warning. An `info` warning, and a warning with no `message`, issue nothing. Each way is one line a client shows: `Not done: ()` coded by the verb, the departure's `text` coded by its code, or `Note: ` coded by the warning's code, in part order with the diagnostics warnings last, and ways that show the same line count once, under the first one's code. A strict fetch raises the `SearchWarning` before any build, with the code of its one line, or a null code when there are several lines. A strict fetch raises it before the `frame` layout's several-member check. - A ref's version is found in this order: the snapshot route and the files route at the stored digest; the file selector, `GET /datasets/{id}/{content_version}/file` with the ref's rendering as the query; and a build of the ref's spec in the ref's rendering, which must answer the same `content_version`. A snapshot refusal other than `artifact_expired` ends the lookup, so `snapshot_not_found` raises `NotFoundError` with no further request. A files route or selector refusal of `artifact_expired`, `artifact_not_found` or `not_found` takes the next step, and a selector file of another digest is not the stored file. A rebuild that answers another version, or that raises `InvalidRequestError`, `NotFoundError` or `VersionUnavailableError`, ends in `VersionUnavailableError` with the first refusal's code, or `version_unavailable` when nothing refused. Its `newest_version` is the version the rebuild answered, or else the newest stored version, which `GET /datasets/{id}/versions?limit=1` lists alone, as a `newest_version` step finds it, since the route lists versions newest first and needs no key; or null when that route lists none or refuses with `NotFoundError`. Any other refusal of the versions route raises, and a page whose `versions` is not a list of versions each with a `content_version` raises `ContractError` `contract_violation`, which `newest-version-unreadable-page` pins. - A build answers 200 with the manifest, or 202 with an operation the client polls at `/datasets/operations/{operation_id}`, the id of the operation it holds. A mint's build answers 202; a record whose mint answers 200 fits no mint step. Before each poll it waits the `Retry-After` of a 429 that refused the last poll, else the last operation resource's `retry_after_ms`, else the `Retry-After` of the response that carried that resource, else a backoff of 1, 2, 4 and then 8 seconds that advances only when it is used. -- A 429 poll spends no retry. Any other retryable refused poll spends one of the two retries, which a poll that answers restores, and a refusal that is not retryable raises. A poll that answers a failed operation whose error is retryable posts the same build once more and polls the operation it starts; a second failure, an error that is not retryable, and a resumed operation, whose build request the client does not hold, raise the operation's error. A refused poll whose code is `operation_failed` is a failed operation with that error. A failed operation whose resource carries no `error` raises `ServerError` with `operation_failed`, retryable by status 500 as a refusal without a document is, which `operation-failed-without-error` pins. A 202 or resumed operation that already reads `failed` raises its error before any poll. -- Any other refusal is retried when it is retryable: as a problem document's `retryable` says, or the website proxy's `retry` of `retry_after_delay`, else when its status is 408, 429, 500, 502, 503 or 504. A client makes two retries by default, and the scenarios assume that default; a build cut off by a retryable 504 is posted once more only, and a second 504 raises. A refusal that is not retryable, or one past the retries, raises its error. +- A 429 poll spends no retry. Any other retryable refused poll spends one of the two retries, which a poll that answers restores, and a refusal that is not retryable raises. A refused poll changes no pacing, so the poll after it waits what the refused poll waited. `fetch-spec-poll-refused` pins two 503s polled again after an answered poll, and `fetch-spec-poll-not-found` a 404 that raises at once. A poll that answers a failed operation whose error is retryable posts the same build once more and polls the operation it starts; a second failure, an error that is not retryable, and a resumed operation, whose build request the client does not hold, raise the operation's error. A refused poll whose code is `operation_failed` is a failed operation with that error. A failed operation whose resource carries no `error` raises `ServerError` with `operation_failed`, retryable by status 500 as a refusal without a document is, which `operation-failed-without-error` pins. A 202 or resumed operation that already reads `failed` raises its error before any poll. +- Any other refusal is retried when it is retryable: as a problem document's `retryable` says, or the website proxy's `retry` of `retry_after_delay`, else when its status is 408, 429, 500, 502, 503 or 504. A client makes two retries by default, and the scenarios assume that default. A build's POST shares those two retries with every other refusal of it, and once a 504 cuts the build off the client posts it once more only, whatever that post answers: a build refused 504 then 503 raises the 503, a build refused 503 then 504 is posted once more after the 504, and a second 504 raises. `fetch-spec-504-then-503`, `fetch-spec-503-then-504` and `fetch-spec-504-twice` pin the three. A refusal that is not retryable, or one past the retries, raises its error. - Each retry waits the refusal's `Retry-After` when it carries one, and otherwise the client's backoff for that attempt: 0.5 seconds before the first retry, doubling to at most 8. The build's 504 cut-off retry follows the same rule. `retry_waits` pins these waits, and `fetch-spec-504-retry-after` pins a cut-off that carries `Retry-After`. +- A 401 resolves the key again by the key-lookup rule. When the key changed, the client sends the request once more at once, with no wait and spending no retry; when it did not, or the second answer is a 401 too, the 401 raises `AuthenticationError`. A replay's key never changes, so `search-unauthorized` pins the second case and no scenario the first. +- A `request(method, path)` whose `path` is not a path on the base URL, because it starts with `//` or names a scheme, raises `InvalidRequestError` `invalid_argument` before any request. No scenario step makes such a request. - A 2xx response of a JSON route with no JSON body raises `ContractError` `unexpected_response`; `search-no-json-body` pins it for Search. -- A `Deprecation` or `Sunset` header on an API response, either alone, issues `route_deprecated` once per process per distinct pair of their values, and an `x-dfo-warning` header issues `server_warning` once per process per message. A signed fetch's headers issue nothing. `search-sunset-warning` pins a Sunset header alone, issued once over two responses that carry the same value. +- A `Deprecation` or `Sunset` header on an API response, either alone, issues `route_deprecated` once per process per distinct pair of their values, and an `x-dfo-warning` header issues `server_warning` once per process per message. A signed fetch's headers issue nothing. `search-sunset-warning` pins a Sunset header alone, issued once over two responses that carry the same value, and `search-server-warning` pins a repeated `x-dfo-warning` message issued once, a new message issued again, and a Deprecation beside the same Sunset issued as a new pair. - Timeouts follow the clients' design and are not replayed, since the replay advances the clock only by the waits the client asks for: the client's `timeout`, 30 s by default, bounds one request attempt; `search(timeout=60)` bounds the whole search, each attempt reading until that deadline, and None means no limit; `fetch(timeout=1800)` bounds the whole fetch, each download getting the time left on the fetch's deadline; a synchronous build POST, and mint's POST, read for up to 150 s within any outer deadline; `result(timeout=1800)` bounds the wait, and None means no limit. A poll attempt that hangs past the per-attempt timeout spends a retry, and a deadline that passes during a body read raises `DfoTimeoutError` `deadline_exceeded`. In TypeScript an infinite remaining time arms no timer, and a finite one above 2^31-1 ms is clamped. No scenario step takes a timeout. ## Recording diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json new file mode 100644 index 0000000..c0c05c5 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json @@ -0,0 +1,104 @@ +{ + "format_version": 1, + "name": "answer-empty-parts", + "description": "A resolution with no parts, which the served schema gives at least one, raises ContractError contract_violation at /parts.", + "origin": { + "kind": "synthetic", + "derived_from": "search-place-ambiguous", + "edit": "The answer's parts become []." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Congo", + "normalized_query": "ODA disbursements from Germany to Congo", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "warnings": [], + "timing_ms": { + "total": 1788, + "by_step": { + "coverage": 0, + "extract": 1353 + } + }, + "llm_usage": { + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "no_data" + } + } + } + ], + "expect": [ + { + "error": { + "class": "ContractError", + "code": "contract_violation" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-nested-specs-unchecked.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-nested-specs-unchecked.json new file mode 100644 index 0000000..b37085a --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-nested-specs-unchecked.json @@ -0,0 +1,4418 @@ +{ + "format_version": 1, + "name": "answer-nested-specs-unchecked", + "description": "A client checks strict members only where a rule reads them, so a spec nested in resolved.alternative_measures may lack them, and the fetch reaches the same dataset.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-definite-fetch", + "edit": "Each alternative measure of part 0's spec loses its definition's identity and its resolved." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Nigeria for basic health care" + }, + { + "op": "fetch" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Nigeria for basic health care" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Nigeria for basic health care", + "normalized_query": "ODA disbursements from Germany to Nigeria for basic health care", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", + "warnings": [], + "timing_ms": { + "total": 4556, + "by_step": { + "coverage": 0, + "extract": 889 + } + }, + "llm_usage": { + "input_tokens": 6116, + "output_tokens": 408, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "basic health care ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 3505, + "by_step": { + "recall": 628, + "shape_arcs": 1, + "shape_probe_coverage": 5, + "shape_probe": 477, + "shape_groups": 22, + "shape_labels": 1, + "shape_admission": 1, + "shape": 1283, + "bind": 1188, + "materialise": 11, + "answer": 381, + "options": 14 + } + }, + "restatement": { + "variable_text": "basic health care ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Nigeria", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal", + "label": "gross disbursements (basic health care, official development assistance, standard grant)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 21, + "member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "financialObligationType" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 5, + "member_count_exact": true, + "served_count": 21, + "data_date_range": { + "start": "1995", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 30, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 15 + }, + { + "label": "variables", + "count": 5 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 3, + "series": 3, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2024, + "observations": 3, + "series": 3, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + } + ] + }, + "download": { + "rows": 30, + "rows_exact": true, + "series": 5, + "window": { + "start_year": 1995, + "end_year": 2024 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 88, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 30, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 7, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1606, + "served_rows": 1, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 6, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 7, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 7, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 1, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 1600, + "served_rows": 1, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFinance", + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Nigeria", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/NGA" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "basic health care", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1995 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "measure_elected" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/NGA", + "label": "Nigeria" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [ + { + "text": "basic health care", + "named": [ + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + } + ], + "slot": "crsPurpose", + "disposition": "bound", + "selected": [] + }, + { + "text": "ODA", + "named": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "slot": "crsTypeOfFlow", + "disposition": "bound", + "selected": [] + } + ], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "high", + "available_at_place": true, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_80b92ca1ba1114b426eb5e79b84361d4" + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 30, + "served_rows_exact": true + }, + { + "definition": { + "schema_version": 1, + "spec_id": "spec_c394f9108db2100f1c8e4532d8d1c804" + }, + "label": "commitments", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialObligation", + "label": "financial obligation" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialObligationType", + "value": { + "ref": "Commitment", + "label": "commitment" + } + } + ], + "served_rows": 24, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "open_axis_facts": [ + { + "property": "crsTypeOfFinance", + "varies": false, + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "distinct_count": 1, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "count": 5 + } + ] + }, + { + "property": "crsCooperationModality", + "varies": true, + "distinct_count": 4, + "undeclared_count": 1, + "values": [ + { + "value": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "count": 1 + } + ] + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1995, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 2023, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1995, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "NGN", + "origin": "EUR" + } + } + } + } + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFinance", + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Nigeria", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/NGA" + ], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "basic health care", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1995 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "status": "definite" + } + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + }, + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "prepared_at": "2026-10-21T08:57:19Z", + "coverage": { + "rows": 30, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 27 + } + ], + "window": { + "kind": "all", + "start_year": 1995, + "end_year": 2024, + "origin": "default" + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "applied_window": { + "kind": "all", + "start_year": 1995, + "end_year": 2024, + "origin": "default" + }, + "graph_revision": null, + "code_index_stamp": { + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", + "graph_endpoint": "graph_release" + }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 7 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 15 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "family_member_count": 21, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDCreditorReportingSystem", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + } + ], + "normalisations": [], + "frame_grammar_version": "1.1.0", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:57:19.628756+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9785, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:19.589654+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + }, + { + "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", + "rendering": { + "statistics": "series" + }, + "bytes": 5981, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:19.589654+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" + } + ], + "series_count": 5, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 5 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 27 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "stat_var", + "columns": "time_period", + "state": "available", + "width": 28, + "cells": 140 + }, + { + "index": "time_period", + "columns": "stat_var", + "state": "available", + "width": 6, + "cells": 162 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:19.589587Z" + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "answer-definite-fetch.parquet" + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "definite", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "complete": true, + "specs": [ + "spec_774d6c001a6250aa67ca676ab067895e" + ], + "gaps": [] + } + }, + { + "dataset": { + "rows": 30, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "crsCooperationModality", + "crsCooperationModality_label", + "crsPurpose", + "crsPurpose_label", + "crsTypeOfFinance", + "crsTypeOfFinance_label", + "crsTypeOfFlow", + "crsTypeOfFlow_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [ + "basic health care ODA disbursements" + ], + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." + } + ], + "missing": [], + "search_warning": false + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json new file mode 100644 index 0000000..0f4a602 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json @@ -0,0 +1,3622 @@ +{ + "format_version": 1, + "name": "answer-spec-without-identity", + "description": "A Search spec whose definition has no identity, which a client posts back, raises ContractError contract_violation.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-definite-fetch", + "edit": "Part 0's spec definition loses identity, and the fetch goes." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Nigeria for basic health care" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Nigeria for basic health care" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Nigeria for basic health care", + "normalized_query": "ODA disbursements from Germany to Nigeria for basic health care", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", + "warnings": [], + "timing_ms": { + "total": 4556, + "by_step": { + "coverage": 0, + "extract": 889 + } + }, + "llm_usage": { + "input_tokens": 6116, + "output_tokens": 408, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "basic health care ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 3505, + "by_step": { + "recall": 628, + "shape_arcs": 1, + "shape_probe_coverage": 5, + "shape_probe": 477, + "shape_groups": 22, + "shape_labels": 1, + "shape_admission": 1, + "shape": 1283, + "bind": 1188, + "materialise": 11, + "answer": 381, + "options": 14 + } + }, + "restatement": { + "variable_text": "basic health care ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Nigeria", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e" + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal", + "label": "gross disbursements (basic health care, official development assistance, standard grant)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 21, + "member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "financialObligationType" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 5, + "member_count_exact": true, + "served_count": 21, + "data_date_range": { + "start": "1995", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 30, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 15 + }, + { + "label": "variables", + "count": 5 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 3, + "series": 3, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2024, + "observations": 3, + "series": 3, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + } + ] + }, + "download": { + "rows": 30, + "rows_exact": true, + "series": 5, + "window": { + "start_year": 1995, + "end_year": 2024 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 88, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 30, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 7, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1606, + "served_rows": 1, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 6, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 7, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 7, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 1, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 1600, + "served_rows": 1, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFinance", + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Nigeria", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/NGA" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "basic health care", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1995 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "measure_elected" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/NGA", + "label": "Nigeria" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [ + { + "text": "basic health care", + "named": [ + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + } + ], + "slot": "crsPurpose", + "disposition": "bound", + "selected": [] + }, + { + "text": "ODA", + "named": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "slot": "crsTypeOfFlow", + "disposition": "bound", + "selected": [] + } + ], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "high", + "available_at_place": true, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_80b92ca1ba1114b426eb5e79b84361d4", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 30, + "served_rows_exact": true + }, + { + "definition": { + "schema_version": 1, + "spec_id": "spec_c394f9108db2100f1c8e4532d8d1c804", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialObligation", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialObligationType", + "binding": { + "state": "value", + "ref": "Commitment" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "commitments", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialObligation", + "label": "financial obligation" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialObligationType", + "value": { + "ref": "Commitment", + "label": "commitment" + } + } + ], + "served_rows": 24, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "open_axis_facts": [ + { + "property": "crsTypeOfFinance", + "varies": false, + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "distinct_count": 1, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "count": 5 + } + ] + }, + { + "property": "crsCooperationModality", + "varies": true, + "distinct_count": 4, + "undeclared_count": 1, + "values": [ + { + "value": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "count": 1 + } + ] + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1995, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 2023, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1995, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "NGN", + "origin": "EUR" + } + } + } + } + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFinance", + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Nigeria", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/NGA" + ], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "basic health care", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1995 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "status": "definite" + } + } + } + ], + "expect": [ + { + "error": { + "class": "ContractError", + "code": "contract_violation" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json new file mode 100644 index 0000000..e5b08a4 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json @@ -0,0 +1,402 @@ +{ + "format_version": 1, + "name": "answer-spec-without-resolved", + "description": "A Search spec with no resolved, whose entity_groups a client reads, raises ContractError contract_violation.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-definite-fetch", + "edit": "Part 0's spec loses resolved, and the fetch goes." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Nigeria for basic health care" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Nigeria for basic health care" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Nigeria for basic health care", + "normalized_query": "ODA disbursements from Germany to Nigeria for basic health care", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", + "warnings": [], + "timing_ms": { + "total": 4556, + "by_step": { + "coverage": 0, + "extract": 889 + } + }, + "llm_usage": { + "input_tokens": 6116, + "output_tokens": 408, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "basic health care ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 3505, + "by_step": { + "recall": 628, + "shape_arcs": 1, + "shape_probe_coverage": 5, + "shape_probe": 477, + "shape_groups": 22, + "shape_labels": 1, + "shape_admission": 1, + "shape": 1283, + "bind": 1188, + "materialise": 11, + "answer": 381, + "options": 14 + } + }, + "restatement": { + "variable_text": "basic health care ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Nigeria", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + } + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFinance", + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Nigeria", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/NGA" + ], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "basic health care", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1995 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "status": "definite" + } + } + } + ], + "expect": [ + { + "error": { + "class": "ContractError", + "code": "contract_violation" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-echoes-separate-and-operations.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-echoes-separate-and-operations.json new file mode 100644 index 0000000..eb6706c --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-echoes-separate-and-operations.json @@ -0,0 +1,10817 @@ +{ + "format_version": 1, + "name": "choose-echoes-separate-and-operations", + "description": "A definite part's identity entry echoes the part's separate flag when it is true and its operations when it has any.", + "origin": { + "kind": "synthetic", + "derived_from": "choose-option-beside-definite", + "edit": "Part 0, the definite part, carries separate true and the operation {'verb': 'growth', 'phrase': 'growth of GDP', 'over': 'year'}." + }, + "call": [ + { + "op": "search", + "question": "GDP of sub-Saharan Africa, and debt of Kenya" + }, + { + "op": "choose", + "part": 1, + "option": 0 + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "GDP of sub-Saharan Africa, and debt of Kenya" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "GDP of sub-Saharan Africa, and debt of Kenya", + "normalized_query": "GDP of sub-Saharan Africa, and debt of Kenya", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "36b57c8d82ea4b938e42ca11105ac21c", + "warnings": [], + "timing_ms": { + "total": 4230, + "by_step": { + "coverage": 0, + "extract": 875 + } + }, + "llm_usage": { + "input_tokens": 12972, + "output_tokens": 920, + "cached_tokens": 5719 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GDP", + "warnings": [], + "timing_ms": { + "total": 2775, + "by_step": { + "recall": 0, + "shape_arcs": 3, + "shape_probe_coverage": 4, + "shape_probe": 298, + "shape_groups": 17, + "shape_labels": 4, + "shape_admission": 1, + "shape": 1305, + "bind": 1041, + "materialise": 182, + "answer": 5, + "options": 242 + } + }, + "restatement": { + "variable_text": "GDP", + "entities": [ + { + "text": "Sub-Saharan Africa" + }, + { + "text": "Kenya" + } + ], + "sources": [], + "operations": [] + }, + "operations": [ + { + "verb": "growth", + "phrase": "growth of GDP", + "over": "year" + } + ], + "departures": [ + { + "code": "group_read_as_members", + "binding_ref": "where:", + "asked": "sub-Saharan Africa", + "text": "You asked for sub-Saharan Africa. This shows the countries in it, each on its own." + } + ], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_3c3d4e571162850b30db0321638f955b", + "definition": { + "schema_version": 1, + "spec_id": "spec_3c3d4e571162850b30db0321638f955b", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + }, + { + "property": "economicSector", + "binding": { + "state": "unbound" + } + }, + { + "property": "naics", + "binding": { + "state": "unbound" + } + }, + { + "property": "schoolGradeLevel", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "USDollar" + } + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_nominal", + "label": "Nominal gross domestic product", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 65, + "member_digest": "73519eeb75639bdae33042fc844830cd46becc08e4f9122dfcd0886e9875f657", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "economicSector", + "naics", + "schoolGradeLevel" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 41, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "entity_groups": { + "observationAbout": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 2859, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 48 + }, + { + "label": "observations", + "count": 66 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 2859, + "rows_exact": true, + "series": 48, + "window": { + "start_year": 1960, + "end_year": 2025 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "bound", + "ref": "USDollar", + "label": "USDollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossValueAdded", + "label": "GrossValueAdded" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NetDomesticProduction", + "label": "Net Domestic Production" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NetValueAdded", + "label": "Net Value Added" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "AgricultureForestryFishingSector", + "label": "Agriculture,Forestry and Fishing Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ConstructionSector", + "label": "Construction Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ElectricityGasSteamAirConditionSupply", + "label": "Electric Gas Steam Air Condition Supply" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinanceService", + "label": "Finance Service" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MOSPI_OtherService", + "label": "MOSPI Other Service" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ManufacturingSector", + "label": "Manufacturing Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MiningQuarrying", + "label": "Mining quarrying" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TradeSector", + "label": "Trade Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AccommodationAndFoodSector", + "label": "Accommodation and food sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AdministrativeAndSupportServices", + "label": "Administrative and support services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AgriculturalSupportActivities", + "label": "Agricultural support activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Agriculture", + "label": "Agriculture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AirTransportAndSupportServices", + "label": "Air transport and support services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AllEconomicActivities", + "label": "All economic activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AnimalProduction", + "label": "Animal production" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ArtsEntertainmentRecreation", + "label": "Arts entertainment recreation" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Education", + "label": "Education" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ElectricitySupply", + "label": "Electricity supply" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EmployerHouseholdActivities", + "label": "Employer household activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialActivities", + "label": "FinancialActivities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialAndInsuranceActivities", + "label": "Financial and insurance activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialIntermediationServicesIndirectlyMeasured", + "label": "Financial intermediation services indirectly measured" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FishingAquaculture", + "label": "Fishing aquaculture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FoodBeveragesTobaccoManufacture", + "label": "Food beverages tobacco manufacture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ForestryLogging", + "label": "Forestry logging" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "HumanHealthAndSocialWork", + "label": "Human health and social work" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "InformationAndCommunication", + "label": "Information and communication" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "InsuranceActivities", + "label": "Insurance activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "LandTransport", + "label": "Land transport" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherManufacturingAndRepair", + "label": "Other manufacturing and repair" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherServiceSector", + "label": "Other service sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherTransportPostalCourierActivities", + "label": "Other transport postal courier activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ProductTaxes", + "label": "Product taxes" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ProfessionalScientificTechnicalActivities", + "label": "Professional scientific technical activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PublicAdministrationAndDefence", + "label": "Public administration and defence" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PublishingBroadcastingInformationActivities", + "label": "Publishing Broadcasting Information Activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "RealEstate", + "label": "Real estate" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Telecommunications", + "label": "Telecommunications" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TransportStorageSector", + "label": "Transport and Storage" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "WaterSupplySewerageWasteManagement", + "label": "Water supply sewerage waste management" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "WholesaleRetailTradeAndRepair", + "label": "Wholesale retail trade and repair" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "BankingAndInsuranceSector", + "label": "Banking And Insurance Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Construction", + "label": "Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialServices", + "label": "Financial Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Industry", + "label": "Industry" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Services", + "label": "Services" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "options": [ + { + "value": { + "ref": { + "ref": "NAICS/23", + "label": "Construction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/44-45", + "label": "Retail trade" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/53", + "label": "Real estate and rental and leasing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/22", + "label": "Utilities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/55", + "label": "Management of companies and enterprises" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/48-49", + "label": "Transportation and warehousing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/61", + "label": "Educational services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/51", + "label": "Information" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/42", + "label": "Wholesale trade" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/21", + "label": "Mining, quarrying, and oil and gas extraction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/11", + "label": "Agriculture, forestry, fishing and hunting" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/72", + "label": "Accommodation and food services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/52", + "label": "Finance and insurance" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/54", + "label": "Professional, Scientific, and Technical Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/71", + "label": "Arts, entertainment, and recreation" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/311-316_322-326", + "label": "Durable Goods Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/31-33", + "label": "Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/321_327-339", + "label": "Durable Goods Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/56", + "label": "Administrative and Support and Waste Management Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/62", + "label": "Health care and social assistance" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/81", + "label": "Other services, except public administration" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/92", + "label": "Public administration" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "options": [ + { + "value": { + "ref": { + "ref": "HigherSecondaryEducation", + "label": "Higher Secondary Education" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PrePrimaryAndPrimaryEducation", + "label": "PrePrimary and Primary" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SecondaryEducation", + "label": "SecondaryEducation" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "USDollar", + "label": "USDollar" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "XAF", + "label": "XAF" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAccommodationFoodServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSFinanceInsurance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSMiningQuarryingOilGasExtraction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSProfessionalScientificTechnicalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSWholesaleTrade_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826", + "dc/zz6gwv838v9w" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "equivalent_readings": [ + { + "spec_id": "spec_22cfb22f6e4a1cff1584eaf03285ce73", + "definition": { + "schema_version": 1, + "spec_id": "spec_22cfb22f6e4a1cff1584eaf03285ce73", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicProduction", + "measured_property": "valueAdded", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "currencyConversionBasis", + "binding": { + "state": "unbound" + } + }, + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + }, + { + "property": "productTaxBasis", + "binding": { + "state": "value", + "ref": "IncludingProductTaxes" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "CurrencyUSD" + } + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicproduction_valueadded_measuredvalue_nominal", + "label": "Gross domestic product (GDP)", + "population_type": { + "ref": "EconomicProduction", + "label": "economic production" + }, + "measured_property": { + "ref": "valueAdded", + "label": "value added" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 2, + "member_digest": "ef9c4356618ed98aab762248e68799d78c74ad249a6041dad0e8a345c85ee02f", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "currencyConversionBasis" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 2, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1980", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "entity_groups": { + "observationAbout": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 2031, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 48 + }, + { + "label": "observations", + "count": 46 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 2031, + "rows_exact": true, + "series": 48, + "window": { + "start_year": 1980, + "end_year": 2025 + }, + "licence": { + "label": "IMF Copyright and Usage" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/IMFWorldEconomicOutlook", + "label": "IMF World Economic Outlook (WEO)", + "source": { + "ref": "source/InternationalMonetaryFund", + "label": "International Monetary Fund (IMF)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/IMFWorldEconomicOutlook" + }, + "unit": { + "basis": "bound", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "PurchasingPowerParityRate", + "label": "purchasing power parity rate" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [], + "trace": { + "resolved_entities": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "provenance/IMFWorldEconomicOutlook", + "label": "IMF World Economic Outlook (WEO)", + "source": { + "ref": "source/InternationalMonetaryFund", + "label": "International Monetary Fund (IMF)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/IMFWorldEconomicOutlook" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAccommodationFoodServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSFinanceInsurance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSMiningQuarryingOilGasExtraction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSProfessionalScientificTechnicalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSWholesaleTrade_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826", + "dc/zz6gwv838v9w" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "measure_label_axes": [], + "measure_axis_values": [], + "related_group": { + "ref": "dc/g/EconomicActivity_ActivitySource-GrossDomesticProduction", + "label": "Economic Activity With Activity Source = Gross Domestic Production" + }, + "related_measures": [ + { + "stat_var": { + "ref": "GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "label": "Gross domestic product growth rate" + }, + "definition": { + "schema_version": 1, + "spec_id": "spec_df3e3c939162b3cfe113d2d78d4b4986", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "growthRate" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + } + ] + } + }, + "separate": true + }, + { + "variable_text": "debt", + "warnings": [ + { + "code": "retrieval_score_weak", + "severity": "info", + "message": "the chosen reading's match to the query is weak; treat it with less confidence than a strong match." + } + ], + "timing_ms": { + "total": 2694, + "by_step": { + "recall": 1, + "shape_arcs": 1, + "shape_probe_coverage": 4, + "shape_probe": 287, + "shape_groups": 2, + "shape_labels": 0, + "shape_admission": 0, + "shape": 1117, + "bind": 1576 + } + }, + "rendered_sentence": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "sentence_plan": [ + { + "kind": "text", + "text": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "operations": [], + "departures": [], + "assumptions": [], + "status": "no_data", + "no_data": { + "reason": "role_not_resolved", + "category": "unresolved", + "message": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "entity_terms": [ + "sub-Saharan Africa", + "Kenya" + ], + "ambiguous_entities": [], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "sub-Saharan Africa", + "Kenya" + ], + "label": "sub-Saharan Africa to Kenya", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "debt", + "entities": [ + { + "text": "Sub-Saharan Africa", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "sub-Saharan Africa", + "Kenya" + ], + "label": "Kenya to sub-Saharan Africa", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "debt", + "entities": [ + { + "text": "Sub-Saharan Africa", + "role_text": "to" + }, + { + "text": "Kenya", + "role_text": "from" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + ] + } + } + ], + "rendered_sentence": "Answered 1 of 2 parts. GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators. You asked for sub-Saharan Africa. This shows the countries in it, each on its own. Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "You asked for sub-Saharan Africa. This shows the countries in it, each on its own.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + } + ], + "status": "mixed" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "dataset_resubmit", + "entries": [ + { + "entry_kind": "identity", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + }, + { + "property": "economicSector", + "binding": { + "state": "unbound" + } + }, + { + "property": "naics", + "binding": { + "state": "unbound" + } + }, + { + "property": "schoolGradeLevel", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "USDollar" + } + } + }, + "entity_groups": { + "observationAbout": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "assumptions": [], + "variable_text": "GDP", + "separate": true, + "operations": [ + { + "verb": "growth", + "phrase": "growth of GDP", + "over": "year" + } + ] + }, + { + "entry_kind": "parsed", + "part": { + "variable_text": "debt", + "entities": [ + { + "text": "Sub-Saharan Africa", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + } + } + ] + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "dataset_resubmit", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "6bb21f75d7374cb1882111e02c35a590", + "warnings": [], + "timing_ms": { + "total": 2350, + "by_step": { + "coverage": 0 + } + }, + "llm_usage": { + "input_tokens": 4539, + "output_tokens": 503, + "cached_tokens": 1544 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GDP", + "warnings": [], + "timing_ms": { + "total": 1426, + "by_step": { + "validate": 0, + "walk": 0, + "reread_arcs": 0, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 952, + "bind": 0, + "where_places": 0, + "materialise": 213, + "answer": 1, + "options": 260 + } + }, + "operations": [], + "departures": [ + { + "code": "group_read_as_members", + "binding_ref": "where:", + "text": "This shows the 48 countries in Sub-Saharan Africa, each on its own." + } + ], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_3c3d4e571162850b30db0321638f955b", + "definition": { + "schema_version": 1, + "spec_id": "spec_3c3d4e571162850b30db0321638f955b", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + }, + { + "property": "economicSector", + "binding": { + "state": "unbound" + } + }, + { + "property": "naics", + "binding": { + "state": "unbound" + } + }, + { + "property": "schoolGradeLevel", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "USDollar" + } + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_nominal", + "label": "Nominal gross domestic product", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 65, + "member_digest": "73519eeb75639bdae33042fc844830cd46becc08e4f9122dfcd0886e9875f657", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "economicSector", + "naics", + "schoolGradeLevel" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 41, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "entity_groups": { + "observationAbout": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 2859, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 48 + }, + { + "label": "observations", + "count": 66 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 2859, + "rows_exact": true, + "series": 48, + "window": { + "start_year": 1960, + "end_year": 2025 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "bound", + "ref": "USDollar", + "label": "USDollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "AccommodationAndFoodSector", + "label": "Accommodation and food sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AdministrativeAndSupportServices", + "label": "Administrative and support services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AgriculturalSupportActivities", + "label": "Agricultural support activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Agriculture", + "label": "Agriculture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AgricultureForestryFishingSector", + "label": "Agriculture,Forestry and Fishing Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AirTransportAndSupportServices", + "label": "Air transport and support services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AllEconomicActivities", + "label": "All economic activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AnimalProduction", + "label": "Animal production" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ArtsEntertainmentRecreation", + "label": "Arts entertainment recreation" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ConstructionSector", + "label": "Construction Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Education", + "label": "Education" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ElectricitySupply", + "label": "Electricity supply" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EmployerHouseholdActivities", + "label": "Employer household activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialActivities", + "label": "FinancialActivities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialAndInsuranceActivities", + "label": "Financial and insurance activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialIntermediationServicesIndirectlyMeasured", + "label": "Financial intermediation services indirectly measured" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FishingAquaculture", + "label": "Fishing aquaculture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FoodBeveragesTobaccoManufacture", + "label": "Food beverages tobacco manufacture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ForestryLogging", + "label": "Forestry logging" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "HumanHealthAndSocialWork", + "label": "Human health and social work" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "InformationAndCommunication", + "label": "Information and communication" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "InsuranceActivities", + "label": "Insurance activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "LandTransport", + "label": "Land transport" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ManufacturingSector", + "label": "Manufacturing Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MiningQuarrying", + "label": "Mining quarrying" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherManufacturingAndRepair", + "label": "Other manufacturing and repair" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherServiceSector", + "label": "Other service sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherTransportPostalCourierActivities", + "label": "Other transport postal courier activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ProductTaxes", + "label": "Product taxes" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ProfessionalScientificTechnicalActivities", + "label": "Professional scientific technical activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PublicAdministrationAndDefence", + "label": "Public administration and defence" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PublishingBroadcastingInformationActivities", + "label": "Publishing Broadcasting Information Activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "RealEstate", + "label": "Real estate" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Telecommunications", + "label": "Telecommunications" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TransportStorageSector", + "label": "Transport and Storage" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "WaterSupplySewerageWasteManagement", + "label": "Water supply sewerage waste management" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "WholesaleRetailTradeAndRepair", + "label": "Wholesale retail trade and repair" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "BankingAndInsuranceSector", + "label": "Banking And Insurance Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Construction", + "label": "Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ElectricityGasSteamAirConditionSupply", + "label": "Electric Gas Steam Air Condition Supply" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "options": [ + { + "value": { + "ref": { + "ref": "HigherSecondaryEducation", + "label": "Higher Secondary Education" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PrePrimaryAndPrimaryEducation", + "label": "PrePrimary and Primary" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SecondaryEducation", + "label": "SecondaryEducation" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "USDollar", + "label": "USDollar" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "XAF", + "label": "XAF" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec" + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [], + "related_group": { + "ref": "dc/g/EconomicActivity_ActivitySource-GrossDomesticProduction", + "label": "Economic Activity With Activity Source = Gross Domestic Production" + }, + "related_measures": [ + { + "stat_var": { + "ref": "GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "label": "Gross domestic product growth rate" + }, + "definition": { + "schema_version": 1, + "spec_id": "spec_df3e3c939162b3cfe113d2d78d4b4986", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "growthRate" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + } + ] + } + } + }, + { + "variable_text": "debt", + "warnings": [ + { + "code": "retrieval_score_weak", + "severity": "info", + "message": "the chosen reading's match to the query is weak; treat it with less confidence than a strong match." + }, + { + "code": "time_window_defaulted", + "severity": "warn", + "message": "no time_text was given; the answer was resolved across every period with data." + } + ], + "timing_ms": { + "total": 2327, + "by_step": { + "recall": 0, + "shape_arcs": 1, + "shape_probe_coverage": 3, + "shape_probe": 218, + "shape_groups": 1, + "shape_labels": 0, + "shape_admission": 1, + "shape": 817, + "bind": 1494, + "materialise": 5, + "answer": 11 + } + }, + "rendered_sentence": "2 readings. Kenya's outstanding external debt owed to the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 1973 to 2024 · Current US dollars. Commitments of public or publicly guaranteed external debt (debt instrument), by creditor to Kenya from the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 2023 · Current US dollars.", + "sentence_plan": [ + { + "kind": "text", + "text": "2 readings.", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "outstanding external debt", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " owed to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Bank International Debt Statistics (IDS)", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "1973 to 2024", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Commitments of public or publicly guaranteed external debt (debt instrument), by creditor", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " from ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Bank International Debt Statistics (IDS)", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2023", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "debt", + "entities": [ + { + "text": "Sub-Saharan Africa", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "candidates", + "candidates": { + "ordering": "intent_rank", + "max_candidates": 6, + "specs": [ + { + "spec_id": "spec_db19b572801b0e2db437bf4722826ef1", + "definition": { + "schema_version": 1, + "spec_id": "spec_db19b572801b0e2db437bf4722826ef1", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialPosition", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "financialPositionType", + "binding": { + "state": "unbound" + } + }, + { + "property": "financingResource", + "binding": { + "state": "unbound" + } + }, + { + "property": "guaranteeStatus", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsConcessionality", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsCreditorType", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsDebtorType", + "binding": { + "state": "unbound" + } + }, + { + "property": "includesIMFCredit", + "binding": { + "state": "unbound" + } + }, + { + "property": "interestRateVariability", + "binding": { + "state": "unbound" + } + }, + { + "property": "maturityBand", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialposition_amount_measuredvalue_nominal_by_role", + "label": "Outstanding external debt, by creditor", + "population_type": { + "ref": "FinancialPosition", + "label": "financial position" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "financialPositionType", + "label": "financial position type" + }, + "label": "financial position type" + }, + { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + { + "axis": "how", + "property": { + "ref": "interestRateVariability", + "label": "interest rate variability" + }, + "label": "interest rate variability" + }, + { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 85, + "member_digest": "59b8172b4da7c06ded4825c4f3f96a3b90414a056cb5c6447595c6be1748066b", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialPositionType", + "label": "financial position type" + }, + "label": "financial position type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "interestRateVariability", + "label": "interest rate variability" + }, + "label": "interest rate variability" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "guaranteeStatus", + "idsDebtorType", + "idsCreditorType", + "financingResource", + "interestRateVariability", + "idsConcessionality", + "includesIMFCredit", + "maturityBand" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1973", + "end": "2024" + }, + "source_codes": [ + { + "provenance": "provenance/WorldBankInternationalDebtStatistics", + "code": "DT.DOD.DECT.CD" + } + ] + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "origin" + } + ], + "entity_groups": { + "origin": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 13, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 11 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2024, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 0, + "series": 0, + "role_counts": {} + } + ] + }, + "download": { + "rows": 13, + "rows_exact": true, + "series": 2, + "window": { + "start_year": 1973, + "end_year": 2024 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialPositionType", + "label": "financial position type" + }, + "label": "financial position type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "AmountOutstanding", + "label": "amount outstanding" + }, + "value_kind": "enum_value" + }, + "served_rows": 13, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "options": [ + { + "value": { + "ref": { + "ref": "PublicOrPubliclyGuaranteed", + "label": "public or publicly guaranteed" + }, + "value_kind": "enum_value" + }, + "served_rows": 13, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSDebtorTypeGG", + "label": "general government (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 2, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSDebtorTypePS", + "label": "public sector (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 13, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSDebtorTypeOPS", + "label": "other public sector (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 11, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSCreditorTypePRVT", + "label": "private creditors (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 2, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypeBLAT", + "label": "bilateral (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 11, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypeOFFT", + "label": "official creditors (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 11, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypePCBK", + "label": "commercial banks (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 2, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "options": [ + { + "value": { + "ref": { + "ref": "DebtInstrument", + "label": "debt instrument" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Loan", + "label": "loan" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SDRAllocation", + "label": "SDR allocation" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "interestRateVariability", + "label": "interest rate variability" + }, + "label": "interest rate variability" + }, + "options": [ + { + "value": { + "ref": { + "ref": "VariableInterestRate", + "label": "variable interest rate" + }, + "value_kind": "enum_value" + }, + "served_rows": 2, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSConcessional", + "label": "concessional (IDS concessionality)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "IDSNonConcessional", + "label": "non-concessional (IDS concessionality)" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "options": [ + { + "value": { + "ref": { + "ref": "WithoutIMFCredit", + "label": "without IMF credit" + }, + "value_kind": "enum_value" + }, + "served_rows": 13, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "options": [ + { + "value": { + "ref": { + "ref": "LongTermMaturity", + "label": "long-term maturity" + }, + "value_kind": "enum_value" + }, + "served_rows": 26, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Kenya's outstanding external debt owed to the 48 countries in Sub-Saharan Africa, 1973 to 2024. Current US dollars · World Bank International Debt Statistics (IDS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "outstanding external debt", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialPositionType", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " owed to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financingResource", + "binding_ref": "how:financingResource", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "guaranteeStatus", + "binding_ref": "how:guaranteeStatus", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsConcessionality", + "binding_ref": "how:idsConcessionality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsCreditorType", + "binding_ref": "how:idsCreditorType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsDebtorType", + "binding_ref": "how:idsDebtorType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "includesIMFCredit", + "binding_ref": "how:includesIMFCredit", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "interestRateVariability", + "binding_ref": "how:interestRateVariability", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "maturityBand", + "binding_ref": "how:maturityBand", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialPositionType", + "binding_ref": "how:financialPositionType", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1973 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Bank International Debt Statistics (IDS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialPositionType", + "label": "financial position type" + }, + "label": "financial position type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "interestRateVariability", + "label": "interest rate variability" + }, + "label": "interest rate variability" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "low", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [], + "open_axis_facts": [ + { + "property": "financialPositionType", + "varies": false, + "value": { + "ref": "AmountOutstanding", + "label": "amount outstanding" + }, + "distinct_count": 1, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "AmountOutstanding", + "label": "amount outstanding" + }, + "count": 1 + } + ] + } + ] + } + }, + { + "spec_id": "spec_6eb3e2b7e6bc64c3f0ae0ac0d41c9b3c", + "definition": { + "schema_version": 1, + "spec_id": "spec_6eb3e2b7e6bc64c3f0ae0ac0d41c9b3c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialObligation", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "financialObligationType", + "binding": { + "state": "value", + "ref": "Commitment" + } + }, + { + "property": "financingResource", + "binding": { + "state": "value", + "ref": "DebtInstrument" + } + }, + { + "property": "guaranteeStatus", + "binding": { + "state": "value", + "ref": "PublicOrPubliclyGuaranteed" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialobligation_amount_measuredvalue_nominal_by_role", + "label": "Commitments of public or publicly guaranteed external debt (debt instrument), by creditor", + "population_type": { + "ref": "FinancialObligation", + "label": "financial obligation" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "financialObligationType", + "label": "financial obligation type" + }, + "label": "financial obligation type" + }, + { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "9c8389fcc18b49e94e1286c629ec5260fce8837ba425bc60c6f31d333d34a73c", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialObligationType", + "label": "financial obligation type" + }, + "label": "financial obligation type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Commitment", + "label": "commitment" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "DebtInstrument", + "label": "debt instrument" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "PublicOrPubliclyGuaranteed", + "label": "public or publicly guaranteed" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2023", + "end": "2023" + }, + "source_codes": [ + { + "provenance": "provenance/WorldBankInternationalDebtStatistics", + "code": "DT.COM.DPPG.CD", + "exact": true + } + ] + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "origin" + } + ], + "entity_groups": { + "origin": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 1, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 1 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "headline": { + "year": 2023, + "year_named": false, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 0, + "series": 0, + "role_counts": {} + }, + { + "year": 2021, + "observations": 0, + "series": 0, + "role_counts": {} + } + ] + }, + "download": { + "rows": 1, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2023, + "end_year": 2023 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialObligationType", + "label": "financial obligation type" + }, + "label": "financial obligation type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Commitment", + "label": "commitment" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "options": [ + { + "value": { + "ref": { + "ref": "DebtInstrument", + "label": "debt instrument" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "options": [ + { + "value": { + "ref": { + "ref": "PublicOrPubliclyGuaranteed", + "label": "public or publicly guaranteed" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Commitments of public or publicly guaranteed external debt (debt instrument), by creditor to Kenya from the 48 countries in Sub-Saharan Africa in 2023. Current US dollars · World Bank International Debt Statistics (IDS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Commitments of public or publicly guaranteed external debt (debt instrument), by creditor", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialObligationType", + "how:financingResource", + "how:guaranteeStatus" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " from ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialObligationType", + "binding_ref": "how:financialObligationType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financingResource", + "binding_ref": "how:financingResource", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "guaranteeStatus", + "binding_ref": "how:guaranteeStatus", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "in 2023", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Bank International Debt Statistics (IDS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialObligationType", + "label": "financial obligation type" + }, + "label": "financial obligation type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Commitment", + "label": "commitment" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "DebtInstrument", + "label": "debt instrument" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "PublicOrPubliclyGuaranteed", + "label": "public or publicly guaranteed" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "low", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "truncated": false + }, + "reading_assumptions": { + "spec_db19b572801b0e2db437bf4722826ef1": [], + "spec_6eb3e2b7e6bc64c3f0ae0ac0d41c9b3c": [] + } + } + ], + "rendered_sentence": "Answered 1 of 2 parts. GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators. This shows the 48 countries in Sub-Saharan Africa, each on its own. Debt has 2 readings. Kenya's outstanding external debt owed to the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 1973 to 2024 · Current US dollars. Commitments of public or publicly guaranteed external debt (debt instrument), by creditor to Kenya from the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 2023 · Current US dollars.", + "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "This shows the 48 countries in Sub-Saharan Africa, each on its own.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Debt", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " has 2 readings.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "outstanding external debt", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " owed to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "World Bank International Debt Statistics (IDS)", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "1973 to 2024", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "Commitments of public or publicly guaranteed external debt (debt instrument), by creditor", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " from ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "World Bank International Debt Statistics (IDS)", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "2023", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + } + ], + "status": "mixed" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "mixed", + "sentence": "Answered 1 of 2 parts. GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators. You asked for sub-Saharan Africa. This shows the countries in it, each on its own. Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "complete": false, + "specs": [ + "spec_3c3d4e571162850b30db0321638f955b" + ], + "gaps": [ + { + "part": 1, + "kind": "choice", + "options": 2 + } + ] + } + }, + { + "answer": { + "kind": "resolution", + "status": "mixed", + "sentence": "Answered 1 of 2 parts. GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators. This shows the 48 countries in Sub-Saharan Africa, each on its own. Debt has 2 readings. Kenya's outstanding external debt owed to the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 1973 to 2024 · Current US dollars. Commitments of public or publicly guaranteed external debt (debt instrument), by creditor to Kenya from the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 2023 · Current US dollars.", + "complete": false, + "specs": [ + "spec_3c3d4e571162850b30db0321638f955b" + ], + "gaps": [ + { + "part": 1, + "kind": "choice", + "options": 2 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-option-two-part-query.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-two-part-query.json new file mode 100644 index 0000000..b9fdad7 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-two-part-query.json @@ -0,0 +1,283 @@ +{ + "format_version": 1, + "name": "choose-option-two-part-query", + "description": "A chosen option whose data_query holds other than one part raises ContractError contract_violation before any request, in a one-part answer as in a several-part one.", + "origin": { + "kind": "synthetic", + "derived_from": "choose-place-one-part", + "edit": "The chosen option's data_query holds its one part twice." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + }, + { + "op": "choose", + "option": "Congo [DRC]" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Congo", + "normalized_query": "ODA disbursements from Germany to Congo", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "9c755dc7ffaf4568afe68d812e56d8fa", + "warnings": [], + "timing_ms": { + "total": 1084, + "by_step": { + "coverage": 0, + "extract": 1082 + } + }, + "llm_usage": { + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 0, + "by_step": { + "recall": 0 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + }, + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + ] + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "no_data" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "no_data", + "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 2 + } + ] + } + }, + { + "error": { + "class": "ContractError", + "code": "contract_violation" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-posts-unsupported-placeholder.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-posts-unsupported-placeholder.json new file mode 100644 index 0000000..1336e17 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-posts-unsupported-placeholder.json @@ -0,0 +1,6615 @@ +{ + "format_version": 1, + "name": "choose-posts-unsupported-placeholder", + "description": "A part that is unsupported and has no restatement posts a placeholder entry with its unsupported code and variable_text.", + "origin": { + "kind": "synthetic", + "derived_from": "choose-option-beside-definite", + "edit": "Part 0 becomes an unsupported part with code scope_too_broad and no restatement." + }, + "call": [ + { + "op": "search", + "question": "GDP of sub-Saharan Africa, and debt of Kenya" + }, + { + "op": "choose", + "part": 1, + "option": 0 + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "GDP of sub-Saharan Africa, and debt of Kenya" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "GDP of sub-Saharan Africa, and debt of Kenya", + "normalized_query": "GDP of sub-Saharan Africa, and debt of Kenya", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "36b57c8d82ea4b938e42ca11105ac21c", + "warnings": [], + "timing_ms": { + "total": 4230, + "by_step": { + "coverage": 0, + "extract": 875 + } + }, + "llm_usage": { + "input_tokens": 12972, + "output_tokens": 920, + "cached_tokens": 5719 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GDP", + "warnings": [], + "timing_ms": { + "total": 2775, + "by_step": { + "recall": 0, + "shape_arcs": 3, + "shape_probe_coverage": 4, + "shape_probe": 298, + "shape_groups": 17, + "shape_labels": 4, + "shape_admission": 1, + "shape": 1305, + "bind": 1041, + "materialise": 182, + "answer": 5, + "options": 242 + } + }, + "operations": [], + "departures": [ + { + "code": "group_read_as_members", + "binding_ref": "where:", + "asked": "sub-Saharan Africa", + "text": "You asked for sub-Saharan Africa. This shows the countries in it, each on its own." + } + ], + "status": "unsupported", + "unsupported": { + "code": "scope_too_broad", + "pointer": "/definition/identity", + "detail": "the family is too broad to settle; bind a what or how slot" + } + }, + { + "variable_text": "debt", + "warnings": [ + { + "code": "retrieval_score_weak", + "severity": "info", + "message": "the chosen reading's match to the query is weak; treat it with less confidence than a strong match." + } + ], + "timing_ms": { + "total": 2694, + "by_step": { + "recall": 1, + "shape_arcs": 1, + "shape_probe_coverage": 4, + "shape_probe": 287, + "shape_groups": 2, + "shape_labels": 0, + "shape_admission": 0, + "shape": 1117, + "bind": 1576 + } + }, + "rendered_sentence": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "sentence_plan": [ + { + "kind": "text", + "text": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "operations": [], + "departures": [], + "assumptions": [], + "status": "no_data", + "no_data": { + "reason": "role_not_resolved", + "category": "unresolved", + "message": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "entity_terms": [ + "sub-Saharan Africa", + "Kenya" + ], + "ambiguous_entities": [], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "sub-Saharan Africa", + "Kenya" + ], + "label": "sub-Saharan Africa to Kenya", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "debt", + "entities": [ + { + "text": "Sub-Saharan Africa", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "sub-Saharan Africa", + "Kenya" + ], + "label": "Kenya to sub-Saharan Africa", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "debt", + "entities": [ + { + "text": "Sub-Saharan Africa", + "role_text": "to" + }, + { + "text": "Kenya", + "role_text": "from" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + ] + } + } + ], + "rendered_sentence": "Answered 1 of 2 parts. GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators. You asked for sub-Saharan Africa. This shows the countries in it, each on its own. Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "You asked for sub-Saharan Africa. This shows the countries in it, each on its own.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + } + ], + "status": "mixed" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "dataset_resubmit", + "entries": [ + { + "entry_kind": "placeholder", + "status": "unsupported", + "code": "scope_too_broad", + "variable_text": "GDP" + }, + { + "entry_kind": "parsed", + "part": { + "variable_text": "debt", + "entities": [ + { + "text": "Sub-Saharan Africa", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + } + } + ] + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "dataset_resubmit", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "6bb21f75d7374cb1882111e02c35a590", + "warnings": [], + "timing_ms": { + "total": 2350, + "by_step": { + "coverage": 0 + } + }, + "llm_usage": { + "input_tokens": 4539, + "output_tokens": 503, + "cached_tokens": 1544 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GDP", + "warnings": [], + "timing_ms": { + "total": 1426, + "by_step": { + "validate": 0, + "walk": 0, + "reread_arcs": 0, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 952, + "bind": 0, + "where_places": 0, + "materialise": 213, + "answer": 1, + "options": 260 + } + }, + "operations": [], + "departures": [ + { + "code": "group_read_as_members", + "binding_ref": "where:", + "text": "This shows the 48 countries in Sub-Saharan Africa, each on its own." + } + ], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_3c3d4e571162850b30db0321638f955b", + "definition": { + "schema_version": 1, + "spec_id": "spec_3c3d4e571162850b30db0321638f955b", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + }, + { + "property": "economicSector", + "binding": { + "state": "unbound" + } + }, + { + "property": "naics", + "binding": { + "state": "unbound" + } + }, + { + "property": "schoolGradeLevel", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "USDollar" + } + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_nominal", + "label": "Nominal gross domestic product", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 65, + "member_digest": "73519eeb75639bdae33042fc844830cd46becc08e4f9122dfcd0886e9875f657", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "economicSector", + "naics", + "schoolGradeLevel" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 41, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "entity_groups": { + "observationAbout": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 2859, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 48 + }, + { + "label": "observations", + "count": 66 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 2859, + "rows_exact": true, + "series": 48, + "window": { + "start_year": 1960, + "end_year": 2025 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "bound", + "ref": "USDollar", + "label": "USDollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "AccommodationAndFoodSector", + "label": "Accommodation and food sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AdministrativeAndSupportServices", + "label": "Administrative and support services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AgriculturalSupportActivities", + "label": "Agricultural support activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Agriculture", + "label": "Agriculture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AgricultureForestryFishingSector", + "label": "Agriculture,Forestry and Fishing Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AirTransportAndSupportServices", + "label": "Air transport and support services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AllEconomicActivities", + "label": "All economic activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AnimalProduction", + "label": "Animal production" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ArtsEntertainmentRecreation", + "label": "Arts entertainment recreation" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ConstructionSector", + "label": "Construction Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Education", + "label": "Education" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ElectricitySupply", + "label": "Electricity supply" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EmployerHouseholdActivities", + "label": "Employer household activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialActivities", + "label": "FinancialActivities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialAndInsuranceActivities", + "label": "Financial and insurance activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialIntermediationServicesIndirectlyMeasured", + "label": "Financial intermediation services indirectly measured" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FishingAquaculture", + "label": "Fishing aquaculture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FoodBeveragesTobaccoManufacture", + "label": "Food beverages tobacco manufacture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ForestryLogging", + "label": "Forestry logging" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "HumanHealthAndSocialWork", + "label": "Human health and social work" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "InformationAndCommunication", + "label": "Information and communication" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "InsuranceActivities", + "label": "Insurance activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "LandTransport", + "label": "Land transport" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ManufacturingSector", + "label": "Manufacturing Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MiningQuarrying", + "label": "Mining quarrying" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherManufacturingAndRepair", + "label": "Other manufacturing and repair" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherServiceSector", + "label": "Other service sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherTransportPostalCourierActivities", + "label": "Other transport postal courier activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ProductTaxes", + "label": "Product taxes" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ProfessionalScientificTechnicalActivities", + "label": "Professional scientific technical activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PublicAdministrationAndDefence", + "label": "Public administration and defence" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PublishingBroadcastingInformationActivities", + "label": "Publishing Broadcasting Information Activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "RealEstate", + "label": "Real estate" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Telecommunications", + "label": "Telecommunications" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TransportStorageSector", + "label": "Transport and Storage" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "WaterSupplySewerageWasteManagement", + "label": "Water supply sewerage waste management" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "WholesaleRetailTradeAndRepair", + "label": "Wholesale retail trade and repair" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "BankingAndInsuranceSector", + "label": "Banking And Insurance Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Construction", + "label": "Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ElectricityGasSteamAirConditionSupply", + "label": "Electric Gas Steam Air Condition Supply" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "options": [ + { + "value": { + "ref": { + "ref": "HigherSecondaryEducation", + "label": "Higher Secondary Education" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PrePrimaryAndPrimaryEducation", + "label": "PrePrimary and Primary" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SecondaryEducation", + "label": "SecondaryEducation" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "USDollar", + "label": "USDollar" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "XAF", + "label": "XAF" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec" + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [], + "related_group": { + "ref": "dc/g/EconomicActivity_ActivitySource-GrossDomesticProduction", + "label": "Economic Activity With Activity Source = Gross Domestic Production" + }, + "related_measures": [ + { + "stat_var": { + "ref": "GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "label": "Gross domestic product growth rate" + }, + "definition": { + "schema_version": 1, + "spec_id": "spec_df3e3c939162b3cfe113d2d78d4b4986", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "growthRate" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + } + ] + } + } + }, + { + "variable_text": "debt", + "warnings": [ + { + "code": "retrieval_score_weak", + "severity": "info", + "message": "the chosen reading's match to the query is weak; treat it with less confidence than a strong match." + }, + { + "code": "time_window_defaulted", + "severity": "warn", + "message": "no time_text was given; the answer was resolved across every period with data." + } + ], + "timing_ms": { + "total": 2327, + "by_step": { + "recall": 0, + "shape_arcs": 1, + "shape_probe_coverage": 3, + "shape_probe": 218, + "shape_groups": 1, + "shape_labels": 0, + "shape_admission": 1, + "shape": 817, + "bind": 1494, + "materialise": 5, + "answer": 11 + } + }, + "rendered_sentence": "2 readings. Kenya's outstanding external debt owed to the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 1973 to 2024 · Current US dollars. Commitments of public or publicly guaranteed external debt (debt instrument), by creditor to Kenya from the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 2023 · Current US dollars.", + "sentence_plan": [ + { + "kind": "text", + "text": "2 readings.", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "outstanding external debt", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " owed to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Bank International Debt Statistics (IDS)", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "1973 to 2024", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Commitments of public or publicly guaranteed external debt (debt instrument), by creditor", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " from ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Bank International Debt Statistics (IDS)", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2023", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "debt", + "entities": [ + { + "text": "Sub-Saharan Africa", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "candidates", + "candidates": { + "ordering": "intent_rank", + "max_candidates": 6, + "specs": [ + { + "spec_id": "spec_db19b572801b0e2db437bf4722826ef1", + "definition": { + "schema_version": 1, + "spec_id": "spec_db19b572801b0e2db437bf4722826ef1", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialPosition", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "financialPositionType", + "binding": { + "state": "unbound" + } + }, + { + "property": "financingResource", + "binding": { + "state": "unbound" + } + }, + { + "property": "guaranteeStatus", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsConcessionality", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsCreditorType", + "binding": { + "state": "unbound" + } + }, + { + "property": "idsDebtorType", + "binding": { + "state": "unbound" + } + }, + { + "property": "includesIMFCredit", + "binding": { + "state": "unbound" + } + }, + { + "property": "interestRateVariability", + "binding": { + "state": "unbound" + } + }, + { + "property": "maturityBand", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialposition_amount_measuredvalue_nominal_by_role", + "label": "Outstanding external debt, by creditor", + "population_type": { + "ref": "FinancialPosition", + "label": "financial position" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "financialPositionType", + "label": "financial position type" + }, + "label": "financial position type" + }, + { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + { + "axis": "how", + "property": { + "ref": "interestRateVariability", + "label": "interest rate variability" + }, + "label": "interest rate variability" + }, + { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 85, + "member_digest": "59b8172b4da7c06ded4825c4f3f96a3b90414a056cb5c6447595c6be1748066b", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialPositionType", + "label": "financial position type" + }, + "label": "financial position type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "interestRateVariability", + "label": "interest rate variability" + }, + "label": "interest rate variability" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "guaranteeStatus", + "idsDebtorType", + "idsCreditorType", + "financingResource", + "interestRateVariability", + "idsConcessionality", + "includesIMFCredit", + "maturityBand" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1973", + "end": "2024" + }, + "source_codes": [ + { + "provenance": "provenance/WorldBankInternationalDebtStatistics", + "code": "DT.DOD.DECT.CD" + } + ] + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "origin" + } + ], + "entity_groups": { + "origin": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 13, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 11 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2024, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 0, + "series": 0, + "role_counts": {} + } + ] + }, + "download": { + "rows": 13, + "rows_exact": true, + "series": 2, + "window": { + "start_year": 1973, + "end_year": 2024 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialPositionType", + "label": "financial position type" + }, + "label": "financial position type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "AmountOutstanding", + "label": "amount outstanding" + }, + "value_kind": "enum_value" + }, + "served_rows": 13, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "options": [ + { + "value": { + "ref": { + "ref": "PublicOrPubliclyGuaranteed", + "label": "public or publicly guaranteed" + }, + "value_kind": "enum_value" + }, + "served_rows": 13, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSDebtorTypeGG", + "label": "general government (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 2, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSDebtorTypePS", + "label": "public sector (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 13, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSDebtorTypeOPS", + "label": "other public sector (IDS debtor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 11, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSCreditorTypePRVT", + "label": "private creditors (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 2, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypeBLAT", + "label": "bilateral (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 11, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypeOFFT", + "label": "official creditors (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 11, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "IDSCreditorTypePCBK", + "label": "commercial banks (IDS creditor type)" + }, + "value_kind": "enum_value" + }, + "served_rows": 2, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "options": [ + { + "value": { + "ref": { + "ref": "DebtInstrument", + "label": "debt instrument" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Loan", + "label": "loan" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SDRAllocation", + "label": "SDR allocation" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "interestRateVariability", + "label": "interest rate variability" + }, + "label": "interest rate variability" + }, + "options": [ + { + "value": { + "ref": { + "ref": "VariableInterestRate", + "label": "variable interest rate" + }, + "value_kind": "enum_value" + }, + "served_rows": 2, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IDSConcessional", + "label": "concessional (IDS concessionality)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "IDSNonConcessional", + "label": "non-concessional (IDS concessionality)" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "options": [ + { + "value": { + "ref": { + "ref": "WithoutIMFCredit", + "label": "without IMF credit" + }, + "value_kind": "enum_value" + }, + "served_rows": 13, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "options": [ + { + "value": { + "ref": { + "ref": "LongTermMaturity", + "label": "long-term maturity" + }, + "value_kind": "enum_value" + }, + "served_rows": 26, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Kenya's outstanding external debt owed to the 48 countries in Sub-Saharan Africa, 1973 to 2024. Current US dollars · World Bank International Debt Statistics (IDS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "outstanding external debt", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialPositionType", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " owed to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financingResource", + "binding_ref": "how:financingResource", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "guaranteeStatus", + "binding_ref": "how:guaranteeStatus", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsConcessionality", + "binding_ref": "how:idsConcessionality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsCreditorType", + "binding_ref": "how:idsCreditorType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "idsDebtorType", + "binding_ref": "how:idsDebtorType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "includesIMFCredit", + "binding_ref": "how:includesIMFCredit", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "interestRateVariability", + "binding_ref": "how:interestRateVariability", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "maturityBand", + "binding_ref": "how:maturityBand", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialPositionType", + "binding_ref": "how:financialPositionType", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1973 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Bank International Debt Statistics (IDS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialPositionType", + "label": "financial position type" + }, + "label": "financial position type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsDebtorType", + "label": "IDS debtor type" + }, + "label": "IDS debtor type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsCreditorType", + "label": "IDS creditor type" + }, + "label": "IDS creditor type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "interestRateVariability", + "label": "interest rate variability" + }, + "label": "interest rate variability" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "idsConcessionality", + "label": "IDS concessionality" + }, + "label": "IDS concessionality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "includesIMFCredit", + "label": "includes IMF credit" + }, + "label": "includes IMF credit" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "maturityBand", + "label": "maturity band" + }, + "label": "maturity band" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "low", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [], + "open_axis_facts": [ + { + "property": "financialPositionType", + "varies": false, + "value": { + "ref": "AmountOutstanding", + "label": "amount outstanding" + }, + "distinct_count": 1, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "AmountOutstanding", + "label": "amount outstanding" + }, + "count": 1 + } + ] + } + ] + } + }, + { + "spec_id": "spec_6eb3e2b7e6bc64c3f0ae0ac0d41c9b3c", + "definition": { + "schema_version": 1, + "spec_id": "spec_6eb3e2b7e6bc64c3f0ae0ac0d41c9b3c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialObligation", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "financialObligationType", + "binding": { + "state": "value", + "ref": "Commitment" + } + }, + { + "property": "financingResource", + "binding": { + "state": "value", + "ref": "DebtInstrument" + } + }, + { + "property": "guaranteeStatus", + "binding": { + "state": "value", + "ref": "PublicOrPubliclyGuaranteed" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialobligation_amount_measuredvalue_nominal_by_role", + "label": "Commitments of public or publicly guaranteed external debt (debt instrument), by creditor", + "population_type": { + "ref": "FinancialObligation", + "label": "financial obligation" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "financialObligationType", + "label": "financial obligation type" + }, + "label": "financial obligation type" + }, + { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "9c8389fcc18b49e94e1286c629ec5260fce8837ba425bc60c6f31d333d34a73c", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialObligationType", + "label": "financial obligation type" + }, + "label": "financial obligation type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Commitment", + "label": "commitment" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "DebtInstrument", + "label": "debt instrument" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "PublicOrPubliclyGuaranteed", + "label": "public or publicly guaranteed" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2023", + "end": "2023" + }, + "source_codes": [ + { + "provenance": "provenance/WorldBankInternationalDebtStatistics", + "code": "DT.COM.DPPG.CD", + "exact": true + } + ] + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "origin" + } + ], + "entity_groups": { + "origin": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 1, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 1 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "headline": { + "year": 2023, + "year_named": false, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 0, + "series": 0, + "role_counts": {} + }, + { + "year": 2021, + "observations": 0, + "series": 0, + "role_counts": {} + } + ] + }, + "download": { + "rows": 1, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2023, + "end_year": 2023 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialObligationType", + "label": "financial obligation type" + }, + "label": "financial obligation type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Commitment", + "label": "commitment" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "options": [ + { + "value": { + "ref": { + "ref": "DebtInstrument", + "label": "debt instrument" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "options": [ + { + "value": { + "ref": { + "ref": "PublicOrPubliclyGuaranteed", + "label": "public or publicly guaranteed" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Commitments of public or publicly guaranteed external debt (debt instrument), by creditor to Kenya from the 48 countries in Sub-Saharan Africa in 2023. Current US dollars · World Bank International Debt Statistics (IDS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Commitments of public or publicly guaranteed external debt (debt instrument), by creditor", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialObligationType", + "how:financingResource", + "how:guaranteeStatus" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " from ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialObligationType", + "binding_ref": "how:financialObligationType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financingResource", + "binding_ref": "how:financingResource", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "guaranteeStatus", + "binding_ref": "how:guaranteeStatus", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "in 2023", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Bank International Debt Statistics (IDS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "financialObligationType", + "label": "financial obligation type" + }, + "label": "financial obligation type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Commitment", + "label": "commitment" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financingResource", + "label": "financing resource" + }, + "label": "financing resource" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "DebtInstrument", + "label": "debt instrument" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "guaranteeStatus", + "label": "guarantee status" + }, + "label": "guarantee status" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "PublicOrPubliclyGuaranteed", + "label": "public or publicly guaranteed" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "low", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "truncated": false + }, + "reading_assumptions": { + "spec_db19b572801b0e2db437bf4722826ef1": [], + "spec_6eb3e2b7e6bc64c3f0ae0ac0d41c9b3c": [] + } + } + ], + "rendered_sentence": "Answered 1 of 2 parts. GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators. This shows the 48 countries in Sub-Saharan Africa, each on its own. Debt has 2 readings. Kenya's outstanding external debt owed to the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 1973 to 2024 · Current US dollars. Commitments of public or publicly guaranteed external debt (debt instrument), by creditor to Kenya from the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 2023 · Current US dollars.", + "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "This shows the 48 countries in Sub-Saharan Africa, each on its own.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Debt", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " has 2 readings.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "outstanding external debt", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " owed to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "World Bank International Debt Statistics (IDS)", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "1973 to 2024", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "Commitments of public or publicly guaranteed external debt (debt instrument), by creditor", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " from ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "World Bank International Debt Statistics (IDS)", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "2023", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + } + ], + "status": "mixed" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "mixed", + "sentence": "Answered 1 of 2 parts. GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators. You asked for sub-Saharan Africa. This shows the countries in it, each on its own. Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "unsupported", + "options": 0 + }, + { + "part": 1, + "kind": "choice", + "options": 2 + } + ] + } + }, + { + "answer": { + "kind": "resolution", + "status": "mixed", + "sentence": "Answered 1 of 2 parts. GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators. This shows the 48 countries in Sub-Saharan Africa, each on its own. Debt has 2 readings. Kenya's outstanding external debt owed to the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 1973 to 2024 · Current US dollars. Commitments of public or publicly guaranteed external debt (debt instrument), by creditor to Kenya from the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 2023 · Current US dollars.", + "complete": false, + "specs": [ + "spec_3c3d4e571162850b30db0321638f955b" + ], + "gaps": [ + { + "part": 1, + "kind": "choice", + "options": 2 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-part-without-variable-text.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-part-without-variable-text.json new file mode 100644 index 0000000..96be9af --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-part-without-variable-text.json @@ -0,0 +1,4529 @@ +{ + "format_version": 1, + "name": "choose-refused-part-without-variable-text", + "description": "An identity entry carries its part's variable_text, so a part without one cannot be posted back and the choice raises InvalidRequestError with no request.", + "origin": { + "kind": "synthetic", + "derived_from": "choose-option-beside-definite", + "edit": "Part 0, the definite part, loses its variable_text." + }, + "call": [ + { + "op": "search", + "question": "GDP of sub-Saharan Africa, and debt of Kenya" + }, + { + "op": "choose", + "part": 1, + "option": 0 + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "GDP of sub-Saharan Africa, and debt of Kenya" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "GDP of sub-Saharan Africa, and debt of Kenya", + "normalized_query": "GDP of sub-Saharan Africa, and debt of Kenya", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "36b57c8d82ea4b938e42ca11105ac21c", + "warnings": [], + "timing_ms": { + "total": 4230, + "by_step": { + "coverage": 0, + "extract": 875 + } + }, + "llm_usage": { + "input_tokens": 12972, + "output_tokens": 920, + "cached_tokens": 5719 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "warnings": [], + "timing_ms": { + "total": 2775, + "by_step": { + "recall": 0, + "shape_arcs": 3, + "shape_probe_coverage": 4, + "shape_probe": 298, + "shape_groups": 17, + "shape_labels": 4, + "shape_admission": 1, + "shape": 1305, + "bind": 1041, + "materialise": 182, + "answer": 5, + "options": 242 + } + }, + "restatement": { + "variable_text": "GDP", + "entities": [ + { + "text": "Sub-Saharan Africa" + }, + { + "text": "Kenya" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [ + { + "code": "group_read_as_members", + "binding_ref": "where:", + "asked": "sub-Saharan Africa", + "text": "You asked for sub-Saharan Africa. This shows the countries in it, each on its own." + } + ], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_3c3d4e571162850b30db0321638f955b", + "definition": { + "schema_version": 1, + "spec_id": "spec_3c3d4e571162850b30db0321638f955b", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + }, + { + "property": "economicSector", + "binding": { + "state": "unbound" + } + }, + { + "property": "naics", + "binding": { + "state": "unbound" + } + }, + { + "property": "schoolGradeLevel", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "USDollar" + } + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_nominal", + "label": "Nominal gross domestic product", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 65, + "member_digest": "73519eeb75639bdae33042fc844830cd46becc08e4f9122dfcd0886e9875f657", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "economicSector", + "naics", + "schoolGradeLevel" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 41, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "entity_groups": { + "observationAbout": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 2859, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 48 + }, + { + "label": "observations", + "count": 66 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 2859, + "rows_exact": true, + "series": 48, + "window": { + "start_year": 1960, + "end_year": 2025 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "bound", + "ref": "USDollar", + "label": "USDollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossValueAdded", + "label": "GrossValueAdded" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NetDomesticProduction", + "label": "Net Domestic Production" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NetValueAdded", + "label": "Net Value Added" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "AgricultureForestryFishingSector", + "label": "Agriculture,Forestry and Fishing Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ConstructionSector", + "label": "Construction Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ElectricityGasSteamAirConditionSupply", + "label": "Electric Gas Steam Air Condition Supply" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinanceService", + "label": "Finance Service" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MOSPI_OtherService", + "label": "MOSPI Other Service" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ManufacturingSector", + "label": "Manufacturing Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MiningQuarrying", + "label": "Mining quarrying" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TradeSector", + "label": "Trade Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AccommodationAndFoodSector", + "label": "Accommodation and food sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AdministrativeAndSupportServices", + "label": "Administrative and support services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AgriculturalSupportActivities", + "label": "Agricultural support activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Agriculture", + "label": "Agriculture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AirTransportAndSupportServices", + "label": "Air transport and support services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AllEconomicActivities", + "label": "All economic activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AnimalProduction", + "label": "Animal production" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ArtsEntertainmentRecreation", + "label": "Arts entertainment recreation" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Education", + "label": "Education" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ElectricitySupply", + "label": "Electricity supply" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EmployerHouseholdActivities", + "label": "Employer household activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialActivities", + "label": "FinancialActivities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialAndInsuranceActivities", + "label": "Financial and insurance activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialIntermediationServicesIndirectlyMeasured", + "label": "Financial intermediation services indirectly measured" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FishingAquaculture", + "label": "Fishing aquaculture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FoodBeveragesTobaccoManufacture", + "label": "Food beverages tobacco manufacture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ForestryLogging", + "label": "Forestry logging" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "HumanHealthAndSocialWork", + "label": "Human health and social work" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "InformationAndCommunication", + "label": "Information and communication" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "InsuranceActivities", + "label": "Insurance activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "LandTransport", + "label": "Land transport" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherManufacturingAndRepair", + "label": "Other manufacturing and repair" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherServiceSector", + "label": "Other service sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherTransportPostalCourierActivities", + "label": "Other transport postal courier activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ProductTaxes", + "label": "Product taxes" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ProfessionalScientificTechnicalActivities", + "label": "Professional scientific technical activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PublicAdministrationAndDefence", + "label": "Public administration and defence" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PublishingBroadcastingInformationActivities", + "label": "Publishing Broadcasting Information Activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "RealEstate", + "label": "Real estate" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Telecommunications", + "label": "Telecommunications" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TransportStorageSector", + "label": "Transport and Storage" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "WaterSupplySewerageWasteManagement", + "label": "Water supply sewerage waste management" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "WholesaleRetailTradeAndRepair", + "label": "Wholesale retail trade and repair" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "BankingAndInsuranceSector", + "label": "Banking And Insurance Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Construction", + "label": "Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialServices", + "label": "Financial Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Industry", + "label": "Industry" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Services", + "label": "Services" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "options": [ + { + "value": { + "ref": { + "ref": "NAICS/23", + "label": "Construction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/44-45", + "label": "Retail trade" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/53", + "label": "Real estate and rental and leasing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/22", + "label": "Utilities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/55", + "label": "Management of companies and enterprises" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/48-49", + "label": "Transportation and warehousing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/61", + "label": "Educational services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/51", + "label": "Information" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/42", + "label": "Wholesale trade" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/21", + "label": "Mining, quarrying, and oil and gas extraction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/11", + "label": "Agriculture, forestry, fishing and hunting" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/72", + "label": "Accommodation and food services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/52", + "label": "Finance and insurance" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/54", + "label": "Professional, Scientific, and Technical Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/71", + "label": "Arts, entertainment, and recreation" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/311-316_322-326", + "label": "Durable Goods Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/31-33", + "label": "Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/321_327-339", + "label": "Durable Goods Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/56", + "label": "Administrative and Support and Waste Management Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/62", + "label": "Health care and social assistance" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/81", + "label": "Other services, except public administration" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/92", + "label": "Public administration" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "options": [ + { + "value": { + "ref": { + "ref": "HigherSecondaryEducation", + "label": "Higher Secondary Education" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PrePrimaryAndPrimaryEducation", + "label": "PrePrimary and Primary" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SecondaryEducation", + "label": "SecondaryEducation" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "USDollar", + "label": "USDollar" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "XAF", + "label": "XAF" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAccommodationFoodServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSFinanceInsurance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSMiningQuarryingOilGasExtraction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSProfessionalScientificTechnicalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSWholesaleTrade_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826", + "dc/zz6gwv838v9w" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "equivalent_readings": [ + { + "spec_id": "spec_22cfb22f6e4a1cff1584eaf03285ce73", + "definition": { + "schema_version": 1, + "spec_id": "spec_22cfb22f6e4a1cff1584eaf03285ce73", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicProduction", + "measured_property": "valueAdded", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "currencyConversionBasis", + "binding": { + "state": "unbound" + } + }, + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + }, + { + "property": "productTaxBasis", + "binding": { + "state": "value", + "ref": "IncludingProductTaxes" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "CurrencyUSD" + } + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicproduction_valueadded_measuredvalue_nominal", + "label": "Gross domestic product (GDP)", + "population_type": { + "ref": "EconomicProduction", + "label": "economic production" + }, + "measured_property": { + "ref": "valueAdded", + "label": "value added" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 2, + "member_digest": "ef9c4356618ed98aab762248e68799d78c74ad249a6041dad0e8a345c85ee02f", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "currencyConversionBasis" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 2, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1980", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "entity_groups": { + "observationAbout": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 2031, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 48 + }, + { + "label": "observations", + "count": 46 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 2031, + "rows_exact": true, + "series": 48, + "window": { + "start_year": 1980, + "end_year": 2025 + }, + "licence": { + "label": "IMF Copyright and Usage" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/IMFWorldEconomicOutlook", + "label": "IMF World Economic Outlook (WEO)", + "source": { + "ref": "source/InternationalMonetaryFund", + "label": "International Monetary Fund (IMF)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/IMFWorldEconomicOutlook" + }, + "unit": { + "basis": "bound", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "PurchasingPowerParityRate", + "label": "purchasing power parity rate" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [], + "trace": { + "resolved_entities": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "provenance/IMFWorldEconomicOutlook", + "label": "IMF World Economic Outlook (WEO)", + "source": { + "ref": "source/InternationalMonetaryFund", + "label": "International Monetary Fund (IMF)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/IMFWorldEconomicOutlook" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAccommodationFoodServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSFinanceInsurance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSMiningQuarryingOilGasExtraction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSProfessionalScientificTechnicalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSWholesaleTrade_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826", + "dc/zz6gwv838v9w" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "measure_label_axes": [], + "measure_axis_values": [], + "related_group": { + "ref": "dc/g/EconomicActivity_ActivitySource-GrossDomesticProduction", + "label": "Economic Activity With Activity Source = Gross Domestic Production" + }, + "related_measures": [ + { + "stat_var": { + "ref": "GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "label": "Gross domestic product growth rate" + }, + "definition": { + "schema_version": 1, + "spec_id": "spec_df3e3c939162b3cfe113d2d78d4b4986", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "growthRate" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + } + ] + } + } + }, + { + "variable_text": "debt", + "warnings": [ + { + "code": "retrieval_score_weak", + "severity": "info", + "message": "the chosen reading's match to the query is weak; treat it with less confidence than a strong match." + } + ], + "timing_ms": { + "total": 2694, + "by_step": { + "recall": 1, + "shape_arcs": 1, + "shape_probe_coverage": 4, + "shape_probe": 287, + "shape_groups": 2, + "shape_labels": 0, + "shape_admission": 0, + "shape": 1117, + "bind": 1576 + } + }, + "rendered_sentence": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "sentence_plan": [ + { + "kind": "text", + "text": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "operations": [], + "departures": [], + "assumptions": [], + "status": "no_data", + "no_data": { + "reason": "role_not_resolved", + "category": "unresolved", + "message": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "entity_terms": [ + "sub-Saharan Africa", + "Kenya" + ], + "ambiguous_entities": [], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "sub-Saharan Africa", + "Kenya" + ], + "label": "sub-Saharan Africa to Kenya", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "debt", + "entities": [ + { + "text": "Sub-Saharan Africa", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "sub-Saharan Africa", + "Kenya" + ], + "label": "Kenya to sub-Saharan Africa", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "debt", + "entities": [ + { + "text": "Sub-Saharan Africa", + "role_text": "to" + }, + { + "text": "Kenya", + "role_text": "from" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + ] + } + } + ], + "rendered_sentence": "Answered 1 of 2 parts. GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators. You asked for sub-Saharan Africa. This shows the countries in it, each on its own. Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "You asked for sub-Saharan Africa. This shows the countries in it, each on its own.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + } + ], + "status": "mixed" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "mixed", + "sentence": "Answered 1 of 2 parts. GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators. You asked for sub-Saharan Africa. This shows the countries in it, each on its own. Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "complete": false, + "specs": [ + "spec_3c3d4e571162850b30db0321638f955b" + ], + "gaps": [ + { + "part": 1, + "kind": "choice", + "options": 2 + } + ] + } + }, + { + "error": { + "class": "InvalidRequestError", + "code": "choice_invalid" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-label.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-label.json new file mode 100644 index 0000000..a75ce8d --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-label.json @@ -0,0 +1,266 @@ +{ + "format_version": 1, + "name": "choose-refused-shared-label", + "description": "A label two options share matches several, so choosing by it raises InvalidRequestError with no request.", + "origin": { + "kind": "synthetic", + "derived_from": "choose-place-one-part", + "edit": "The no_data part's second option takes the first one's label." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + }, + { + "op": "choose", + "option": "Congo [DRC]" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Congo", + "normalized_query": "ODA disbursements from Germany to Congo", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "9c755dc7ffaf4568afe68d812e56d8fa", + "warnings": [], + "timing_ms": { + "total": 1084, + "by_step": { + "coverage": 0, + "extract": 1082 + } + }, + "llm_usage": { + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 0, + "by_step": { + "recall": 0 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + ] + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "no_data" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "no_data", + "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 2 + } + ] + } + }, + { + "error": { + "class": "InvalidRequestError", + "code": "choice_invalid" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-status.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-status.json new file mode 100644 index 0000000..97d3e91 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-status.json @@ -0,0 +1,4520 @@ +{ + "format_version": 1, + "name": "choose-refused-unknown-status", + "description": "A part of a status the client does not know, with no restatement, cannot be posted back, so the choice raises InvalidRequestError with no request.", + "origin": { + "kind": "synthetic", + "derived_from": "choose-option-beside-definite", + "edit": "Part 0 takes the status \"deferred\" and loses its restatement." + }, + "call": [ + { + "op": "search", + "question": "GDP of sub-Saharan Africa, and debt of Kenya" + }, + { + "op": "choose", + "part": 1, + "option": 0 + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "GDP of sub-Saharan Africa, and debt of Kenya" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "GDP of sub-Saharan Africa, and debt of Kenya", + "normalized_query": "GDP of sub-Saharan Africa, and debt of Kenya", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "36b57c8d82ea4b938e42ca11105ac21c", + "warnings": [], + "timing_ms": { + "total": 4230, + "by_step": { + "coverage": 0, + "extract": 875 + } + }, + "llm_usage": { + "input_tokens": 12972, + "output_tokens": 920, + "cached_tokens": 5719 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GDP", + "warnings": [], + "timing_ms": { + "total": 2775, + "by_step": { + "recall": 0, + "shape_arcs": 3, + "shape_probe_coverage": 4, + "shape_probe": 298, + "shape_groups": 17, + "shape_labels": 4, + "shape_admission": 1, + "shape": 1305, + "bind": 1041, + "materialise": 182, + "answer": 5, + "options": 242 + } + }, + "operations": [], + "departures": [ + { + "code": "group_read_as_members", + "binding_ref": "where:", + "asked": "sub-Saharan Africa", + "text": "You asked for sub-Saharan Africa. This shows the countries in it, each on its own." + } + ], + "assumptions": [], + "status": "deferred", + "spec": { + "spec_id": "spec_3c3d4e571162850b30db0321638f955b", + "definition": { + "schema_version": 1, + "spec_id": "spec_3c3d4e571162850b30db0321638f955b", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + }, + { + "property": "economicSector", + "binding": { + "state": "unbound" + } + }, + { + "property": "naics", + "binding": { + "state": "unbound" + } + }, + { + "property": "schoolGradeLevel", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "USDollar" + } + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_nominal", + "label": "Nominal gross domestic product", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 65, + "member_digest": "73519eeb75639bdae33042fc844830cd46becc08e4f9122dfcd0886e9875f657", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "economicSector", + "naics", + "schoolGradeLevel" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 41, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "entity_groups": { + "observationAbout": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 2859, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 48 + }, + { + "label": "observations", + "count": 66 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 2859, + "rows_exact": true, + "series": 48, + "window": { + "start_year": 1960, + "end_year": 2025 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "bound", + "ref": "USDollar", + "label": "USDollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossValueAdded", + "label": "GrossValueAdded" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NetDomesticProduction", + "label": "Net Domestic Production" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NetValueAdded", + "label": "Net Value Added" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "AgricultureForestryFishingSector", + "label": "Agriculture,Forestry and Fishing Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ConstructionSector", + "label": "Construction Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ElectricityGasSteamAirConditionSupply", + "label": "Electric Gas Steam Air Condition Supply" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinanceService", + "label": "Finance Service" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MOSPI_OtherService", + "label": "MOSPI Other Service" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ManufacturingSector", + "label": "Manufacturing Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MiningQuarrying", + "label": "Mining quarrying" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TradeSector", + "label": "Trade Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AccommodationAndFoodSector", + "label": "Accommodation and food sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AdministrativeAndSupportServices", + "label": "Administrative and support services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AgriculturalSupportActivities", + "label": "Agricultural support activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Agriculture", + "label": "Agriculture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AirTransportAndSupportServices", + "label": "Air transport and support services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AllEconomicActivities", + "label": "All economic activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AnimalProduction", + "label": "Animal production" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ArtsEntertainmentRecreation", + "label": "Arts entertainment recreation" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Education", + "label": "Education" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ElectricitySupply", + "label": "Electricity supply" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EmployerHouseholdActivities", + "label": "Employer household activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialActivities", + "label": "FinancialActivities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialAndInsuranceActivities", + "label": "Financial and insurance activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialIntermediationServicesIndirectlyMeasured", + "label": "Financial intermediation services indirectly measured" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FishingAquaculture", + "label": "Fishing aquaculture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FoodBeveragesTobaccoManufacture", + "label": "Food beverages tobacco manufacture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ForestryLogging", + "label": "Forestry logging" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "HumanHealthAndSocialWork", + "label": "Human health and social work" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "InformationAndCommunication", + "label": "Information and communication" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "InsuranceActivities", + "label": "Insurance activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "LandTransport", + "label": "Land transport" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherManufacturingAndRepair", + "label": "Other manufacturing and repair" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherServiceSector", + "label": "Other service sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherTransportPostalCourierActivities", + "label": "Other transport postal courier activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ProductTaxes", + "label": "Product taxes" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ProfessionalScientificTechnicalActivities", + "label": "Professional scientific technical activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PublicAdministrationAndDefence", + "label": "Public administration and defence" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PublishingBroadcastingInformationActivities", + "label": "Publishing Broadcasting Information Activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "RealEstate", + "label": "Real estate" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Telecommunications", + "label": "Telecommunications" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TransportStorageSector", + "label": "Transport and Storage" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "WaterSupplySewerageWasteManagement", + "label": "Water supply sewerage waste management" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "WholesaleRetailTradeAndRepair", + "label": "Wholesale retail trade and repair" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "BankingAndInsuranceSector", + "label": "Banking And Insurance Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Construction", + "label": "Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialServices", + "label": "Financial Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Industry", + "label": "Industry" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Services", + "label": "Services" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "options": [ + { + "value": { + "ref": { + "ref": "NAICS/23", + "label": "Construction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/44-45", + "label": "Retail trade" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/53", + "label": "Real estate and rental and leasing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/22", + "label": "Utilities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/55", + "label": "Management of companies and enterprises" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/48-49", + "label": "Transportation and warehousing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/61", + "label": "Educational services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/51", + "label": "Information" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/42", + "label": "Wholesale trade" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/21", + "label": "Mining, quarrying, and oil and gas extraction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/11", + "label": "Agriculture, forestry, fishing and hunting" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/72", + "label": "Accommodation and food services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/52", + "label": "Finance and insurance" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/54", + "label": "Professional, Scientific, and Technical Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/71", + "label": "Arts, entertainment, and recreation" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/311-316_322-326", + "label": "Durable Goods Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/31-33", + "label": "Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/321_327-339", + "label": "Durable Goods Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/56", + "label": "Administrative and Support and Waste Management Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/62", + "label": "Health care and social assistance" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/81", + "label": "Other services, except public administration" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/92", + "label": "Public administration" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "options": [ + { + "value": { + "ref": { + "ref": "HigherSecondaryEducation", + "label": "Higher Secondary Education" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PrePrimaryAndPrimaryEducation", + "label": "PrePrimary and Primary" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SecondaryEducation", + "label": "SecondaryEducation" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "USDollar", + "label": "USDollar" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "XAF", + "label": "XAF" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAccommodationFoodServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSFinanceInsurance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSMiningQuarryingOilGasExtraction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSProfessionalScientificTechnicalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSWholesaleTrade_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826", + "dc/zz6gwv838v9w" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "equivalent_readings": [ + { + "spec_id": "spec_22cfb22f6e4a1cff1584eaf03285ce73", + "definition": { + "schema_version": 1, + "spec_id": "spec_22cfb22f6e4a1cff1584eaf03285ce73", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicProduction", + "measured_property": "valueAdded", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "currencyConversionBasis", + "binding": { + "state": "unbound" + } + }, + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + }, + { + "property": "productTaxBasis", + "binding": { + "state": "value", + "ref": "IncludingProductTaxes" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "CurrencyUSD" + } + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicproduction_valueadded_measuredvalue_nominal", + "label": "Gross domestic product (GDP)", + "population_type": { + "ref": "EconomicProduction", + "label": "economic production" + }, + "measured_property": { + "ref": "valueAdded", + "label": "value added" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 2, + "member_digest": "ef9c4356618ed98aab762248e68799d78c74ad249a6041dad0e8a345c85ee02f", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "currencyConversionBasis" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 2, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1980", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "entity_groups": { + "observationAbout": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 2031, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 48 + }, + { + "label": "observations", + "count": 46 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 2031, + "rows_exact": true, + "series": 48, + "window": { + "start_year": 1980, + "end_year": 2025 + }, + "licence": { + "label": "IMF Copyright and Usage" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/IMFWorldEconomicOutlook", + "label": "IMF World Economic Outlook (WEO)", + "source": { + "ref": "source/InternationalMonetaryFund", + "label": "International Monetary Fund (IMF)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/IMFWorldEconomicOutlook" + }, + "unit": { + "basis": "bound", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "PurchasingPowerParityRate", + "label": "purchasing power parity rate" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [], + "trace": { + "resolved_entities": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "provenance/IMFWorldEconomicOutlook", + "label": "IMF World Economic Outlook (WEO)", + "source": { + "ref": "source/InternationalMonetaryFund", + "label": "International Monetary Fund (IMF)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/IMFWorldEconomicOutlook" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAccommodationFoodServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSFinanceInsurance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSMiningQuarryingOilGasExtraction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSProfessionalScientificTechnicalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSWholesaleTrade_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826", + "dc/zz6gwv838v9w" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "measure_label_axes": [], + "measure_axis_values": [], + "related_group": { + "ref": "dc/g/EconomicActivity_ActivitySource-GrossDomesticProduction", + "label": "Economic Activity With Activity Source = Gross Domestic Production" + }, + "related_measures": [ + { + "stat_var": { + "ref": "GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "label": "Gross domestic product growth rate" + }, + "definition": { + "schema_version": 1, + "spec_id": "spec_df3e3c939162b3cfe113d2d78d4b4986", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "growthRate" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + } + ] + } + } + }, + { + "variable_text": "debt", + "warnings": [ + { + "code": "retrieval_score_weak", + "severity": "info", + "message": "the chosen reading's match to the query is weak; treat it with less confidence than a strong match." + } + ], + "timing_ms": { + "total": 2694, + "by_step": { + "recall": 1, + "shape_arcs": 1, + "shape_probe_coverage": 4, + "shape_probe": 287, + "shape_groups": 2, + "shape_labels": 0, + "shape_admission": 0, + "shape": 1117, + "bind": 1576 + } + }, + "rendered_sentence": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "sentence_plan": [ + { + "kind": "text", + "text": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "operations": [], + "departures": [], + "assumptions": [], + "status": "no_data", + "no_data": { + "reason": "role_not_resolved", + "category": "unresolved", + "message": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "entity_terms": [ + "sub-Saharan Africa", + "Kenya" + ], + "ambiguous_entities": [], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "sub-Saharan Africa", + "Kenya" + ], + "label": "sub-Saharan Africa to Kenya", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "debt", + "entities": [ + { + "text": "Sub-Saharan Africa", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "sub-Saharan Africa", + "Kenya" + ], + "label": "Kenya to sub-Saharan Africa", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "debt", + "entities": [ + { + "text": "Sub-Saharan Africa", + "role_text": "to" + }, + { + "text": "Kenya", + "role_text": "from" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + ] + } + } + ], + "rendered_sentence": "Answered 1 of 2 parts. GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators. You asked for sub-Saharan Africa. This shows the countries in it, each on its own. Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "You asked for sub-Saharan Africa. This shows the countries in it, each on its own.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + } + ], + "status": "mixed" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "mixed", + "sentence": "Answered 1 of 2 parts. GDP in the 48 countries in Sub-Saharan Africa, 1960 to 2025. Current US dollars · World Development Indicators. You asked for sub-Saharan Africa. This shows the countries in it, each on its own. Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "unknown", + "options": 0 + }, + { + "part": 1, + "kind": "choice", + "options": 2 + } + ] + } + }, + { + "error": { + "class": "InvalidRequestError", + "code": "choice_invalid" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-503-then-504.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-503-then-504.json new file mode 100644 index 0000000..8a18b8e --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-503-then-504.json @@ -0,0 +1,1135 @@ +{ + "format_version": 1, + "name": "fetch-spec-503-then-504", + "description": "A 504 that cuts off the first retry is the first cut-off, so the build is posted once more, the second of its two retries, after waits of 0.5 and 1 seconds, and reaches the same dataset.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "A 503 service_unavailable answers the build, and a 504 timeout its first retry." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 503, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/service_unavailable", + "title": "Service Unavailable", + "status": 503, + "detail": "The service is busy.", + "code": "service_unavailable", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": true + } + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 504, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/timeout", + "title": "Gateway Timeout", + "status": 504, + "detail": "The build passed its 120 s limit.", + "code": "timeout", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": true + } + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "prepared_at": "2026-10-21T08:57:50Z", + "coverage": { + "rows": 4, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 4 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "head", + "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal, which hold none at the observation period the other members serve in the requested years." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9541, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:50.451120+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + { + "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", + "rendering": { + "statistics": "series" + }, + "bytes": 5741, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:50.451120+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" + } + ], + "series_count": 1, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 4 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:50.451687Z" + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "fetch-spec-known-sentence.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 4, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "crsCooperationModality", + "crsCooperationModality_label", + "crsPurpose", + "crsPurpose_label", + "crsTypeOfFinance", + "crsTypeOfFinance_label", + "crsTypeOfFlow", + "crsTypeOfFlow_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + ], + "missing": [], + "retry_waits": [ + 0.5, + 1.0 + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-then-503.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-then-503.json new file mode 100644 index 0000000..1cf4d40 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-then-503.json @@ -0,0 +1,305 @@ +{ + "format_version": 1, + "name": "fetch-spec-504-then-503", + "description": "After a 504 cut-off the build is posted once more only, so the 503 that answers that post raises its ServerError although one retry of the two is left.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "A 504 timeout answers the build, and a 503 service_unavailable its one retry." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 504, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/timeout", + "title": "Gateway Timeout", + "status": 504, + "detail": "The build passed its 120 s limit.", + "code": "timeout", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": true + } + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 503, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/service_unavailable", + "title": "Service Unavailable", + "status": 503, + "detail": "The service is busy.", + "code": "service_unavailable", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": true + } + } + } + ], + "expect": [ + { + "error": { + "class": "ServerError", + "code": "service_unavailable", + "retry_waits": [ + 0.5 + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-foreign-artifact-url.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-foreign-artifact-url.json new file mode 100644 index 0000000..1e30a1f --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-foreign-artifact-url.json @@ -0,0 +1,865 @@ +{ + "format_version": 1, + "name": "fetch-spec-foreign-artifact-url", + "description": "An artifact url on an origin other than the API's raises ContractError contract_violation before any request for the file.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "Every artifact url of the build's manifest becomes absolute on https://downloads.example.com, and the exchanges after the build go." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "prepared_at": "2026-10-21T08:57:50Z", + "coverage": { + "rows": 4, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 4 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "head", + "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal, which hold none at the observation period the other members serve in the requested years." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9541, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:50.451120+00:00", + "tier": "working", + "url": "https://downloads.example.com/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + { + "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", + "rendering": { + "statistics": "series" + }, + "bytes": 5741, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:50.451120+00:00", + "tier": "working", + "url": "https://downloads.example.com/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" + } + ], + "series_count": 1, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 4 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:50.451687Z" + } + } + } + } + ], + "expect": [ + { + "error": { + "class": "ContractError", + "code": "contract_violation" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json new file mode 100644 index 0000000..5fdf8ad --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json @@ -0,0 +1,800 @@ +{ + "format_version": 1, + "name": "fetch-spec-manifest-without-identity", + "description": "A manifest whose definition has no identity, a strict member, raises ContractError contract_violation on the build response, before any download.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "The build's manifest definition loses identity, and the exchanges after it go." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6" + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "prepared_at": "2026-10-21T08:57:50Z", + "coverage": { + "rows": 4, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 4 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "head", + "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal, which hold none at the observation period the other members serve in the requested years." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9541, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:50.451120+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + { + "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", + "rendering": { + "statistics": "series" + }, + "bytes": 5741, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:50.451120+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" + } + ], + "series_count": 1, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 4 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:50.451687Z" + } + } + } + } + ], + "expect": [ + { + "error": { + "class": "ContractError", + "code": "contract_violation" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json new file mode 100644 index 0000000..16b4c78 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json @@ -0,0 +1,203 @@ +{ + "format_version": 1, + "name": "fetch-spec-poll-not-found", + "description": "A refused poll that is not retryable raises its error at once, with the one poll made in long_builds.", + "origin": { + "kind": "synthetic", + "derived_from": "mint-async-build", + "edit": "As fetch-spec-async-build, with a 404 operation_not_found answering the first poll, and the exchanges after it go." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + }, + "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 202, + "headers": { + "content-type": "application/json", + "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "pending", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500 + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 404, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/operation_not_found", + "title": "Not Found", + "status": 404, + "detail": "No operation has this id.", + "code": "operation_not_found", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": false + } + } + } + ], + "expect": [ + { + "error": { + "class": "NotFoundError", + "code": "operation_not_found", + "long_builds": [ + { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll_waits": [ + 1.5 + ], + "resubmissions": 0 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused.json new file mode 100644 index 0000000..df9163b --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused.json @@ -0,0 +1,1277 @@ +{ + "format_version": 1, + "name": "fetch-spec-poll-refused", + "description": "A retryable refused poll other than a 429 spends one of the two retries, and a poll that answers restores them, so two 503s in a row after an answered poll are polled again too. A refused poll changes no pacing: the poll after it waits what the refused one waited.", + "origin": { + "kind": "synthetic", + "derived_from": "mint-async-build", + "edit": "As fetch-spec-async-build, with a 503 service_unavailable answering the first poll, and two answering the third." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + }, + "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 202, + "headers": { + "content-type": "application/json", + "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "pending", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500 + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 503, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/service_unavailable", + "title": "Service Unavailable", + "status": 503, + "detail": "The service is busy.", + "code": "service_unavailable", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": true + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 503, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/service_unavailable", + "title": "Service Unavailable", + "status": 503, + "detail": "The service is busy.", + "code": "service_unavailable", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": true + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 503, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/service_unavailable", + "title": "Service Unavailable", + "status": 503, + "detail": "The service is busy.", + "code": "service_unavailable", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": true + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1516, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1900, + "progress": { + "rows_written": 14493, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "3" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 2377, + "progress": { + "rows_written": 41372, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "3" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 2975, + "progress": { + "rows_written": 75380, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "4" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 3755, + "progress": { + "rows_written": 108798, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "done" + }, + "manifest": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "ref": "DAC2aAidType206", + "state": "value" + }, + "property": "dac2aAidType" + }, + { + "binding": { + "state": "unbound" + }, + "property": "dacTypeOfFinance" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "facets": { + "provenance": { + "ref": "provenance/OECDDAC2A", + "state": "value" + } + }, + "entities": {}, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2024, + "start_year": 2018 + } + } + }, + "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", + "prepared_at": "2026-10-21T08:58:24Z", + "coverage": { + "rows": 108798, + "dimensions": [ + { + "label": "financingProvider", + "count": 172, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 238, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 7 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 2018 + } + }, + "citation": { + "text": "OECD DAC2A (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=dac2a&pg=0&snb=1&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_DAC2%40DF_DAC2A&df[ag]=OECD.DCD.FSD&df[vs]=1.6&dq=.DPGC.206.USD.Q&lom=LASTNPERIODS&lo=5&to[TIME_PERIOD]=false&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "DAC2A is the OECD Development Assistance Committee's table of ODA disbursements by donor and recipient country or region. It covers bilateral donors and multilateral agencies reporting their own outflows, and includes the OECD's estimate of each donor's core multilateral contributions attributed to recipients.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip", + "attribution": "OECD (2026), OECD DAC2A, OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip (accessed on 2026-10-12)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1960-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The OECD publishes DAC2A in April, June, September and December. The complete table is downloaded from the OECD each time it is republished, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets. The totals DAC2A reports for groups of providers, such as all DAC countries, and for groups of recipients, such as regions and income groups, are included as providers and recipients of their own. Where two provider codes name the same organisation and report the same figures, the figures are counted once. Where two recipient codes name the same organisation, such as IDA and IDA's Multilateral Debt Relief Initiative, their flows are added." + }, + { + "transformation": "Select figures", + "description": "Only figures in current US dollars are included, not constant US dollars. Only flows to recipients on Part I of the DAC List are included: the developing countries, and the multilateral organisations DAC2A reports as recipients, such as development banks and UN agencies. Flows to Part II recipients, the countries in transition, are excluded." + }, + { + "transformation": "Convert to whole units", + "description": "DAC2A reports amounts in millions, which are converted to whole units. ODA per person and ODA as a share of GNI are kept as reported." + }, + { + "transformation": "Select dimensions", + "description": "Each figure is reported by year, provider, recipient and type of aid, such as grants, repayments, interest received, or debt forgiven or rescheduled. DAC2A is a table of disbursements, so every figure, repayments and interest included, is recorded as a disbursement. Figures are marked as gross or net, except where DAC2A does not say which, and as grants or non-grants where the type of aid is wholly one or the other. Imputed multilateral ODA, the OECD's estimate of each provider's share of multilateral organisations' ODA, is marked as modelled. ODA as a share of GNI records the recipient's GNI as its denominator, and ODA per person records the recipient's population." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "ODA disbursements by donor and recipient country or region, including the OECD's imputed multilateral contributions, and ODA per person and as a share of recipient GNI." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDDAC2A", + "axis": "provenance", + "basis": "bound", + "default_policy": null, + "selection_reason": null, + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": null + }, + { + "ref": null, + "axis": "measurementMethod", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 2018 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDDAC2A", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 108798 + } + ], + "family_member_count": 1, + "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:58:25.535416+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 913395, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:58:25.500374+00:00", + "tier": "working", + "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + }, + { + "artifact_digest": "sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93", + "rendering": { + "statistics": "series" + }, + "bytes": 967921, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:58:25.500374+00:00", + "tier": "working", + "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" + } + ], + "series_count": 21017, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 172 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 238 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 7 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 172, + "covered": 50 + }, + "missing": [ + { + "ref": "AdaptationFund", + "label": "Adaptation Fund" + }, + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentBankGroup", + "label": "African Development Bank Group" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AndrewCarnegieFoundation", + "label": "Andrew Carnegie Foundation" + }, + { + "ref": "ArabFundForEconomicAndSocialDevelopment", + "label": "Arab Fund for Economic and Social Development" + }, + { + "ref": "Arcadia", + "label": "Arcadia" + }, + { + "ref": "ArcusFoundation", + "label": "Arcus Foundation" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianInfrastructureInvestmentBank", + "label": "Asian Infrastructure Investment Bank" + } + ], + "truncated": true + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 172, + "covered": 50 + }, + "missing": [ + { + "ref": "AdaptationFund", + "label": "Adaptation Fund" + }, + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentBankGroup", + "label": "African Development Bank Group" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AndrewCarnegieFoundation", + "label": "Andrew Carnegie Foundation" + }, + { + "ref": "ArabFundForEconomicAndSocialDevelopment", + "label": "Arab Fund for Economic and Social Development" + }, + { + "ref": "Arcadia", + "label": "Arcadia" + }, + { + "ref": "ArcusFoundation", + "label": "Arcus Foundation" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianInfrastructureInvestmentBank", + "label": "Asian Infrastructure Investment Bank" + } + ], + "truncated": true + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 238, + "covered": 143 + }, + "missing": [ + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianDevelopmentBankSpecialFunds", + "label": "Asian Development Bank Special Funds" + }, + { + "ref": "CaribbeanDevelopmentBank", + "label": "Caribbean Development Bank" + }, + { + "ref": "CentralAmericanBankForEconomicIntegration", + "label": "Central American Bank for Economic Integration" + }, + { + "ref": "DACACPCountries", + "label": "ACP countries (DAC)" + }, + { + "ref": "DACAfrica", + "label": "Africa (DAC)" + }, + { + "ref": "DACAfricaUnallocated", + "label": "Africa, unallocated by country (DAC)" + }, + { + "ref": "DACAllMultilateralRecipients", + "label": "all multilateral recipients (DAC)" + } + ], + "truncated": true + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 238, + "covered": 141 + }, + "missing": [ + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianDevelopmentBankSpecialFunds", + "label": "Asian Development Bank Special Funds" + }, + { + "ref": "CaribbeanDevelopmentBank", + "label": "Caribbean Development Bank" + }, + { + "ref": "CentralAmericanBankForEconomicIntegration", + "label": "Central American Bank for Economic Integration" + }, + { + "ref": "DACACPCountries", + "label": "ACP countries (DAC)" + }, + { + "ref": "DACAfrica", + "label": "Africa (DAC)" + }, + { + "ref": "DACAfricaUnallocated", + "label": "Africa, unallocated by country (DAC)" + }, + { + "ref": "DACAllMultilateralRecipients", + "label": "all multilateral recipients (DAC)" + } + ], + "truncated": true + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "financingProvider", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 7 + } + ] + }, + { + "index": "financingProvider", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 238 + } + ] + }, + { + "index": "financingRecipient", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 7 + } + ] + }, + { + "index": "financingRecipient", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 172 + } + ] + }, + { + "index": "time_period", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 238 + } + ] + }, + { + "index": "time_period", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 172 + } + ] + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:58:25.500506Z" + } + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "mint-async-build.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 108798, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "dac2aAidType", + "dac2aAidType_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", + "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + } + ], + "missing": [], + "long_builds": [ + { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll_waits": [ + 1.5, + 1.5, + 1.5, + 1.5, + 1.5, + 1.5, + 1.5, + 1.516, + 1.9, + 2.377, + 2.975, + 3.755 + ], + "resubmissions": 0 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-same-origin-artifact-url.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-same-origin-artifact-url.json new file mode 100644 index 0000000..1ed945b --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-same-origin-artifact-url.json @@ -0,0 +1,927 @@ +{ + "format_version": 1, + "name": "fetch-spec-same-origin-artifact-url", + "description": "An absolute artifact url on the API's origin names the same files route as its root-relative form, so the client asks it as that origin_path and reaches the same dataset.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "Every artifact url of the build's manifest becomes absolute on the API's origin." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "prepared_at": "2026-10-21T08:57:50Z", + "coverage": { + "rows": 4, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 4 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "head", + "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal, which hold none at the observation period the other members serve in the requested years." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9541, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:50.451120+00:00", + "tier": "working", + "url": "http://127.0.0.1:19493/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + { + "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", + "rendering": { + "statistics": "series" + }, + "bytes": 5741, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:50.451120+00:00", + "tier": "working", + "url": "http://127.0.0.1:19493/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" + } + ], + "series_count": 1, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 4 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:50.451687Z" + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "fetch-spec-known-sentence.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 4, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "crsCooperationModality", + "crsCooperationModality_label", + "crsPurpose", + "crsPurpose_label", + "crsTypeOfFinance", + "crsTypeOfFinance_label", + "crsTypeOfFlow", + "crsTypeOfFlow_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + ], + "missing": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json new file mode 100644 index 0000000..268467c --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json @@ -0,0 +1,865 @@ +{ + "format_version": 1, + "name": "fetch-spec-storage-artifact-url", + "description": "An artifact url names a files route, which is on the API's origin; one on the storage host raises ContractError contract_violation before any request for the file, as on any other origin.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "Every artifact url of the build's manifest becomes absolute on https://storage.googleapis.com, and the exchanges after the build go." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "prepared_at": "2026-10-21T08:57:50Z", + "coverage": { + "rows": 4, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 4 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "head", + "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal, which hold none at the observation period the other members serve in the requested years." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9541, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:50.451120+00:00", + "tier": "working", + "url": "https://storage.googleapis.com/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + { + "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", + "rendering": { + "statistics": "series" + }, + "bytes": 5741, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:57:50.451120+00:00", + "tier": "working", + "url": "https://storage.googleapis.com/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" + } + ], + "series_count": 1, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 4 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:57:50.451687Z" + } + } + } + } + ], + "expect": [ + { + "error": { + "class": "ContractError", + "code": "contract_violation" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json b/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json new file mode 100644 index 0000000..9be0338 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json @@ -0,0 +1,248 @@ +{ + "format_version": 1, + "name": "search-body-not-an-object", + "description": "A Search response body that is not an object raises ContractError contract_violation.", + "origin": { + "kind": "synthetic", + "derived_from": "search-place-ambiguous", + "edit": "The Search response body becomes a list holding the answer." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": [ + { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Congo", + "normalized_query": "ODA disbursements from Germany to Congo", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "warnings": [], + "timing_ms": { + "total": 1788, + "by_step": { + "coverage": 0, + "extract": 1353 + } + }, + "llm_usage": { + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 434, + "by_step": { + "recall": 434 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + ] + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "no_data" + } + ] + } + } + ], + "expect": [ + { + "error": { + "class": "ContractError", + "code": "contract_violation" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-refused-without-code.json b/python/client-contract/src/dfo_client_contract/scenarios/search-refused-without-code.json new file mode 100644 index 0000000..8b6b3bc --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-refused-without-code.json @@ -0,0 +1,53 @@ +{ + "format_version": 1, + "name": "search-refused-without-code", + "description": "A problem document with no code raises refusal_without_code with the class its status maps to, and keeps its body's retryable, so a retryable false 503 is not retried.", + "origin": { + "kind": "synthetic", + "derived_from": "search-place-ambiguous", + "edit": "A 503 problem document with no code, retryable false and a trace_id answers the search." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 503, + "headers": { + "content-type": "application/problem+json", + "x-dfo-trace-id": "22222222222222222222222222222222" + }, + "json": { + "title": "Service Unavailable", + "status": 503, + "detail": "The service is busy.", + "trace_id": "11111111111111111111111111111111", + "retryable": false + } + } + } + ], + "expect": [ + { + "error": { + "class": "ServerError", + "code": "refusal_without_code" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-server-warning.json b/python/client-contract/src/dfo_client_contract/scenarios/search-server-warning.json new file mode 100644 index 0000000..200f732 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-server-warning.json @@ -0,0 +1,752 @@ +{ + "format_version": 1, + "name": "search-server-warning", + "description": "An x-dfo-warning header issues server_warning once per process per message, and Deprecation and Sunset issue route_deprecated once per distinct pair of their values: the second search warns route_deprecated alone, and the third, a new pair and a new message, warns both.", + "origin": { + "kind": "synthetic", + "derived_from": "search-place-ambiguous", + "edit": "The search is made three times. Its responses carry x-dfo-warning 'Search runs on a reduced index while it is rebuilt.', then the same with Sunset 'Sat, 01 May 2027 00:00:00 GMT', then 'Search answers from a cached release.' with Deprecation '@1777593600' and the same Sunset." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + }, + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + }, + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-warning": "Search runs on a reduced index while it is rebuilt." + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Congo", + "normalized_query": "ODA disbursements from Germany to Congo", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "warnings": [], + "timing_ms": { + "total": 1788, + "by_step": { + "coverage": 0, + "extract": 1353 + } + }, + "llm_usage": { + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 434, + "by_step": { + "recall": 434 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + ] + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "no_data" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-warning": "Search runs on a reduced index while it is rebuilt.", + "sunset": "Sat, 01 May 2027 00:00:00 GMT" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Congo", + "normalized_query": "ODA disbursements from Germany to Congo", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "warnings": [], + "timing_ms": { + "total": 1788, + "by_step": { + "coverage": 0, + "extract": 1353 + } + }, + "llm_usage": { + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 434, + "by_step": { + "recall": 434 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + ] + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "no_data" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-warning": "Search answers from a cached release.", + "deprecation": "@1777593600", + "sunset": "Sat, 01 May 2027 00:00:00 GMT" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Congo", + "normalized_query": "ODA disbursements from Germany to Congo", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "warnings": [], + "timing_ms": { + "total": 1788, + "by_step": { + "coverage": 0, + "extract": 1353 + } + }, + "llm_usage": { + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 434, + "by_step": { + "recall": 434 + } + }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Congo", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + ] + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "no_data" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "no_data", + "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 2 + } + ], + "warnings": [ + "server_warning" + ] + } + }, + { + "answer": { + "kind": "resolution", + "status": "no_data", + "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 2 + } + ], + "warnings": [ + "route_deprecated" + ] + } + }, + { + "answer": { + "kind": "resolution", + "status": "no_data", + "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 2 + } + ], + "warnings": [ + "route_deprecated", + "server_warning" + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-unauthorized.json b/python/client-contract/src/dfo_client_contract/scenarios/search-unauthorized.json new file mode 100644 index 0000000..05dc2fc --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-unauthorized.json @@ -0,0 +1,45 @@ +{ + "format_version": 1, + "name": "search-unauthorized", + "description": "A 401 resolves the key again; the key is unchanged, so the client sends nothing more and raises AuthenticationError refusal_without_code.", + "origin": { + "kind": "synthetic", + "derived_from": "search-place-ambiguous", + "edit": "A bodiless 401 answers the search." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Congo" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Congo" + } + } + }, + "response": { + "status": 401, + "headers": { + "www-authenticate": "Bearer" + } + } + } + ], + "expect": [ + { + "error": { + "class": "AuthenticationError", + "code": "refusal_without_code" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/strict-fields.json b/python/client-contract/src/dfo_client_contract/strict-fields.json index e5e1f5a..ff799a3 100644 --- a/python/client-contract/src/dfo_client_contract/strict-fields.json +++ b/python/client-contract/src/dfo_client_contract/strict-fields.json @@ -43,9 +43,15 @@ { "pointer": "/components/schemas/Spec/properties/definition" }, + { + "pointer": "/components/schemas/Spec/properties/resolved" + }, { "pointer": "/components/schemas/SpecDefinition/properties/spec_id" }, + { + "pointer": "/components/schemas/SpecDefinition/properties/identity" + }, { "pointer": "/components/schemas/Manifest/properties/definition" }, @@ -58,6 +64,9 @@ { "pointer": "/components/schemas/DefinitionModel/properties/spec_id" }, + { + "pointer": "/components/schemas/DefinitionModel/properties/identity" + }, { "pointer": "/components/schemas/ArtifactEntryModel/properties/artifact_digest" }, diff --git a/tools/capture_client_contract.py b/tools/capture_client_contract.py index d404ef2..cb062da 100644 --- a/tools/capture_client_contract.py +++ b/tools/capture_client_contract.py @@ -87,6 +87,7 @@ answer_gaps, answer_members, answer_outcome, + artifact_route, build_body, choice_for, choice_input, @@ -662,13 +663,13 @@ def _retried( """Sends `request` through `send`, and again after each refusal `may_retry` allows, waiting `retry_wait` before each retry.""" response = send() - used = 0 - while may_retry(request, _read(response), used): - wait = retry_wait(response.headers, used) + answers = [_read(response)] + while may_retry(request, answers): + wait = retry_wait(response.headers, len(answers) - 1) self.retry_waits.append(wait) self.sleep(wait) response = send() - used += 1 + answers.append(_read(response)) return response def _api(self, method: str, path: str, json_body: Any = None) -> Response: @@ -892,13 +893,14 @@ def _member( artifact = pick_artifact(manifest, rendering) if artifact is None: raise ClientError("contract_violation") + route = artifact_route(self.recorder.base_url, artifact["url"]) definition = manifest["definition"] sentence = None if spec is None else spec.sentence if spec is None or definition["spec_id"] != spec.spec_id or sentence is None: held = None if spec is None else spec.step() sentence = self._identity_sentence(parts, definition, held) digest = artifact["artifact_digest"] - rows, columns = self.read_shape(self._download(artifact["url"], digest)) + rows, columns = self.read_shape(self._download(route, digest)) return Member( parts, definition, @@ -921,8 +923,9 @@ def _identity_sentence( return resubmitted_sentence(answer, definition["spec_id"]) def _download(self, target: str, digest: str, *, origin: bool = True) -> bytes: - """A file through the route that redirects to it: an artifact's - root-relative url, or a path under the base URL. The redirect's + """A file through the route that redirects to it: an `origin_path`, + as `artifact_route` places an artifact's url, or a path under the + base URL. The redirect's location is fetched once, where `download_target` places it; a local app's blob URL on the API's origin stands for the storage URL a deployment signs. A refused fetch or bytes of another digest ask the @@ -1046,7 +1049,8 @@ def _stored_file( ) if artifact is not None: try: - return self._download(artifact["url"], digest), None + route = artifact_route(self.recorder.base_url, artifact["url"]) + return self._download(route, digest), None except ClientError as error: if error.code not in FILE_GONE: raise @@ -1864,16 +1868,18 @@ def _refused_first( return Derived(copy.deepcopy(parent["call"]), exchanges, expect) +_BUSY = _problem( + "service_unavailable", + 503, + "Service Unavailable", + "The service is busy.", + retryable=True, +) + + def _retry_after_503(parent: dict[str, Any], ctx: Context) -> Derived: first = parent["exchanges"][0] - problem = _problem( - "service_unavailable", - 503, - "Service Unavailable", - "The service is busy.", - retryable=True, - ) - refused = _refusal(first["request"], 503, problem, {"retry-after": "1"}) + refused = _refusal(first["request"], 503, _BUSY, {"retry-after": "1"}) return _refused_first(parent, 0, refused) @@ -1987,6 +1993,29 @@ def _cut_off_twice( return [refused, copy.deepcopy(refused)], _waited(error, refused) +def _cut_off_then_busy( + build: dict[str, Any], ctx: Context +) -> tuple[list[dict[str, Any]], dict[str, Any]]: + """A 504 cut-off, then a 503 on the one post after it, which raises.""" + cut_off = _refusal(build["request"], 504, _TIMEOUT) + busy = _refusal(build["request"], 503, _BUSY) + error = refusal_error(503, _BUSY, ctx.actions).outcome(ctx.client_codes) + return [cut_off, busy], _waited(error, cut_off) + + +def _busy_then_cut_off(parent: dict[str, Any], ctx: Context) -> Derived: + """A 503, then a 504 cut-off, answer the build before the recorded + answer, and the retries' waits go in the outcome.""" + index = _build_index(parent) + build = parent["exchanges"][index]["request"] + refused = [_refusal(build, 503, _BUSY), _refusal(build, 504, _TIMEOUT)] + exchanges = copy.deepcopy(parent["exchanges"]) + exchanges[index:index] = refused + expect = copy.deepcopy(parent["expect"]) + expect[-1] = _waited(expect[-1], *refused) + return Derived(copy.deepcopy(parent["call"]), exchanges, expect) + + def _not_resolvable( build: dict[str, Any], ctx: Context ) -> tuple[list[dict[str, Any]], dict[str, Any]]: @@ -2252,6 +2281,47 @@ def _operation_failed(exchanges: list[dict[str, Any]], build: dict[str, Any]) -> build["resubmissions"] = 1 +def _poll_busy(exchanges: list[dict[str, Any]], build: dict[str, Any]) -> None: + """A 503 answers the first poll, and two more answer the third, after + the second answered: each spends a retry, the answer between restores + both, and each poll after a 503 waits the wait the 503's poll waited.""" + first = _poll_index(exchanges) + poll = exchanges[first]["request"] + exchanges.insert(first + 2, _refusal(poll, 503, _BUSY)) + exchanges.insert(first + 2, _refusal(poll, 503, _BUSY)) + exchanges.insert(first, _refusal(poll, 503, _BUSY)) + waits = build["poll_waits"] + build["poll_waits"] = [waits[0], waits[0], waits[1], *[waits[2]] * 3, *waits[3:]] + + +_OPERATION_NOT_FOUND = _problem( + "operation_not_found", + 404, + "Not Found", + "No operation has this id.", + retryable=False, +) + + +def _poll_not_found(parent: dict[str, Any], ctx: Context) -> Derived: + """A 404 operation_not_found, which is not retryable, answers the first + poll, and the exchanges after it go.""" + derived = _async_fetch()(parent, ctx) + index = _poll_index(derived.exchanges) + refused = _refusal(derived.exchanges[index]["request"], 404, _OPERATION_NOT_FOUND) + (outcome,) = derived.expect + (build,) = outcome["dataset"]["long_builds"] + error = refusal_error(404, _OPERATION_NOT_FOUND, ctx.actions).outcome( + ctx.client_codes + ) + entry = {**build, "poll_waits": build["poll_waits"][:1]} + return Derived( + derived.call, + [*derived.exchanges[:index], refused], + [with_step_notes(error, long_builds=[entry], retry_waits=(), warnings=())], + ) + + def _signed_url_refused(parent: dict[str, Any], ctx: Context) -> Derived: exchanges = copy.deepcopy(parent["exchanges"]) index = next(i for i, e in enumerate(exchanges) if "url" in e["request"]) @@ -2571,6 +2641,80 @@ def _sunset_twice(parent: dict[str, Any], ctx: Context) -> Derived: ) +# The origin of `fetch-spec-foreign-artifact-url`'s artifact urls, neither the +# API's nor the storage host's. +FOREIGN_ORIGIN = "https://downloads.example.com" + + +def _artifact_urls_on( + origin: Callable[[dict[str, Any]], str], +) -> Callable[[dict[str, Any], Context], Derived]: + """Every artifact `url` of the parent's build becomes absolute on the + origin `origin` gives for the parent: on the API's own origin the record + stands, and on any other the build raises ContractError and the + exchanges after it go.""" + + def derive(parent: dict[str, Any], ctx: Context) -> Derived: + exchanges = copy.deepcopy(parent["exchanges"]) + index = _build_index(parent) + at = origin(parent) + for artifact in exchanges[index]["response"]["json"]["artifacts"]: + artifact["url"] = at + artifact["url"] + if at == _origin(parent["origin"]["base_url"]): + return _same(parent, exchanges) + return Derived( + copy.deepcopy(parent["call"]), + exchanges[: index + 1], + [*copy.deepcopy(parent["expect"][:-1]), ctx.raised("contract_violation")], + ) + + return derive + + +# The x-dfo-warning messages and the Deprecation value +# `search-server-warning`'s responses carry. +SERVER_MESSAGE = "Search runs on a reduced index while it is rebuilt." +OTHER_SERVER_MESSAGE = "Search answers from a cached release." +DEPRECATION = "@1777593600" + + +def _server_warnings(parent: dict[str, Any], ctx: Context) -> Derived: + """The parent's search made three times. The first response carries + SERVER_MESSAGE; the second the same message and SUNSET; the third + OTHER_SERVER_MESSAGE, DEPRECATION and SUNSET. The warnings each step + issues are written out, so a change to the warning rules fails the + record.""" + (step,) = parent["call"] + (outcome,) = parent["expect"] + exchange = parent["exchanges"][0] + carried = [ + {"x-dfo-warning": SERVER_MESSAGE}, + {"x-dfo-warning": SERVER_MESSAGE, "sunset": SUNSET}, + { + "x-dfo-warning": OTHER_SERVER_MESSAGE, + "deprecation": DEPRECATION, + "sunset": SUNSET, + }, + ] + issued = [ + ["server_warning"], + ["route_deprecated"], + ["route_deprecated", "server_warning"], + ] + exchanges = [] + for headers in carried: + made = copy.deepcopy(exchange) + made["response"]["headers"].update(headers) + exchanges.append(made) + expect = [ + with_step_notes( + copy.deepcopy(outcome), long_builds=(), retry_waits=(), warnings=codes + ) + for codes in issued + ] + return Derived([copy.deepcopy(step) for _ in carried], exchanges, expect) + + def _search_ends( change: Callable[[dict[str, Any]], None], code: str ) -> Callable[[dict[str, Any], Context], Derived]: @@ -2623,6 +2767,181 @@ def _choice_without_data_query(parent: dict[str, Any], ctx: Context) -> Derived: return derived +def _choice_posted(edit: BodyEdit) -> Callable[[dict[str, Any], Context], Derived]: + """The parent's search, its answer body changed by `edit`, then its + choice, which posts the input the rules give for the changed answer and + takes the parent's recorded response to it.""" + + def derive(parent: dict[str, Any], ctx: Context) -> Derived: + search, choose = parent["call"] + canned = copy.deepcopy(parent["exchanges"][:2]) + body = edit(canned[0]["response"]["json"], ctx) + canned[0]["response"]["json"] = body + answer = answer_from_body(body) + choice = choice_for( + answer, gap_kinds(ctx.actions), choose.get("part"), choose["option"] + ) + canned[1]["request"]["json"] = search_body(choice_input(answer, choice)) + session = ctx.session("synthetic", canned=canned) + answered = session.search(search["question"]) + session.choose(answered, choose["option"], part=choose.get("part")) + return Derived(session.call, session.recorder.exchanges, session.expect) + + return derive + + +# The operation `choose-echoes-separate-and-operations`'s definite part asks for. +GROWTH = {"verb": "growth", "phrase": "growth of GDP", "over": "year"} + + +def _separate_with_operation(body: Any, ctx: Context) -> Any: + """Part 0, the definite one, is asked beside the others and asks for + GROWTH.""" + body = copy.deepcopy(body) + body["parts"][0].update(separate=True, operations=[dict(GROWTH)]) + return body + + +def _definite_unsupported(body: Any, ctx: Context) -> Any: + """Part 0, the definite one, becomes an unsupported part with no + restatement.""" + body = copy.deepcopy(body) + part = body["parts"][0] + for member in ("spec", "restatement", "assumptions"): + part.pop(member, None) + part["status"] = "unsupported" + part["unsupported"] = { + "code": "scope_too_broad", + "pointer": "/definition/identity", + "detail": "the family is too broad to settle; bind a what or how slot", + } + return body + + +def _definite_deferred(body: Any, ctx: Context) -> Any: + """Part 0 takes the status "deferred", which no client knows, and loses + its restatement.""" + body = copy.deepcopy(body) + body["parts"][0]["status"] = "deferred" + body["parts"][0].pop("restatement", None) + return body + + +def _definite_unnamed(body: Any, ctx: Context) -> Any: + """Part 0, the definite one, loses its variable_text.""" + body = copy.deepcopy(body) + del body["parts"][0]["variable_text"] + return body + + +def _labels_shared(body: Any, ctx: Context) -> Any: + """The no_data part's second option takes the first one's label.""" + body = copy.deepcopy(body) + options = body["parts"][0]["no_data"]["options"] + options[1]["label"] = options[0]["label"] + return body + + +def _two_part_query(body: Any, ctx: Context) -> Any: + """The first option's data_query holds its one part twice.""" + body = copy.deepcopy(body) + query = body["parts"][0]["no_data"]["options"][0]["data_query"] + query["parts"] = [query["parts"][0], copy.deepcopy(query["parts"][0])] + return body + + +def _choice_raises( + code: str, edit: BodyEdit +) -> Callable[[dict[str, Any], Context], Derived]: + """The parent's choice over its answer changed by `edit`, which raises + the client code `code` with no request.""" + + def derive(parent: dict[str, Any], ctx: Context) -> Derived: + choose = parent["call"][1] + derived = _choice(choose["option"], choose.get("part"), edit=edit)(parent, ctx) + require(derived.expect[-1] == ctx.raised(code), f"the choice raises {code}") + return derived + + return derive + + +def _not_an_object(response: dict[str, Any]) -> None: + response["json"] = [response["json"]] + + +def _no_parts(response: dict[str, Any]) -> None: + response["json"]["parts"] = [] + + +def _spec_without(member: str) -> Callable[[dict[str, Any]], None]: + """Part 0's spec loses `member`, or its definition loses it when the + member is `identity`.""" + + def change(response: dict[str, Any]) -> None: + spec = response["json"]["parts"][0]["spec"] + (spec["definition"] if member == "identity" else spec).pop(member) + + return change + + +def _manifest_without_identity(parent: dict[str, Any], ctx: Context) -> Derived: + index = _build_index(parent) + exchanges = copy.deepcopy(parent["exchanges"][: index + 1]) + del exchanges[index]["response"]["json"]["definition"]["identity"] + return Derived( + copy.deepcopy(parent["call"]), + exchanges, + [*copy.deepcopy(parent["expect"][:-1]), ctx.raised("contract_violation")], + ) + + +def _nested_specs_unchecked(parent: dict[str, Any], ctx: Context) -> Derived: + """Each alternative measure of part 0's spec loses its definition's + identity and its resolved, members no client reads.""" + exchanges = copy.deepcopy(parent["exchanges"]) + resolved = exchanges[0]["response"]["json"]["parts"][0]["spec"]["resolved"] + measures = resolved["alternative_measures"] + require(bool(measures), "part 0's spec has alternative measures") + for measure in measures: + measure["definition"].pop("identity") + measure.pop("resolved", None) + return _same(parent, exchanges) + + +# The trace id the codeless problem document of `search-refused-without-code` +# carries. +BODY_TRACE_ID = "1" * 32 + + +def _refused_without_code(parent: dict[str, Any], ctx: Context) -> Derived: + """A 503 problem document with no code, retryable false and a trace id + answers the search, which raises it unretried.""" + first = parent["exchanges"][0] + body = { + "title": "Service Unavailable", + "status": 503, + "detail": "The service is busy.", + "trace_id": BODY_TRACE_ID, + "retryable": False, + } + refused = _refusal(first["request"], 503, body) + refused["response"]["headers"]["x-dfo-trace-id"] = "2" * 32 + error = refusal_error(503, body, ctx.actions).outcome(ctx.client_codes) + return Derived(copy.deepcopy(parent["call"]), [refused], [error]) + + +def _unauthorized(parent: dict[str, Any], ctx: Context) -> Derived: + """A bodiless 401 answers the search. The replay's key does not change + when the client resolves it again, so the client sends nothing more.""" + first = parent["exchanges"][0] + refused = { + "request": copy.deepcopy(first["request"]), + "response": {"status": 401, "headers": {"www-authenticate": "Bearer"}}, + } + error = refusal_error(401, None, ctx.actions).outcome(ctx.client_codes) + return Derived(copy.deepcopy(parent["call"]), [refused], [error]) + + def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: """The fetch names `entities: {}` and `facets: {}`, which narrow nothing.""" derived = _same(parent, copy.deepcopy(parent["exchanges"])) @@ -2682,6 +3001,23 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: "timeout code's ServerError.", _ends_at_build(_cut_off_twice), ), + Synthetic( + "fetch-spec-504-then-503", + "fetch-spec-known-sentence", + "A 504 timeout answers the build, and a 503 service_unavailable its one retry.", + "After a 504 cut-off the build is posted once more only, so the 503 that answers " + "that post raises its ServerError although one retry of the two is left.", + _ends_at_build(_cut_off_then_busy), + ), + Synthetic( + "fetch-spec-503-then-504", + "fetch-spec-known-sentence", + "A 503 service_unavailable answers the build, and a 504 timeout its first retry.", + "A 504 that cuts off the first retry is the first cut-off, so the build is posted " + "once more, the second of its two retries, after waits of 0.5 and 1 seconds, and " + "reaches the same dataset.", + _busy_then_cut_off, + ), Synthetic( "fetch-spec-member-not-resolvable", "fetch-spec-known-sentence", @@ -2787,6 +3123,26 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: "again and keeps the server's pacing after it.", _async_fetch(_poll_rate_limited), ), + Synthetic( + "fetch-spec-poll-refused", + "mint-async-build", + "As fetch-spec-async-build, with a 503 service_unavailable answering the first poll, " + "and two answering the third.", + "A retryable refused poll other than a 429 spends one of the two retries, and a poll " + "that answers restores them, so two 503s in a row after an answered poll are polled " + "again too. A refused poll changes no pacing: the poll after it waits what the " + "refused one waited.", + _async_fetch(_poll_busy), + ), + Synthetic( + "fetch-spec-poll-not-found", + "mint-async-build", + "As fetch-spec-async-build, with a 404 operation_not_found answering the first poll, " + "and the exchanges after it go.", + "A refused poll that is not retryable raises its error at once, with the one poll " + "made in long_builds.", + _poll_not_found, + ), Synthetic( "fetch-spec-operation-failed-resubmitted", "mint-async-build", @@ -2822,6 +3178,42 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: "same dataset.", _relative_location, ), + Synthetic( + "fetch-spec-foreign-artifact-url", + "fetch-spec-known-sentence", + f"Every artifact url of the build's manifest becomes absolute on {FOREIGN_ORIGIN}, " + "and the exchanges after the build go.", + "An artifact url on an origin other than the API's raises ContractError " + "contract_violation before any request for the file.", + _artifact_urls_on(lambda parent: FOREIGN_ORIGIN), + ), + Synthetic( + "fetch-spec-same-origin-artifact-url", + "fetch-spec-known-sentence", + "Every artifact url of the build's manifest becomes absolute on the API's origin.", + "An absolute artifact url on the API's origin names the same files route as its " + "root-relative form, so the client asks it as that origin_path and reaches the same " + "dataset.", + _artifact_urls_on(lambda parent: _origin(parent["origin"]["base_url"])), + ), + Synthetic( + "fetch-spec-storage-artifact-url", + "fetch-spec-known-sentence", + f"Every artifact url of the build's manifest becomes absolute on {STORAGE_ORIGIN}, " + "and the exchanges after the build go.", + "An artifact url names a files route, which is on the API's origin; one on the " + "storage host raises ContractError contract_violation before any request for the " + "file, as on any other origin.", + _artifact_urls_on(lambda parent: STORAGE_ORIGIN), + ), + Synthetic( + "fetch-spec-manifest-without-identity", + "fetch-spec-known-sentence", + "The build's manifest definition loses identity, and the exchanges after it go.", + "A manifest whose definition has no identity, a strict member, raises ContractError " + "contract_violation on the build response, before any download.", + _manifest_without_identity, + ), Synthetic( "operation-failed-without-error", "operation-resume", @@ -2849,6 +3241,18 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: "warns nothing.", _sunset_twice, ), + Synthetic( + "search-server-warning", + "search-place-ambiguous", + "The search is made three times. Its responses carry x-dfo-warning " + f"{SERVER_MESSAGE!r}, then the same with Sunset {SUNSET!r}, then " + f"{OTHER_SERVER_MESSAGE!r} with Deprecation {DEPRECATION!r} and the same Sunset.", + "An x-dfo-warning header issues server_warning once per process per message, and " + "Deprecation and Sunset issue route_deprecated once per distinct pair of their " + "values: the second search warns route_deprecated alone, and the third, a new pair " + "and a new message, warns both.", + _server_warnings, + ), Synthetic( "answer-part-status-not-a-string", "answer-mixed-fetch-raises", @@ -2865,6 +3269,115 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: "contract_violation, in a Search response as in a ref.", _search_ends(_definition_spec_id_differs, "contract_violation"), ), + Synthetic( + "answer-spec-without-identity", + "answer-definite-fetch", + "Part 0's spec definition loses identity, and the fetch goes.", + "A Search spec whose definition has no identity, which a client posts back, raises " + "ContractError contract_violation.", + _search_ends(_spec_without("identity"), "contract_violation"), + ), + Synthetic( + "answer-spec-without-resolved", + "answer-definite-fetch", + "Part 0's spec loses resolved, and the fetch goes.", + "A Search spec with no resolved, whose entity_groups a client reads, raises " + "ContractError contract_violation.", + _search_ends(_spec_without("resolved"), "contract_violation"), + ), + Synthetic( + "answer-nested-specs-unchecked", + "answer-definite-fetch", + "Each alternative measure of part 0's spec loses its definition's identity and its " + "resolved.", + "A client checks strict members only where a rule reads them, so a spec nested in " + "resolved.alternative_measures may lack them, and the fetch reaches the same " + "dataset.", + _nested_specs_unchecked, + ), + Synthetic( + "answer-empty-parts", + "search-place-ambiguous", + "The answer's parts become [].", + "A resolution with no parts, which the served schema gives at least one, raises " + "ContractError contract_violation at /parts.", + _search_ends(_no_parts, "contract_violation"), + ), + Synthetic( + "search-body-not-an-object", + "search-place-ambiguous", + "The Search response body becomes a list holding the answer.", + "A Search response body that is not an object raises ContractError " + "contract_violation.", + _search_ends(_not_an_object, "contract_violation"), + ), + Synthetic( + "search-refused-without-code", + "search-place-ambiguous", + "A 503 problem document with no code, retryable false and a trace_id answers the " + "search.", + "A problem document with no code raises refusal_without_code with the class its " + "status maps to, and keeps its body's retryable, so a retryable false 503 is not " + "retried.", + _refused_without_code, + ), + Synthetic( + "search-unauthorized", + "search-place-ambiguous", + "A bodiless 401 answers the search.", + "A 401 resolves the key again; the key is unchanged, so the client sends nothing " + "more and raises AuthenticationError refusal_without_code.", + _unauthorized, + ), + Synthetic( + "choose-echoes-separate-and-operations", + "choose-option-beside-definite", + f"Part 0, the definite part, carries separate true and the operation {GROWTH}.", + "A definite part's identity entry echoes the part's separate flag when it is true " + "and its operations when it has any.", + _choice_posted(_separate_with_operation), + ), + Synthetic( + "choose-posts-unsupported-placeholder", + "choose-option-beside-definite", + "Part 0 becomes an unsupported part with code scope_too_broad and no restatement.", + "A part that is unsupported and has no restatement posts a placeholder entry with " + "its unsupported code and variable_text.", + _choice_posted(_definite_unsupported), + ), + Synthetic( + "choose-refused-unknown-status", + "choose-option-beside-definite", + 'Part 0 takes the status "deferred" and loses its restatement.', + "A part of a status the client does not know, with no restatement, cannot be posted " + "back, so the choice raises InvalidRequestError with no request.", + _choice_raises("choice_invalid", _definite_deferred), + ), + Synthetic( + "choose-refused-part-without-variable-text", + "choose-option-beside-definite", + "Part 0, the definite part, loses its variable_text.", + "An identity entry carries its part's variable_text, so a part without one cannot " + "be posted back and the choice raises InvalidRequestError with no request.", + _choice_raises("choice_invalid", _definite_unnamed), + ), + Synthetic( + "choose-refused-shared-label", + "choose-place-one-part", + "The no_data part's second option takes the first one's label.", + "A label two options share matches several, so choosing by it raises " + "InvalidRequestError with no request.", + _choice_raises("choice_invalid", _labels_shared), + ), + Synthetic( + "choose-option-two-part-query", + "choose-place-one-part", + "The chosen option's data_query holds its one part twice.", + "A chosen option whose data_query holds other than one part raises ContractError " + "contract_violation before any request, in a one-part answer as in a several-part " + "one.", + _choice_raises("contract_violation", _two_part_query), + ), Synthetic( "search-no-json-body", "search-place-ambiguous", diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index 7c7da46..2d559d5 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -23,6 +23,7 @@ from collections.abc import Callable from pathlib import Path from typing import Any +from urllib.parse import urlsplit import pytest @@ -323,6 +324,68 @@ def _second_fetch_served(doc: Any) -> None: _SUNSET = "scenarios/search-sunset-warning.json" _FOREIGN = "https://downloads.example.com/b/o?X-Goog-Signature=redacted" +_SERVER_WARNING = "scenarios/search-server-warning.json" +_FOREIGN_ARTIFACT = "scenarios/fetch-spec-foreign-artifact-url.json" +_SAME_ORIGIN_ARTIFACT = "scenarios/fetch-spec-same-origin-artifact-url.json" +_POLL_REFUSED = "scenarios/fetch-spec-poll-refused.json" +_POLL_NOT_FOUND = "scenarios/fetch-spec-poll-not-found.json" +_CUT_OFF_THEN_BUSY = "scenarios/fetch-spec-504-then-503.json" +_BUSY_THEN_CUT_OFF = "scenarios/fetch-spec-503-then-504.json" + + +def _artifact_urls(origin: str) -> Callable[[Any], None]: + """The build's artifact urls become absolute on `origin`.""" + + def change(doc: Any) -> None: + for artifact in doc["exchanges"][0]["response"]["json"]["artifacts"]: + artifact["url"] = origin + urlsplit(artifact["url"]).path + + return change + + +def _warned(index: int, codes: list[str]) -> Callable[[Any], None]: + def change(doc: Any) -> None: + answer = doc["expect"][index]["answer"] + if codes: + answer["warnings"] = codes + else: + answer.pop("warnings") + + return change + + +_ECHOES_SEPARATE = "scenarios/choose-echoes-separate-and-operations.json" +_PLACEHOLDER = "scenarios/choose-posts-unsupported-placeholder.json" +_CODELESS = "scenarios/search-refused-without-code.json" + + +def _first_part(change: Callable[[Any], None]) -> Callable[[Any], None]: + return _set_body(0, lambda body: change(body["parts"][0])) + + +def _first_entry(change: Callable[[Any], None]) -> Callable[[Any], None]: + return lambda doc: change( + doc["exchanges"][1]["request"]["json"]["input"]["entries"][0] + ) + + +def _second_option(**fields: Any) -> Callable[[Any], None]: + return _first_part(lambda part: part["no_data"]["options"][1].update(fields)) + + +def _one_part_query(part: Any) -> None: + query = part["no_data"]["options"][0]["data_query"] + query["parts"] = query["parts"][:1] + + +def _ends_in(error: dict[str, Any], keep: int) -> Callable[[Any], None]: + """The record keeps its first `keep` exchanges and expects `error`.""" + + def change(doc: Any) -> None: + doc["exchanges"] = doc["exchanges"][:keep] + doc["expect"] = [{"error": error}] + + return change @pytest.mark.parametrize( @@ -1136,6 +1199,176 @@ def _second_fetch_served(doc: Any) -> None: ), "step 0 expects", ), + ( + _SAME_ORIGIN_ARTIFACT, + _artifact_urls("https://downloads.example.com"), + "the steps never make exchanges 1 to 2", + ), + ( + _FOREIGN_ARTIFACT, + _artifact_urls("http://127.0.0.1:19493"), + "the steps make a GET /api/datasets/", + ), + ( + _SAME_ORIGIN_ARTIFACT, + _artifact_urls("http://127.0.0.1:8083"), + "the steps never make exchanges 1 to 2", + ), + (_SERVER_WARNING, _warned(0, []), "step 0 expects"), + (_SERVER_WARNING, _warned(1, []), "step 1 expects"), + ( + _SERVER_WARNING, + _warned(1, ["route_deprecated", "server_warning"]), + "step 1 expects", + ), + (_SERVER_WARNING, _warned(2, ["route_deprecated"]), "step 2 expects"), + (_SERVER_WARNING, _warned(2, ["server_warning"]), "step 2 expects"), + (_POLL_REFUSED, _repeat(4, 1), "the steps never make exchanges 7 to 15"), + ( + _POLL_REFUSED, + _set_outcome( + 0, lambda o: o["dataset"]["long_builds"][0]["poll_waits"].pop(0) + ), + "step 0 expects", + ), + (_POLL_NOT_FOUND, _repeat(1, 1), "the steps never make exchanges 2 to 2"), + ( + _POLL_NOT_FOUND, + _set_body(1, lambda body: body.update(retryable=True)), + "the record lacks", + ), + (_CUT_OFF_THEN_BUSY, _repeat(1, 1), "the steps never make exchanges 2 to 2"), + ( + _BUSY_THEN_CUT_OFF, + _ends_in({"class": "ServerError", "code": "timeout"}, 2), + "is a retryable refusal with retries left", + ), + ( + _BUSY_THEN_CUT_OFF, + _set_outcome(0, lambda o: o["dataset"].update(retry_waits=[0.5])), + "step 0 expects", + ), + ( + "client-codes.json", + _drop_action("key_empty"), + "no row for 'key_empty', an error the key-lookup rule raises", + ), + ( + "client-codes.json", + _drop_action("profile_not_found"), + "no row for 'profile_not_found', an error the key-lookup rule raises", + ), + ( + "client-codes.json", + _drop_action("profile_without_key"), + "no row for 'profile_without_key', an error the key-lookup rule raises", + ), + ( + "client-codes.json", + _drop_action("credentials_file_invalid"), + ( + "no row for 'credentials_file_invalid', an error the key-lookup " + "rule raises" + ), + ), + ( + "client-codes.json", + _set_action("key_empty", **{"class": "ContractError"}), + "takes 'ContractError', not 'AuthenticationError'", + ), + ( + "scenarios/search-proxy-unavailable.json", + lambda doc: doc["exchanges"][0]["response"]["json"].update( + error=["transient_unavailable"] + ), + "proxy code ['transient_unavailable'] is not a code", + ), + ( + _FETCH, + _artifact_urls("https://storage.googleapis.com"), + "the steps never make exchanges 1 to 2", + ), + ( + _FETCH, + _set_body(0, lambda body: body["definition"].pop("identity")), + "the steps never make exchanges 1 to 2", + ), + ( + "scenarios/answer-definite-fetch.json", + _first_part(lambda part: part["spec"]["definition"].pop("identity")), + "the step follows no answer", + ), + ( + "scenarios/answer-definite-fetch.json", + _first_part(lambda part: part["spec"].pop("resolved")), + "the step follows no answer", + ), + ( + "scenarios/answer-nested-specs-unchecked.json", + _first_part(lambda part: part["spec"].pop("resolved")), + "the step follows no answer", + ), + (_SEARCH, _set_body(0, lambda body: body.update(parts=[])), "step 0 expects"), + ( + _SEARCH, + lambda doc: doc["exchanges"][0]["response"].update(json=[]), + "step 0 expects", + ), + ( + _CODELESS, + _set_body(0, lambda body: body.update(retryable=True)), + "is a retryable refusal with retries left", + ), + (_CODELESS, _repeat(0, 1), "the steps never make exchanges 1 to 1"), + ( + "scenarios/search-unauthorized.json", + _repeat(0, 1), + "the steps never make exchanges 1 to 1", + ), + ( + _ECHOES_SEPARATE, + _first_entry(lambda entry: entry.pop("separate")), + "where the rules post", + ), + ( + _ECHOES_SEPARATE, + _first_entry(lambda entry: entry.update(separate=False)), + "where the rules post", + ), + ( + _ECHOES_SEPARATE, + _first_entry(lambda entry: entry.pop("operations")), + "where the rules post", + ), + ( + _PLACEHOLDER, + _first_entry(lambda entry: entry.update(code="scope_unsupported")), + "where the rules post", + ), + ( + "scenarios/choose-refused-unknown-status.json", + _first_part( + lambda part: part.update( + status="unsupported", unsupported={"code": "scope_too_broad"} + ) + ), + "the record lacks", + ), + ( + "scenarios/choose-refused-part-without-variable-text.json", + _first_part(lambda part: part.update(variable_text="GDP")), + "the record lacks", + ), + ( + "scenarios/choose-refused-shared-label.json", + _second_option(label="Congo [Republic]"), + "the record lacks", + ), + ( + "scenarios/choose-option-two-part-query.json", + _first_part(_one_part_query), + "the record lacks", + ), ], ids=[ "strict-pointer-unresolved", @@ -1291,6 +1524,45 @@ def _second_fetch_served(doc: Any) -> None: "definition-spec-id-mismatch", "one-part-option-without-data-query", "refusal-in-another-content-type", + "artifact-url-foreign-fetched", + "artifact-url-same-origin-refused", + "artifact-url-other-port-fetched", + "server-warning-missing", + "deprecation-pair-keyed-per-process", + "server-warning-repeated", + "server-warning-new-message-missing", + "deprecation-new-pair-missing", + "poll-retried-past-the-budget", + "poll-wait-after-refusal-missing", + "non-retryable-poll-polled-again", + "poll-refusal-made-retryable", + "build-posted-twice-after-cut-off", + "cut-off-after-a-503-not-posted-again", + "cut-off-retry-waits-short", + "key-lookup-reason-key-empty-missing", + "key-lookup-reason-profile-not-found-missing", + "key-lookup-reason-profile-without-key-missing", + "key-lookup-reason-credentials-file-invalid-missing", + "key-lookup-reason-of-another-class", + "proxy-code-not-a-string", + "artifact-url-on-storage-fetched", + "manifest-without-identity-read", + "search-spec-without-identity-read", + "search-spec-without-resolved-read", + "read-spec-without-resolved-beside-unread-ones", + "empty-parts-read-as-an-answer", + "search-body-not-an-object-read", + "codeless-refusal-retryable-by-body-unretried", + "codeless-refusal-not-retryable-retried", + "unchanged-key-sent-again-after-401", + "separate-not-echoed", + "separate-false-echoed", + "operations-not-echoed", + "placeholder-of-another-code", + "unknown-status-refusal-on-a-postable-part", + "variable-text-refusal-on-a-named-part", + "shared-label-refusal-on-distinct-labels", + "two-part-query-refusal-on-a-one-part-query", ], ) def test_a_broken_contract_is_reported( diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index 2c8f473..831a0a8 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -30,7 +30,8 @@ `actions.json` or `registries/codes.json`. Each row's class is one a scenario's error may name, other than a warning's, and only `refusal_without_code` takes the class its status maps to, and its - retryable flag `by_status`. + retryable flag `by_status`. Each reason the key-lookup rule raises is a + row of class `AuthenticationError`. - `proxy-codes.json` and `warning-codes.json` list codes in order, each once, none of them a code another table or `registries/codes.json` holds, and the warning codes are those the client rules issue: `route_deprecated`, @@ -65,8 +66,9 @@ `search_body` gives. A POST carries its body, a refused request repeated is a retry only as `may_retry` allows, a record that ends a run of retries while `may_retry` holds does not fit, each poll names the operation the - client holds, and each signed download is where `download_target` places - the `location` the files route answered. The outcomes give the waits + client holds, each files route is where `artifact_route` places the + artifact's `url`, and each signed download is where `download_target` + places the `location` the files route answered. The outcomes give the waits before retries and the warnings response headers issue. Every absolute URL a record holds, a `url` request or a `location` header, is a signed URL on the storage host with the query `X-Goog-Signature=redacted`, or a @@ -393,6 +395,7 @@ def _check_client_codes( actions: dict[str, Any], registry: dict[str, Any], classes: Sequence[str], + lookup_reasons: Sequence[str], ) -> list[str]: codes = [row["code"] for row in document["codes"]] problems = [ @@ -430,6 +433,19 @@ def _check_client_codes( for row in document["codes"] if (row["retryable"] == BY_STATUS) != (row["class"] == BY_STATUS) ) + classes_by_code = {row["code"]: row["class"] for row in document["codes"]} + for reason in lookup_reasons: + found = classes_by_code.get(reason) + if found is None: + problems.append( + f"client-codes.json: no row for {reason!r}, an error the " + "key-lookup rule raises" + ) + elif found != KEY_LOOKUP_CLASS: + problems.append( + f"client-codes.json: {reason!r}, an error the key-lookup rule " + f"raises, takes {found!r}, not {KEY_LOOKUP_CLASS!r}" + ) return problems @@ -457,13 +473,6 @@ def _check_other_codes( return problems -def _check_proxy_codes( - document: dict[str, Any], taken: Mapping[str, set[str]] -) -> list[str]: - codes = [row["code"] for row in document["codes"]] - return _check_other_codes("proxy-codes.json", codes, taken) - - def _check_warning_codes( document: dict[str, Any], taken: Mapping[str, set[str]], @@ -492,6 +501,17 @@ def key_format_reasons(rules_schema: Mapping[str, Any]) -> list[str]: return vectors["items"]["properties"]["reason"]["enum"] +# The class of every error the key-lookup rule raises. +KEY_LOOKUP_CLASS = "AuthenticationError" + + +def key_lookup_reasons(rules_schema: Mapping[str, Any]) -> list[str]: + """The reasons the key-lookup rule raises an error with.""" + vectors = rules_schema["$defs"]["key_lookup"]["properties"]["vectors"] + error = vectors["items"]["properties"]["error"] + return error["properties"]["reason"]["enum"] + + # --- scenarios -------------------------------------------------------------- @@ -641,7 +661,8 @@ def _check_problem_code( if "code" not in body: if "error" not in body: return [] - row = proxy_codes.get(body["error"]) + error = body["error"] + row = proxy_codes.get(error) if isinstance(error, str) else None if row is None or row["status"] != response["status"]: return [ ( @@ -708,23 +729,27 @@ def _check_problem_code( _PROXY_RETRY = "retry_after_delay" # The retries a client makes by default after a retryable refusal. MAX_RETRIES = 2 -# A build cut off by a retryable 504 is posted once more only. -MAX_BUILD_TIMEOUT_RETRIES = 1 +# The status that cuts a synchronous build off at the server's limit. +BUILD_CUT_OFF = 504 def may_retry( - request: Mapping[str, Any], response: Mapping[str, Any], used: int + request: Mapping[str, Any], responses: Sequence[Mapping[str, Any]] ) -> bool: - """Whether a client sends `request` again after `response`, having retried - it `used` times: the response is a retryable refusal and the retries stay - within MAX_RETRIES, or within MAX_BUILD_TIMEOUT_RETRIES for a build cut - off by a 504.""" + """Whether a client sends `request` again after `responses`, the answers + to it so far in order: the last is a retryable refusal, the retries made + stay under MAX_RETRIES, and for a build, no earlier answer was a 504 + cut-off, after which the build is posted once more only. So a build + refused 504 then 503 raises the 503, and one refused 503 then 504 is + posted once more after the 504.""" + *earlier, response = responses status = response["status"] if status < 400 or not retryable(status, problem_body(response)): return False + if len(earlier) >= MAX_RETRIES: + return False build = request["method"] == "POST" and request.get("path") == "/datasets" - limit = MAX_BUILD_TIMEOUT_RETRIES if build and status == 504 else MAX_RETRIES - return used < limit + return not (build and any(r["status"] == BUILD_CUT_OFF for r in earlier)) # The content types a client reads a refusal's body as a problem document, or @@ -944,6 +969,7 @@ def refusal_error( # The answer kinds a client reads. Any other kind raises ContractError. ANSWER_KINDS = ("resolution", "catalogue", "declined") +RESOLUTION = "resolution" # The variable text an identity resubmit sends for a member no answer part names. UNNAMED_VARIABLE_TEXT = "dataset" # The warning severities a fetch reports in its SearchWarning; `info` stays quiet. @@ -963,14 +989,16 @@ class Answer: def answer_from_body(body: Any) -> Answer: """The answer a search response holds. A body that is not an object, a - kind no client knows, a part whose `status` is not a string, and a spec - whose `definition.spec_id` differs from its `spec_id` raise - ContractError.""" + kind no client knows, a resolution with no parts, a part whose `status` + is not a string, and a spec whose `definition.spec_id` differs from its + `spec_id` raise ContractError.""" if not isinstance(body, dict) or body.get("kind") not in ANSWER_KINDS: raise ClientError("contract_violation") parts = body.get("parts", []) if not isinstance(parts, list) or not all(_readable(part) for part in parts): raise ClientError("contract_violation") + if body["kind"] == RESOLUTION and not parts: + raise ClientError("contract_violation") return Answer(body, parts, body.get("rendered_sentence"), body.get("status")) @@ -1078,6 +1106,7 @@ def choice_input(answer: Answer, choice: Choice) -> dict[str, Any]: per part, in part order, so a picked candidate in a one-part answer posts its identity as the one entry, and Search answers the picked reading.""" if len(answer.parts) == 1 and choice.option is not None: + _option_part(choice.option) return _data_query(choice.option) entries = [ resubmit_entry(part, choice if index == choice.part else None) @@ -1103,10 +1132,7 @@ def resubmit_entry(part: dict[str, Any], choice: Choice | None) -> dict[str, Any **_identity(candidate, reading_echo(part, candidate)), ) if choice is not None and choice.option is not None: - parts = _data_query(choice.option).get("parts") - if not isinstance(parts, list) or len(parts) != 1: - raise ClientError("contract_violation") - return {"entry_kind": "parsed", "part": parts[0]} + return {"entry_kind": "parsed", "part": _option_part(choice.option)} match part.get("status"): case "definite": spec = part["spec"] @@ -1137,6 +1163,16 @@ def _data_query(option: Mapping[str, Any]) -> dict[str, Any]: return query +def _option_part(option: Mapping[str, Any]) -> Any: + """The one part a no_data option's `data_query` holds; a query of other + than one part raises ContractError, in a one-part answer as in a + several-part one.""" + parts = _data_query(option).get("parts") + if not isinstance(parts, list) or len(parts) != 1: + raise ClientError("contract_violation") + return parts[0] + + def reading_echo(part: Mapping[str, Any], spec: Mapping[str, Any]) -> Any: """The assumptions a resubmitted reading of `part` echoes: a definite part's `assumptions`, or a candidates part's `reading_assumptions` under @@ -1262,14 +1298,16 @@ def answer_gaps(answer: Answer, kinds: Mapping[str, str]) -> list[dict[str, Any] def answer_members(answer: Answer) -> list[tuple[list[str], dict[str, Any]]]: """One member per distinct spec_id of the definite parts, in part order: - the variable text of every part it answers, and the first such part's - spec.""" + the variable text of every part it answers that names one, and the first + such part's spec.""" members: dict[str, tuple[list[str], dict[str, Any]]] = {} for part in answer.parts: if part.get("status") != "definite": continue spec = part["spec"] - members.setdefault(spec["spec_id"], ([], spec))[0].append(part["variable_text"]) + named = members.setdefault(spec["spec_id"], ([], spec))[0] + if part.get("variable_text"): + named.append(part["variable_text"]) return list(members.values()) @@ -1351,25 +1389,30 @@ def strict_gaps( schema: Any, body: Any, where: str = "", + component: str | None = None, ) -> list[str]: """The strict members `body` lacks or holds as null, read through `schema`: each component schema it reaches names its own, and a - discriminated union whose discriminator `body` lacks is a gap. A - discriminator value the union does not map, and a union without a - discriminator that offers more than one object branch, reach nothing.""" + discriminated union whose discriminator `body` lacks is a gap. The walk + goes down only through strict members, the ones a client reads, so a + member no client reads, such as a spec's `resolved.equivalent_readings`, + is never checked. A discriminator value the union does not map, and a + union without a discriminator that offers more than one object branch, + reach nothing. `component` is the component schema `schema` belongs to.""" if not isinstance(schema, dict): return [] ref = schema.get("$ref") if isinstance(ref, str) and ref.startswith("#/"): + name = ref.rsplit("/", 1)[-1] gaps = [] if isinstance(body, dict): gaps = [ - f"{where}/{name}" - for name in members.get(ref.rsplit("/", 1)[-1], ()) - if body.get(name) is None + f"{where}/{member}" + for member in members.get(name, ()) + if body.get(member) is None ] return gaps + strict_gaps( - openapi, members, _resolve(openapi, ref[1:]), body, where + openapi, members, _resolve(openapi, ref[1:]), body, where, name ) discriminator = schema.get("discriminator") if isinstance(discriminator, dict) and isinstance(body, dict): @@ -1384,12 +1427,15 @@ def strict_gaps( for keyword in ("anyOf", "oneOf"): branches = [b for b in schema.get(keyword, []) if b.get("type") != "null"] if len(branches) == 1: - gaps.extend(strict_gaps(openapi, members, branches[0], body, where)) + gaps.extend( + strict_gaps(openapi, members, branches[0], body, where, component) + ) for branch in schema.get("allOf", []): - gaps.extend(strict_gaps(openapi, members, branch, body, where)) + gaps.extend(strict_gaps(openapi, members, branch, body, where, component)) if isinstance(body, dict): + read = members.get(component, ()) if component is not None else () for name, member in schema.get("properties", {}).items(): - if name in body: + if name in body and name in read: gaps.extend( strict_gaps(openapi, members, member, body[name], f"{where}/{name}") ) @@ -1562,6 +1608,19 @@ def download_target(base_url: str, route_url: str, location: str) -> tuple[str, return "origin_path", urlunsplit(("", "", resolved.path, resolved.query, "")) +def artifact_route(base_url: str, url: str) -> str: + """The `origin_path` of the files route a manifest artifact's `url` + names: a root-relative url as it resolves on the API's origin, and an + absolute url on that origin as its path and query. A url on any other + origin, the storage host's included, raises ContractError.""" + base = urlsplit(base_url) + origin = f"{base.scheme}://{base.netloc}" + resolved = urlsplit(urljoin(f"{origin}/", url)) + if f"{resolved.scheme}://{resolved.netloc}" != origin: + raise ClientError("contract_violation") + return urlunsplit(("", "", resolved.path, resolved.query, "")) + + def data_warning(manifest: Mapping[str, Any]) -> ClientError | None: """The DataWarning a strict fetch raises for a manifest: its first warning above `info` severity, with that warning's code; None when it has none.""" @@ -1791,20 +1850,20 @@ def call( ) self.cursor += 1 self.took(exchange) - used = 0 + answers = [exchange["response"]] while ( retries and self.cursor < len(self.exchanges) and self.exchanges[self.cursor]["request"] == request - and may_retry(request, exchange["response"], used) + and may_retry(request, answers) ): headers = exchange["response"].get("headers", {}) - self.retry_waits.append(retry_wait(headers, used)) + self.retry_waits.append(retry_wait(headers, len(answers) - 1)) exchange = self.exchanges[self.cursor] self.cursor += 1 self.took(exchange) - used += 1 - if retries and may_retry(request, exchange["response"], used): + answers.append(exchange["response"]) + if retries and may_retry(request, answers): raise _UnfitError( f"exchange {self.cursor - 1} is a retryable refusal with retries " f"left, and the record holds no retry of {method} {target}" @@ -1866,8 +1925,8 @@ def body(self, response: dict[str, Any]) -> bytes: def download(self, target: str, digest: str, *, origin: bool) -> None: """A file through the route that redirects to its signed URL: an - artifact's root-relative `url` when `origin`, else a path under the - base URL. The client fetches once the URL the route's `location` + `origin_path`, as `artifact_route` places an artifact's `url`, when + `origin`, else a path under the base URL. The client fetches once the URL the route's `location` names, as `download_target` places it. A refused fetch, or bytes that do not hash to `digest`, ask the route once more, and a second failure raises.""" @@ -1996,11 +2055,12 @@ def member( artifact = pick_artifact(manifest, rendering) if artifact is None: raise ClientError("contract_violation") + route = artifact_route(self.base_url, artifact["url"]) built = manifest["definition"]["spec_id"] sentence = None if spec is None else spec.get("sentence") if spec is None or built != spec["spec_id"] or sentence is None: sentence = self.sentence(parts, manifest["definition"], spec) - self.download(artifact["url"], artifact["artifact_digest"], origin=True) + self.download(route, artifact["artifact_digest"], origin=True) return { "parts": parts, "spec_id": built, @@ -2088,7 +2148,8 @@ def stored_file( ) if artifact is not None: try: - self.download(artifact["url"], digest, origin=True) + route = artifact_route(self.base_url, artifact["url"]) + self.download(route, digest, origin=True) except ClientError as error: if error.code not in FILE_GONE: raise @@ -2762,10 +2823,15 @@ def validate() -> list[str]: "client-codes.json", validators["client-codes.schema.json"], client_codes ) scenario_schema = validators["scenario.schema.json"].schema + rules_schema = validators["rules/rules.schema.json"].schema problems.extend( errors or _check_client_codes( - client_codes, actions, registry, error_classes(scenario_schema) + client_codes, + actions, + registry, + error_classes(scenario_schema), + key_lookup_reasons(rules_schema), ) ) client_rows = [] if errors else client_codes["codes"] @@ -2779,7 +2845,12 @@ def validate() -> list[str]: errors = _schema_problems( "proxy-codes.json", validators["proxy-codes.schema.json"], proxy_codes ) - problems.extend(errors or _check_proxy_codes(proxy_codes, taken)) + problems.extend( + errors + or _check_other_codes( + "proxy-codes.json", [row["code"] for row in proxy_codes["codes"]], taken + ) + ) proxy_rows = [] if errors else proxy_codes["codes"] warning_codes = _load(PACKAGE_DIR / "warning-codes.json") errors = _schema_problems( @@ -2790,7 +2861,7 @@ def validate() -> list[str]: or _check_warning_codes( warning_codes, {**taken, "proxy-codes.json": {row["code"] for row in proxy_rows}}, - key_format_reasons(validators["rules/rules.schema.json"].schema), + key_format_reasons(rules_schema), ) ) From 142192ab25f8257eaaf15f6db5205509064c169f Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Wed, 21 Oct 2026 14:32:43 +0200 Subject: [PATCH 21/39] feat(client-contract): pin each error's trace id Every error outcome carries trace_id. An error that describes a response carries that response's trace id: the body's trace_id when the body is an object holding one, else the x-dfo-trace-id header, else null. Refusals, failed operations, VersionUnavailableError, unexpected_response, contract_violation on a body, answer_declined, answer_incomplete and a strict SearchWarning or DataWarning describe a response. An error that describes the caller's input, such as choice_invalid, invalid_argument or a key-lookup reason, and one raised on a storage-host response carry null. The capture tool keeps x-dfo-trace-id on recorded responses and writes trace_id on every error outcome. search-refused-without-code pins the body over the header, search-unauthorized the header on a bodiless refusal, answer-timed-out an incomplete answer taking the Search response's header, and choose-refused-shared-label a choice_invalid that stays null beside one. --- python/client-contract/CHANGELOG.md | 2 +- python/client-contract/README.md | 4 +- .../dfo_client_contract/scenario.schema.json | 11 +- .../scenarios/answer-catalogue.json | 3 +- .../scenarios/answer-declined.json | 3 +- .../answer-definition-spec-id-mismatch.json | 3 +- .../scenarios/answer-empty-parts.json | 3 +- .../scenarios/answer-mixed-fetch-raises.json | 3 +- .../answer-part-status-not-a-string.json | 3 +- .../answer-spec-without-identity.json | 3 +- .../answer-spec-without-resolved.json | 3 +- .../scenarios/answer-timed-out.json | 10 +- .../scenarios/answer-unknown-kind.json | 3 +- .../scenarios/answer-unknown-part-status.json | 3 +- .../scenarios/answer-unsupported-part.json | 3 +- .../choose-option-two-part-query.json | 3 +- .../choose-option-without-data-query.json | 3 +- .../choose-refused-answered-part.json | 3 +- ...hoose-refused-mention-names-two-parts.json | 3 +- .../scenarios/choose-refused-no-choice.json | 3 +- .../scenarios/choose-refused-no-options.json | 3 +- .../choose-refused-option-out-of-range.json | 3 +- ...se-refused-part-without-variable-text.json | 3 +- .../choose-refused-shared-label.json | 10 +- .../scenarios/choose-refused-two-choices.json | 3 +- .../choose-refused-unknown-label.json | 3 +- .../choose-refused-unknown-part.json | 3 +- .../choose-refused-unknown-status.json | 3 +- .../fetch-frame-several-readings.json | 3 +- .../fetch-partial-nothing-answered.json | 3 +- .../fetch-ref-expired-newer-version.json | 1 + .../fetch-ref-expired-not-reproducible.json | 1 + .../fetch-ref-signed-url-refused-twice.json | 3 +- .../scenarios/fetch-ref-unknown-version.json | 3 +- .../scenarios/fetch-renamed-strict-field.json | 3 +- .../scenarios/fetch-spec-504-then-503.json | 1 + .../scenarios/fetch-spec-504-twice.json | 1 + .../fetch-spec-capability-unavailable.json | 3 +- .../scenarios/fetch-spec-digest-mismatch.json | 3 +- .../fetch-spec-foreign-artifact-url.json | 3 +- .../fetch-spec-manifest-without-identity.json | 3 +- .../fetch-spec-member-not-resolvable.json | 3 +- .../scenarios/fetch-spec-poll-not-found.json | 1 + .../scenarios/fetch-spec-request-invalid.json | 3 +- .../fetch-spec-resubmit-other-spec.json | 3 +- .../fetch-spec-storage-artifact-url.json | 3 +- .../scenarios/fetch-spec-strict-warning.json | 10 +- .../newest-version-unreadable-page.json | 3 +- .../operation-failed-without-error.json | 1 + .../scenarios/search-body-not-an-object.json | 3 +- .../scenarios/search-no-json-body.json | 10 +- .../scenarios/search-proxy-unavailable.json | 1 + .../search-refused-without-code.json | 7 +- .../scenarios/search-unauthorized.json | 10 +- .../scenarios/search-warning-top5.json | 3 +- tools/capture_client_contract.py | 213 +++++++++++++----- tools/tests/test_capture_client_contract.py | 6 +- tools/tests/test_validate_client_contract.py | 94 +++++++- tools/validate_client_contract.py | 142 +++++++++--- 59 files changed, 489 insertions(+), 164 deletions(-) diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index a2a9b4f..92c3c21 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -14,7 +14,7 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be - `scenario.schema.json`, the scenario record, and 101 scenarios: 31 recorded against the composed dfo-apis app at `635943e03`, and 70 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 2,105,201 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, a part without variable_text, an unknown status without a restatement, a shared label, a one-part option whose data_query holds two parts, the separate and operations echo, an unsupported part's placeholder, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a cut-off build retried after its Retry-After, a build refused 504 then 503 and one refused 503 then 504, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, a signed URL refused on both rounds, a relative files-route Location, an artifact url on a foreign origin, on the storage host and absolute on the API's origin, a manifest definition without identity, a Search spec without identity or resolved, nested specs no rule reads, an empty parts list, a Search body that is not an object, a codeless 503 problem document that is not retryable, a 401, an identity resubmit answering another spec, a part whose status is not a string, a Search spec whose definition names another spec_id, a Search response with no JSON body, an option with no data_query, empty entities and facets, a Sunset header issued once, `x-dfo-warning` messages and a Deprecation and Sunset pair, an unreadable versions page, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, 503 polls retried within the budget an answered poll restores, a 404 poll that raises, a failed operation posted again, a failed operation with no error, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route. - `client-codes.json` and its schema: the 17 codes a client sets on the errors it raises itself, each with its error class, retryable flag and condition, disjoint from `actions.json` and `registries/codes.json`, and the `client_codes()` and `client_codes_schema()` accessors. Every scenario error the client raises itself carries its code, and `refusal_without_code` names a refusal whose body carries no code. - `proxy-codes.json` and its schema, the website proxy's `rate_limited` and `transient_unavailable` codes with their statuses, and `warning-codes.json` and its schema, the 5 codes a client sets on the warnings it issues itself, with the `proxy_codes()` and `warning_codes()` accessors. -- Scenario outcomes give `retry_waits`, the waits before each retry, and `warnings`, the warning codes a step's responses issued. Scenario steps take no `timeout`. +- Error outcomes give the error's `trace_id`, the body's, else the `x-dfo-trace-id` header's, else null. Scenario outcomes give `retry_waits`, the waits before each retry, and `warnings`, the warning codes a step's responses issued. Scenario steps take no `timeout`. - `dataset-ref.schema.json`, the frozen `DatasetRef` format, with accepted and rejected examples. - `tools/capture_client_contract.py`, which captures `served/openapi.json` from a dfo-apis checkout in process and records the scenarios against a base URL, dev by default, or with `record --offline` derives their outcomes again from the records with no request. A local app's signed URLs are written as the storage URLs a deployment signs. - `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, checks `client-codes.json` against them and against the reasons the key-lookup rule raises, and checks each scenario's `expect` against the outcomes its exchanges, `actions.json` and `client-codes.json` give, each Search request against the input its steps derive, a sentence lookup's `entity_groups` included, each build's `input.scope` against the narrowing its step names over the spec's bound roles, each build's options against its layout, each Search request's whole body, each download against its artifact's digest, each recorded scenario's commit against `served/SOURCE.json`, each proxy refusal's code against `proxy-codes.json`, and each absolute URL against the storage host. A record that ends a run of retries while a retry remains does not fit. The outcomes include each long build's operation id, poll waits and resubmissions, and a `VersionUnavailableError`'s newest version. diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 2c720fe..88ee026 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -118,7 +118,7 @@ An answer's gaps follow from its parts. A candidates part is a `choice` gap, its ## Client codes -`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, `retryable`, and a one-line `condition`. `retryable` is the flag both clients generate onto the error: `deadline_exceeded`, `download_failed` and `network_error` are retryable, `digest_mismatch` and the rest are not, and `refusal_without_code` is retryable as its status is, which its row gives as `by_status`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps the server's code: the problem document's `code`, or the website proxy's `error`. A refusal whose body carries neither raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`; no other row does. A problem document without a code still gives the error its `retryable` and `trace_id`, so a 503 whose body says `retryable: false` raises at once, which `search-refused-without-code` pins. Every refusal's trace id is the body's `trace_id`, else the `x-dfo-trace-id` header; no outcome carries it, so no scenario pins it. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. Each reason the key-lookup rule raises, `key_empty`, `profile_not_found`, `profile_without_key` and `credentials_file_invalid`, is a row of class `AuthenticationError`. The list holds no warning. `warning-codes.json` lists, sorted by code, each code a client sets on a warning it issues itself, with its class and condition: `route_deprecated`, a `DfoDeprecationWarning`, for a `Deprecation` or `Sunset` header; `server_warning`, a `DfoWarning`, for an `x-dfo-warning` header; and `key_checksum_mismatch`, `key_not_base62` and `key_unknown_prefix`, each a `DfoWarning`, for a key that fails the key-format rule with that reason. Both clients generate their warning codes from it and issue no other. No warning code is a code in another table or in `registries/codes.json`. A `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and a null code when they differ in several ways. A `DataWarning` carries the manifest warning's code. +`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, `retryable`, and a one-line `condition`. `retryable` is the flag both clients generate onto the error: `deadline_exceeded`, `download_failed` and `network_error` are retryable, `digest_mismatch` and the rest are not, and `refusal_without_code` is retryable as its status is, which its row gives as `by_status`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps the server's code: the problem document's `code`, or the website proxy's `error`. A refusal whose body carries neither raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`; no other row does. A problem document without a code still gives the error its `retryable` and `trace_id`, so a 503 whose body says `retryable: false` raises at once, which `search-refused-without-code` pins. Every refusal's trace id is the body's `trace_id`, else the `x-dfo-trace-id` header, else null: `search-refused-without-code` pins the body's winning over the header, and `search-unauthorized` the header's for a refusal with no body. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. Each reason the key-lookup rule raises, `key_empty`, `profile_not_found`, `profile_without_key` and `credentials_file_invalid`, is a row of class `AuthenticationError`. The list holds no warning. `warning-codes.json` lists, sorted by code, each code a client sets on a warning it issues itself, with its class and condition: `route_deprecated`, a `DfoDeprecationWarning`, for a `Deprecation` or `Sunset` header; `server_warning`, a `DfoWarning`, for an `x-dfo-warning` header; and `key_checksum_mismatch`, `key_not_base62` and `key_unknown_prefix`, each a `DfoWarning`, for a key that fails the key-format rule with that reason. Both clients generate their warning codes from it and issue no other. No warning code is a code in another table or in `registries/codes.json`. A `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and a null code when they differ in several ways. A `DataWarning` carries the manifest warning's code. ## Scenarios @@ -138,7 +138,7 @@ A step that acts on an earlier result follows one: `choose` follows `search` or An exchange's request names its target in one of three ways. `path` is a path the client composes under the base URL, such as `/search/resolve`. `origin_path` is a root-relative URL the server returned, such as an artifact's `url`, or the path and query of an absolute one on the API's origin, which resolves against the base URL's origin and never against its path. `url` is an absolute URL outside the API, such as the signed storage URL a files route redirects to, which the client fetches with a bare request carrying no client header and no key. `json` holds the request body members that must match; a recorded scenario lists every member the client sent. The response gives `status`, the `headers` a client reads, and a `json` body or a `body_file`, a binary body in `scenarios/`. A scenario's own body files are named `.` and `-.`; a synthetic scenario may instead name a body file its parent names. -A `newest_version` outcome gives the `content_version` the step found, or null. An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a warning's code, which for a `SearchWarning` may be null, or for any other error the client raises itself its code in `client-codes.json`. A `VersionUnavailableError` also gives `newest_version`, the version the lookup found, or null. A dataset or error outcome of a step that made a long build gives `long_builds`, one entry per build the server ran on, in order: the `operation_id` the client polled last, the `poll_waits` in seconds before each poll, and the number of `resubmissions`. Any outcome of a step that retried a refused request gives `retry_waits`, the seconds before each retry in order, and any outcome of a step whose API responses issued warnings gives `warnings`, their codes from `warning-codes.json` in order. +A `newest_version` outcome gives the `content_version` the step found, or null. An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a warning's code, which for a `SearchWarning` may be null, or for any other error the client raises itself its code in `client-codes.json`. Every error outcome gives its `trace_id`: a refusal's, as the refusal rules below give it; a failed operation's, its error document's `trace_id`, else the `x-dfo-trace-id` header of the response that carried the failed resource; a `VersionUnavailableError`'s, its first refusal's. An error the client raises itself follows one rule: an error that describes a response carries that response's trace id, and an error that describes the caller's input carries null. The trace id is the one a user quotes to find the fault in the server's logs. The errors that describe a response are `unexpected_response`, `contract_violation` on a body, `answer_declined`, `answer_incomplete`, and a strict fetch's `SearchWarning` or `DataWarning`. The id is the body's `trace_id` when the body is an object holding one, else the `x-dfo-trace-id` header, else null. `answer_declined`, `answer_incomplete`, a `SearchWarning`, and a `contract_violation` a choice raises on an option describe the held answer, so they carry the trace id of the Search response that answered it. The errors that describe the caller's input, `choice_invalid`, `invalid_argument` and the key-lookup reasons, carry null, and so do `digest_mismatch` and `download_failed`, which describe a storage-host fetch. `search-no-json-body`, `fetch-spec-strict-warning` and `answer-timed-out` pin a trace id on an error that describes a response, and `choose-refused-shared-label` a null one on a choice whose answer's response carries a trace id. A `VersionUnavailableError` also gives `newest_version`, the version the lookup found, or null. A dataset or error outcome of a step that made a long build gives `long_builds`, one entry per build the server ran on, in order: the `operation_id` the client polled last, the `poll_waits` in seconds before each poll, and the number of `resubmissions`. Any outcome of a step that retried a refused request gives `retry_waits`, the seconds before each retry in order, and any outcome of a step whose API responses issued warnings gives `warnings`, their codes from `warning-codes.json` in order. Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry where the retry rules allow one, except on a poll, where the long-build rules count retries, and a record that ends a run of retries while the rules allow another does not fit, since the client makes it, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, each POST carries its body, each build posts the body the rules give for the spec it builds, so the builds' order and spec_ids are checked, each Search request posts the whole body `{"schema_version": 1, "input": ...}` with the input the rules give: the question, a choice's input, or a member's identity, each poll names the operation the client holds, each files route is the one the artifact's `url` names, each signed download is the URL the files route's `location` names, each retry waits the wait the retry rules give, and each response's warning headers issue the warnings the warning rules give. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. diff --git a/python/client-contract/src/dfo_client_contract/scenario.schema.json b/python/client-contract/src/dfo_client_contract/scenario.schema.json index e455121..b0af29b 100644 --- a/python/client-contract/src/dfo_client_contract/scenario.schema.json +++ b/python/client-contract/src/dfo_client_contract/scenario.schema.json @@ -882,7 +882,8 @@ "additionalProperties": false, "required": [ "class", - "code" + "code", + "trace_id" ], "properties": { "class": { @@ -911,6 +912,14 @@ "null" ] }, + "trace_id": { + "description": "A refusal's trace id: its body's trace_id, else its x-dfo-trace-id header, else null. A failed operation's is its error document's, else the header of the response that carried the failed resource; a VersionUnavailableError's is its first refusal's. An error the client raises itself that describes a response, an unexpected_response, a contract_violation, an answer_declined, an answer_incomplete, a SearchWarning or a DataWarning, carries that response's trace id, the held answer's Search response for those that describe the answer, as the body's trace_id, else the x-dfo-trace-id header, else null. An error that describes the caller's input, or a storage-host fetch, carries null.", + "type": [ + "string", + "null" + ], + "minLength": 1 + }, "newest_version": { "description": "For a VersionUnavailableError only: the newest version the lookup found, or null.", "oneOf": [ diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json index 93ba6dd..72e1089 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json @@ -80,7 +80,8 @@ { "error": { "class": "DeclinedError", - "code": "answer_declined" + "code": "answer_declined", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json index 8d4a5ff..6b94385 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json @@ -86,7 +86,8 @@ { "error": { "class": "DeclinedError", - "code": "answer_declined" + "code": "answer_declined", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json index 0d47b11..e711a79 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json @@ -3678,7 +3678,8 @@ { "error": { "class": "ContractError", - "code": "contract_violation" + "code": "contract_violation", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json index c0c05c5..591e0c3 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json @@ -97,7 +97,8 @@ { "error": { "class": "ContractError", - "code": "contract_violation" + "code": "contract_violation", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json index d856c89..be12d86 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json @@ -3624,7 +3624,8 @@ { "error": { "class": "IncompleteAnswerError", - "code": "answer_incomplete" + "code": "answer_incomplete", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-part-status-not-a-string.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-part-status-not-a-string.json index 788437b..1ad50c4 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-part-status-not-a-string.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-part-status-not-a-string.json @@ -3602,7 +3602,8 @@ { "error": { "class": "ContractError", - "code": "contract_violation" + "code": "contract_violation", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json index 0f4a602..d08faaf 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json @@ -3615,7 +3615,8 @@ { "error": { "class": "ContractError", - "code": "contract_violation" + "code": "contract_violation", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json index e5b08a4..9ae502b 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json @@ -395,7 +395,8 @@ { "error": { "class": "ContractError", - "code": "contract_violation" + "code": "contract_violation", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json index cc8a3e9..830edf4 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json @@ -1,11 +1,11 @@ { "format_version": 1, "name": "answer-timed-out", - "description": "A no_data part of an answer whose diagnostics say Search timed out is a timed_out gap, whatever its reason, and fetching the answer raises IncompleteAnswerError.", + "description": "A no_data part of an answer whose diagnostics say Search timed out is a timed_out gap, whatever its reason, and fetching the answer raises IncompleteAnswerError, which describes the answer and carries its response's trace id.", "origin": { "kind": "synthetic", "derived_from": "answer-mixed-fetch-raises", - "edit": "The answer's diagnostics.timed_out becomes true." + "edit": "The answer's diagnostics.timed_out becomes true, and its response carries x-dfo-trace-id 55555555555555555555555555555555." }, "call": [ { @@ -32,7 +32,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "55555555555555555555555555555555" }, "json": { "schema_version": 1, @@ -3623,7 +3624,8 @@ { "error": { "class": "IncompleteAnswerError", - "code": "answer_incomplete" + "code": "answer_incomplete", + "trace_id": "55555555555555555555555555555555" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json index 3110dcf..df6d751 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json @@ -239,7 +239,8 @@ { "error": { "class": "ContractError", - "code": "contract_violation" + "code": "contract_violation", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json index 857a8b9..33ebe05 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json @@ -3623,7 +3623,8 @@ { "error": { "class": "IncompleteAnswerError", - "code": "answer_incomplete" + "code": "answer_incomplete", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json index 66452cb..6111beb 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json @@ -3617,7 +3617,8 @@ { "error": { "class": "IncompleteAnswerError", - "code": "answer_incomplete" + "code": "answer_incomplete", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-option-two-part-query.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-two-part-query.json index b9fdad7..c0e7bbc 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-option-two-part-query.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-two-part-query.json @@ -276,7 +276,8 @@ { "error": { "class": "ContractError", - "code": "contract_violation" + "code": "contract_violation", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-option-without-data-query.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-without-data-query.json index ac4f30a..dcde7b4 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-option-without-data-query.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-without-data-query.json @@ -237,7 +237,8 @@ { "error": { "class": "ContractError", - "code": "contract_violation" + "code": "contract_violation", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json index 7409751..0eb6866 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json @@ -3625,7 +3625,8 @@ { "error": { "class": "InvalidRequestError", - "code": "choice_invalid" + "code": "choice_invalid", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json index 02fec5e..5463b8c 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json @@ -431,7 +431,8 @@ { "error": { "class": "InvalidRequestError", - "code": "choice_invalid" + "code": "choice_invalid", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json index 2c869e7..ed37c67 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json @@ -3694,7 +3694,8 @@ { "error": { "class": "InvalidRequestError", - "code": "choice_invalid" + "code": "choice_invalid", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json index 481c899..d11d387 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json @@ -201,7 +201,8 @@ { "error": { "class": "InvalidRequestError", - "code": "choice_invalid" + "code": "choice_invalid", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json index 0e8785d..04e665d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json @@ -2384,7 +2384,8 @@ { "error": { "class": "InvalidRequestError", - "code": "choice_invalid" + "code": "choice_invalid", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-part-without-variable-text.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-part-without-variable-text.json index 96be9af..b73e2d7 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-part-without-variable-text.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-part-without-variable-text.json @@ -4522,7 +4522,8 @@ { "error": { "class": "InvalidRequestError", - "code": "choice_invalid" + "code": "choice_invalid", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-label.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-label.json index a75ce8d..958aecf 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-label.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-label.json @@ -1,11 +1,11 @@ { "format_version": 1, "name": "choose-refused-shared-label", - "description": "A label two options share matches several, so choosing by it raises InvalidRequestError with no request.", + "description": "A label two options share matches several, so choosing by it raises InvalidRequestError with no request. The error describes the caller's choice, so it carries no trace id although the answer's response has one.", "origin": { "kind": "synthetic", "derived_from": "choose-place-one-part", - "edit": "The no_data part's second option takes the first one's label." + "edit": "The no_data part's second option takes the first one's label, and the search's response carries x-dfo-trace-id 55555555555555555555555555555555." }, "call": [ { @@ -33,7 +33,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "55555555555555555555555555555555" }, "json": { "schema_version": 1, @@ -259,7 +260,8 @@ { "error": { "class": "InvalidRequestError", - "code": "choice_invalid" + "code": "choice_invalid", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json index 5c2f432..45c6f9d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json @@ -430,7 +430,8 @@ { "error": { "class": "InvalidRequestError", - "code": "choice_invalid" + "code": "choice_invalid", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json index 46e373f..c7c6902 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json @@ -259,7 +259,8 @@ { "error": { "class": "InvalidRequestError", - "code": "choice_invalid" + "code": "choice_invalid", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json index e49f3bb..e2e4f9c 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json @@ -3625,7 +3625,8 @@ { "error": { "class": "InvalidRequestError", - "code": "choice_invalid" + "code": "choice_invalid", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-status.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-status.json index 97d3e91..f8ce75c 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-status.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-status.json @@ -4513,7 +4513,8 @@ { "error": { "class": "InvalidRequestError", - "code": "choice_invalid" + "code": "choice_invalid", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json index 7923382..59b702c 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json @@ -9849,7 +9849,8 @@ { "error": { "class": "InvalidRequestError", - "code": "invalid_argument" + "code": "invalid_argument", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json index fbd95ea..3497b90 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json @@ -259,7 +259,8 @@ { "error": { "class": "IncompleteAnswerError", - "code": "answer_incomplete" + "code": "answer_incomplete", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json index c53b99d..0cf5707 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json @@ -902,6 +902,7 @@ "error": { "class": "VersionUnavailableError", "code": "artifact_expired", + "trace_id": "00000000000000000000000000000000", "newest_version": "cv_11111111111111111111111111111111" } } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json index 2334584..c41d811 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json @@ -254,6 +254,7 @@ "error": { "class": "VersionUnavailableError", "code": "artifact_expired", + "trace_id": "00000000000000000000000000000000", "newest_version": "cv_b92d94774702c7f05f2075d0b03dd756" } } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused-twice.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused-twice.json index bb60be9..4fd7e89 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused-twice.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused-twice.json @@ -858,7 +858,8 @@ { "error": { "class": "ServerError", - "code": "download_failed" + "code": "download_failed", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-unknown-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-unknown-version.json index 3e65680..ffbebd5 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-unknown-version.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-unknown-version.json @@ -130,7 +130,8 @@ { "error": { "class": "NotFoundError", - "code": "snapshot_not_found" + "code": "snapshot_not_found", + "trace_id": "a2f44c8df4c642a58f0a2a0723f7e104" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json index 26487f6..69122ec 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json @@ -4465,7 +4465,8 @@ { "error": { "class": "ContractError", - "code": "contract_violation" + "code": "contract_violation", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-then-503.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-then-503.json index 1cf4d40..7f82896 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-then-503.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-then-503.json @@ -296,6 +296,7 @@ "error": { "class": "ServerError", "code": "service_unavailable", + "trace_id": "00000000000000000000000000000000", "retry_waits": [ 0.5 ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-twice.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-twice.json index 9653e39..22f9d24 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-twice.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-twice.json @@ -296,6 +296,7 @@ "error": { "class": "ServerError", "code": "timeout", + "trace_id": "00000000000000000000000000000000", "retry_waits": [ 0.5 ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-capability-unavailable.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-capability-unavailable.json index 0bb8cf1..f5495bf 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-capability-unavailable.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-capability-unavailable.json @@ -191,7 +191,8 @@ { "error": { "class": "InvalidRequestError", - "code": "capability_unavailable" + "code": "capability_unavailable", + "trace_id": "00000000000000000000000000000000" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json index 4815ccb..e0da9df 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json @@ -908,7 +908,8 @@ { "error": { "class": "ServerError", - "code": "digest_mismatch" + "code": "digest_mismatch", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-foreign-artifact-url.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-foreign-artifact-url.json index 1e30a1f..a6647fe 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-foreign-artifact-url.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-foreign-artifact-url.json @@ -858,7 +858,8 @@ { "error": { "class": "ContractError", - "code": "contract_violation" + "code": "contract_violation", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json index 5fdf8ad..f6083d2 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json @@ -793,7 +793,8 @@ { "error": { "class": "ContractError", - "code": "contract_violation" + "code": "contract_violation", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-member-not-resolvable.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-member-not-resolvable.json index 0b7cd7a..ff7635a 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-member-not-resolvable.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-member-not-resolvable.json @@ -193,7 +193,8 @@ { "error": { "class": "InvalidRequestError", - "code": "member_not_resolvable" + "code": "member_not_resolvable", + "trace_id": "00000000000000000000000000000000" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json index 16b4c78..72285d3 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json @@ -188,6 +188,7 @@ "error": { "class": "NotFoundError", "code": "operation_not_found", + "trace_id": "00000000000000000000000000000000", "long_builds": [ { "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json index 3957888..3b50acf 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json @@ -201,7 +201,8 @@ { "error": { "class": "InvalidRequestError", - "code": "request_invalid" + "code": "request_invalid", + "trace_id": "a36e8b07217c4469b8cba617c14c6170" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json index 6f503da..dd4cda0 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json @@ -4582,7 +4582,8 @@ { "error": { "class": "ContractError", - "code": "contract_violation" + "code": "contract_violation", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json index 268467c..c8a6696 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json @@ -858,7 +858,8 @@ { "error": { "class": "ContractError", - "code": "contract_violation" + "code": "contract_violation", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json index d703c98..286a518 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json @@ -1,11 +1,11 @@ { "format_version": 1, "name": "fetch-spec-strict-warning", - "description": "A strict fetch raises the manifest's first warning above info severity, coverage_below_scope at warn here, as DataWarning before the download.", + "description": "A strict fetch raises the manifest's first warning above info severity, coverage_below_scope at warn here, as DataWarning before the download, with the trace id of the build response it read.", "origin": { "kind": "synthetic", "derived_from": "fetch-spec-known-sentence", - "edit": "The fetch is strict, and the exchanges after the build go." + "edit": "The fetch is strict, the build's response carries x-dfo-trace-id 33333333333333333333333333333333, and the exchanges after the build go." }, "call": [ { @@ -175,7 +175,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "33333333333333333333333333333333" }, "json": { "schema_version": 1, @@ -859,7 +860,8 @@ { "error": { "class": "DataWarning", - "code": "coverage_below_scope" + "code": "coverage_below_scope", + "trace_id": "33333333333333333333333333333333" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json b/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json index 95d6791..29fcfc3 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json @@ -115,7 +115,8 @@ { "error": { "class": "ContractError", - "code": "contract_violation" + "code": "contract_violation", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json b/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json index 5893a9d..d4c2725 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json @@ -75,6 +75,7 @@ "error": { "class": "ServerError", "code": "operation_failed", + "trace_id": null, "long_builds": [ { "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json b/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json index 9be0338..c488590 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json @@ -241,7 +241,8 @@ { "error": { "class": "ContractError", - "code": "contract_violation" + "code": "contract_violation", + "trace_id": null } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-no-json-body.json b/python/client-contract/src/dfo_client_contract/scenarios/search-no-json-body.json index d121b47..269e29d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-no-json-body.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-no-json-body.json @@ -1,11 +1,11 @@ { "format_version": 1, "name": "search-no-json-body", - "description": "A 2xx Search response with no JSON body raises ContractError unexpected_response.", + "description": "A 2xx Search response with no JSON body raises ContractError unexpected_response, with that response's trace id.", "origin": { "kind": "synthetic", "derived_from": "search-place-ambiguous", - "edit": "The search answers 200 with an empty text/html body." + "edit": "The search answers 200 with an empty text/html body and x-dfo-trace-id 33333333333333333333333333333333." }, "call": [ { @@ -29,7 +29,8 @@ "response": { "status": 200, "headers": { - "content-type": "text/html; charset=utf-8" + "content-type": "text/html; charset=utf-8", + "x-dfo-trace-id": "33333333333333333333333333333333" } } } @@ -38,7 +39,8 @@ { "error": { "class": "ContractError", - "code": "unexpected_response" + "code": "unexpected_response", + "trace_id": "33333333333333333333333333333333" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json index e56c3a9..8382069 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json @@ -92,6 +92,7 @@ "error": { "class": "ServerError", "code": "transient_unavailable", + "trace_id": null, "retry_waits": [ 0.5, 1.0 diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-refused-without-code.json b/python/client-contract/src/dfo_client_contract/scenarios/search-refused-without-code.json index 8b6b3bc..5cb7282 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-refused-without-code.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-refused-without-code.json @@ -1,11 +1,11 @@ { "format_version": 1, "name": "search-refused-without-code", - "description": "A problem document with no code raises refusal_without_code with the class its status maps to, and keeps its body's retryable, so a retryable false 503 is not retried.", + "description": "A problem document with no code raises refusal_without_code with the class its status maps to, and keeps its body's retryable and trace_id, so a retryable false 503 is not retried and its trace id is the body's, not the header's.", "origin": { "kind": "synthetic", "derived_from": "search-place-ambiguous", - "edit": "A 503 problem document with no code, retryable false and a trace_id answers the search." + "edit": "A 503 problem document with no code, retryable false and trace_id 11111111111111111111111111111111 answers the search, with x-dfo-trace-id 22222222222222222222222222222222." }, "call": [ { @@ -46,7 +46,8 @@ { "error": { "class": "ServerError", - "code": "refusal_without_code" + "code": "refusal_without_code", + "trace_id": "11111111111111111111111111111111" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-unauthorized.json b/python/client-contract/src/dfo_client_contract/scenarios/search-unauthorized.json index 05dc2fc..0a65d0d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-unauthorized.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-unauthorized.json @@ -1,11 +1,11 @@ { "format_version": 1, "name": "search-unauthorized", - "description": "A 401 resolves the key again; the key is unchanged, so the client sends nothing more and raises AuthenticationError refusal_without_code.", + "description": "A 401 resolves the key again; the key is unchanged, so the client sends nothing more and raises AuthenticationError refusal_without_code, whose trace id is the header's, since the refusal has no body.", "origin": { "kind": "synthetic", "derived_from": "search-place-ambiguous", - "edit": "A bodiless 401 answers the search." + "edit": "A bodiless 401 with x-dfo-trace-id 22222222222222222222222222222222 answers the search." }, "call": [ { @@ -29,7 +29,8 @@ "response": { "status": 401, "headers": { - "www-authenticate": "Bearer" + "www-authenticate": "Bearer", + "x-dfo-trace-id": "22222222222222222222222222222222" } } } @@ -38,7 +39,8 @@ { "error": { "class": "AuthenticationError", - "code": "refusal_without_code" + "code": "refusal_without_code", + "trace_id": "22222222222222222222222222222222" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json b/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json index 641b614..e20d08e 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json @@ -4004,7 +4004,8 @@ { "error": { "class": "SearchWarning", - "code": null + "code": null, + "trace_id": null } }, { diff --git a/tools/capture_client_contract.py b/tools/capture_client_contract.py index cb062da..f41af4c 100644 --- a/tools/capture_client_contract.py +++ b/tools/capture_client_contract.py @@ -106,6 +106,7 @@ pick_artifact, posted_scope, problem_body, + read_from, refusal_error, rendering_for, resubmitted_sentence, @@ -116,6 +117,7 @@ selector_path, sentence_entry, surface_problems, + trace_id, versions_path, with_step_notes, ) @@ -137,6 +139,7 @@ "deprecation", "sunset", "x-dfo-warning", + "x-dfo-trace-id", ) @@ -381,6 +384,7 @@ class Recorder: canned_served: int = 0 warned: set[tuple[str, ...]] = field(default_factory=set) warnings: list[str] = field(default_factory=list) + read_trace: str | None = None def api(self, method: str, path: str, json_body: Any = None) -> Response: """A request to `path` under the base URL.""" @@ -420,6 +424,7 @@ def _send( exchange = self.canned.pop(0) self.exchanges.append(exchange) self.canned_served += 1 + self._traced(exchange["response"], bare=bare) return self._warned(_canned_response(exchange["response"]), bare=bare) headers = {} if bare else {"user-agent": "dfo-client-contract-recorder/1"} @@ -432,9 +437,17 @@ def _send( ) if not bare and "x-dfo-commit" in response.headers: self.commits.add(response.headers["x-dfo-commit"]) - self.exchanges.append({"request": request, "response": self._keep(response)}) + kept = self._keep(response) + self.exchanges.append({"request": request, "response": kept}) + self._traced(kept, bare=bare) return self._warned(response, bare=bare) + def _traced(self, kept: Mapping[str, Any], *, bare: bool) -> None: + """Notes an API response's trace id, as the record keeps it, as the + one an error raised on reading it carries.""" + if not bare: + self.read_trace = trace_id(kept.get("json"), kept.get("headers", {})) + def _warned(self, response: Response, *, bare: bool) -> Response: """Notes the warnings an API response's headers issue.""" if not bare: @@ -641,10 +654,12 @@ def _step(self, step: dict[str, Any], run: Callable[[], dict[str, Any]]) -> None self.call.append(step) self.long_builds, self.retry_waits = [], [] self.recorder.warnings = [] + self.recorder.read_trace = None try: outcome = run() except ClientError as error: - outcome = error.outcome(self.client_codes) + trace = self.recorder.read_trace + outcome = read_from(error, trace).outcome(self.client_codes) self.expect.append( with_step_notes( outcome, @@ -683,7 +698,8 @@ def _api(self, method: str, path: str, json_body: Any = None) -> Response: def _resolve(self, input_: dict[str, Any]) -> Answer: response = self._api("POST", "/search/resolve", search_body(input_)) - return answer_from_body(self._acted(response)) + answer = answer_from_body(self._acted(response)) + return replace(answer, trace_id=self.recorder.read_trace) def search(self, question: str) -> Answer: answers: list[Answer] = [] @@ -708,8 +724,12 @@ def choose( answers: list[Answer] = [] def run() -> dict[str, Any]: - choice = choice_for(answer, self.gap_kinds, part, option) - answers.append(self._resolve(choice_input(answer, choice))) + try: + choice = choice_for(answer, self.gap_kinds, part, option) + posts = choice_input(answer, choice) + except ClientError as error: + raise read_from(error, answer.trace_id) from None + answers.append(self._resolve(posts)) return self._answered(answers[0]) self._step(step, run) @@ -733,14 +753,17 @@ def fetch_answer( def run() -> dict[str, Any]: if answer.body["kind"] != "resolution": - raise ClientError("answer_declined") + raise read_from(ClientError("answer_declined"), answer.trace_id) gaps = answer_gaps(answer, self.gap_kinds) readings = _members(answer) if gaps and (not partial or not readings): - raise ClientError("answer_incomplete") + raise read_from(ClientError("answer_incomplete"), answer.trace_id) warns = search_warns(answer) if warns and strict: - raise ClientError(search_warning_code(answer), error="SearchWarning") + raise read_from( + ClientError(search_warning_code(answer), error="SearchWarning"), + answer.trace_id, + ) rendering = rendering_for(layout) if "layout" in rendering and len(readings) > 1: raise ClientError("invalid_argument") @@ -1037,6 +1060,8 @@ def _stored(self, member: dict[str, Any]) -> Member: refusal.code if refusal is not None else "version_unavailable", error=VERSION_UNAVAILABLE, newest_version=newest, + trace_id=refusal.trace_id if refusal is not None else None, + traced=True, ) def _stored_file( @@ -1089,7 +1114,10 @@ def _raise_problem(self, response: Response) -> None: if response.status < 400: return raise refusal_error( - response.status, problem_body(_read(response)), self.actions + response.status, + problem_body(_read(response)), + self.actions, + response.headers, ) @@ -1178,9 +1206,17 @@ def session(self, name: str, **recorder: Any) -> Session: read_shape=self.read_shape, ) - def raised(self, code: str) -> dict[str, Any]: - """The outcome of an error the client raises with `code`.""" - return ClientError(code).outcome(self.client_codes) + def raised( + self, code: str, response: Mapping[str, Any] | None = None + ) -> dict[str, Any]: + """The outcome of an error the client raises with `code`, on reading + the API response `response` when one is given, or else before any + response.""" + error = ClientError(code) + if response is not None: + body, headers = response.get("json"), response.get("headers", {}) + read_from(error, trace_id(body, headers)) + return error.outcome(self.client_codes) def definite_answer(self, question: str) -> Answer: if question not in self._cache: @@ -2031,16 +2067,26 @@ def _capability_unavailable( return [_refusal(build["request"], 501, problem)], error +# The x-dfo-trace-id header of the responses `search-no-json-body` and +# `fetch-spec-strict-warning` raise on, which the errors carry. +READ_TRACE_ID = "3" * 32 + + def _strict_warning(parent: dict[str, Any], ctx: Context) -> Derived: + """The fetch is strict, and its build's manifest, whose response carries + READ_TRACE_ID, raises its first warning above info.""" index = _build_index(parent) - manifest = parent["exchanges"][index]["response"]["json"] - warning = data_warning(manifest) + exchanges = copy.deepcopy(parent["exchanges"][: index + 1]) + response = exchanges[index]["response"] + response.setdefault("headers", {})["x-dfo-trace-id"] = READ_TRACE_ID + warning = data_warning(response["json"]) require(warning is not None, "the manifest carries a warning above info") + read_from(warning, trace_id(response["json"], response["headers"])) call = copy.deepcopy(parent["call"]) call[-1]["strict"] = True return Derived( call, - copy.deepcopy(parent["exchanges"][: index + 1]), + exchanges, [*copy.deepcopy(parent["expect"][:-1]), warning.outcome(ctx.client_codes)], ) @@ -2079,10 +2125,11 @@ def _resubmit_other_spec(parent: dict[str, Any], ctx: Context) -> Derived: posted = parent["call"][-1]["spec"]["spec_id"] require(spec["spec_id"] != posted, "the build answered another spec_id") spec["spec_id"] = spec["definition"]["spec_id"] = posted + error = ctx.raised("contract_violation", exchanges[index]["response"]) return Derived( copy.deepcopy(parent["call"]), exchanges, - [*copy.deepcopy(parent["expect"][:-1]), ctx.raised("contract_violation")], + [*copy.deepcopy(parent["expect"][:-1]), error], ) @@ -2149,7 +2196,10 @@ def _expired_newer(parent: dict[str, Any], ctx: Context) -> Derived: build = copy.deepcopy(parent["exchanges"][_build_index(parent)]) build["response"]["json"]["content_version"] = NEWER_VERSION error = ClientError( - FILE_EXPIRED, error=VERSION_UNAVAILABLE, newest_version=NEWER_VERSION + FILE_EXPIRED, + error=VERSION_UNAVAILABLE, + newest_version=NEWER_VERSION, + trace_id=_EXPIRED["trace_id"], ) return Derived( [{"op": "fetch", "ref": ref}], @@ -2365,7 +2415,7 @@ def _renamed_strict_field(parent: dict[str, Any], ctx: Context) -> Derived: exchanges = copy.deepcopy(parent["exchanges"][: index + 1]) manifest = exchanges[index]["response"]["json"] manifest["contentVersion"] = manifest.pop("content_version") - error = ctx.raised("contract_violation") + error = ctx.raised("contract_violation", exchanges[index]["response"]) return Derived( copy.deepcopy(parent["call"]), exchanges, [parent["expect"][0], error] ) @@ -2379,14 +2429,18 @@ def _choice( part: int | str | None = None, *, edit: BodyEdit | None = None, + headers: Mapping[str, str] | None = None, ) -> Callable[[dict[str, Any], Context], Derived]: - """The parent's search, its answer body changed by `edit`, then a choice - that refuses and makes no request.""" + """The parent's search, its answer body changed by `edit` and its + response carrying `headers` too, then a choice that refuses and makes no + request.""" def derive(parent: dict[str, Any], ctx: Context) -> Derived: canned = copy.deepcopy(parent["exchanges"][:1]) + response = canned[0]["response"] + if headers is not None: + response.setdefault("headers", {}).update(headers) if edit is not None: - response = canned[0]["response"] response["json"] = edit(response["json"], ctx) session = ctx.session("synthetic", canned=canned) answer = session.search(parent["call"][0]["question"]) @@ -2422,14 +2476,23 @@ def derive(parent: dict[str, Any], ctx: Context) -> Derived: def _answer_edit( change: Callable[[dict[str, Any]], None], + headers: Mapping[str, str] | None = None, ) -> Callable[[dict[str, Any], Context], Derived]: """The parent with its first answer body changed, and that answer's - outcome derived again.""" + outcome derived again. With `headers`, the answer's response carries + them too, and the parent's steps run again over the changed exchanges, + so every outcome that reads the answer follows from them.""" def derive(parent: dict[str, Any], ctx: Context) -> Derived: exchanges = copy.deepcopy(parent["exchanges"]) body = exchanges[0]["response"]["json"] change(body) + if headers is not None: + exchanges[0]["response"].setdefault("headers", {}).update(headers) + session = ctx.session("synthetic", canned=exchanges) + drive(session, parent["call"]) + require(not session.recorder.canned, "the steps make every exchange") + return Derived(session.call, session.recorder.exchanges, session.expect) expect = copy.deepcopy(parent["expect"]) expect[0] = answer_outcome(answer_from_body(body), gap_kinds(ctx.actions)) return Derived(copy.deepcopy(parent["call"]), exchanges, expect) @@ -2437,6 +2500,13 @@ def derive(parent: dict[str, Any], ctx: Context) -> Derived: return derive +# The x-dfo-trace-id header the Search responses of `answer-timed-out` and +# `choose-refused-shared-label` carry: the first's answer_incomplete carries +# it, and the second's choice_invalid, which describes the caller's choice, +# does not. +ANSWER_TRACE_ID = "5" * 32 + + def _timed_out(body: dict[str, Any]) -> None: body["diagnostics"]["timed_out"] = True @@ -2455,9 +2525,8 @@ def _unsupported(body: dict[str, Any]) -> None: def _unknown_kind(parent: dict[str, Any], ctx: Context) -> Derived: exchanges = copy.deepcopy(parent["exchanges"]) exchanges[0]["response"]["json"]["kind"] = "verdict" - return Derived( - copy.deepcopy(parent["call"]), exchanges, [ctx.raised("contract_violation")] - ) + error = ctx.raised("contract_violation", exchanges[0]["response"]) + return Derived(copy.deepcopy(parent["call"]), exchanges, [error]) def _partial_nothing_answered(parent: dict[str, Any], ctx: Context) -> Derived: @@ -2611,9 +2680,8 @@ def _versions_renamed(parent: dict[str, Any], ctx: Context) -> Derived: exchanges = copy.deepcopy(parent["exchanges"]) body = exchanges[0]["response"]["json"] body["items"] = body.pop("versions") - return Derived( - copy.deepcopy(parent["call"]), exchanges, [ctx.raised("contract_violation")] - ) + error = ctx.raised("contract_violation", exchanges[0]["response"]) + return Derived(copy.deepcopy(parent["call"]), exchanges, [error]) # The Sunset header `search-sunset-warning`'s responses carry, with no @@ -2662,10 +2730,11 @@ def derive(parent: dict[str, Any], ctx: Context) -> Derived: artifact["url"] = at + artifact["url"] if at == _origin(parent["origin"]["base_url"]): return _same(parent, exchanges) + error = ctx.raised("contract_violation", exchanges[index]["response"]) return Derived( copy.deepcopy(parent["call"]), exchanges[: index + 1], - [*copy.deepcopy(parent["expect"][:-1]), ctx.raised("contract_violation")], + [*copy.deepcopy(parent["expect"][:-1]), error], ) return derive @@ -2724,9 +2793,8 @@ def _search_ends( def derive(parent: dict[str, Any], ctx: Context) -> Derived: exchange = copy.deepcopy(parent["exchanges"][0]) change(exchange["response"]) - return Derived( - copy.deepcopy(parent["call"][:1]), [exchange], [ctx.raised(code)] - ) + error = ctx.raised(code, exchange["response"]) + return Derived(copy.deepcopy(parent["call"][:1]), [exchange], [error]) return derive @@ -2746,7 +2814,10 @@ def _definition_spec_id_differs(response: dict[str, Any]) -> None: def _without_json(response: dict[str, Any]) -> None: del response["json"] - response["headers"] = {"content-type": "text/html; charset=utf-8"} + response["headers"] = { + "content-type": "text/html; charset=utf-8", + "x-dfo-trace-id": READ_TRACE_ID, + } def _without_data_query(body: Any, ctx: Context) -> Any: @@ -2851,14 +2922,17 @@ def _two_part_query(body: Any, ctx: Context) -> Any: def _choice_raises( - code: str, edit: BodyEdit + code: str, edit: BodyEdit, headers: Mapping[str, str] | None = None ) -> Callable[[dict[str, Any], Context], Derived]: - """The parent's choice over its answer changed by `edit`, which raises - the client code `code` with no request.""" + """The parent's choice over its answer changed by `edit`, its Search + response carrying `headers` too, which raises the client code `code` + with no request.""" def derive(parent: dict[str, Any], ctx: Context) -> Derived: choose = parent["call"][1] - derived = _choice(choose["option"], choose.get("part"), edit=edit)(parent, ctx) + derived = _choice( + choose["option"], choose.get("part"), edit=edit, headers=headers + )(parent, ctx) require(derived.expect[-1] == ctx.raised(code), f"the choice raises {code}") return derived @@ -2888,10 +2962,11 @@ def _manifest_without_identity(parent: dict[str, Any], ctx: Context) -> Derived: index = _build_index(parent) exchanges = copy.deepcopy(parent["exchanges"][: index + 1]) del exchanges[index]["response"]["json"]["definition"]["identity"] + error = ctx.raised("contract_violation", exchanges[index]["response"]) return Derived( copy.deepcopy(parent["call"]), exchanges, - [*copy.deepcopy(parent["expect"][:-1]), ctx.raised("contract_violation")], + [*copy.deepcopy(parent["expect"][:-1]), error], ) @@ -2909,8 +2984,9 @@ def _nested_specs_unchecked(parent: dict[str, Any], ctx: Context) -> Derived: # The trace id the codeless problem document of `search-refused-without-code` -# carries. +# carries, and the x-dfo-trace-id header it and `search-unauthorized` carry. BODY_TRACE_ID = "1" * 32 +HEADER_TRACE_ID = "2" * 32 def _refused_without_code(parent: dict[str, Any], ctx: Context) -> Derived: @@ -2925,20 +3001,24 @@ def _refused_without_code(parent: dict[str, Any], ctx: Context) -> Derived: "retryable": False, } refused = _refusal(first["request"], 503, body) - refused["response"]["headers"]["x-dfo-trace-id"] = "2" * 32 - error = refusal_error(503, body, ctx.actions).outcome(ctx.client_codes) + refused["response"]["headers"]["x-dfo-trace-id"] = HEADER_TRACE_ID + error = refusal_error( + 503, body, ctx.actions, refused["response"]["headers"] + ).outcome(ctx.client_codes) return Derived(copy.deepcopy(parent["call"]), [refused], [error]) def _unauthorized(parent: dict[str, Any], ctx: Context) -> Derived: - """A bodiless 401 answers the search. The replay's key does not change - when the client resolves it again, so the client sends nothing more.""" + """A bodiless 401 with a trace id header answers the search. The + replay's key does not change when the client resolves it again, so the + client sends nothing more, and the error's trace id is the header's.""" first = parent["exchanges"][0] + headers = {"www-authenticate": "Bearer", "x-dfo-trace-id": HEADER_TRACE_ID} refused = { "request": copy.deepcopy(first["request"]), - "response": {"status": 401, "headers": {"www-authenticate": "Bearer"}}, + "response": {"status": 401, "headers": headers}, } - error = refusal_error(401, None, ctx.actions).outcome(ctx.client_codes) + error = refusal_error(401, None, ctx.actions, headers).outcome(ctx.client_codes) return Derived(copy.deepcopy(parent["call"]), [refused], [error]) @@ -3038,9 +3118,11 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: Synthetic( "fetch-spec-strict-warning", "fetch-spec-known-sentence", - "The fetch is strict, and the exchanges after the build go.", + f"The fetch is strict, the build's response carries x-dfo-trace-id {READ_TRACE_ID}, " + "and the exchanges after the build go.", "A strict fetch raises the manifest's first warning above info severity, " - "coverage_below_scope at warn here, as DataWarning before the download.", + "coverage_below_scope at warn here, as DataWarning before the download, with the " + "trace id of the build response it read.", _strict_warning, ), Synthetic( @@ -3314,19 +3396,20 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: Synthetic( "search-refused-without-code", "search-place-ambiguous", - "A 503 problem document with no code, retryable false and a trace_id answers the " - "search.", + f"A 503 problem document with no code, retryable false and trace_id {BODY_TRACE_ID} " + f"answers the search, with x-dfo-trace-id {HEADER_TRACE_ID}.", "A problem document with no code raises refusal_without_code with the class its " - "status maps to, and keeps its body's retryable, so a retryable false 503 is not " - "retried.", + "status maps to, and keeps its body's retryable and trace_id, so a retryable false " + "503 is not retried and its trace id is the body's, not the header's.", _refused_without_code, ), Synthetic( "search-unauthorized", "search-place-ambiguous", - "A bodiless 401 answers the search.", + f"A bodiless 401 with x-dfo-trace-id {HEADER_TRACE_ID} answers the search.", "A 401 resolves the key again; the key is unchanged, so the client sends nothing " - "more and raises AuthenticationError refusal_without_code.", + "more and raises AuthenticationError refusal_without_code, whose trace id is the " + "header's, since the refusal has no body.", _unauthorized, ), Synthetic( @@ -3364,10 +3447,14 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: Synthetic( "choose-refused-shared-label", "choose-place-one-part", - "The no_data part's second option takes the first one's label.", + "The no_data part's second option takes the first one's label, and the search's " + f"response carries x-dfo-trace-id {ANSWER_TRACE_ID}.", "A label two options share matches several, so choosing by it raises " - "InvalidRequestError with no request.", - _choice_raises("choice_invalid", _labels_shared), + "InvalidRequestError with no request. The error describes the caller's choice, so " + "it carries no trace id although the answer's response has one.", + _choice_raises( + "choice_invalid", _labels_shared, {"x-dfo-trace-id": ANSWER_TRACE_ID} + ), ), Synthetic( "choose-option-two-part-query", @@ -3381,8 +3468,10 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: Synthetic( "search-no-json-body", "search-place-ambiguous", - "The search answers 200 with an empty text/html body.", - "A 2xx Search response with no JSON body raises ContractError unexpected_response.", + f"The search answers 200 with an empty text/html body and x-dfo-trace-id " + f"{READ_TRACE_ID}.", + "A 2xx Search response with no JSON body raises ContractError unexpected_response, " + "with that response's trace id.", _search_ends(_without_json, "unexpected_response"), ), Synthetic( @@ -3439,10 +3528,12 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: Synthetic( "answer-timed-out", "answer-mixed-fetch-raises", - "The answer's diagnostics.timed_out becomes true.", + "The answer's diagnostics.timed_out becomes true, and its response carries " + f"x-dfo-trace-id {ANSWER_TRACE_ID}.", "A no_data part of an answer whose diagnostics say Search timed out is a timed_out gap, " - "whatever its reason, and fetching the answer raises IncompleteAnswerError.", - _answer_edit(_timed_out), + "whatever its reason, and fetching the answer raises IncompleteAnswerError, which " + "describes the answer and carries its response's trace id.", + _answer_edit(_timed_out, {"x-dfo-trace-id": ANSWER_TRACE_ID}), ), Synthetic( "answer-unsupported-part", diff --git a/tools/tests/test_capture_client_contract.py b/tools/tests/test_capture_client_contract.py index 44fffdb..41a734e 100644 --- a/tools/tests/test_capture_client_contract.py +++ b/tools/tests/test_capture_client_contract.py @@ -282,7 +282,11 @@ def test_a_renamed_strict_field_ends_the_call_at_the_build() -> None: assert "content_version" not in manifest assert "contentVersion" in manifest assert record["expect"][-1] == { - "error": {"class": "ContractError", "code": "contract_violation"} + "error": { + "class": "ContractError", + "code": "contract_violation", + "trace_id": None, + } } diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index 2d559d5..bc817e0 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -164,7 +164,11 @@ def change(doc: Any) -> None: response["status"] = response["json"]["status"] = status del response["json"]["code"] doc["expect"][0] = { - "error": {"class": "InvalidRequestError", "code": "refusal_without_code"} + "error": { + "class": "InvalidRequestError", + "code": "refusal_without_code", + "trace_id": response["json"]["trace_id"], + } } return change @@ -274,7 +278,16 @@ def _keep_exchanges(count: int) -> Callable[[Any], None]: def _never_retried(doc: Any) -> None: """The 503 ends the record, and the search raises it unretried.""" doc["exchanges"] = doc["exchanges"][:1] - doc["expect"] = [{"error": {"class": "ServerError", "code": "service_unavailable"}}] + trace = doc["exchanges"][0]["response"]["json"]["trace_id"] + doc["expect"] = [ + { + "error": { + "class": "ServerError", + "code": "service_unavailable", + "trace_id": trace, + } + } + ] def _proxy_code(code: str) -> Callable[[Any], None]: @@ -378,6 +391,22 @@ def _one_part_query(part: Any) -> None: query["parts"] = query["parts"][:1] +def _trace(trace_id: str | None, index: int = 0) -> Callable[[Any], None]: + return _set_outcome(index, lambda o: o["error"].update(trace_id=trace_id)) + + +def _header_trace(index: int, trace: str | None) -> Callable[[Any], None]: + """Exchange `index` carries an x-dfo-trace-id header, and step 1 expects + `trace` as its error's trace id.""" + + def change(doc: Any) -> None: + response = doc["exchanges"][index]["response"] + response.setdefault("headers", {})["x-dfo-trace-id"] = "4" * 32 + doc["expect"][1]["error"]["trace_id"] = trace + + return change + + def _ends_in(error: dict[str, Any], keep: int) -> Callable[[Any], None]: """The record keeps its first `keep` exchanges and expects `error`.""" @@ -832,17 +861,17 @@ def change(doc: Any) -> None: ( _NO_CHOICE, _error_code(1, "invalid_argument"), - '"code": "choice_invalid"}}', + '"code": "choice_invalid"', ), ( _REQUEST_INVALID, _set_body(0, lambda body: body.pop("code")), - '"code": "refusal_without_code"}}', + '"code": "refusal_without_code"', ), ( _TOP5, _set_body(0, _one_hint), - '"code": "slot_defaulted"}}', + '"code": "slot_defaulted"', ), ( "served/SOURCE.json", @@ -871,7 +900,8 @@ def change(doc: Any) -> None: _set_outcome(0, lambda o: o["error"].pop("newest_version")), ( "expect/0: {'error': {'class': 'VersionUnavailableError', 'code': " - "'artifact_expired'}} is not valid" + "'artifact_expired', 'trace_id': '00000000000000000000000000000000'}} " + "is not valid" ), ), ( @@ -1240,7 +1270,9 @@ def change(doc: Any) -> None: (_CUT_OFF_THEN_BUSY, _repeat(1, 1), "the steps never make exchanges 2 to 2"), ( _BUSY_THEN_CUT_OFF, - _ends_in({"class": "ServerError", "code": "timeout"}, 2), + _ends_in( + {"class": "ServerError", "code": "timeout", "trace_id": "0" * 32}, 2 + ), "is a retryable refusal with retries left", ), ( @@ -1276,6 +1308,38 @@ def change(doc: Any) -> None: _set_action("key_empty", **{"class": "ContractError"}), "takes 'ContractError', not 'AuthenticationError'", ), + ("scenarios/search-no-json-body.json", _trace(None), "step 0 expects"), + ("scenarios/fetch-spec-strict-warning.json", _trace(None), "step 0 expects"), + (_TOP5, _header_trace(0, None), "step 1 expects"), + (_NO_CHOICE, _trace("f" * 32, 1), "step 1 expects"), + (_NO_CHOICE, _header_trace(0, "4" * 32), "step 1 expects"), + ( + "scenarios/fetch-spec-digest-mismatch.json", + _trace("f" * 32), + "step 0 expects", + ), + ("scenarios/answer-timed-out.json", _trace(None, 1), "step 1 expects"), + ( + "scenarios/choose-refused-shared-label.json", + _trace("5" * 32, 1), + "step 1 expects", + ), + (_DECLINED, _header_trace(0, None), "step 1 expects"), + (_CODELESS, _trace("2" * 32), "step 0 expects"), + ( + _CODELESS, + _set_body(0, lambda body: body.pop("trace_id")), + "step 0 expects", + ), + ("scenarios/search-unauthorized.json", _trace(None), "step 0 expects"), + ("scenarios/search-proxy-unavailable.json", _trace("f" * 32), "step 0 expects"), + ("scenarios/answer-empty-parts.json", _trace("f" * 32), "step 0 expects"), + (_NEWER, _trace(None), "step 0 expects"), + ( + _CODELESS, + _set_outcome(0, lambda o: o["error"].pop("trace_id")), + "'code': 'refusal_without_code'}} is not valid", + ), ( "scenarios/search-proxy-unavailable.json", lambda doc: doc["exchanges"][0]["response"]["json"].update( @@ -1544,6 +1608,22 @@ def change(doc: Any) -> None: "key-lookup-reason-profile-without-key-missing", "key-lookup-reason-credentials-file-invalid-missing", "key-lookup-reason-of-another-class", + "unexpected-response-without-its-response-trace-id", + "data-warning-without-its-response-trace-id", + "search-warning-without-its-answer-trace-id", + "choice-invalid-with-a-trace-id", + "choice-invalid-takes-the-answer-trace-id", + "storage-failure-with-a-trace-id", + "answer-incomplete-without-its-answer-trace-id", + "choice-invalid-takes-the-answer-response-trace-id", + "answer-declined-without-its-answer-trace-id", + "trace-id-of-the-header-over-the-body", + "trace-id-header-fallback-ignored", + "trace-id-header-fallback-dropped", + "trace-id-on-a-refusal-with-neither", + "trace-id-on-a-client-error", + "version-unavailable-without-its-refusal-trace-id", + "error-outcome-without-trace-id", "proxy-code-not-a-string", "artifact-url-on-storage-fetched", "manifest-without-identity-read", diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index 831a0a8..b48f9cf 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -92,7 +92,7 @@ import re import sys from collections.abc import Iterator, Mapping, Sequence -from dataclasses import dataclass, field +from dataclasses import dataclass, field, replace from pathlib import Path from typing import Any from urllib.parse import urljoin, urlsplit, urlunsplit @@ -909,11 +909,13 @@ def error_outcome(error: str, code: str | None, **members: Any) -> dict[str, Any class ClientError(Exception): - """A step ends in an error a client raises. A refusal names its class and - the server's code, a SearchWarning or DataWarning names the server's - warning, departure or operation code, and any other error names a code - from `client-codes.json`, whose row gives its class. A - VersionUnavailableError also names the newest version, or None.""" + """A step ends in an error a client raises. A refusal names its class, + the server's code and its trace id, a SearchWarning or DataWarning names + the server's warning, departure or operation code, and any other error + names a code from `client-codes.json`, whose row gives its class. A + VersionUnavailableError also names the newest version, or None, and the + trace id of the refusal that gave its code. `traced` says the trace id is + settled; an error raised without one takes it as `read_from` gives.""" def __init__( self, @@ -921,11 +923,15 @@ def __init__( *, error: str | None = None, newest_version: str | None = None, + trace_id: str | None = None, + traced: bool = False, ) -> None: super().__init__(f"{error or 'client'} {code}") self.code = code self.error = error self.newest_version = newest_version + self.trace_id = trace_id + self.traced = traced or trace_id is not None def error_class(self, client_codes: Mapping[str, Mapping[str, Any]]) -> str: """The error class: the one it names, else its client code's. @@ -951,22 +957,72 @@ def outcome(self, client_codes: Mapping[str, Mapping[str, Any]]) -> dict[str, An """ error = self.error_class(client_codes) if error == VERSION_UNAVAILABLE: - return error_outcome(error, self.code, newest_version=self.newest_version) - return error_outcome(error, self.code) + return error_outcome( + error, + self.code, + trace_id=self.trace_id, + newest_version=self.newest_version, + ) + return error_outcome(error, self.code, trace_id=self.trace_id) + + +TRACE_HEADER = "x-dfo-trace-id" + + +def trace_id(body: Any, headers: Mapping[str, str] | None) -> str | None: + """A refusal's trace id: its body's `trace_id`, else its TRACE_HEADER + header, else None.""" + found = body.get("trace_id") if isinstance(body, dict) else None + if isinstance(found, str) and found: + return found + header = (headers or {}).get(TRACE_HEADER) + return header or None def refusal_error( - status: int, body: Any, actions: Mapping[str, Mapping[str, Any]] + status: int, + body: Any, + actions: Mapping[str, Mapping[str, Any]], + headers: Mapping[str, str] | None = None, ) -> ClientError: """The error a refusal raises: its code's class and the server's code, or for a body with no code the class its status maps to and - `refusal_without_code`.""" + `refusal_without_code`, with the trace id `trace_id` gives for its body + and `headers`.""" code = refusal_code(body) return ClientError( - code or REFUSAL_WITHOUT_CODE, error=error_class(status, code, actions) + code or REFUSAL_WITHOUT_CODE, + error=error_class(status, code, actions), + trace_id=trace_id(body, headers), + traced=True, ) +# The codes of the errors a client raises itself that describe a response, +# beside the warnings it raises under strict; every other client code +# describes the caller's input or a storage-host fetch. +RESPONSE_ERRORS = frozenset( + { + "unexpected_response", + "contract_violation", + "answer_declined", + "answer_incomplete", + } +) + + +def read_from(error: ClientError, trace: str | None) -> ClientError: + """`error`, raised on the API response whose trace id is `trace`: an + error that describes a response, a RESPONSE_ERRORS code, SearchWarning + or DataWarning, takes `trace` unless it is traced already; an error that + describes the caller's input, or a storage-host fetch, keeps null.""" + reads = error.code in RESPONSE_ERRORS or error.error in WARNING_CLASSES + if not error.traced and reads: + error.trace_id = trace + error.traced = True + return error + + # The answer kinds a client reads. Any other kind raises ContractError. ANSWER_KINDS = ("resolution", "catalogue", "declined") RESOLUTION = "resolution" @@ -985,6 +1041,7 @@ class Answer: parts: list[dict[str, Any]] sentence: str | None status: str | None + trace_id: str | None = None def answer_from_body(body: Any) -> Answer: @@ -1682,20 +1739,28 @@ def sentence_entry( def failed_operation( - resource: Mapping[str, Any], actions: Mapping[str, Mapping[str, Any]] + resource: Mapping[str, Any], + actions: Mapping[str, Mapping[str, Any]], + headers: Mapping[str, str] | None = None, ) -> tuple[ClientError, bool]: """A failed operation's error, the refusal its problem document states at that document's status or else 500, and whether it is retryable. A - failed operation with no document raises `operation_failed`.""" + failed operation with no document raises `operation_failed`. Its trace id + is the document's, else the `headers` of the response that carried the + resource.""" problem = resource.get("error") if not isinstance(problem, dict): error = ClientError( - OPERATION_FAILED, error=error_class(500, OPERATION_FAILED, actions) + OPERATION_FAILED, + error=error_class(500, OPERATION_FAILED, actions), + trace_id=trace_id(None, headers), + traced=True, ) return error, retryable(500, None) status = problem.get("status") status = status if isinstance(status, int) else 500 - return refusal_error(status, problem, actions), retryable(status, problem) + error = refusal_error(status, problem, actions, headers) + return error, retryable(status, problem) class LongBuild: @@ -1729,6 +1794,7 @@ def __init__( def _take(self, resource: Mapping[str, Any], headers: Mapping[str, str]) -> None: self.resource = resource + self.headers = headers self.pacing.took(resource["operation"], headers) if resource["operation"]["status"] == "done": manifest = resource.get("manifest") @@ -1739,7 +1805,7 @@ def _take(self, resource: Mapping[str, Any], headers: Mapping[str, str]) -> None def next_wait(self) -> float: """The wait before the next poll, kept in `entry`.""" if self.resource["operation"]["status"] == "failed": - raise failed_operation(self.resource, self.actions)[0] + raise failed_operation(self.resource, self.actions, self.headers)[0] wait = self.pacing.next_wait() self.entry["poll_waits"].append(wait) return wait @@ -1755,9 +1821,9 @@ def polled(self, status: int, headers: Mapping[str, str], body: Any) -> bool: self._take(body, headers) if body["operation"]["status"] != "failed": return False - error, again = failed_operation(body, self.actions) + error, again = failed_operation(body, self.actions, headers) else: - error = refusal_error(status, body, self.actions) + error = refusal_error(status, body, self.actions, headers) again = retryable(status, body) if error.code != OPERATION_FAILED: if status == 429: @@ -1776,7 +1842,7 @@ def reposted(self, status: int, headers: Mapping[str, str], body: Any) -> None: """Takes the answer to the build posted again: a refusal raises, a 202 starts the operation the client polls next, and a 200 is done.""" if status >= 400: - raise refusal_error(status, body, self.actions) + raise refusal_error(status, body, self.actions, headers) if status != 202: self.result = body return @@ -1817,6 +1883,7 @@ class _Replay: retry_waits: list[float] = field(default_factory=list) warnings: list[str] = field(default_factory=list) warned: set[tuple[str, ...]] = field(default_factory=set) + read_trace: str | None = None @property def kinds(self) -> dict[str, str]: @@ -1871,10 +1938,13 @@ def call( return exchange def took(self, exchange: dict[str, Any]) -> None: - """Notes the warnings an API response's headers issue.""" + """Notes the warnings an API response's headers issue, and its trace + id as the one an error raised on reading it carries.""" if "url" not in exchange["request"]: - headers = exchange["response"].get("headers", {}) + response = exchange["response"] + headers = response.get("headers", {}) self.warnings.extend(header_warnings(headers, self.warned)) + self.read_trace = trace_id(response.get("json"), headers) def acted_on(self, exchange: dict[str, Any], schema: Any = None) -> Any: """The JSON body a client acts on, read through `schema` or else its @@ -1886,7 +1956,10 @@ def acted_on(self, exchange: dict[str, Any], schema: Any = None) -> Any: body = response.get("json") if response["status"] >= 400: raise refusal_error( - response["status"], problem_body(response), self.actions + response["status"], + problem_body(response), + self.actions, + response.get("headers"), ) if schema is None: schema = self.routes.response_schema( @@ -1958,7 +2031,8 @@ def resolve(self, posts: dict[str, Any]) -> Answer: """A Search request whose recorded body is the one `search_body` gives for the input `posts`.""" exchange = self.posted(_SEARCH, search_body(posts)) - return answer_from_body(self.acted_on(exchange)) + answer = answer_from_body(self.acted_on(exchange)) + return replace(answer, trace_id=self.read_trace) def posted(self, route: tuple[str, str], posts: dict[str, Any]) -> dict[str, Any]: """A request to `route` whose recorded body is `posts`, whole.""" @@ -2132,6 +2206,8 @@ def stored_version(self, member: dict[str, Any]) -> dict[str, Any]: refusal.code if refusal is not None else "version_unavailable", error=VERSION_UNAVAILABLE, newest_version=newest, + trace_id=refusal.trace_id if refusal is not None else None, + traced=True, ) def stored_file( @@ -2192,6 +2268,7 @@ def step(self, step: dict[str, Any]) -> dict[str, Any]: `retry_waits`, and a step whose responses issued warnings gives their codes in `warnings`.""" self.long_builds, self.retry_waits, self.warnings = [], [], [] + self.read_trace = None op = step["op"] if op == "fetch": op = ( @@ -2202,7 +2279,7 @@ def step(self, step: dict[str, Any]) -> dict[str, Any]: except ClientError as ended: if op in {"search", "choose"}: self.answer = None - outcome = ended.outcome(self.client_codes) + outcome = read_from(ended, self.read_trace).outcome(self.client_codes) return with_step_notes( outcome, long_builds=self.long_builds, @@ -2221,8 +2298,12 @@ def _search(self, step: dict[str, Any]) -> dict[str, Any]: def _choose(self, step: dict[str, Any]) -> dict[str, Any]: answer = self._answered() - choice = choice_for(answer, self.kinds, step.get("part"), step["option"]) - chosen = self.resolve(choice_input(answer, choice)) + try: + choice = choice_for(answer, self.kinds, step.get("part"), step["option"]) + posts = choice_input(answer, choice) + except ClientError as error: + raise read_from(error, answer.trace_id) from None + chosen = self.resolve(posts) self.answer = chosen return answer_outcome(chosen, self.kinds) @@ -2234,15 +2315,18 @@ def _fetch(self, step: dict[str, Any]) -> dict[str, Any]: several members raises InvalidRequestError; all before any request.""" answer = self._answered() if answer.body.get("kind") != "resolution": - raise ClientError("answer_declined") + raise read_from(ClientError("answer_declined"), answer.trace_id) gaps = answer_gaps(answer, self.kinds) readings = answer_members(answer) if gaps and (not step.get("partial", False) or not readings): - raise ClientError("answer_incomplete") + raise read_from(ClientError("answer_incomplete"), answer.trace_id) warns = search_warns(answer) strict = step.get("strict", False) if warns and strict: - raise ClientError(search_warning_code(answer), error="SearchWarning") + raise read_from( + ClientError(search_warning_code(answer), error="SearchWarning"), + answer.trace_id, + ) rendering = rendering_for(step.get("layout")) if "layout" in rendering and len(readings) > 1: raise ClientError("invalid_argument") From 9d1948343217a45d4cf23161a1895ca49835426c Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Wed, 21 Oct 2026 15:31:11 +0200 Subject: [PATCH 22/39] fix(client-contract): record trace ids, replay under a second host, and pin malformed members Every recorded scenario and served/openapi.json are recorded again at dfo-apis 635943e03, now keeping x-dfo-trace-id; the capture refuses an API response without it unless the response is Cache-Control: public, which the server sends untraced. The served document is unchanged. The validator replays each scenario under its recorded base URL and under https://replay.example.org with the recorded origin replaced in bodies and headers, so a record that holds only under its own host fails. A refused poll waits its Retry-After whatever its status, else the ordinary pacing. The trace id is a body's top-level trace_id, else the header; diagnostics.trace_id is not read. A signed fetch answering anything but 200 fails its round, and a files route answering a 2xx other than 200 or 302 raises unexpected_response. A strict member of the wrong JSON type raises contract_violation, and a non-strict list member of another type reads as absent. A ref member the snapshot manifest does not list takes its rendering from the ref. The README states the stacking, part column, variable_text and label rules, and the errors that carry no trace id. 108 scenarios, 31 recorded and 77 synthetic. --- python/client-contract/README.md | 21 +- .../answer-candidate-specs-not-a-list.json | 2373 +++++++++ .../answer-candidates-choose-fetch.json | 71 +- .../scenarios/answer-catalogue.json | 15 +- .../scenarios/answer-declined.json | 13 +- .../scenarios/answer-definite-fetch.json | 50 +- .../answer-definition-spec-id-mismatch.json | 31 +- .../scenarios/answer-empty-parts.json | 11 +- .../scenarios/answer-mixed-fetch-partial.json | 58 +- .../scenarios/answer-mixed-fetch-raises.json | 45 +- .../answer-nested-specs-unchecked.json | 2434 +++------ .../answer-operations-not-a-list.json | 4545 +++++++++++++++++ .../answer-part-status-not-a-string.json | 43 +- .../answer-several-readings-folded.json | 164 +- .../answer-spec-without-identity.json | 31 +- .../answer-spec-without-resolved.json | 31 +- .../scenarios/answer-timed-out.json | 38 +- .../scenarios/answer-unknown-enum-value.json | 13 +- .../scenarios/answer-unknown-kind.json | 15 +- .../scenarios/answer-unknown-part-status.json | 43 +- .../scenarios/answer-unsupported-part.json | 43 +- .../choose-candidate-assumed-reading.json | 50 +- .../choose-candidate-echoes-assumptions.json | 68 +- .../scenarios/choose-candidate-two-parts.json | 112 +- ...choose-echoes-separate-and-operations.json | 84 +- .../choose-option-beside-definite.json | 86 +- .../choose-option-two-part-query.json | 11 +- .../choose-option-without-data-query.json | 11 +- .../scenarios/choose-part-by-mention.json | 42 +- .../scenarios/choose-place-one-part.json | 34 +- .../scenarios/choose-place-two-parts.json | 44 +- .../choose-posts-unsupported-placeholder.json | 84 +- .../choose-refused-answered-part.json | 41 +- ...hoose-refused-mention-names-two-parts.json | 13 +- .../scenarios/choose-refused-no-choice.json | 29 +- .../scenarios/choose-refused-no-options.json | 13 +- .../choose-refused-option-out-of-range.json | 31 +- ...se-refused-part-without-variable-text.json | 47 +- .../choose-refused-shared-label.json | 6 +- .../scenarios/choose-refused-two-choices.json | 13 +- .../choose-refused-unknown-label.json | 13 +- .../choose-refused-unknown-part.json | 41 +- .../choose-refused-unknown-status.json | 47 +- .../fetch-frame-several-readings.json | 124 +- .../scenarios/fetch-null-member.json | 48 +- .../fetch-partial-nothing-answered.json | 15 +- .../fetch-ref-artifact-unlisted.json | 871 ++++ .../fetch-ref-expired-file-selector.json | 19 +- .../fetch-ref-expired-newer-version.json | 13 +- .../fetch-ref-expired-not-reproducible.json | 3 +- ...etch-ref-expired-rebuild-same-version.json | 19 +- .../scenarios/fetch-ref-newest-version.json | 5 +- .../fetch-ref-signed-url-refused-twice.json | 19 +- .../fetch-ref-signed-url-refused.json | 22 +- .../scenarios/fetch-ref-unknown-version.json | 9 +- .../scenarios/fetch-ref.json | 21 +- .../scenarios/fetch-renamed-strict-field.json | 44 +- .../scenarios/fetch-retry-after-504.json | 48 +- .../scenarios/fetch-spec-503-then-504.json | 19 +- .../scenarios/fetch-spec-504-retry-after.json | 19 +- .../scenarios/fetch-spec-async-build.json | 64 +- .../scenarios/fetch-spec-digest-mismatch.json | 25 +- .../scenarios/fetch-spec-empty-narrowing.json | 19 +- .../scenarios/fetch-spec-entity-dropped.json | 40 +- .../scenarios/fetch-spec-entity-rebound.json | 42 +- .../fetch-spec-files-route-no-content.json | 879 ++++ .../fetch-spec-foreign-artifact-url.json | 15 +- .../scenarios/fetch-spec-frame-layout.json | 21 +- .../scenarios/fetch-spec-group-narrowed.json | 36 +- .../fetch-spec-group-origin-rebound.json | 34 +- .../scenarios/fetch-spec-known-sentence.json | 21 +- .../fetch-spec-manifest-without-identity.json | 15 +- .../scenarios/fetch-spec-narrowed.json | 44 +- ...tch-spec-operation-failed-resubmitted.json | 70 +- .../scenarios/fetch-spec-poll-not-found.json | 3 +- .../fetch-spec-poll-rate-limited.json | 64 +- .../fetch-spec-poll-refused-backoff.json | 1225 +++++ .../fetch-spec-poll-refused-retry-after.json | 1244 +++++ .../scenarios/fetch-spec-poll-refused.json | 64 +- .../fetch-spec-relative-location.json | 19 +- .../scenarios/fetch-spec-request-invalid.json | 9 +- .../fetch-spec-resubmit-other-spec.json | 38 +- .../fetch-spec-same-origin-artifact-url.json | 19 +- .../fetch-spec-signed-fetch-partial.json | 957 ++++ .../fetch-spec-storage-artifact-url.json | 15 +- .../scenarios/fetch-spec-strict-warning.json | 10 +- .../scenarios/fetch-strict-info-notice.json | 48 +- .../scenarios/mint-async-build.json | 66 +- .../newest-version-unreadable-page.json | 5 +- .../operation-failed-without-error.json | 8 +- .../scenarios/operation-resume.json | 114 +- .../resubmit-candidates-sibling.json | 60 +- ...ubmit-placeholder-without-restatement.json | 58 +- .../scenarios/search-body-not-an-object.json | 15 +- .../scenarios/search-place-ambiguous.json | 15 +- .../scenarios/search-proxy-rate-limited.json | 13 +- .../scenarios/search-retry-after-503.json | 13 +- .../scenarios/search-server-warning.json | 33 +- .../scenarios/search-sunset-warning.json | 22 +- .../search-two-parts-place-ambiguous.json | 15 +- .../scenarios/search-warning-top5.json | 52 +- tools/capture_client_contract.py | 267 +- tools/tests/test_capture_client_contract.py | 45 +- tools/tests/test_validate_client_contract.py | 82 +- tools/validate_client_contract.py | 235 +- 105 files changed, 15261 insertions(+), 3223 deletions(-) create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-candidate-specs-not-a-list.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-operations-not-a-list.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-artifact-unlisted.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-no-content.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-backoff.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-retry-after.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-signed-fetch-partial.json diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 88ee026..61f464a 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -73,7 +73,7 @@ uv run ty check src/dfo_client_contract ## Strict fields -`strict-fields.json` lists the members a client cannot act without. Each pointer names one property of one component schema, `/components/schemas//properties/`. A `required` entry stays in its schema's `required` list and admits no null, so a client raises `ContractError` when one is missing or null. Every entry is a member some client rule acts on, and a client checks a body only along them: from the body's root it goes down through strict members alone, so a member no client reads goes unchecked, however deep. A spec nested where no rule reads it, in `resolved.alternative_measures`, `resolved.equivalent_readings` or `resolved.related_measures`, or in `no_data.flagged_match` or `no_data.nearest_real`, may lack `resolved` or `identity` and raises nothing, which `answer-nested-specs-unchecked` pins. An `enums` entry keeps every listed value, the values a client branches on: the answer kinds, the part statuses and the operation statuses. A client still accepts a value no entry lists. +`strict-fields.json` lists the members a client cannot act without. Each pointer names one property of one component schema, `/components/schemas//properties/`. A `required` entry stays in its schema's `required` list and admits no null, so a client raises `ContractError` when one is missing or null. Every entry is a member some client rule acts on, and a client checks a body only along them: from the body's root it goes down through strict members alone, so a member no client reads goes unchecked, however deep. A `Spec` where no rule reads it, in `resolved.equivalent_readings`, `no_data.flagged_match` or `no_data.alternate_match`, may lack `resolved` or its definition's `identity` and raises nothing, which `answer-nested-specs-unchecked` pins at all three. A strict member that holds a JSON type its schema does not admit raises `ContractError` `contract_violation` at its pointer, as a missing one does, which `answer-candidate-specs-not-a-list` pins with `candidates.specs` as an object. A member a client reads that no strict pointer names, and that holds a JSON type its schema does not admit, reads as absent, which `answer-operations-not-a-list` pins with a definite part's `operations` as an object. An `enums` entry keeps every listed value, the values a client branches on: the answer kinds, the part statuses and the operation statuses. A client still accepts a value no entry lists. The answer's `kind` and each part's `status` are the discriminators of their unions in the served document. A search response with no `kind` raises `ContractError`, as a part with no `status` does, although the served document gives `kind` a default and leaves it out of `required`. A part `status` a client does not know raises nothing and makes the part an `unknown` gap. An answer `kind` a client does not know raises `ContractError`, because the client cannot read the answer. A Search response body that is not an object, a `resolution` answer whose `parts` is empty, at pointer `/parts`, since the served schema gives it at least one item, a part whose `status` is not a string, at pointer `/parts//status`, and a definite or candidate spec whose `definition.spec_id` differs from its `spec_id` raise `ContractError` `contract_violation`, in a Search response as in a ref; `search-body-not-an-object`, `answer-empty-parts`, `answer-part-status-not-a-string` and `answer-definition-spec-id-mismatch` pin the four. @@ -118,7 +118,7 @@ An answer's gaps follow from its parts. A candidates part is a `choice` gap, its ## Client codes -`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, `retryable`, and a one-line `condition`. `retryable` is the flag both clients generate onto the error: `deadline_exceeded`, `download_failed` and `network_error` are retryable, `digest_mismatch` and the rest are not, and `refusal_without_code` is retryable as its status is, which its row gives as `by_status`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps the server's code: the problem document's `code`, or the website proxy's `error`. A refusal whose body carries neither raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`; no other row does. A problem document without a code still gives the error its `retryable` and `trace_id`, so a 503 whose body says `retryable: false` raises at once, which `search-refused-without-code` pins. Every refusal's trace id is the body's `trace_id`, else the `x-dfo-trace-id` header, else null: `search-refused-without-code` pins the body's winning over the header, and `search-unauthorized` the header's for a refusal with no body. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. Each reason the key-lookup rule raises, `key_empty`, `profile_not_found`, `profile_without_key` and `credentials_file_invalid`, is a row of class `AuthenticationError`. The list holds no warning. `warning-codes.json` lists, sorted by code, each code a client sets on a warning it issues itself, with its class and condition: `route_deprecated`, a `DfoDeprecationWarning`, for a `Deprecation` or `Sunset` header; `server_warning`, a `DfoWarning`, for an `x-dfo-warning` header; and `key_checksum_mismatch`, `key_not_base62` and `key_unknown_prefix`, each a `DfoWarning`, for a key that fails the key-format rule with that reason. Both clients generate their warning codes from it and issue no other. No warning code is a code in another table or in `registries/codes.json`. A `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and a null code when they differ in several ways. A `DataWarning` carries the manifest warning's code. +`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, `retryable`, and a one-line `condition`. `retryable` is the flag both clients generate onto the error: `deadline_exceeded`, `download_failed` and `network_error` are retryable, `digest_mismatch` and the rest are not, and `refusal_without_code` is retryable as its status is, which its row gives as `by_status`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps the server's code: the problem document's `code`, or the website proxy's `error`. A refusal whose body carries neither raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`; no other row does. A problem document without a code still gives the error its `retryable` and `trace_id`, so a 503 whose body says `retryable: false` raises at once, which `search-refused-without-code` pins. Every refusal's trace id is the response's trace id, as the trace-id rule under Scenarios gives it: `search-refused-without-code` pins the body's winning over the header, and `search-unauthorized` the header's for a refusal with no body. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. Each reason the key-lookup rule raises, `key_empty`, `profile_not_found`, `profile_without_key` and `credentials_file_invalid`, is a row of class `AuthenticationError`. The list holds no warning. `warning-codes.json` lists, sorted by code, each code a client sets on a warning it issues itself, with its class and condition: `route_deprecated`, a `DfoDeprecationWarning`, for a `Deprecation` or `Sunset` header; `server_warning`, a `DfoWarning`, for an `x-dfo-warning` header; and `key_checksum_mismatch`, `key_not_base62` and `key_unknown_prefix`, each a `DfoWarning`, for a key that fails the key-format rule with that reason. Both clients generate their warning codes from it and issue no other. No warning code is a code in another table or in `registries/codes.json`. A `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and a null code when they differ in several ways. A `DataWarning` carries the manifest warning's code. ## Scenarios @@ -138,7 +138,7 @@ A step that acts on an earlier result follows one: `choose` follows `search` or An exchange's request names its target in one of three ways. `path` is a path the client composes under the base URL, such as `/search/resolve`. `origin_path` is a root-relative URL the server returned, such as an artifact's `url`, or the path and query of an absolute one on the API's origin, which resolves against the base URL's origin and never against its path. `url` is an absolute URL outside the API, such as the signed storage URL a files route redirects to, which the client fetches with a bare request carrying no client header and no key. `json` holds the request body members that must match; a recorded scenario lists every member the client sent. The response gives `status`, the `headers` a client reads, and a `json` body or a `body_file`, a binary body in `scenarios/`. A scenario's own body files are named `.` and `-.`; a synthetic scenario may instead name a body file its parent names. -A `newest_version` outcome gives the `content_version` the step found, or null. An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a warning's code, which for a `SearchWarning` may be null, or for any other error the client raises itself its code in `client-codes.json`. Every error outcome gives its `trace_id`: a refusal's, as the refusal rules below give it; a failed operation's, its error document's `trace_id`, else the `x-dfo-trace-id` header of the response that carried the failed resource; a `VersionUnavailableError`'s, its first refusal's. An error the client raises itself follows one rule: an error that describes a response carries that response's trace id, and an error that describes the caller's input carries null. The trace id is the one a user quotes to find the fault in the server's logs. The errors that describe a response are `unexpected_response`, `contract_violation` on a body, `answer_declined`, `answer_incomplete`, and a strict fetch's `SearchWarning` or `DataWarning`. The id is the body's `trace_id` when the body is an object holding one, else the `x-dfo-trace-id` header, else null. `answer_declined`, `answer_incomplete`, a `SearchWarning`, and a `contract_violation` a choice raises on an option describe the held answer, so they carry the trace id of the Search response that answered it. The errors that describe the caller's input, `choice_invalid`, `invalid_argument` and the key-lookup reasons, carry null, and so do `digest_mismatch` and `download_failed`, which describe a storage-host fetch. `search-no-json-body`, `fetch-spec-strict-warning` and `answer-timed-out` pin a trace id on an error that describes a response, and `choose-refused-shared-label` a null one on a choice whose answer's response carries a trace id. A `VersionUnavailableError` also gives `newest_version`, the version the lookup found, or null. A dataset or error outcome of a step that made a long build gives `long_builds`, one entry per build the server ran on, in order: the `operation_id` the client polled last, the `poll_waits` in seconds before each poll, and the number of `resubmissions`. Any outcome of a step that retried a refused request gives `retry_waits`, the seconds before each retry in order, and any outcome of a step whose API responses issued warnings gives `warnings`, their codes from `warning-codes.json` in order. +A `newest_version` outcome gives the `content_version` the step found, or null. An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a warning's code, which for a `SearchWarning` may be null, or for any other error the client raises itself its code in `client-codes.json`. Every error outcome gives its `trace_id`: a refusal's, as the refusal rules below give it; a failed operation's, its error document's `trace_id`, else the `x-dfo-trace-id` header of the response that carried the failed resource; a `VersionUnavailableError`'s, its first refusal's, or null when nothing refused. An error the client raises itself follows one rule: an error that describes a response carries that response's trace id, and an error that describes the caller's input carries null. The trace id is the one a user quotes to find the fault in the server's logs. The errors that describe a response are `unexpected_response`, `contract_violation` on a body, `answer_declined`, `answer_incomplete`, and a strict fetch's `SearchWarning` or `DataWarning`. A response's trace id is the top-level `trace_id` member of its body when the body is a JSON object holding one, a problem document or any other body, else its `x-dfo-trace-id` header, else null. A Search answer's `diagnostics.trace_id` is not read, and `answer-timed-out` pins the header's winning over a `diagnostics.trace_id` that differs from it. `answer_declined`, `answer_incomplete`, a `SearchWarning`, and a `contract_violation` a choice raises on an option describe the held answer, so they carry the trace id of the Search response that answered it. The errors that describe the caller's input, `choice_invalid`, `invalid_argument` and the key-lookup reasons, carry null, and so do `digest_mismatch` and `download_failed`, which describe a storage-host fetch, and `deadline_exceeded`, `network_error` and `offline`, which describe no response. `search-no-json-body`, `fetch-spec-strict-warning`, `answer-timed-out`, `answer-empty-parts`, `fetch-spec-files-route-no-content` and `choose-option-two-part-query` pin a trace id on an error that describes a response, `operation-failed-without-error` the header of the response that carried a failed resource with no error, and `choose-refused-shared-label` a null one on a choice whose answer's response carries a trace id. A `VersionUnavailableError` also gives `newest_version`, the version the lookup found, or null. A dataset or error outcome of a step that made a long build gives `long_builds`, one entry per build the server ran on, in order: the `operation_id` the client polled last, the `poll_waits` in seconds before each poll, and the number of `resubmissions`. Any outcome of a step that retried a refused request gives `retry_waits`, the seconds before each retry in order, and any outcome of a step whose API responses issued warnings gives `warnings`, their codes from `warning-codes.json` in order. Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry where the retry rules allow one, except on a poll, where the long-build rules count retries, and a record that ends a run of retries while the rules allow another does not fit, since the client makes it, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, each POST carries its body, each build posts the body the rules give for the spec it builds, so the builds' order and spec_ids are checked, each Search request posts the whole body `{"schema_version": 1, "input": ...}` with the input the rules give: the question, a choice's input, or a member's identity, each poll names the operation the client holds, each files route is the one the artifact's `url` names, each signed download is the URL the files route's `location` names, each retry waits the wait the retry rules give, and each response's warning headers issue the warnings the warning rules give. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. @@ -149,6 +149,7 @@ A client replays a scenario by serving the exchanges in order: - A request matches the next exchange on its method and target, and on each listed `json` member, compared as parsed JSON values. - A request with no exchange left, or one that matches none, fails the scenario, and so does an exchange the call never makes. - `path` resolves against the base URL the replay gives the client, and `origin_path` against that base URL's origin, so a replay can run under any base URL form. +- A replay substitutes its own base URL's origin for the origin of the record's `origin.base_url`, a synthetic record's parent's, wherever a response names it, in its JSON body and its headers. `fetch-spec-same-origin-artifact-url` names the recorded origin in its manifest's artifact `url`s, and the validator replays every scenario under its recorded base URL and again under `https://replay.example.org` with the same path, so a record that holds only under its recorded host fails. - Sleeps are not replayed: the replay injects the client's clock and sleep, and each wait the client asks for advances the clock at once. The waits before polls are the outcome's `poll_waits`, and the waits before retries its `retry_waits`. - A replay runs each scenario as a fresh process, so no warning has been issued when it starts. - Every absolute URL a record holds, a `url` request or a `location` header, is a signed URL on `https://storage.googleapis.com` with its path kept and its query `X-Goog-Signature=redacted`, whatever signed it; a `location` may also name a route under the base URL. The validator compares hostnames and refuses any other host, a local app's under any name or port included. @@ -158,8 +159,8 @@ The records also fix these client rules: - A fetch builds each distinct `spec_id` once, in part order, and finishes one member (build, the sentence when the client lacks it, files, download) before the next. - A fetch of a spec posts its narrowing as the build's `input.scope`, and posts no `scope` when it narrows nothing. A mint takes a layout and no narrowing, so it posts no `scope`. `window` posts `{"kind": "range", "start_year", "end_year"}` for a pair of years, or `{"kind": "all"}` or `{"kind": "latest"}`, and `facets` posts each axis as `{"ref": ...}`, and `facets: {}` names no axis and posts no `facets`. The server's `scope.entities` replaces the spec's whole entity binding, so `entities` posts a whole map: the roles the spec's `definition.identity.entities` binds, with each role the caller names replaced by its refs and each role the caller binds to null dropped. Naming `origin` alone on a spec bound to `origin` and `destination` keeps `destination`. A fetch that names no role, `entities: {}` included, posts no `entities`, so a fetch whose narrowing is all empty posts no `scope`; `fetch-spec-empty-narrowing` pins it. - A built `spec_id` that differs from the posted one, or a spec with no sentence, takes its sentence from Search: the client posts the built definition's `identity` as one `dataset_resubmit` identity entry, with the member's first part as `variable_text`, or `"dataset"` when no answer part names it, and checks the answer's `spec_id` equals the built one. The entry's `entity_groups` holds the spec's `resolved.entity_groups` for each role the built identity binds to the same entities as the spec's definition, so a window or facets narrowing keeps every group and a role the narrowing rebound or dropped loses its group. The entry leaves `entity_groups` out when it keeps no group, as for a resumed operation, whose spec the client does not hold. The server reads a role posted without its group as its members, so a narrowed spec of flows to the least developed countries would read "44 recipients" in place of "the 44 Least Developed Countries". -- A dataset of several members puts the `part` column first, then each member's columns in member order, each column once. The `part` value on a member's rows is the member's `parts` joined by `"; "`, so a member that answers two folded parts reads `"health ODA disbursements; education ODA disbursements"`, or the member's sentence when `parts` is empty. -- A choice names its part by index, by variable text, or by a word that one gap's options mention, and its option by index or label; a candidate is named by index. A label is matched among the options that mention the word the part was named by. With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. +- A dataset of several members puts the `part` column first, then each member's columns in member order, each column once. A column that members hold in different types widens as pyarrow's permissive promotion widens it, and a pair that cannot widen raises `ContractError` `contract_violation`; a member file that already holds a `part` column raises `contract_violation` when members stack. Rows and columns are not derived, so no scenario pins these. The `part` value on a member's rows is the member's `parts` joined by `"; "`, so a member that answers two folded parts reads `"health ODA disbursements; education ODA disbursements"`, or the member's sentence when `parts` is empty. A definite part without `variable_text` adds nothing to its member's `parts`. +- A choice names its part by index, by variable text, or by a word that one gap's options mention, and its option by index or label; a candidate is named by index. A candidate with neither a heading nor a sentence has a null label; no scenario pins it. A label is matched among the options that mention the word the part was named by. With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. - A choice raises `InvalidRequestError` `choice_invalid` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is out of range or matches no label or several. It raises the same when an entry it would post cannot be built: a part with no `variable_text`, or a part of a status the client does not know that has no `restatement`. A chosen option whose `data_query` holds other than one part raises `ContractError`, and so does a chosen option with no `data_query`, in a one-part answer as in a several-part one, before any request. `choose-refused-shared-label`, `choose-refused-part-without-variable-text`, `choose-refused-unknown-status`, `choose-option-two-part-query` and `choose-option-without-data-query` pin these. - Every pick of a candidate asks Search for the picked answer, and no client builds it locally. In a one-part answer the pick posts `dataset_resubmit`, without `raw_query`, with one identity entry: the candidate's identity and `entity_groups`, and the part's `variable_text`, `separate` and `operations` as below. The picked answer, its sentence with any "Assumed: …" clause, and its assumptions are Search's response. A choice of a no_data option in a one-part answer posts the option's `data_query` as the input. - In a several-part answer a choice posts `dataset_resubmit`, without `raw_query`, with one entry per part in part order. The chosen candidate posts an identity entry with its identity and `entity_groups`, and the chosen option its `data_query`'s one part as a parsed entry. A definite part posts an identity entry with its spec's identity and `entity_groups`. A candidates part left alone posts a `candidates` entry: its candidate set in the server's order, each with its identity and `entity_groups`, and its `ordering` and `truncated` echoed. The server cannot recompute that order, because it rests on the first answer's bind election and availability reads, and a parsed entry would cost an LLM bind. Any other part posts its `restatement` as a parsed entry, or a placeholder entry with its no_data `reason` or unsupported `code` when it has none. Every entry but a parsed one carries the part's `variable_text`, `separate` when true and `operations` when the part has any; `entity_groups` is left out when the spec has none. `choose-echoes-separate-and-operations` pins the echo on a definite part's entry, and `choose-posts-unsupported-placeholder` an unsupported part's placeholder. @@ -167,15 +168,15 @@ The records also fix these client rules: - A strict fetch raises the manifest's first warning above `info` severity as a `DataWarning` with that warning's code, before the sentence lookup and the download. - An identity resubmit whose answer is not one definite part of the built `spec_id`, with a sentence, raises `ContractError`. - The `frame` layout posts `{"format": "parquet", "bundle": false, "layout": "frame"}` as the build's `options` and downloads the artifact whose rendering's `layout` is `frame`; the `long` layout posts `{"format": "parquet", "bundle": false}` and downloads the bare Parquet artifact with any other layout. A fetch of an answer with several members in the `frame` layout raises `InvalidRequestError` before any build. -- A download asks the route that redirects to the signed URL, an artifact's `url` or the file selector, and fetches the URL its `location` names once. The route ask is an API request and follows the retry rules below, so a retryable refusal is retried within the budget and any other refusal, `artifact_expired` among them, raises at once. A failed fetch gets exactly one more round: a refused fetch or bytes that do not hash to the artifact's digest ask the route again, under the same retry rules, and fetch again, with no wait between rounds. A second failure raises `ServerError` with `download_failed`, or `digest_mismatch` when the bytes are wrong. A network error or timeout on the fetch is retryable, so it starts the second round too, and when the second round fails the same way the client raises that failure as itself, `network_error` or `deadline_exceeded`. The replay holds no network failure, so no scenario pins that case. +- A download asks the route that redirects to the signed URL, an artifact's `url` or the file selector, and fetches the URL its `location` names once. A route that answers a 2xx other than 200 or 302 raises `ContractError` `unexpected_response` with that response's trace id, which `fetch-spec-files-route-no-content` pins with a 204. The route ask is an API request and follows the retry rules below, so a retryable refusal is retried within the budget and any other refusal, `artifact_expired` among them, raises at once. A failed fetch gets exactly one more round: a fetch that answers anything but 200, which `fetch-spec-signed-fetch-partial` pins with a 206, or bytes that do not hash to the artifact's digest ask the route again, under the same retry rules, and fetch again, with no wait between rounds. A second failure raises `ServerError` with `download_failed`, or `digest_mismatch` when the bytes are wrong. A network error or timeout on the fetch is retryable, so it starts the second round too, and when the second round fails the same way the client raises that failure as itself, `network_error` or `deadline_exceeded`. The replay holds no network failure, so no scenario pins that case. - A manifest artifact's `url` names its files route on the API's origin: a root-relative `url` resolves against the base URL's origin, and an absolute one on that origin is asked as its path and query, so both make the same `origin_path` request, which `fetch-spec-same-origin-artifact-url` pins. An artifact `url` on any other origin, the storage host's included, raises `ContractError` `contract_violation` before the sentence lookup and any request for the file, which `fetch-spec-foreign-artifact-url` and `fetch-spec-storage-artifact-url` pin. - A relative `location` resolves against the files route's URL, and the client fetches it on the API's origin as an `origin_path` request. A `location` on an origin other than the API's or `https://storage.googleapis.com` raises `ContractError` `contract_violation` before any fetch. A fetch on the storage host is bare and carries no API key. `fetch-spec-relative-location` pins the relative case. - A declined or catalogue answer is not complete, and fetching it raises `DeclinedError`. - Fetching an answer with a gap raises `IncompleteAnswerError` before any request, unless the fetch is partial and some part has a reading. - A fetch of an answer issues one `SearchWarning` when a definite part has an operation Search did not run, a departure, or a warning at severity `warn` or `degraded` with a `message`, or the answer's `diagnostics.warnings` holds such a warning. An `info` warning, and a warning with no `message`, issue nothing. Each way is one line a client shows: `Not done: ()` coded by the verb, the departure's `text` coded by its code, or `Note: ` coded by the warning's code, in part order with the diagnostics warnings last, and ways that show the same line count once, under the first one's code. A strict fetch raises the `SearchWarning` before any build, with the code of its one line, or a null code when there are several lines. A strict fetch raises it before the `frame` layout's several-member check. -- A ref's version is found in this order: the snapshot route and the files route at the stored digest; the file selector, `GET /datasets/{id}/{content_version}/file` with the ref's rendering as the query; and a build of the ref's spec in the ref's rendering, which must answer the same `content_version`. A snapshot refusal other than `artifact_expired` ends the lookup, so `snapshot_not_found` raises `NotFoundError` with no further request. A files route or selector refusal of `artifact_expired`, `artifact_not_found` or `not_found` takes the next step, and a selector file of another digest is not the stored file. A rebuild that answers another version, or that raises `InvalidRequestError`, `NotFoundError` or `VersionUnavailableError`, ends in `VersionUnavailableError` with the first refusal's code, or `version_unavailable` when nothing refused. Its `newest_version` is the version the rebuild answered, or else the newest stored version, which `GET /datasets/{id}/versions?limit=1` lists alone, as a `newest_version` step finds it, since the route lists versions newest first and needs no key; or null when that route lists none or refuses with `NotFoundError`. Any other refusal of the versions route raises, and a page whose `versions` is not a list of versions each with a `content_version` raises `ContractError` `contract_violation`, which `newest-version-unreadable-page` pins. -- A build answers 200 with the manifest, or 202 with an operation the client polls at `/datasets/operations/{operation_id}`, the id of the operation it holds. A mint's build answers 202; a record whose mint answers 200 fits no mint step. Before each poll it waits the `Retry-After` of a 429 that refused the last poll, else the last operation resource's `retry_after_ms`, else the `Retry-After` of the response that carried that resource, else a backoff of 1, 2, 4 and then 8 seconds that advances only when it is used. -- A 429 poll spends no retry. Any other retryable refused poll spends one of the two retries, which a poll that answers restores, and a refusal that is not retryable raises. A refused poll changes no pacing, so the poll after it waits what the refused poll waited. `fetch-spec-poll-refused` pins two 503s polled again after an answered poll, and `fetch-spec-poll-not-found` a 404 that raises at once. A poll that answers a failed operation whose error is retryable posts the same build once more and polls the operation it starts; a second failure, an error that is not retryable, and a resumed operation, whose build request the client does not hold, raise the operation's error. A refused poll whose code is `operation_failed` is a failed operation with that error. A failed operation whose resource carries no `error` raises `ServerError` with `operation_failed`, retryable by status 500 as a refusal without a document is, which `operation-failed-without-error` pins. A 202 or resumed operation that already reads `failed` raises its error before any poll. +- A ref's version is found in this order: the snapshot route and the files route at the stored digest; the file selector, `GET /datasets/{id}/{content_version}/file` with the ref's rendering as the query; and a build of the ref's spec in the ref's rendering, which must answer the same `content_version`. A snapshot refusal other than `artifact_expired` ends the lookup, so `snapshot_not_found` raises `NotFoundError` with no further request. A files route or selector refusal of `artifact_expired`, `artifact_not_found` or `not_found` takes the next step, and a selector file of another digest is not the stored file. A snapshot manifest whose artifacts list no artifact of the ref member's digest sends the client to the selector in the ref member's own rendering, and a file that hashes to that digest gives the dataset, which `fetch-ref-artifact-unlisted` pins. A rebuild that answers another version, or that raises `InvalidRequestError`, `NotFoundError` or `VersionUnavailableError`, ends in `VersionUnavailableError` with the first refusal's code, or `version_unavailable` when nothing refused. Its `newest_version` is the version the rebuild answered, or else the newest stored version, which `GET /datasets/{id}/versions?limit=1` lists alone, as a `newest_version` step finds it, since the route lists versions newest first and needs no key; or null when that route lists none or refuses with `NotFoundError`. Any other refusal of the versions route raises, and a page whose `versions` is not a list of versions each with a `content_version` raises `ContractError` `contract_violation`, which `newest-version-unreadable-page` pins. +- A build answers 200 with the manifest, or 202 with an operation the client polls at `/datasets/operations/{operation_id}`, the id of the operation it holds. A mint's build answers 202; a record whose mint answers 200 fits no mint step. Before each poll it waits the `Retry-After` of the refusal that answered the last poll, whatever its status, as every retry of a refused request waits; else the last operation resource's `retry_after_ms`, else the `Retry-After` of the last answered poll, the response that carried that resource, else a backoff of 1, 2, 4 and then 8 seconds that advances one step each time it is used, a poll after a refusal included. +- A 429 poll spends no retry. Any other retryable refused poll spends one of the two retries, which a poll that answers restores, and a refusal that is not retryable raises. `fetch-spec-poll-refused` pins two 503s polled again after an answered poll, `fetch-spec-poll-refused-backoff` a 503 with no `Retry-After` among polls no response paces, after which the backoff advances, `fetch-spec-poll-refused-retry-after` a 503 whose `Retry-After` paces the next poll, and `fetch-spec-poll-not-found` a 404 that raises at once. A poll that answers a failed operation whose error is retryable posts the same build once more and polls the operation it starts; a second failure, an error that is not retryable, and a resumed operation, whose build request the client does not hold, raise the operation's error. A refused poll whose code is `operation_failed` is a failed operation with that error. A failed operation whose resource carries no `error` raises `ServerError` with `operation_failed`, retryable by status 500 as a refusal without a document is, which `operation-failed-without-error` pins. A 202 or resumed operation that already reads `failed` raises its error before any poll. - Any other refusal is retried when it is retryable: as a problem document's `retryable` says, or the website proxy's `retry` of `retry_after_delay`, else when its status is 408, 429, 500, 502, 503 or 504. A client makes two retries by default, and the scenarios assume that default. A build's POST shares those two retries with every other refusal of it, and once a 504 cuts the build off the client posts it once more only, whatever that post answers: a build refused 504 then 503 raises the 503, a build refused 503 then 504 is posted once more after the 504, and a second 504 raises. `fetch-spec-504-then-503`, `fetch-spec-503-then-504` and `fetch-spec-504-twice` pin the three. A refusal that is not retryable, or one past the retries, raises its error. - Each retry waits the refusal's `Retry-After` when it carries one, and otherwise the client's backoff for that attempt: 0.5 seconds before the first retry, doubling to at most 8. The build's 504 cut-off retry follows the same rule. `retry_waits` pins these waits, and `fetch-spec-504-retry-after` pins a cut-off that carries `Retry-After`. - A 401 resolves the key again by the key-lookup rule. When the key changed, the client sends the request once more at once, with no wait and spending no retry; when it did not, or the second answer is a 401 too, the 401 raises `AuthenticationError`. A replay's key never changes, so `search-unauthorized` pins the second case and no scenario the first. @@ -193,7 +194,7 @@ uv sync --directory ../dfo-apis --extra eval --extra api --extra engine --extra uv run tools/capture_client_contract.py openapi --dfo-apis ../dfo-apis ``` -Its `record` command runs every scenario against a base URL, dev's Cloud Run URL by default, checks each live answer still has the shape its scenario names, derives the synthetic scenarios from the fresh records with no request, and then runs the validator. A recorded scenario holds only exchanges the server made, and the run refuses one that a canned exchange answered; the record names the commit the server's responses name. It fails when the validator reports a problem or the binary bodies pass 5 MB. `--only` records the scenarios it names. `--offline` makes no request: each recorded scenario's steps run again over its own exchanges and rewrite its `expect`, and each synthetic scenario is derived again from its parent, so a change to the outcome rules or to `client-codes.json` reaches the records without a recording: +Its `record` command runs every scenario against a base URL, dev's Cloud Run URL by default, checks each live answer still has the shape its scenario names, derives the synthetic scenarios from the fresh records with no request, and then runs the validator. A recorded scenario holds only exchanges the server made, and the run refuses one that a canned exchange answered, and an API response without the `x-dfo-trace-id` header the server sends on every response but a shared-cacheable one, marked `Cache-Control: public`; the record names the commit the server's responses name. It fails when the validator reports a problem or the binary bodies pass 5 MB. `--only` records the scenarios it names. `--offline` makes no request: each recorded scenario's steps run again over its own exchanges and rewrite its `expect`, and each synthetic scenario is derived again from its parent, so a change to the outcome rules or to `client-codes.json` reaches the records without a recording: ```bash uv run tools/capture_client_contract.py record --offline --only answer-declined choose-refused-no-choice diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-candidate-specs-not-a-list.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidate-specs-not-a-list.json new file mode 100644 index 0000000..c8d1bb2 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidate-specs-not-a-list.json @@ -0,0 +1,2373 @@ +{ + "format_version": 1, + "name": "answer-candidate-specs-not-a-list", + "description": "A strict member of a JSON type its schema does not admit raises ContractError contract_violation at its pointer, /parts/0/candidates/specs, as a missing one does.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-candidates-choose-fetch", + "edit": "Part 0's candidates.specs becomes an object keyed by index, and the choice and fetch go." + }, + "call": [ + { + "op": "search", + "question": "GNI of Germany from 2015 to 2022" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "GNI of Germany from 2015 to 2022" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "d107dd88e50147378d54464bcdaf9695" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "GNI of Germany from 2015 to 2022", + "normalized_query": "GNI of Germany from 2015 to 2022", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "d107dd88e50147378d54464bcdaf9695", + "warnings": [], + "timing_ms": { + "total": 4075, + "by_step": { + "coverage": 0, + "extract": 1004 + } + }, + "llm_usage": { + "input_tokens": 7300, + "output_tokens": 300, + "cached_tokens": 861 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GNI", + "warnings": [], + "timing_ms": { + "total": 2799, + "by_step": { + "recall": 381, + "shape_arcs": 2, + "shape_probe_coverage": 1, + "shape_probe": 203, + "shape_groups": 18, + "shape_labels": 5, + "shape_admission": 0, + "shape": 1186, + "bind": 829, + "materialise": 217, + "answer": 186 + } + }, + "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "sentence_plan": [ + { + "kind": "text", + "text": "3 readings.", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "primary income", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross of fixed capital consumption", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "OECD DAC1", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity per capita", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "GNI", + "entities": [ + { + "text": "Germany" + } + ], + "time_text": "2015 to 2022", + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "candidates", + "candidates": { + "ordering": "intent_rank", + "max_candidates": 6, + "specs": { + "0": { + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "definition": { + "schema_version": 1, + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicunit_primaryincome_measuredvalue_nominal", + "label": "Gross national income", + "population_type": { + "ref": "EconomicUnit", + "label": "economic unit" + }, + "measured_property": { + "ref": "primaryIncome", + "label": "primary income" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "distinguishes": true + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + }, + "1": { + "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "definition": { + "schema_version": 1, + "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "PurchasingPowerParity" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossNationalIncome" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity", + "label": "Gross National Income Based on Purchasing Power Parity", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "PurchasingPowerParity", + "label": "PurchasingPowerParity" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "833b9da89613fa6c1775652daac2388f38204c6c9f9929ca113deed9a0d08369", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ], + "upstream": { + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + } + } + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "fallback", + "ref": "InternationalDollar", + "label": "InternationalDollar" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "InternationalDollar", + "label": "InternationalDollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross national income based on purchasing power parity in international dollars, 2015 to 2022. World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross national income based on purchasing power parity", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "in international dollars", + "axis": "unit", + "segment": "heading", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + }, + "2": { + "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", + "definition": { + "schema_version": 1, + "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "PurchasingPowerParity", + "measurement_denominator": { + "unresolved": true + } + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossNationalIncome" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity_per_unresolved", + "label": "Gross National Income Based on Purchasing Power Parity Per Capita", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "PurchasingPowerParity", + "label": "PurchasingPowerParity" + }, + "measurement_denominator": { + "ref": "PerCapita", + "label": "PerCapita" + }, + "measurement_denominator_unresolved": true, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "7b2d5b0fc09cfc0215c8d7c6c21a5195fa21e79f2a148a6bca9ce6c3af8bbb9f", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ], + "upstream": { + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + } + } + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "fallback", + "ref": "InternationalDollar", + "label": "InternationalDollar" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "InternationalDollar", + "label": "InternationalDollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross national income based on purchasing power parity per capita in international dollars, 2015 to 2022. World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross national income based on purchasing power parity per capita", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "in international dollars", + "axis": "unit", + "segment": "heading", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + }, + "truncated": false + }, + "reading_assumptions": { + "spec_c0f61f3ca3558aac184973441a67601e": [], + "spec_403a96317ee8b97f1d8569c71015e5ce": [], + "spec_d94656e5d53b7b6c6b0c683145a1cd98": [] + } + } + ], + "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "sentence_plan": [ + { + "kind": "text", + "text": "3 readings.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "primary income", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross of fixed capital consumption", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "OECD DAC1", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity per capita", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "candidates" + } + } + } + ], + "expect": [ + { + "error": { + "class": "ContractError", + "code": "contract_violation", + "trace_id": "d107dd88e50147378d54464bcdaf9695" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json index ee9d38f..433d123 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:57:19Z" + "recorded_at": "2026-10-21T13:05:06Z" }, "call": [ { @@ -37,7 +37,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "d107dd88e50147378d54464bcdaf9695" }, "json": { "schema_version": 1, @@ -49,13 +50,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "8a56f4a56757466094a49079c6a116c4", + "trace_id": "d107dd88e50147378d54464bcdaf9695", "warnings": [], "timing_ms": { - "total": 4642, + "total": 4075, "by_step": { "coverage": 0, - "extract": 1227 + "extract": 1004 } }, "llm_usage": { @@ -71,19 +72,19 @@ "variable_text": "GNI", "warnings": [], "timing_ms": { - "total": 3202, + "total": 2799, "by_step": { - "recall": 421, - "shape_arcs": 4, - "shape_probe_coverage": 2, - "shape_probe": 211, - "shape_groups": 29, - "shape_labels": 15, + "recall": 381, + "shape_arcs": 2, + "shape_probe_coverage": 1, + "shape_probe": 203, + "shape_groups": 18, + "shape_labels": 5, "shape_admission": 0, - "shape": 1184, - "bind": 1000, - "materialise": 429, - "answer": 168 + "shape": 1186, + "bind": 829, + "materialise": 217, + "answer": 186 } }, "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", @@ -2417,7 +2418,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "4386e87708a64f078f39a795faeb0100" }, "json": { "schema_version": 1, @@ -2427,10 +2429,10 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "2841fbd5b3f24a44b79d2e01ed6faf58", + "trace_id": "4386e87708a64f078f39a795faeb0100", "warnings": [], "timing_ms": { - "total": 6, + "total": 9, "by_step": { "coverage": 0 } @@ -2443,18 +2445,18 @@ "variable_text": "GNI", "warnings": [], "timing_ms": { - "total": 6, + "total": 8, "by_step": { - "validate": 1, - "walk": 3, + "validate": 0, + "walk": 5, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, "shape": 0, "bind": 0, - "where_places": 0, - "materialise": 1, - "answer": 0, + "where_places": 1, + "materialise": 0, + "answer": 1, "options": 1 } }, @@ -3153,7 +3155,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "1b25ce6b48064cf199e5d3f405c4275a" }, "json": { "schema_version": 1, @@ -3191,7 +3194,7 @@ } }, "content_version": "cv_3cae36487750f272df16f77858171e89", - "prepared_at": "2026-10-21T08:57:25Z", + "prepared_at": "2026-10-21T13:05:11Z", "coverage": { "rows": 8, "dimensions": [ @@ -3344,7 +3347,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:57:25.351460+00:00" + "confirmed_at": "2026-10-21T13:05:11.583868+00:00" }, "warnings": [], "diagnostics": [ @@ -3364,7 +3367,7 @@ }, "bytes": 4800, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:25.321163+00:00", + "created_at": "2026-10-21T13:05:11.551892+00:00", "tier": "working", "url": "/api/datasets/spec_c0f61f3ca3558aac184973441a67601e/cv_3cae36487750f272df16f77858171e89/files/sha256:9086e741fcbfa1fe56a9d8af57c54ae3784744b50a03086d9e715623d9c71766" }, @@ -3375,7 +3378,7 @@ }, "bytes": 5294, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:25.321163+00:00", + "created_at": "2026-10-21T13:05:11.551892+00:00", "tier": "working", "url": "/api/datasets/spec_c0f61f3ca3558aac184973441a67601e/cv_3cae36487750f272df16f77858171e89/files/sha256:d822d05c709d2d1ca448023a433f936b28403893dede278e2b2696eca3587d1c" } @@ -3524,7 +3527,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:25.321231Z" + "held_until": "2026-11-20T13:05:11.551738Z" } } } @@ -3537,7 +3540,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A9086e741fcbfa1fe56a9d8af57c54ae3784744b50a03086d9e715623d9c71766?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A9086e741fcbfa1fe56a9d8af57c54ae3784744b50a03086d9e715623d9c71766?X-Goog-Signature=redacted", + "x-dfo-trace-id": "0abf22ccda6d4496896abfc9dbacd47b" } } }, @@ -3549,7 +3553,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "90ff16f5dd7746d3842158d1e5ae0635" }, "body_file": "answer-candidates-choose-fetch.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json index 72e1089..ec4b825 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:58:54Z" + "recorded_at": "2026-10-21T13:06:45Z" }, "call": [ { @@ -33,7 +33,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "3b78bd49dd0a4d24b3dfd8daa70035a3" }, "json": { "schema_version": 1, @@ -45,13 +46,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "b189cd826f684905bbf71384dbcf93cb", + "trace_id": "3b78bd49dd0a4d24b3dfd8daa70035a3", "warnings": [], "timing_ms": { - "total": 746, + "total": 802, "by_step": { - "coverage": 1, - "extract": 745 + "coverage": 0, + "extract": 802 } }, "llm_usage": { @@ -81,7 +82,7 @@ "error": { "class": "DeclinedError", "code": "answer_declined", - "trace_id": null + "trace_id": "3b78bd49dd0a4d24b3dfd8daa70035a3" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json index 6b94385..1d2ce6c 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:58:51Z" + "recorded_at": "2026-10-21T13:06:43Z" }, "call": [ { @@ -33,7 +33,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "e61600f8e689429293ea320f5079509e" }, "json": { "schema_version": 1, @@ -45,13 +46,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "cfa01996ace144f3900e03b7e31189db", + "trace_id": "e61600f8e689429293ea320f5079509e", "warnings": [], "timing_ms": { - "total": 2072, + "total": 2060, "by_step": { "coverage": 0, - "extract": 2071 + "extract": 2058 } }, "llm_usage": { @@ -87,7 +88,7 @@ "error": { "class": "DeclinedError", "code": "answer_declined", - "trace_id": null + "trace_id": "e61600f8e689429293ea320f5079509e" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-definite-fetch.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-definite-fetch.json index 402b415..54c1b69 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-definite-fetch.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-definite-fetch.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:57:13Z" + "recorded_at": "2026-10-21T13:04:59Z" }, "call": [ { @@ -33,7 +33,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "d09ca5f0ae574410bf93b5d905ea8009" }, "json": { "schema_version": 1, @@ -45,13 +46,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", + "trace_id": "d09ca5f0ae574410bf93b5d905ea8009", "warnings": [], "timing_ms": { - "total": 4556, + "total": 5038, "by_step": { "coverage": 0, - "extract": 889 + "extract": 1141 } }, "llm_usage": { @@ -67,20 +68,20 @@ "variable_text": "basic health care ODA disbursements", "warnings": [], "timing_ms": { - "total": 3505, + "total": 3758, "by_step": { - "recall": 628, + "recall": 694, "shape_arcs": 1, - "shape_probe_coverage": 5, - "shape_probe": 477, - "shape_groups": 22, - "shape_labels": 1, + "shape_probe_coverage": 6, + "shape_probe": 489, + "shape_groups": 16, + "shape_labels": 0, "shape_admission": 1, - "shape": 1283, - "bind": 1188, + "shape": 1365, + "bind": 1248, "materialise": 11, - "answer": 381, - "options": 14 + "answer": 423, + "options": 17 } }, "restatement": { @@ -3763,7 +3764,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "90ec74fce6534d0d8e4142b0e1355782" }, "json": { "schema_version": 1, @@ -3835,7 +3837,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-21T08:57:19Z", + "prepared_at": "2026-10-21T13:05:05Z", "coverage": { "rows": 30, "dimensions": [ @@ -4168,7 +4170,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:57:19.628756+00:00" + "confirmed_at": "2026-10-21T13:05:06.336796+00:00" }, "warnings": [], "diagnostics": [ @@ -4188,7 +4190,7 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, @@ -4199,7 +4201,7 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } @@ -4444,7 +4446,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:19.589587Z" + "held_until": "2026-11-20T13:05:06.298810Z" } } } @@ -4457,7 +4459,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted", + "x-dfo-trace-id": "d14640239a5a4ffa8f113140eb5b23a0" } } }, @@ -4469,7 +4472,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "58cc82a3079f4e4298eb45378fdf10db" }, "body_file": "answer-definite-fetch.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json index e711a79..010956c 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json @@ -29,7 +29,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "d09ca5f0ae574410bf93b5d905ea8009" }, "json": { "schema_version": 1, @@ -41,13 +42,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", + "trace_id": "d09ca5f0ae574410bf93b5d905ea8009", "warnings": [], "timing_ms": { - "total": 4556, + "total": 5038, "by_step": { "coverage": 0, - "extract": 889 + "extract": 1141 } }, "llm_usage": { @@ -63,20 +64,20 @@ "variable_text": "basic health care ODA disbursements", "warnings": [], "timing_ms": { - "total": 3505, + "total": 3758, "by_step": { - "recall": 628, + "recall": 694, "shape_arcs": 1, - "shape_probe_coverage": 5, - "shape_probe": 477, - "shape_groups": 22, - "shape_labels": 1, + "shape_probe_coverage": 6, + "shape_probe": 489, + "shape_groups": 16, + "shape_labels": 0, "shape_admission": 1, - "shape": 1283, - "bind": 1188, + "shape": 1365, + "bind": 1248, "materialise": 11, - "answer": 381, - "options": 14 + "answer": 423, + "options": 17 } }, "restatement": { @@ -3679,7 +3680,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": null + "trace_id": "d09ca5f0ae574410bf93b5d905ea8009" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json index 591e0c3..c9d2c46 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json @@ -29,7 +29,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d" }, "json": { "schema_version": 1, @@ -41,13 +42,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "trace_id": "95b872cf11e44fffb92260b2bb583f0d", "warnings": [], "timing_ms": { - "total": 1788, + "total": 1697, "by_step": { "coverage": 0, - "extract": 1353 + "extract": 982 } }, "llm_usage": { @@ -98,7 +99,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": null + "trace_id": "95b872cf11e44fffb92260b2bb583f0d" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json index e76bef6..4cd0f57 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:57:30Z" + "recorded_at": "2026-10-21T13:05:16Z" }, "call": [ { @@ -34,7 +34,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "8571f47c3ca8460f8e9a594da2fc942b" }, "json": { "schema_version": 1, @@ -46,13 +47,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "dcf1ce440fc24b248c5237bb149d73ef", + "trace_id": "8571f47c3ca8460f8e9a594da2fc942b", "warnings": [], "timing_ms": { - "total": 3081, + "total": 3603, "by_step": { "coverage": 0, - "extract": 930 + "extract": 839 } }, "llm_usage": { @@ -68,18 +69,18 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 2113, + "total": 2725, "by_step": { "recall": 1, - "shape_arcs": 2, - "shape_probe_coverage": 8, - "shape_probe": 8, - "shape_groups": 4, - "shape_labels": 5, + "shape_arcs": 1, + "shape_probe_coverage": 12, + "shape_probe": 13, + "shape_groups": 5, + "shape_labels": 8, "shape_admission": 0, - "shape": 603, - "bind": 1503, - "materialise": 3, + "shape": 788, + "bind": 1929, + "materialise": 4, "answer": 0, "options": 3 } @@ -3250,15 +3251,15 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 7, + "total": 12, "by_step": { - "recall": 2, + "recall": 1, "shape_arcs": 1, - "shape_probe": 2, + "shape_probe": 5, "shape_groups": 0, "shape_labels": 0, - "shape_admission": 0, - "shape": 5 + "shape_admission": 1, + "shape": 11 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", @@ -3694,7 +3695,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "afabd49505e34d9d91854d77caca574d" }, "json": { "schema_version": 1, @@ -3772,7 +3774,7 @@ } }, "content_version": "cv_2c981b422e8f8bdf5dee6067837cff13", - "prepared_at": "2026-10-21T08:57:34Z", + "prepared_at": "2026-10-21T13:05:20Z", "coverage": { "rows": 55, "dimensions": [ @@ -3934,7 +3936,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:57:34.243265+00:00" + "confirmed_at": "2026-10-21T13:05:20.852361+00:00" }, "warnings": [], "diagnostics": [ @@ -3954,7 +3956,7 @@ }, "bytes": 6025, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:34.203372+00:00", + "created_at": "2026-10-21T13:05:20.814206+00:00", "tier": "working", "url": "/api/datasets/spec_78d04fefc3b3f1ef71acd622957e4995/cv_2c981b422e8f8bdf5dee6067837cff13/files/sha256:674d9a4ab33eabc631aba510ed88f9d45ddeef43d11d2aee7b267bd1e3546143" }, @@ -3965,7 +3967,7 @@ }, "bytes": 5343, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:34.203372+00:00", + "created_at": "2026-10-21T13:05:20.814206+00:00", "tier": "working", "url": "/api/datasets/spec_78d04fefc3b3f1ef71acd622957e4995/cv_2c981b422e8f8bdf5dee6067837cff13/files/sha256:8da8a5b081cc06acba677ac2c668e4bcafb796bf040bede5de00740acda9c9ee" } @@ -4127,7 +4129,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:34.203386Z" + "held_until": "2026-11-20T13:05:20.813993Z" } } } @@ -4140,7 +4142,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A674d9a4ab33eabc631aba510ed88f9d45ddeef43d11d2aee7b267bd1e3546143?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A674d9a4ab33eabc631aba510ed88f9d45ddeef43d11d2aee7b267bd1e3546143?X-Goog-Signature=redacted", + "x-dfo-trace-id": "f4cc6b35ba294a0380ca97496ec86733" } } }, @@ -4152,7 +4155,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "7ffed6c80e5f484c9a566956adb5c5c0" }, "body_file": "answer-mixed-fetch-partial.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json index be12d86..4ebd2d7 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:57:25Z" + "recorded_at": "2026-10-21T13:05:11Z" }, "call": [ { @@ -33,7 +33,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "3b0a506d6d2a43a0becd94837bafffa1" }, "json": { "schema_version": 1, @@ -45,13 +46,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d0fa88511b064cc6966082b296cd6ea8", + "trace_id": "3b0a506d6d2a43a0becd94837bafffa1", "warnings": [], "timing_ms": { - "total": 4688, + "total": 4692, "by_step": { "coverage": 0, - "extract": 928 + "extract": 1001 } }, "llm_usage": { @@ -67,20 +68,20 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 3547, + "total": 3475, "by_step": { - "recall": 312, - "shape_arcs": 2, - "shape_probe_coverage": 2, - "shape_probe": 192, - "shape_groups": 2, - "shape_labels": 6, + "recall": 434, + "shape_arcs": 3, + "shape_probe_coverage": 4, + "shape_probe": 243, + "shape_groups": 3, + "shape_labels": 9, "shape_admission": 0, - "shape": 912, - "bind": 1643, - "materialise": 3, - "answer": 462, - "options": 215 + "shape": 893, + "bind": 1563, + "materialise": 9, + "answer": 381, + "options": 195 } }, "restatement": { @@ -3249,15 +3250,15 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 502, + "total": 574, "by_step": { - "recall": 307, + "recall": 380, "shape_arcs": 1, "shape_probe": 190, - "shape_groups": 1, + "shape_groups": 0, "shape_labels": 0, "shape_admission": 0, - "shape": 195 + "shape": 194 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", @@ -3625,7 +3626,7 @@ "error": { "class": "IncompleteAnswerError", "code": "answer_incomplete", - "trace_id": null + "trace_id": "3b0a506d6d2a43a0becd94837bafffa1" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-nested-specs-unchecked.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-nested-specs-unchecked.json index b37085a..9d673fd 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-nested-specs-unchecked.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-nested-specs-unchecked.json @@ -1,19 +1,20 @@ { "format_version": 1, "name": "answer-nested-specs-unchecked", - "description": "A client checks strict members only where a rule reads them, so a spec nested in resolved.alternative_measures may lack them, and the fetch reaches the same dataset.", + "description": "A client checks strict members only where a rule reads them, so a Spec in no_data.flagged_match, no_data.alternate_match or resolved.equivalent_readings may lack resolved and identity, and the search and the choice reach the same answers.", "origin": { "kind": "synthetic", - "derived_from": "answer-definite-fetch", - "edit": "Each alternative measure of part 0's spec loses its definition's identity and its resolved." + "derived_from": "choose-place-one-part", + "edit": "The no_data part's flagged_match and alternate_match, and the chosen spec's resolved.equivalent_readings, hold the chosen spec without resolved and without its definition's identity." }, "call": [ { "op": "search", - "question": "ODA disbursements from Germany to Nigeria for basic health care" + "question": "ODA disbursements from Germany to Congo" }, { - "op": "fetch" + "op": "choose", + "option": "Congo [DRC]" } ], "exchanges": [ @@ -25,72 +26,88 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Nigeria for basic health care" + "query": "ODA disbursements from Germany to Congo" } } }, "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "1ad25aff9f6a4ad7ac21922af623e5e9" }, "json": { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "ODA disbursements from Germany to Nigeria for basic health care", - "normalized_query": "ODA disbursements from Germany to Nigeria for basic health care", + "raw_query": "ODA disbursements from Germany to Congo", + "normalized_query": "ODA disbursements from Germany to Congo", "extract_skipped": false }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", + "trace_id": "1ad25aff9f6a4ad7ac21922af623e5e9", "warnings": [], "timing_ms": { - "total": 4556, + "total": 1084, "by_step": { "coverage": 0, - "extract": 889 + "extract": 1082 } }, "llm_usage": { - "input_tokens": 6116, - "output_tokens": 408, - "cached_tokens": 0 + "input_tokens": 2249, + "output_tokens": 154, + "cached_tokens": 859 }, "timed_out": false }, "kind": "resolution", "parts": [ { - "variable_text": "basic health care ODA disbursements", + "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 3505, + "total": 1, "by_step": { - "recall": 628, - "shape_arcs": 1, - "shape_probe_coverage": 5, - "shape_probe": 477, - "shape_groups": 22, - "shape_labels": 1, - "shape_admission": 1, - "shape": 1283, - "bind": 1188, - "materialise": 11, - "answer": 381, - "options": 14 + "recall": 1 } }, + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], "restatement": { - "variable_text": "basic health care ODA disbursements", + "variable_text": "ODA disbursements", "entities": [ { "text": "Germany", "role_text": "from" }, { - "text": "Nigeria", + "text": "Congo", "role_text": "to" } ], @@ -100,12 +117,260 @@ "operations": [], "departures": [], "assumptions": [], + "status": "no_data", + "no_data": { + "reason": "entity_ambiguous", + "category": "unresolved", + "message": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "entity_terms": [ + "Congo" + ], + "ambiguous_entities": [ + { + "text": "Congo", + "candidates": [ + { + "ref": "country/COD", + "label": "Congo [DRC]", + "kind": "country" + }, + { + "ref": "country/COG", + "label": "Congo [Republic]", + "kind": "country" + } + ] + } + ], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [ + { + "mentions": [ + "Congo" + ], + "label": "Congo [DRC]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + }, + { + "mentions": [ + "Congo" + ], + "label": "Congo [Republic]", + "data_query": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COG" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + ], + "flagged_match": { + "spec_id": "spec_53b1ed52ebddd28ce274d419b53037c3", + "definition": { + "schema_version": 1, + "spec_id": "spec_53b1ed52ebddd28ce274d419b53037c3" + } + }, + "alternate_match": { + "spec_id": "spec_53b1ed52ebddd28ce274d419b53037c3", + "definition": { + "schema_version": 1, + "spec_id": "spec_53b1ed52ebddd28ce274d419b53037c3" + } + } + } + } + ], + "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "sentence_plan": [ + { + "kind": "text", + "text": "\"", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Congo", + "axis": "where", + "segment": "heading", + "role": "destination", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "no_data" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "parsed", + "parts": [ + { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + } + ] + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "11f83a7e47c0452492b5c433c0829ff3" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "parsed", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "11f83a7e47c0452492b5c433c0829ff3", + "warnings": [], + "timing_ms": { + "total": 2651, + "by_step": { + "coverage": 0 + } + }, + "llm_usage": { + "input_tokens": 4231, + "output_tokens": 200, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "ODA disbursements", + "warnings": [ + { + "code": "retrieval_score_weak", + "severity": "info", + "message": "the chosen reading's match to the query is weak; treat it with less confidence than a strong match." + }, + { + "code": "time_window_defaulted", + "severity": "warn", + "message": "no time_text was given; the answer was resolved across every period with data." + } + ], + "timing_ms": { + "total": 2337, + "by_step": { + "recall": 0, + "shape_arcs": 1, + "shape_probe_coverage": 3, + "shape_probe": 205, + "shape_groups": 20, + "shape_labels": 2, + "shape_admission": 0, + "shape": 1074, + "bind": 1250, + "materialise": 6, + "answer": 5, + "options": 2 + } + }, + "restatement": { + "variable_text": "ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from", + "dcid": "country/DEU" + }, + { + "text": "Congo", + "role_text": "to", + "dcid": "country/COD" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], "status": "definite", "spec": { - "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "spec_id": "spec_53b1ed52ebddd28ce274d419b53037c3", "definition": { "schema_version": 1, - "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "spec_id": "spec_53b1ed52ebddd28ce274d419b53037c3", "identity": { "identity_version": "spec1", "shape": { @@ -117,31 +382,18 @@ }, "slots": [ { - "property": "crsCooperationModality", - "binding": { - "state": "unbound" - } - }, - { - "property": "crsPurpose", + "property": "dac2aAidType", "binding": { "state": "value", - "ref": "CRSPurposeCode12220" + "ref": "DAC2aAidType206" } }, { - "property": "crsTypeOfFinance", + "property": "dacTypeOfFinance", "binding": { "state": "unbound" } }, - { - "property": "crsTypeOfFlow", - "binding": { - "state": "value", - "ref": "CRSTypeOfFlow10" - } - }, { "property": "financialFlowType", "binding": { @@ -159,7 +411,7 @@ ], "entities": { "destination": [ - "country/NGA" + "country/COD" ], "origin": [ "country/DEU" @@ -172,8 +424,8 @@ }, "resolved": { "shape": { - "shape_id": "financialflow_amount_measuredvalue_nominal", - "label": "gross disbursements (basic health care, official development assistance, standard grant)", + "shape_id": "financialflow_amount_measuredvalue_nominal_family_f096b1ba", + "label": "gross disbursements (official development assistance)", "population_type": { "ref": "FinancialFlow", "label": "financial flow" @@ -195,26 +447,18 @@ { "axis": "how", "property": { - "ref": "crsPurpose", - "label": "CRS purpose" - }, - "label": "sector" - }, - { - "axis": "how", - "property": { - "ref": "crsTypeOfFinance", - "label": "CRS type of finance" + "ref": "dac2aAidType", + "label": "DAC 2a aid type" }, - "label": "instrument" + "label": "aid type" }, { "axis": "how", "property": { - "ref": "crsTypeOfFlow", - "label": "CRS type of flow" + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" }, - "label": "flow" + "label": "DAC type of finance" }, { "axis": "how", @@ -232,14 +476,6 @@ }, "label": "netting basis" }, - { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, { "axis": "where", "label": "place" @@ -253,8 +489,8 @@ "label": "data source" } ], - "member_count": 21, - "member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "member_count": 1, + "member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", "refine_supported": true, "data_commons": [ { @@ -268,57 +504,36 @@ "key": { "axis": "how", "property": { - "ref": "crsPurpose", - "label": "CRS purpose" + "ref": "dac2aAidType", + "label": "DAC 2a aid type" }, - "label": "sector" + "label": "aid type" }, "binding": { "kind": "value", "value": { "ref": { - "ref": "CRSPurposeCode12220", - "label": "basic health care" + "ref": "DAC2aAidType206", + "label": "official development assistance" }, "value_kind": "enum_value" } }, - "summable": true + "summable": false }, { "key": { "axis": "how", "property": { - "ref": "crsTypeOfFinance", - "label": "CRS type of finance" + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" }, - "label": "instrument" + "label": "DAC type of finance" }, "binding": { "kind": "unbound" }, - "summable": true - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFlow", - "label": "CRS type of flow" - }, - "label": "flow" - }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" - }, - "value_kind": "enum_value" - } - }, - "summable": true + "summable": false }, { "key": { @@ -362,20 +577,6 @@ }, "summable": false }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding": { - "kind": "unbound" - }, - "summable": true - }, { "key": { "axis": "where", @@ -385,8 +586,8 @@ "kind": "value", "value": { "ref": { - "ref": "country/NGA", - "label": "Nigeria" + "ref": "country/COD", + "label": "Democratic Republic of the Congo" }, "value_kind": "entity" } @@ -415,22 +616,23 @@ } ], "inapplicable_slots": [ + "dacTypeOfFinance", "financialObligationType" ], "unresolved_slots": [], "stat_vars": { - "member_count": 5, + "member_count": 1, "member_count_exact": true, - "served_count": 21, + "served_count": 1, "data_date_range": { - "start": "1995", + "start": "1960", "end": "2024" } }, "entities": [ { - "ref": "country/NGA", - "label": "Nigeria", + "ref": "country/COD", + "label": "Democratic Republic of the Congo", "entity_type": "Country", "role": "destination" }, @@ -444,7 +646,7 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 30, + "observation_count": 65, "evidence": "facet_metadata", "dimensions": [ { @@ -453,19 +655,19 @@ }, { "label": "observations", - "count": 15 + "count": 65 }, { "label": "variables", - "count": 5 + "count": 1 } ] }, "headline": { "year": 2024, "year_named": false, - "observations": 3, - "series": 3, + "observations": 1, + "series": 1, "role_counts": { "financingProvider": 1, "financingRecipient": 1 @@ -473,8 +675,8 @@ "recent_years": [ { "year": 2024, - "observations": 3, - "series": 3, + "observations": 1, + "series": 1, "role_counts": { "financingProvider": 1, "financingRecipient": 1 @@ -501,11 +703,11 @@ ] }, "download": { - "rows": 30, + "rows": 65, "rows_exact": true, - "series": 5, + "series": 1, "window": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "licence": { @@ -516,8 +718,8 @@ "facets": { "provenance": { "basis": "fallback", - "ref": "provenance/OECDCreditorReportingSystem", - "label": "OECD Creditor Reporting System (CRS)", + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", "source": { "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", "label": "Organisation for Economic Co-operation and Development (OECD)" @@ -526,7 +728,7 @@ "id": "dfo", "label": "Development Finance Observatory" }, - "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", + "documentation": "/api/graph/documentation/provenance/OECDDAC2A", "account": "provider" }, "unit": { @@ -541,234 +743,110 @@ "key": { "axis": "how", "property": { - "ref": "crsPurpose", - "label": "CRS purpose" + "ref": "dac2aAidType", + "label": "DAC 2a aid type" }, - "label": "sector" + "label": "aid type" }, "options": [ { "value": { "ref": { - "ref": "CRSPurposeCode122", - "label": "basic health" + "ref": "DAC2aAidType218", + "label": "ODA loans and other long-term capital" }, "value_kind": "enum_value" }, - "relation": "parent", - "parent": "CRSPurposeCode120", - "member_count": 4, - "served_rows": 88, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 2, + "served_rows": 45, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType201", + "label": "ODA grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 1, + "served_rows": 65, "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFinance", - "label": "CRS type of finance" }, - "label": "instrument" - }, - "options": [ { "value": { "ref": { - "ref": "CRSTypeOfFinance100", - "label": "grant" + "ref": "DAC2aAidType207", + "label": "free-standing technical co-operation" }, "value_kind": "enum_value" }, "relation": "root", - "member_count": 0, - "served_rows": 30, + "member_count": 1, + "served_rows": 59, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSTypeOfFinance110", - "label": "standard grant" + "ref": "DAC2aAidType213", + "label": "developmental food aid" }, "value_kind": "enum_value" }, - "relation": "child", - "parent": "CRSTypeOfFinance100", - "member_count": 12672, - "served_rows": 30, + "relation": "root", + "member_count": 1, + "served_rows": 27, "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFlow", - "label": "CRS type of flow" }, - "label": "flow" - }, - "options": [ { "value": { "ref": { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "DAC2aAidType216", + "label": "humanitarian aid" }, "value_kind": "enum_value" }, "relation": "root", - "member_count": 14098, - "served_rows": 30, + "member_count": 1, + "served_rows": 29, "served_rows_exact": true } ], "truncated": false, "source": "observed" - }, + } + ], + "entity_options": [], + "facet_options": [ { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, + "axis": "provenance", "options": [ { "value": { "ref": { - "ref": "CRSCooperationModalityB", - "label": "core contribution and pooled programme and fund" + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A" }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 7, - "served_rows_exact": true - }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ { "value": { "ref": { - "ref": "CRSCooperationModalityB03", - "label": "contribution to specific-purpose programme and fund managed by an international organisation" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityB", - "member_count": 1606, - "served_rows": 1, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityB01", - "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityB", - "member_count": 1331, - "served_rows": 6, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityC", - "label": "project-type intervention (group)" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 7, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityC01", - "label": "project-type intervention" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityC", - "member_count": 7005, - "served_rows": 7, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityD", - "label": "expert and other technical assistance" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 1, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityD02", - "label": "other technical assistance" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityD", - "member_count": 1600, - "served_rows": 1, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ - { - "axis": "provenance", - "options": [ - { - "value": { - "ref": { - "ref": "provenance/OECDCreditorReportingSystem", - "label": "OECD Creditor Reporting System (CRS)" - }, - "value_kind": "source" - } - } - ], - "truncated": false, - "source": "observed" - }, - { - "axis": "unit", - "options": [ - { - "value": { - "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" + "ref": "CurrencyUSD", + "label": "US Dollar" }, "value_kind": "enum_value" } @@ -778,7 +856,7 @@ "source": "observed" } ], - "rendered_sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "rendered_sentence": "Germany's gross disbursements to Democratic Republic of the Congo for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", "sentence_plan": [ { "kind": "slot", @@ -809,13 +887,11 @@ }, { "kind": "slot", - "text": "gross ODA disbursements", + "text": "gross disbursements", "axis": "what", "segment": "heading", "entity_refs": [], "states": [ - "how:crsTypeOfFinance", - "how:crsTypeOfFlow", "how:financialFlowType", "how:nettingBasis", "axis:populationType", @@ -831,13 +907,13 @@ }, { "kind": "slot", - "text": "Nigeria", + "text": "Democratic Republic of the Congo", "axis": "where", "segment": "heading", "role": "destination", "binding_ref": "where:", "entity_refs": [ - "country/NGA" + "country/COD" ], "states": [ "where:" @@ -852,14 +928,14 @@ }, { "kind": "slot", - "text": "basic health care", + "text": "official development assistance", "axis": "how", "segment": "heading", - "property_dcid": "crsPurpose", - "binding_ref": "how:crsPurpose", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", "entity_refs": [], "states": [ - "how:crsPurpose" + "how:dac2aAidType" ] }, { @@ -867,28 +943,8 @@ "text": "", "axis": "how", "segment": "heading", - "property_dcid": "crsCooperationModality", - "binding_ref": "how:crsCooperationModality", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "crsTypeOfFinance", - "binding_ref": "how:crsTypeOfFinance", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "crsTypeOfFlow", - "binding_ref": "how:crsTypeOfFlow", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", "entity_refs": [], "states": [] }, @@ -921,7 +977,7 @@ }, { "kind": "slot", - "text": "1995 to 2024", + "text": "1960 to 2024", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -965,7 +1021,7 @@ }, { "kind": "slot", - "text": "OECD Creditor Reporting System (CRS)", + "text": "OECD DAC2a", "axis": "source", "segment": "byline", "entity_refs": [], @@ -984,8 +1040,8 @@ "trace": { "resolved_entities": [ { - "ref": "country/NGA", - "label": "Nigeria" + "ref": "country/COD", + "label": "Democratic Republic of the Congo" }, { "ref": "country/DEU", @@ -994,8 +1050,8 @@ ], "resolved_sources": [ { - "ref": "provenance/OECDCreditorReportingSystem", - "label": "OECD Creditor Reporting System (CRS)", + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2a", "source": { "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", "label": "Organisation for Economic Co-operation and Development (OECD)" @@ -1004,7 +1060,7 @@ "id": "dfo", "label": "Development Finance Observatory" }, - "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem" + "documentation": "/api/graph/documentation/provenance/OECDDAC2A" } ], "slot_filters": [ @@ -1012,16 +1068,16 @@ "key": { "axis": "how", "property": { - "ref": "crsPurpose", - "label": "CRS purpose" + "ref": "dac2aAidType", + "label": "DAC 2a aid type" }, - "label": "sector" + "label": "aid type" }, "binding_kind": "value", "refs": [ { - "ref": "CRSPurposeCode12220", - "label": "basic health care" + "ref": "DAC2aAidType206", + "label": "official development assistance" } ], "provenance": "text_recognized" @@ -1030,33 +1086,15 @@ "key": { "axis": "how", "property": { - "ref": "crsTypeOfFinance", - "label": "CRS type of finance" + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" }, - "label": "instrument" + "label": "DAC type of finance" }, "binding_kind": "unbound", "refs": [], "provenance": "binder" }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFlow", - "label": "CRS type of flow" - }, - "label": "flow" - }, - "binding_kind": "value", - "refs": [ - { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" - } - ], - "provenance": "text_recognized" - }, { "key": { "axis": "how", @@ -1093,19 +1131,6 @@ ], "provenance": "measure_elected" }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "where", @@ -1114,8 +1139,8 @@ "binding_kind": "value", "refs": [ { - "ref": "country/NGA", - "label": "Nigeria" + "ref": "country/COD", + "label": "Democratic Republic of the Congo" } ], "provenance": "binder" @@ -1140,27 +1165,15 @@ } ], "query_qualifiers": [ - { - "text": "basic health care", - "named": [ - { - "ref": "CRSPurposeCode12220", - "label": "basic health care" - } - ], - "slot": "crsPurpose", - "disposition": "bound", - "selected": [] - }, { "text": "ODA", "named": [ { - "ref": "CRSTypeOfFlow10", + "ref": "DAC2aAidType206", "label": "official development assistance" } ], - "slot": "crsTypeOfFlow", + "slot": "dac2aAidType", "disposition": "bound", "selected": [] } @@ -1177,7 +1190,57 @@ { "definition": { "schema_version": 1, - "spec_id": "spec_80b92ca1ba1114b426eb5e79b84361d4" + "spec_id": "spec_2e1f188265cd4f5123438ee26a59cc9e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/COD" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } }, "label": "net disbursements", "axis": "what", @@ -1218,47 +1281,7 @@ } } ], - "served_rows": 30, - "served_rows_exact": true - }, - { - "definition": { - "schema_version": 1, - "spec_id": "spec_c394f9108db2100f1c8e4532d8d1c804" - }, - "label": "commitments", - "axis": "what", - "measure_axis_values": [ - { - "axis": "populationType", - "value": { - "ref": "FinancialObligation", - "label": "financial obligation" - } - }, - { - "axis": "measuredProperty", - "value": { - "ref": "amount", - "label": "amount" - } - }, - { - "axis": "measurementQualifier", - "value": { - "ref": "Nominal", - "label": "nominal" - } - }, - { - "axis": "financialObligationType", - "value": { - "ref": "Commitment", - "label": "commitment" - } - } - ], - "served_rows": 24, + "served_rows": 65, "served_rows_exact": true } ], @@ -1307,63 +1330,6 @@ } } ], - "open_axis_facts": [ - { - "property": "crsTypeOfFinance", - "varies": false, - "value": { - "ref": "CRSTypeOfFinance110", - "label": "standard grant" - }, - "distinct_count": 1, - "undeclared_count": 0, - "values": [ - { - "value": { - "ref": "CRSTypeOfFinance110", - "label": "standard grant" - }, - "count": 5 - } - ] - }, - { - "property": "crsCooperationModality", - "varies": true, - "distinct_count": 4, - "undeclared_count": 1, - "values": [ - { - "value": { - "ref": "CRSCooperationModalityB03", - "label": "contribution to specific-purpose programme and fund managed by an international organisation" - }, - "count": 1 - }, - { - "value": { - "ref": "CRSCooperationModalityB01", - "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" - }, - "count": 1 - }, - { - "value": { - "ref": "CRSCooperationModalityD02", - "label": "other technical assistance" - }, - "count": 1 - }, - { - "value": { - "ref": "CRSCooperationModalityC01", - "label": "project-type intervention" - }, - "count": 1 - } - ] - } - ], "unit_conversion": { "currencies": [ { @@ -1374,7 +1340,7 @@ "end_year": 2021 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 2023, @@ -1388,7 +1354,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 2002, @@ -1398,11 +1364,11 @@ "code": "ALL", "noun": "Albanian leks", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1412,11 +1378,11 @@ "code": "AMD", "noun": "Armenian drams", "current_years": { - "start_year": 1995, + "start_year": 1992, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1992, @@ -1426,11 +1392,11 @@ "code": "AOA", "noun": "Angolan kwanzas", "current_years": { - "start_year": 1995, + "start_year": 1991, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1991, @@ -1440,11 +1406,11 @@ "code": "ARS", "noun": "Argentine pesos", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1454,11 +1420,11 @@ "code": "AUD", "noun": "Australian dollars", "current_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1960, @@ -1472,7 +1438,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1995, @@ -1486,7 +1452,7 @@ "end_year": 2019 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 2023, @@ -1500,7 +1466,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1996, @@ -1510,11 +1476,11 @@ "code": "BBD", "noun": "Barbadian dollars", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1524,11 +1490,11 @@ "code": "BDT", "noun": "Bangladeshi taka", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1538,11 +1504,11 @@ "code": "BHD", "noun": "Bahraini dinars", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1552,11 +1518,11 @@ "code": "BIF", "noun": "Burundian francs", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1566,11 +1532,11 @@ "code": "BND", "noun": "Brunei dollars", "current_years": { - "start_year": 1995, + "start_year": 1985, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1985, @@ -1580,11 +1546,11 @@ "code": "BOB", "noun": "Bolivian bolivianos", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1594,11 +1560,11 @@ "code": "BRL", "noun": "Brazilian reais", "current_years": { - "start_year": 1995, + "start_year": 1986, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1986, @@ -1608,11 +1574,11 @@ "code": "BSD", "noun": "Bahamian dollars", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1622,11 +1588,11 @@ "code": "BTN", "noun": "Bhutanese ngultrums", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1636,11 +1602,11 @@ "code": "BWP", "noun": "Botswana pula", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1650,11 +1616,11 @@ "code": "BYN", "noun": "Belarusian rubles", "current_years": { - "start_year": 1995, + "start_year": 1992, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1992, @@ -1664,11 +1630,11 @@ "code": "BZD", "noun": "Belize dollars", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1678,11 +1644,11 @@ "code": "CAD", "noun": "Canadian dollars", "current_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1960, @@ -1692,11 +1658,11 @@ "code": "CDF", "noun": "Congolese francs", "current_years": { - "start_year": 1995, + "start_year": 1991, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1991, @@ -1706,11 +1672,11 @@ "code": "CHF", "noun": "Swiss francs", "current_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1960, @@ -1720,11 +1686,11 @@ "code": "CLP", "noun": "Chilean pesos", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1734,11 +1700,11 @@ "code": "CNY", "noun": "Chinese yuan", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1748,11 +1714,11 @@ "code": "COP", "noun": "Colombian pesos", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1762,11 +1728,11 @@ "code": "CRC", "noun": "Costa Rican colones", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1776,11 +1742,11 @@ "code": "CVE", "noun": "Cape Verdean escudos", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1794,7 +1760,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1998, @@ -1804,11 +1770,11 @@ "code": "DJF", "noun": "Djiboutian francs", "current_years": { - "start_year": 1995, + "start_year": 1990, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1990, @@ -1818,11 +1784,11 @@ "code": "DKK", "noun": "Danish kroner", "current_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1960, @@ -1832,11 +1798,11 @@ "code": "DOP", "noun": "Dominican pesos", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1846,11 +1812,11 @@ "code": "DZD", "noun": "Algerian dinars", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1860,11 +1826,11 @@ "code": "EGP", "noun": "Egyptian pounds", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1874,11 +1840,11 @@ "code": "ERN", "noun": "Eritrean nakfas", "current_years": { - "start_year": 1995, + "start_year": 1992, "end_year": 2019 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1992, @@ -1888,11 +1854,11 @@ "code": "ETB", "noun": "Ethiopian birr", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1902,11 +1868,11 @@ "code": "EUR", "noun": "euros", "current_years": { - "start_year": 1995, + "start_year": 1973, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1973, @@ -1916,11 +1882,11 @@ "code": "FJD", "noun": "Fijian dollars", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1930,11 +1896,11 @@ "code": "GBP", "noun": "British pounds", "current_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1960, @@ -1944,11 +1910,11 @@ "code": "GEL", "noun": "Georgian lari", "current_years": { - "start_year": 1995, + "start_year": 1994, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1994, @@ -1958,11 +1924,11 @@ "code": "GHS", "noun": "Ghanaian cedis", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1972,11 +1938,11 @@ "code": "GMD", "noun": "Gambian dalasis", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -1986,11 +1952,11 @@ "code": "GNF", "noun": "Guinean francs", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2000,11 +1966,11 @@ "code": "GTQ", "noun": "Guatemalan quetzales", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2014,11 +1980,11 @@ "code": "GYD", "noun": "Guyanese dollars", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2028,11 +1994,11 @@ "code": "HKD", "noun": "Hong Kong dollars", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2042,11 +2008,11 @@ "code": "HNL", "noun": "Honduran lempiras", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2056,11 +2022,11 @@ "code": "HTG", "noun": "Haitian gourdes", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2074,7 +2040,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 2003, @@ -2084,11 +2050,11 @@ "code": "IDR", "noun": "Indonesian rupiahs", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2102,7 +2068,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1997, @@ -2112,11 +2078,11 @@ "code": "INR", "noun": "Indian rupees", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2130,7 +2096,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 2000, @@ -2140,11 +2106,11 @@ "code": "IRR", "noun": "Iranian rials", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2158,7 +2124,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1997, @@ -2168,11 +2134,11 @@ "code": "JMD", "noun": "Jamaican dollars", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2182,11 +2148,11 @@ "code": "JOD", "noun": "Jordanian dinars", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2196,11 +2162,11 @@ "code": "JPY", "noun": "Japanese yen", "current_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1960, @@ -2210,11 +2176,11 @@ "code": "KES", "noun": "Kenyan shillings", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2224,11 +2190,11 @@ "code": "KGS", "noun": "Kyrgyz soms", "current_years": { - "start_year": 1995, + "start_year": 1992, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1992, @@ -2238,11 +2204,11 @@ "code": "KHR", "noun": "Cambodian riels", "current_years": { - "start_year": 1995, + "start_year": 1986, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1986, @@ -2252,11 +2218,11 @@ "code": "KMF", "noun": "Comorian francs", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2266,11 +2232,11 @@ "code": "KRW", "noun": "South Korean won", "current_years": { - "start_year": 1995, + "start_year": 1987, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1987, @@ -2284,7 +2250,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1995, @@ -2298,7 +2264,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 2013, @@ -2308,11 +2274,11 @@ "code": "LAK", "noun": "Lao kip", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2322,11 +2288,11 @@ "code": "LBP", "noun": "Lebanese pounds", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2336,11 +2302,11 @@ "code": "LKR", "noun": "Sri Lankan rupees", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2350,11 +2316,11 @@ "code": "LSL", "noun": "Lesotho maloti", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2364,11 +2330,11 @@ "code": "LYD", "noun": "Libyan dinars", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2378,11 +2344,11 @@ "code": "MAD", "noun": "Moroccan dirhams", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2392,11 +2358,11 @@ "code": "MDL", "noun": "Moldovan lei", "current_years": { - "start_year": 1995, + "start_year": 1992, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1992, @@ -2406,11 +2372,11 @@ "code": "MGA", "noun": "Malagasy ariary", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2420,11 +2386,11 @@ "code": "MKD", "noun": "Macedonian denars", "current_years": { - "start_year": 1995, + "start_year": 1992, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1992, @@ -2438,7 +2404,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1998, @@ -2448,11 +2414,11 @@ "code": "MNT", "noun": "Mongolian tugriks", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2466,7 +2432,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 2001, @@ -2476,11 +2442,11 @@ "code": "MRU", "noun": "Mauritanian ouguiyas", "current_years": { - "start_year": 1995, + "start_year": 1990, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1990, @@ -2490,11 +2456,11 @@ "code": "MUR", "noun": "Mauritian rupees", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2504,11 +2470,11 @@ "code": "MVR", "noun": "Maldivian rufiyaa", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2518,11 +2484,11 @@ "code": "MWK", "noun": "Malawian kwachas", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2532,11 +2498,11 @@ "code": "MXN", "noun": "Mexican pesos", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2546,11 +2512,11 @@ "code": "MYR", "noun": "Malaysian ringgits", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2560,11 +2526,11 @@ "code": "MZN", "noun": "Mozambican meticais", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2574,11 +2540,11 @@ "code": "NAD", "noun": "Namibian dollars", "current_years": { - "start_year": 1995, + "start_year": 1989, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1989, @@ -2588,11 +2554,11 @@ "code": "NGN", "noun": "Nigerian naira", "current_years": { - "start_year": 1995, + "start_year": 1990, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1990, @@ -2602,11 +2568,11 @@ "code": "NIO", "noun": "Nicaraguan córdobas", "current_years": { - "start_year": 1995, + "start_year": 1987, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1987, @@ -2616,11 +2582,11 @@ "code": "NOK", "noun": "Norwegian kroner", "current_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1960, @@ -2630,11 +2596,11 @@ "code": "NPR", "noun": "Nepalese rupees", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2644,11 +2610,11 @@ "code": "NZD", "noun": "New Zealand dollars", "current_years": { - "start_year": 1995, + "start_year": 1961, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1961, @@ -2658,11 +2624,11 @@ "code": "OMR", "noun": "Omani rials", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2672,11 +2638,11 @@ "code": "PEN", "noun": "Peruvian soles", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2686,11 +2652,11 @@ "code": "PGK", "noun": "Papua New Guinean kina", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2700,11 +2666,11 @@ "code": "PHP", "noun": "Philippine pesos", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2714,11 +2680,11 @@ "code": "PKR", "noun": "Pakistani rupees", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2732,7 +2698,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1998, @@ -2742,11 +2708,11 @@ "code": "PYG", "noun": "Paraguayan guaranís", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2756,11 +2722,11 @@ "code": "QAR", "noun": "Qatari riyals", "current_years": { - "start_year": 2023, - "end_year": 2023 + "start_year": 1985, + "end_year": 1990 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 2023, @@ -2774,7 +2740,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 2013, @@ -2788,7 +2754,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1997, @@ -2802,7 +2768,7 @@ "end_year": 2020 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 2010, @@ -2812,11 +2778,11 @@ "code": "RWF", "noun": "Rwandan francs", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2830,7 +2796,7 @@ "end_year": 2023 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 2000, @@ -2840,11 +2806,11 @@ "code": "SBD", "noun": "Solomon Islands dollars", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2854,11 +2820,11 @@ "code": "SCR", "noun": "Seychellois rupees", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2868,11 +2834,11 @@ "code": "SDG", "noun": "Sudanese pounds", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2882,11 +2848,11 @@ "code": "SEK", "noun": "Swedish kronor", "current_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1960, @@ -2896,11 +2862,11 @@ "code": "SGD", "noun": "Singapore dollars", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2910,11 +2876,11 @@ "code": "SLE", "noun": "Sierra Leonean leones", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2924,11 +2890,11 @@ "code": "SRD", "noun": "Surinamese dollars", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2942,7 +2908,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 2011, @@ -2952,11 +2918,11 @@ "code": "STN", "noun": "São Tomé and Príncipe dobras", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2966,11 +2932,11 @@ "code": "SYP", "noun": "Syrian pounds", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2010 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2980,11 +2946,11 @@ "code": "SZL", "noun": "Swazi emalangeni", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -2998,7 +2964,7 @@ "end_year": 2016 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 2018, @@ -3008,11 +2974,11 @@ "code": "TJS", "noun": "Tajikistani somonis", "current_years": { - "start_year": 1995, + "start_year": 1992, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1992, @@ -3022,11 +2988,11 @@ "code": "TMT", "noun": "Turkmenistani manat", "current_years": { - "start_year": 1995, + "start_year": 1992, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1992, @@ -3036,11 +3002,11 @@ "code": "TND", "noun": "Tunisian dinars", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -3050,11 +3016,11 @@ "code": "TOP", "noun": "Tongan paʻanga", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -3064,11 +3030,11 @@ "code": "TRY", "noun": "Turkish lira", "current_years": { - "start_year": 1995, + "start_year": 1990, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1990, @@ -3078,11 +3044,11 @@ "code": "TTD", "noun": "Trinidad and Tobago dollars", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -3096,7 +3062,7 @@ "end_year": 2016 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 2023, @@ -3106,11 +3072,11 @@ "code": "TZS", "noun": "Tanzanian shillings", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -3120,11 +3086,11 @@ "code": "UAH", "noun": "Ukrainian hryvnias", "current_years": { - "start_year": 1995, + "start_year": 1991, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1991, @@ -3134,11 +3100,11 @@ "code": "UGX", "noun": "Ugandan shillings", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -3148,11 +3114,11 @@ "code": "USD", "noun": "US dollars", "current_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1960, @@ -3162,11 +3128,11 @@ "code": "UYU", "noun": "Uruguayan pesos", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -3176,11 +3142,11 @@ "code": "UZS", "noun": "Uzbekistani soms", "current_years": { - "start_year": 1995, + "start_year": 1992, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1992, @@ -3194,7 +3160,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 2017, @@ -3204,11 +3170,11 @@ "code": "VND", "noun": "Vietnamese dong", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -3218,11 +3184,11 @@ "code": "VUV", "noun": "Vanuatu vatu", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -3232,11 +3198,11 @@ "code": "WST", "noun": "Samoan tala", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -3246,11 +3212,11 @@ "code": "XAF", "noun": "Central African CFA francs", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -3260,11 +3226,11 @@ "code": "XCD", "noun": "East Caribbean dollars", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -3274,11 +3240,11 @@ "code": "XOF", "noun": "West African CFA francs", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -3292,7 +3258,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 2014, @@ -3302,11 +3268,11 @@ "code": "ZAR", "noun": "South African rand", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -3316,11 +3282,11 @@ "code": "ZMW", "noun": "Zambian kwachas", "current_years": { - "start_year": 1995, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 1995, + "start_year": 1960, "end_year": 2024 }, "base_year_min": 1980, @@ -3329,15 +3295,24 @@ ], "default_base_year": 2024, "role_currencies": { - "destination": "NGN", + "destination": "CDF", "origin": "EUR" } - } + }, + "equivalent_readings": [ + { + "spec_id": "spec_53b1ed52ebddd28ce274d419b53037c3", + "definition": { + "schema_version": 1, + "spec_id": "spec_53b1ed52ebddd28ce274d419b53037c3" + } + } + ] } } } ], - "rendered_sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "rendered_sentence": "Germany's gross disbursements to Democratic Republic of the Congo for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", "sentence_plan": [ { "kind": "slot", @@ -3371,13 +3346,11 @@ }, { "kind": "slot", - "text": "gross ODA disbursements", + "text": "gross disbursements", "axis": "what", "segment": "heading", "entity_refs": [], "states": [ - "how:crsTypeOfFinance", - "how:crsTypeOfFlow", "how:financialFlowType", "how:nettingBasis", "axis:populationType", @@ -3395,13 +3368,13 @@ }, { "kind": "slot", - "text": "Nigeria", + "text": "Democratic Republic of the Congo", "axis": "where", "segment": "heading", "role": "destination", "binding_ref": "where:", "entity_refs": [ - "country/NGA" + "country/COD" ], "states": [ "where:" @@ -3418,14 +3391,14 @@ }, { "kind": "slot", - "text": "basic health care", + "text": "official development assistance", "axis": "how", "segment": "heading", - "property_dcid": "crsPurpose", - "binding_ref": "how:crsPurpose", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", "entity_refs": [], "states": [ - "how:crsPurpose" + "how:dac2aAidType" ], "part_index": 0 }, @@ -3434,30 +3407,8 @@ "text": "", "axis": "how", "segment": "heading", - "property_dcid": "crsCooperationModality", - "binding_ref": "how:crsCooperationModality", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "crsTypeOfFinance", - "binding_ref": "how:crsTypeOfFinance", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "crsTypeOfFlow", - "binding_ref": "how:crsTypeOfFlow", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", "entity_refs": [], "states": [], "part_index": 0 @@ -3493,7 +3444,7 @@ }, { "kind": "slot", - "text": "1995 to 2024", + "text": "1960 to 2024", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -3537,7 +3488,7 @@ }, { "kind": "slot", - "text": "OECD Creditor Reporting System (CRS)", + "text": "OECD DAC2a", "axis": "source", "segment": "byline", "entity_refs": [], @@ -3556,863 +3507,36 @@ "status": "definite" } } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "no_data", + "sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 2 + } + ] + } }, - { - "request": { - "method": "POST", - "path": "/datasets", - "json": { - "schema_version": 1, - "input": { - "kind": "spec_id", - "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", - "definition": { - "schema_version": 1, - "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "FinancialFlow", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" - }, - "slots": [ - { - "property": "crsCooperationModality", - "binding": { - "state": "unbound" - } - }, - { - "property": "crsPurpose", - "binding": { - "state": "value", - "ref": "CRSPurposeCode12220" - } - }, - { - "property": "crsTypeOfFinance", - "binding": { - "state": "unbound" - } - }, - { - "property": "crsTypeOfFlow", - "binding": { - "state": "value", - "ref": "CRSTypeOfFlow10" - } - }, - { - "property": "financialFlowType", - "binding": { - "state": "value", - "ref": "Disbursement" - } - }, - { - "property": "nettingBasis", - "binding": { - "state": "value", - "ref": "Gross" - } - } - ], - "entities": { - "destination": [ - "country/NGA" - ], - "origin": [ - "country/DEU" - ] - }, - "requested_window": { - "kind": "all" - } - } - } - }, - "options": { - "format": "parquet", - "bundle": false - } - } - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json" - }, - "json": { - "schema_version": 1, - "definition": { - "schema_version": 1, - "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", - "identity": { - "shape": { - "kind": "statvar_schema", - "stat_type": "measuredValue", - "population_type": "FinancialFlow", - "measured_property": "amount", - "measurement_qualifier": "Nominal" - }, - "slots": [ - { - "binding": { - "state": "unbound" - }, - "property": "crsCooperationModality" - }, - { - "binding": { - "ref": "CRSPurposeCode12220", - "state": "value" - }, - "property": "crsPurpose" - }, - { - "binding": { - "state": "unbound" - }, - "property": "crsTypeOfFinance" - }, - { - "binding": { - "ref": "CRSTypeOfFlow10", - "state": "value" - }, - "property": "crsTypeOfFlow" - }, - { - "binding": { - "ref": "Disbursement", - "state": "value" - }, - "property": "financialFlowType" - }, - { - "binding": { - "ref": "Gross", - "state": "value" - }, - "property": "nettingBasis" - } - ], - "entities": { - "origin": [ - "country/DEU" - ], - "destination": [ - "country/NGA" - ] - }, - "identity_version": "spec1", - "requested_window": { - "kind": "all" - } - } - }, - "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-21T08:57:19Z", - "coverage": { - "rows": 30, - "dimensions": [ - { - "label": "financingProvider", - "count": 1, - "axis": "origin", - "noun": { - "singular": "provider", - "plural": "providers" - } - }, - { - "label": "financingRecipient", - "count": 1, - "axis": "destination", - "noun": { - "singular": "recipient", - "plural": "recipients" - } - }, - { - "label": "years", - "count": 27 - } - ], - "window": { - "kind": "all", - "start_year": 1995, - "end_year": 2024, - "origin": "default" - } - }, - "citation": { - "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", - "sources": [ - { - "ref": "provenance/OECDCreditorReportingSystem", - "label": "OECD Creditor Reporting System (CRS)", - "license": "OECD Terms and Conditions", - "license_type": "OECDTermsAndConditions", - "license_url": "https://www.oecd.org/en/about/terms-conditions.html", - "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", - "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" - }, - "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" - }, - "documentation": { - "publisher": "Organisation for Economic Co-operation and Development (OECD)", - "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", - "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", - "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", - "update_cadence": "Quarterly", - "last_update": "2026-10-15", - "years_covered": "1973-2024", - "granularity": "Annual, by provider and recipient", - "currencies": [ - "USD" - ], - "transformation_log": [ - { - "transformation": "Download the source data", - "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." - }, - { - "transformation": "Exclude the partial preliminary year", - "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." - }, - { - "transformation": "Exclude donor core contributions to multilaterals", - "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." - }, - { - "transformation": "Standardise providers and recipients", - "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." - }, - { - "transformation": "Select dimensions", - "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." - }, - { - "transformation": "Aggregate totals", - "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." - } - ], - "version_history": [ - { - "date": "2026-10-15", - "title": "Partial preliminary year excluded", - "changes": [ - { - "kind": "changed", - "note": "The partial preliminary year published ahead of the next full release is excluded." - } - ] - }, - { - "date": "2026-10-14", - "title": "First release", - "changes": [ - { - "kind": "added", - "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." - } - ] - } - ] - } - } - ] - }, - "trace": { - "applied_window": { - "kind": "all", - "start_year": 1995, - "end_year": 2024, - "origin": "default" - }, - "graph_revision": null, - "code_index_stamp": { - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", - "exported_at": "2026-10-20T19:50:14Z", - "graph_endpoint": "graph_release" - }, - "origin_catalogue_build_id": "20261021T070020Z-7262111e", - "source_revisions": [ - { - "source": "provenance/OECDCreditorReportingSystem", - "revision": "2026-10-15" - } - ], - "resolved_stat_vars": [ - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 0 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 6 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 0 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 0 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 0 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 1 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 0 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 7 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 0 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 1 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 0 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 0 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 0 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 15 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 0 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 0 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 0 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 0 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 0 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 0 - }, - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 0 - } - ], - "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", - "family_member_count": 21, - "facets": [ - { - "axis": "provenance", - "ref": "provenance/OECDCreditorReportingSystem", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868" - }, - { - "axis": "unit", - "ref": "CurrencyUSD", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868" - } - ], - "normalisations": [], - "frame_grammar_version": "1.1.0", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "capability_version": "dset_88fecfec3c5b89d1", - "served_from": "materialise", - "confirmed_at": "2026-10-21T08:57:19.628756+00:00" - }, - "warnings": [], - "diagnostics": [ - { - "code": "processing_level_undeclared", - "severity": "info", - "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." - } - ], - "artifacts": [ - { - "artifact_digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", - "rendering": { - "bundle": false, - "format": "parquet", - "layout": 3 - }, - "bytes": 9785, - "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", - "tier": "working", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" - }, - { - "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", - "rendering": { - "statistics": "series" - }, - "bytes": 5981, - "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", - "tier": "working", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" - } - ], - "series_count": 5, - "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", - "columns": [ - { - "name": "stat_var", - "kind": "grain", - "droppable": false, - "distinct": 5 - }, - { - "name": "financingProvider", - "kind": "role", - "droppable": false, - "distinct": 1 - }, - { - "name": "financingRecipient", - "kind": "role", - "droppable": false, - "distinct": 1 - }, - { - "name": "time_period", - "kind": "grain", - "droppable": false, - "distinct": 27 - }, - { - "name": "value", - "kind": "value", - "droppable": true - }, - { - "name": "unit", - "kind": "unit", - "droppable": false, - "distinct": 1 - }, - { - "name": "measurementMethod", - "kind": "facet", - "droppable": true, - "distinct": 1 - }, - { - "name": "provenance", - "kind": "facet", - "droppable": false, - "distinct": 1 - }, - { - "name": "status", - "kind": "status", - "droppable": true - } - ], - "formats": [ - { - "name": "csv", - "state": "available" - }, - { - "name": "xlsx", - "state": "available" - }, - { - "name": "parquet", - "state": "available" - } - ], - "bundle": { - "state": "available" - }, - "enrichments": [ - { - "column": "financingProvider", - "field": "iso3", - "token": "financingProvider_iso3", - "state": "available", - "coverage": { - "entities": 1, - "covered": 1 - }, - "missing": [], - "truncated": false - }, - { - "column": "financingProvider", - "field": "iso2", - "token": "financingProvider_iso2", - "state": "available", - "coverage": { - "entities": 1, - "covered": 1 - }, - "missing": [], - "truncated": false - }, - { - "column": "financingProvider", - "field": "label", - "token": "financingProvider_label", - "state": "available", - "coverage": { - "entities": 1, - "covered": 1 - }, - "missing": [], - "truncated": false - }, - { - "column": "financingProvider", - "field": "type", - "token": "financingProvider_type", - "state": "available", - "coverage": { - "entities": 1, - "covered": 1 - }, - "missing": [], - "truncated": false - }, - { - "column": "financingProvider", - "field": "party_kind", - "token": "financingProvider_party_kind", - "state": "available", - "coverage": { - "entities": 1, - "covered": 1 - }, - "missing": [], - "truncated": false - }, - { - "column": "financingRecipient", - "field": "iso3", - "token": "financingRecipient_iso3", - "state": "available", - "coverage": { - "entities": 1, - "covered": 1 - }, - "missing": [], - "truncated": false - }, - { - "column": "financingRecipient", - "field": "iso2", - "token": "financingRecipient_iso2", - "state": "available", - "coverage": { - "entities": 1, - "covered": 1 - }, - "missing": [], - "truncated": false - }, - { - "column": "financingRecipient", - "field": "label", - "token": "financingRecipient_label", - "state": "available", - "coverage": { - "entities": 1, - "covered": 1 - }, - "missing": [], - "truncated": false - }, - { - "column": "financingRecipient", - "field": "type", - "token": "financingRecipient_type", - "state": "available", - "coverage": { - "entities": 1, - "covered": 1 - }, - "missing": [], - "truncated": false - }, - { - "column": "financingRecipient", - "field": "party_kind", - "token": "financingRecipient_party_kind", - "state": "available", - "coverage": { - "entities": 1, - "covered": 1 - }, - "missing": [], - "truncated": false - } - ], - "long_layout_defaults": [ - "financingProvider_label", - "financingProvider_party_kind", - "financingRecipient_label", - "financingRecipient_party_kind" - ], - "long_layout_totals": [], - "pivots": [ - { - "index": "stat_var", - "columns": "time_period", - "state": "available", - "width": 28, - "cells": 140 - }, - { - "index": "time_period", - "columns": "stat_var", - "state": "available", - "width": 6, - "cells": 162 - } - ], - "groupby": { - "state": "available", - "axes": [ - { - "name": "crsCooperationModality" - }, - { - "name": "crsPurpose" - }, - { - "name": "crsTypeOfFinance" - }, - { - "name": "crsTypeOfFlow" - } - ] - } - }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", - "retention": { - "pinned": false, - "held_until": "2026-11-20T08:57:19.589587Z" - } - } - } - }, - { - "request": { - "method": "GET", - "origin_path": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" - }, - "response": { - "status": 302, - "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" - } - } - }, - { - "request": { - "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/vnd.apache.parquet" - }, - "body_file": "answer-definite-fetch.parquet" - } - } - ], - "expect": [ { "answer": { "kind": "resolution", "status": "definite", - "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence": "Germany's gross disbursements to Democratic Republic of the Congo for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", "complete": true, "specs": [ - "spec_774d6c001a6250aa67ca676ab067895e" + "spec_53b1ed52ebddd28ce274d419b53037c3" ], "gaps": [] } - }, - { - "dataset": { - "rows": 30, - "columns": [ - "stat_var", - "financingProvider", - "financingProvider_label", - "financingProvider_party_kind", - "financingRecipient", - "financingRecipient_label", - "financingRecipient_party_kind", - "crsCooperationModality", - "crsCooperationModality_label", - "crsPurpose", - "crsPurpose_label", - "crsTypeOfFinance", - "crsTypeOfFinance_label", - "crsTypeOfFlow", - "crsTypeOfFlow_label", - "time_period", - "value", - "unit", - "unit_label", - "currency", - "price_basis", - "base_year", - "measurementMethod", - "measurementMethod_label", - "provenance", - "provenance_label" - ], - "complete": true, - "members": [ - { - "parts": [ - "basic health care ODA disbursements" - ], - "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", - "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." - } - ], - "missing": [], - "search_warning": false - } } ] } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-operations-not-a-list.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-operations-not-a-list.json new file mode 100644 index 0000000..d312360 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-operations-not-a-list.json @@ -0,0 +1,4545 @@ +{ + "format_version": 1, + "name": "answer-operations-not-a-list", + "description": "A member a client reads that no strict pointer names, and that holds a JSON type other than its schema's, reads as absent: the part has no operation, and the fetch issues no SearchWarning and reaches the same dataset.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-definite-fetch", + "edit": "Part 0's operations becomes one operation object in place of a list." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements from Germany to Nigeria for basic health care" + }, + { + "op": "fetch" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements from Germany to Nigeria for basic health care" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "d09ca5f0ae574410bf93b5d905ea8009" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements from Germany to Nigeria for basic health care", + "normalized_query": "ODA disbursements from Germany to Nigeria for basic health care", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "d09ca5f0ae574410bf93b5d905ea8009", + "warnings": [], + "timing_ms": { + "total": 5038, + "by_step": { + "coverage": 0, + "extract": 1141 + } + }, + "llm_usage": { + "input_tokens": 6116, + "output_tokens": 408, + "cached_tokens": 0 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "basic health care ODA disbursements", + "warnings": [], + "timing_ms": { + "total": 3758, + "by_step": { + "recall": 694, + "shape_arcs": 1, + "shape_probe_coverage": 6, + "shape_probe": 489, + "shape_groups": 16, + "shape_labels": 0, + "shape_admission": 1, + "shape": 1365, + "bind": 1248, + "materialise": 11, + "answer": 423, + "options": 17 + } + }, + "restatement": { + "variable_text": "basic health care ODA disbursements", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Nigeria", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": { + "verb": "growth", + "phrase": "growth of GDP", + "over": "year" + }, + "departures": [], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal", + "label": "gross disbursements (basic health care, official development assistance, standard grant)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 21, + "member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "financialObligationType" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 5, + "member_count_exact": true, + "served_count": 21, + "data_date_range": { + "start": "1995", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 30, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 15 + }, + { + "label": "variables", + "count": 5 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 3, + "series": 3, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2024, + "observations": 3, + "series": 3, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + } + ] + }, + "download": { + "rows": 30, + "rows_exact": true, + "series": 5, + "window": { + "start_year": 1995, + "end_year": 2024 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 88, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 30, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 7, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1606, + "served_rows": 1, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 6, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 7, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 7, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 1, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 1600, + "served_rows": 1, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFinance", + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Nigeria", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/NGA" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "basic health care", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1995 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "measure_elected" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/NGA", + "label": "Nigeria" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [ + { + "text": "basic health care", + "named": [ + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + } + ], + "slot": "crsPurpose", + "disposition": "bound", + "selected": [] + }, + { + "text": "ODA", + "named": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "slot": "crsTypeOfFlow", + "disposition": "bound", + "selected": [] + } + ], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "high", + "available_at_place": true, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_80b92ca1ba1114b426eb5e79b84361d4", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 30, + "served_rows_exact": true + }, + { + "definition": { + "schema_version": 1, + "spec_id": "spec_c394f9108db2100f1c8e4532d8d1c804", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialObligation", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialObligationType", + "binding": { + "state": "value", + "ref": "Commitment" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "commitments", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialObligation", + "label": "financial obligation" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialObligationType", + "value": { + "ref": "Commitment", + "label": "commitment" + } + } + ], + "served_rows": 24, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "open_axis_facts": [ + { + "property": "crsTypeOfFinance", + "varies": false, + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "distinct_count": 1, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "count": 5 + } + ] + }, + { + "property": "crsCooperationModality", + "varies": true, + "distinct_count": 4, + "undeclared_count": 1, + "values": [ + { + "value": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "count": 1 + } + ] + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1995, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 2023, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1995, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1995, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "NGN", + "origin": "EUR" + } + } + } + } + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFinance", + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Nigeria", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/NGA" + ], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "basic health care", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1995 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "status": "definite" + } + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "90ec74fce6534d0d8e4142b0e1355782" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + }, + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "prepared_at": "2026-10-21T13:05:05Z", + "coverage": { + "rows": 30, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 27 + } + ], + "window": { + "kind": "all", + "start_year": 1995, + "end_year": 2024, + "origin": "default" + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "applied_window": { + "kind": "all", + "start_year": 1995, + "end_year": 2024, + "origin": "default" + }, + "graph_revision": null, + "code_index_stamp": { + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", + "graph_endpoint": "graph_release" + }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 7 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 15 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "family_member_count": 21, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDCreditorReportingSystem", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + } + ], + "normalisations": [], + "frame_grammar_version": "1.1.0", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T13:05:06.336796+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9785, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:06.298931+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + }, + { + "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", + "rendering": { + "statistics": "series" + }, + "bytes": 5981, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:06.298931+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" + } + ], + "series_count": 5, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 5 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 27 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "stat_var", + "columns": "time_period", + "state": "available", + "width": 28, + "cells": 140 + }, + { + "index": "time_period", + "columns": "stat_var", + "state": "available", + "width": 6, + "cells": 162 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T13:05:06.298810Z" + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted", + "x-dfo-trace-id": "d14640239a5a4ffa8f113140eb5b23a0" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "58cc82a3079f4e4298eb45378fdf10db" + }, + "body_file": "answer-definite-fetch.parquet" + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "definite", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "complete": true, + "specs": [ + "spec_774d6c001a6250aa67ca676ab067895e" + ], + "gaps": [] + } + }, + { + "dataset": { + "rows": 30, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "crsCooperationModality", + "crsCooperationModality_label", + "crsPurpose", + "crsPurpose_label", + "crsTypeOfFinance", + "crsTypeOfFinance_label", + "crsTypeOfFlow", + "crsTypeOfFlow_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [ + "basic health care ODA disbursements" + ], + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." + } + ], + "missing": [], + "search_warning": false + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-part-status-not-a-string.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-part-status-not-a-string.json index 1ad50c4..f77f48d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-part-status-not-a-string.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-part-status-not-a-string.json @@ -29,7 +29,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "3b0a506d6d2a43a0becd94837bafffa1" }, "json": { "schema_version": 1, @@ -41,13 +42,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d0fa88511b064cc6966082b296cd6ea8", + "trace_id": "3b0a506d6d2a43a0becd94837bafffa1", "warnings": [], "timing_ms": { - "total": 4688, + "total": 4692, "by_step": { "coverage": 0, - "extract": 928 + "extract": 1001 } }, "llm_usage": { @@ -63,20 +64,20 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 3547, + "total": 3475, "by_step": { - "recall": 312, - "shape_arcs": 2, - "shape_probe_coverage": 2, - "shape_probe": 192, - "shape_groups": 2, - "shape_labels": 6, + "recall": 434, + "shape_arcs": 3, + "shape_probe_coverage": 4, + "shape_probe": 243, + "shape_groups": 3, + "shape_labels": 9, "shape_admission": 0, - "shape": 912, - "bind": 1643, - "materialise": 3, - "answer": 462, - "options": 215 + "shape": 893, + "bind": 1563, + "materialise": 9, + "answer": 381, + "options": 195 } }, "restatement": { @@ -3245,15 +3246,15 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 502, + "total": 574, "by_step": { - "recall": 307, + "recall": 380, "shape_arcs": 1, "shape_probe": 190, - "shape_groups": 1, + "shape_groups": 0, "shape_labels": 0, "shape_admission": 0, - "shape": 195 + "shape": 194 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", @@ -3603,7 +3604,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": null + "trace_id": "3b0a506d6d2a43a0becd94837bafffa1" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json index bb13406..969afb3 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:57:34Z" + "recorded_at": "2026-10-21T13:05:20Z" }, "call": [ { @@ -33,7 +33,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "3ceef86d0eac49fa96380d3340878cf1" }, "json": { "schema_version": 1, @@ -45,18 +46,18 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "c354423648a442189d804c35586bd78a", + "trace_id": "3ceef86d0eac49fa96380d3340878cf1", "warnings": [], "timing_ms": { - "total": 5956, + "total": 5613, "by_step": { "coverage": 0, - "extract": 919 + "extract": 1020 } }, "llm_usage": { "input_tokens": 15731, - "output_tokens": 1037, + "output_tokens": 1021, "cached_tokens": 861 }, "timed_out": false @@ -67,20 +68,20 @@ "variable_text": "ODA disbursements for health", "warnings": [], "timing_ms": { - "total": 3227, + "total": 3674, "by_step": { - "recall": 535, + "recall": 773, "shape_arcs": 0, - "shape_probe_coverage": 1, - "shape_probe": 197, - "shape_groups": 16, - "shape_labels": 4, + "shape_probe_coverage": 11, + "shape_probe": 224, + "shape_groups": 26, + "shape_labels": 8, "shape_admission": 0, - "shape": 1071, - "bind": 1345, - "materialise": 157, - "answer": 20, - "options": 99 + "shape": 1251, + "bind": 1411, + "materialise": 115, + "answer": 15, + "options": 109 } }, "restatement": { @@ -3738,20 +3739,20 @@ } ], "timing_ms": { - "total": 3024, + "total": 3542, "by_step": { - "recall": 456, + "recall": 791, "shape_arcs": 0, - "shape_probe_coverage": 1, - "shape_probe": 183, - "shape_groups": 17, - "shape_labels": 4, - "shape_admission": 0, - "shape": 1070, - "bind": 1243, - "materialise": 82, - "answer": 19, - "options": 154 + "shape_probe_coverage": 2, + "shape_probe": 240, + "shape_groups": 39, + "shape_labels": 5, + "shape_admission": 1, + "shape": 1008, + "bind": 1505, + "materialise": 146, + "answer": 13, + "options": 79 } }, "restatement": { @@ -7414,20 +7415,20 @@ } ], "timing_ms": { - "total": 3386, + "total": 3536, "by_step": { - "recall": 579, + "recall": 778, "shape_arcs": 2, - "shape_probe_coverage": 1, - "shape_probe": 263, - "shape_groups": 19, - "shape_labels": 4, - "shape_admission": 0, - "shape": 1015, - "bind": 1274, + "shape_probe_coverage": 2, + "shape_probe": 277, + "shape_groups": 24, + "shape_labels": 5, + "shape_admission": 1, + "shape": 973, + "bind": 1109, "materialise": 1, - "answer": 159, - "options": 358 + "answer": 210, + "options": 465 } }, "restatement": { @@ -9427,7 +9428,50 @@ } ], "measure_label_axes": [], - "measure_axis_values": [] + "measure_axis_values": [], + "related_group": { + "ref": "dc/g/EconomicActivity_ActivitySource-GrossDomesticProduction", + "label": "Economic Activity With Activity Source = Gross Domestic Production" + }, + "related_measures": [ + { + "stat_var": { + "ref": "GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "label": "Gross domestic product growth rate" + }, + "definition": { + "schema_version": 1, + "spec_id": "spec_4535d09baf2bdffef7c19c7796e96687", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "growthRate" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + } + ] } } } @@ -9920,7 +9964,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "ee49afa94b0440c9b557ce3413d538a5" }, "json": { "schema_version": 1, @@ -9995,7 +10040,7 @@ } }, "content_version": "cv_d6ce435ea267b46680c94eae9423d420", - "prepared_at": "2026-10-21T08:57:44Z", + "prepared_at": "2026-10-21T13:05:29Z", "coverage": { "rows": 512, "dimensions": [ @@ -14520,7 +14565,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:57:44.735225+00:00" + "confirmed_at": "2026-10-21T13:05:29.417660+00:00" }, "warnings": [], "diagnostics": [ @@ -14540,7 +14585,7 @@ }, "bytes": 16150, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:44.689444+00:00", + "created_at": "2026-10-21T13:05:29.374895+00:00", "tier": "working", "url": "/api/datasets/spec_25f482395c5d012ec278118f38dff29c/cv_d6ce435ea267b46680c94eae9423d420/files/sha256:20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d" }, @@ -14551,7 +14596,7 @@ }, "bytes": 11612, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:44.689444+00:00", + "created_at": "2026-10-21T13:05:29.374895+00:00", "tier": "working", "url": "/api/datasets/spec_25f482395c5d012ec278118f38dff29c/cv_d6ce435ea267b46680c94eae9423d420/files/sha256:a5d2d7627c8fe1357519ca0ac021c791182ab08c76f44e8055b4bb50a6059179" } @@ -14796,7 +14841,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:44.689446Z" + "held_until": "2026-11-20T13:05:29.374859Z" } } } @@ -14809,7 +14854,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d?X-Goog-Signature=redacted", + "x-dfo-trace-id": "cee84dbe25214a0f8ea3f0a28ce10adc" } } }, @@ -14821,7 +14867,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "c3f031f1d3724d2ea9b19e58197e4f03" }, "body_file": "answer-several-readings-folded.parquet" } @@ -14901,7 +14948,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "e043b83fa1f8472e814c68afde278ab8" }, "json": { "schema_version": 1, @@ -14962,7 +15010,7 @@ } }, "content_version": "cv_91f57bfc5bbc5f09983596996238787d", - "prepared_at": "2026-10-21T08:57:46Z", + "prepared_at": "2026-10-21T13:05:30Z", "coverage": { "rows": 132, "dimensions": [ @@ -15078,7 +15126,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:57:46.634620+00:00" + "confirmed_at": "2026-10-21T13:05:30.811140+00:00" }, "warnings": [], "diagnostics": [ @@ -15098,7 +15146,7 @@ }, "bytes": 6545, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:46.604801+00:00", + "created_at": "2026-10-21T13:05:30.778158+00:00", "tier": "working", "url": "/api/datasets/spec_f8dea3052d1ef6ba5667628815d1a663/cv_91f57bfc5bbc5f09983596996238787d/files/sha256:9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839" }, @@ -15109,7 +15157,7 @@ }, "bytes": 5379, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:46.604801+00:00", + "created_at": "2026-10-21T13:05:30.778158+00:00", "tier": "working", "url": "/api/datasets/spec_f8dea3052d1ef6ba5667628815d1a663/cv_91f57bfc5bbc5f09983596996238787d/files/sha256:8eecb62c1741271464d6d66841353d96f7e36aa9c3915f7948ea7c78c7dbc9e7" } @@ -15273,7 +15321,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:46.604983Z" + "held_until": "2026-11-20T13:05:30.778009Z" } } } @@ -15286,7 +15334,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839?X-Goog-Signature=redacted", + "x-dfo-trace-id": "8bf21c550f584bcaa21bcb8d69498a7d" } } }, @@ -15298,7 +15347,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "8072bc19c0fc4a5aa825d37c5956317c" }, "body_file": "answer-several-readings-folded-2.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json index d08faaf..a449a5d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json @@ -29,7 +29,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "d09ca5f0ae574410bf93b5d905ea8009" }, "json": { "schema_version": 1, @@ -41,13 +42,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", + "trace_id": "d09ca5f0ae574410bf93b5d905ea8009", "warnings": [], "timing_ms": { - "total": 4556, + "total": 5038, "by_step": { "coverage": 0, - "extract": 889 + "extract": 1141 } }, "llm_usage": { @@ -63,20 +64,20 @@ "variable_text": "basic health care ODA disbursements", "warnings": [], "timing_ms": { - "total": 3505, + "total": 3758, "by_step": { - "recall": 628, + "recall": 694, "shape_arcs": 1, - "shape_probe_coverage": 5, - "shape_probe": 477, - "shape_groups": 22, - "shape_labels": 1, + "shape_probe_coverage": 6, + "shape_probe": 489, + "shape_groups": 16, + "shape_labels": 0, "shape_admission": 1, - "shape": 1283, - "bind": 1188, + "shape": 1365, + "bind": 1248, "materialise": 11, - "answer": 381, - "options": 14 + "answer": 423, + "options": 17 } }, "restatement": { @@ -3616,7 +3617,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": null + "trace_id": "d09ca5f0ae574410bf93b5d905ea8009" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json index 9ae502b..eb08965 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json @@ -29,7 +29,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "d09ca5f0ae574410bf93b5d905ea8009" }, "json": { "schema_version": 1, @@ -41,13 +42,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", + "trace_id": "d09ca5f0ae574410bf93b5d905ea8009", "warnings": [], "timing_ms": { - "total": 4556, + "total": 5038, "by_step": { "coverage": 0, - "extract": 889 + "extract": 1141 } }, "llm_usage": { @@ -63,20 +64,20 @@ "variable_text": "basic health care ODA disbursements", "warnings": [], "timing_ms": { - "total": 3505, + "total": 3758, "by_step": { - "recall": 628, + "recall": 694, "shape_arcs": 1, - "shape_probe_coverage": 5, - "shape_probe": 477, - "shape_groups": 22, - "shape_labels": 1, + "shape_probe_coverage": 6, + "shape_probe": 489, + "shape_groups": 16, + "shape_labels": 0, "shape_admission": 1, - "shape": 1283, - "bind": 1188, + "shape": 1365, + "bind": 1248, "materialise": 11, - "answer": 381, - "options": 14 + "answer": 423, + "options": 17 } }, "restatement": { @@ -396,7 +397,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": null + "trace_id": "d09ca5f0ae574410bf93b5d905ea8009" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json index 830edf4..3afa337 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json @@ -45,13 +45,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d0fa88511b064cc6966082b296cd6ea8", + "trace_id": "3b0a506d6d2a43a0becd94837bafffa1", "warnings": [], "timing_ms": { - "total": 4688, + "total": 4692, "by_step": { "coverage": 0, - "extract": 928 + "extract": 1001 } }, "llm_usage": { @@ -67,20 +67,20 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 3547, + "total": 3475, "by_step": { - "recall": 312, - "shape_arcs": 2, - "shape_probe_coverage": 2, - "shape_probe": 192, - "shape_groups": 2, - "shape_labels": 6, + "recall": 434, + "shape_arcs": 3, + "shape_probe_coverage": 4, + "shape_probe": 243, + "shape_groups": 3, + "shape_labels": 9, "shape_admission": 0, - "shape": 912, - "bind": 1643, - "materialise": 3, - "answer": 462, - "options": 215 + "shape": 893, + "bind": 1563, + "materialise": 9, + "answer": 381, + "options": 195 } }, "restatement": { @@ -3249,15 +3249,15 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 502, + "total": 574, "by_step": { - "recall": 307, + "recall": 380, "shape_arcs": 1, "shape_probe": 190, - "shape_groups": 1, + "shape_groups": 0, "shape_labels": 0, "shape_admission": 0, - "shape": 195 + "shape": 194 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json index ad7a507..5c8c6b2 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json @@ -29,7 +29,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d" }, "json": { "schema_version": 1, @@ -41,13 +42,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "trace_id": "95b872cf11e44fffb92260b2bb583f0d", "warnings": [], "timing_ms": { - "total": 1788, + "total": 1697, "by_step": { "coverage": 0, - "extract": 1353 + "extract": 982 } }, "llm_usage": { @@ -63,9 +64,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 434, + "total": 715, "by_step": { - "recall": 434 + "recall": 715 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json index df6d751..2c609b2 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json @@ -29,7 +29,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d" }, "json": { "schema_version": 1, @@ -41,13 +42,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "trace_id": "95b872cf11e44fffb92260b2bb583f0d", "warnings": [], "timing_ms": { - "total": 1788, + "total": 1697, "by_step": { "coverage": 0, - "extract": 1353 + "extract": 982 } }, "llm_usage": { @@ -63,9 +64,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 434, + "total": 715, "by_step": { - "recall": 434 + "recall": 715 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -240,7 +241,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": null + "trace_id": "95b872cf11e44fffb92260b2bb583f0d" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json index 33ebe05..c3fac94 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json @@ -32,7 +32,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "3b0a506d6d2a43a0becd94837bafffa1" }, "json": { "schema_version": 1, @@ -44,13 +45,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d0fa88511b064cc6966082b296cd6ea8", + "trace_id": "3b0a506d6d2a43a0becd94837bafffa1", "warnings": [], "timing_ms": { - "total": 4688, + "total": 4692, "by_step": { "coverage": 0, - "extract": 928 + "extract": 1001 } }, "llm_usage": { @@ -66,20 +67,20 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 3547, + "total": 3475, "by_step": { - "recall": 312, - "shape_arcs": 2, - "shape_probe_coverage": 2, - "shape_probe": 192, - "shape_groups": 2, - "shape_labels": 6, + "recall": 434, + "shape_arcs": 3, + "shape_probe_coverage": 4, + "shape_probe": 243, + "shape_groups": 3, + "shape_labels": 9, "shape_admission": 0, - "shape": 912, - "bind": 1643, - "materialise": 3, - "answer": 462, - "options": 215 + "shape": 893, + "bind": 1563, + "materialise": 9, + "answer": 381, + "options": 195 } }, "restatement": { @@ -3248,15 +3249,15 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 502, + "total": 574, "by_step": { - "recall": 307, + "recall": 380, "shape_arcs": 1, "shape_probe": 190, - "shape_groups": 1, + "shape_groups": 0, "shape_labels": 0, "shape_admission": 0, - "shape": 195 + "shape": 194 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", @@ -3624,7 +3625,7 @@ "error": { "class": "IncompleteAnswerError", "code": "answer_incomplete", - "trace_id": null + "trace_id": "3b0a506d6d2a43a0becd94837bafffa1" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json index 6111beb..8fc9421 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json @@ -32,7 +32,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "3b0a506d6d2a43a0becd94837bafffa1" }, "json": { "schema_version": 1, @@ -44,13 +45,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d0fa88511b064cc6966082b296cd6ea8", + "trace_id": "3b0a506d6d2a43a0becd94837bafffa1", "warnings": [], "timing_ms": { - "total": 4688, + "total": 4692, "by_step": { "coverage": 0, - "extract": 928 + "extract": 1001 } }, "llm_usage": { @@ -66,20 +67,20 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 3547, + "total": 3475, "by_step": { - "recall": 312, - "shape_arcs": 2, - "shape_probe_coverage": 2, - "shape_probe": 192, - "shape_groups": 2, - "shape_labels": 6, + "recall": 434, + "shape_arcs": 3, + "shape_probe_coverage": 4, + "shape_probe": 243, + "shape_groups": 3, + "shape_labels": 9, "shape_admission": 0, - "shape": 912, - "bind": 1643, - "materialise": 3, - "answer": 462, - "options": 215 + "shape": 893, + "bind": 1563, + "materialise": 9, + "answer": 381, + "options": 195 } }, "restatement": { @@ -3248,15 +3249,15 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 502, + "total": 574, "by_step": { - "recall": 307, + "recall": 380, "shape_arcs": 1, "shape_probe": 190, - "shape_groups": 1, + "shape_groups": 0, "shape_labels": 0, "shape_admission": 0, - "shape": 195 + "shape": 194 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", @@ -3618,7 +3619,7 @@ "error": { "class": "IncompleteAnswerError", "code": "answer_incomplete", - "trace_id": null + "trace_id": "3b0a506d6d2a43a0becd94837bafffa1" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-assumed-reading.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-assumed-reading.json index 1f20d23..0a7a407 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-assumed-reading.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-assumed-reading.json @@ -33,7 +33,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "d107dd88e50147378d54464bcdaf9695" }, "json": { "schema_version": 1, @@ -45,13 +46,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "8a56f4a56757466094a49079c6a116c4", + "trace_id": "d107dd88e50147378d54464bcdaf9695", "warnings": [], "timing_ms": { - "total": 4642, + "total": 4075, "by_step": { "coverage": 0, - "extract": 1227 + "extract": 1004 } }, "llm_usage": { @@ -67,19 +68,19 @@ "variable_text": "GNI", "warnings": [], "timing_ms": { - "total": 3202, + "total": 2799, "by_step": { - "recall": 421, - "shape_arcs": 4, - "shape_probe_coverage": 2, - "shape_probe": 211, - "shape_groups": 29, - "shape_labels": 15, + "recall": 381, + "shape_arcs": 2, + "shape_probe_coverage": 1, + "shape_probe": 203, + "shape_groups": 18, + "shape_labels": 5, "shape_admission": 0, - "shape": 1184, - "bind": 1000, - "materialise": 429, - "answer": 168 + "shape": 1186, + "bind": 829, + "materialise": 217, + "answer": 186 } }, "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", @@ -2431,7 +2432,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "4386e87708a64f078f39a795faeb0100" }, "json": { "schema_version": 1, @@ -2441,10 +2443,10 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "2841fbd5b3f24a44b79d2e01ed6faf58", + "trace_id": "4386e87708a64f078f39a795faeb0100", "warnings": [], "timing_ms": { - "total": 6, + "total": 9, "by_step": { "coverage": 0 } @@ -2457,18 +2459,18 @@ "variable_text": "GNI", "warnings": [], "timing_ms": { - "total": 6, + "total": 8, "by_step": { - "validate": 1, - "walk": 3, + "validate": 0, + "walk": 5, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, "shape": 0, "bind": 0, - "where_places": 0, - "materialise": 1, - "answer": 0, + "where_places": 1, + "materialise": 0, + "answer": 1, "options": 1 } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-echoes-assumptions.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-echoes-assumptions.json index 476e117..6c18b3a 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-echoes-assumptions.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-echoes-assumptions.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:59:25Z" + "recorded_at": "2026-10-21T13:07:25Z" }, "call": [ { @@ -35,7 +35,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "810e4170976b4e69aade88273e59e8c2" }, "json": { "schema_version": 1, @@ -47,13 +48,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "a9c72d49f9a0435598d030e5ce335a36", + "trace_id": "810e4170976b4e69aade88273e59e8c2", "warnings": [], "timing_ms": { - "total": 3445, + "total": 3563, "by_step": { "coverage": 0, - "extract": 1025 + "extract": 915 } }, "llm_usage": { @@ -75,19 +76,19 @@ } ], "timing_ms": { - "total": 1504, + "total": 2206, "by_step": { "recall": 1, - "shape_arcs": 2, - "shape_probe_coverage": 5, - "shape_probe": 6, - "shape_groups": 24, - "shape_labels": 9, + "shape_arcs": 1, + "shape_probe_coverage": 3, + "shape_probe": 270, + "shape_groups": 201, + "shape_labels": 6, "shape_admission": 0, - "shape": 698, - "bind": 802, + "shape": 1165, + "bind": 1038, "materialise": 1, - "answer": 2 + "answer": 1 } }, "rendered_sentence": "2 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 1960 to 2025 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 1990 to 2025. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", @@ -1429,19 +1430,19 @@ } ], "timing_ms": { - "total": 2329, + "total": 2564, "by_step": { - "recall": 476, + "recall": 607, "shape_arcs": 1, - "shape_probe_coverage": 4, - "shape_probe": 282, - "shape_groups": 22, + "shape_probe_coverage": 3, + "shape_probe": 218, + "shape_groups": 18, "shape_labels": 0, - "shape_admission": 1, - "shape": 1001, - "bind": 838, + "shape_admission": 0, + "shape": 930, + "bind": 1014, "materialise": 6, - "answer": 5, + "answer": 4, "options": 3 } }, @@ -5052,7 +5053,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "2e151fcdeb6f40b3be7b3da99c277765" }, "json": { "schema_version": 1, @@ -5062,10 +5064,10 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "e6a2e3be3760490a92f536f24e5b3be0", + "trace_id": "2e151fcdeb6f40b3be7b3da99c277765", "warnings": [], "timing_ms": { - "total": 1743, + "total": 947, "by_step": { "coverage": 0 } @@ -5082,10 +5084,10 @@ "by_step": { "validate": 0, "walk": 0, - "reread_arcs": 0, + "reread_arcs": 1, "detect_edits": 0, "resolve_survivors": 0, - "shape": 1, + "shape": 0, "bind": 0, "where_places": 0, "materialise": 0, @@ -5621,17 +5623,17 @@ "variable_text": "aid flows", "warnings": [], "timing_ms": { - "total": 1718, + "total": 924, "by_step": { "validate": 0, - "walk": 6, + "walk": 5, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 1700, + "shape": 909, "bind": 0, - "where_places": 1, - "materialise": 5, + "where_places": 0, + "materialise": 4, "answer": 5, "options": 1 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json index 23c879d..951784d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:59:13Z" + "recorded_at": "2026-10-21T13:07:05Z" }, "call": [ { @@ -38,7 +38,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "a9c284c85fd74d4283998be9c492aab4" }, "json": { "schema_version": 1, @@ -50,13 +51,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "f1b9ad36ed4747939262b9ac26591ecf", + "trace_id": "a9c284c85fd74d4283998be9c492aab4", "warnings": [], "timing_ms": { - "total": 4221, + "total": 4415, "by_step": { "coverage": 0, - "extract": 1149 + "extract": 1049 } }, "llm_usage": { @@ -83,19 +84,19 @@ } ], "timing_ms": { - "total": 2297, + "total": 2710, "by_step": { - "recall": 1, + "recall": 0, "shape_arcs": 2, "shape_probe_coverage": 3, "shape_probe": 4, - "shape_groups": 19, - "shape_labels": 6, - "shape_admission": 297, - "shape": 1171, - "bind": 890, - "materialise": 220, - "answer": 15 + "shape_groups": 18, + "shape_labels": 7, + "shape_admission": 562, + "shape": 1553, + "bind": 893, + "materialise": 246, + "answer": 18 } }, "rendered_sentence": "3 readings. Primary income for gross of fixed capital consumption in 49 places. World Bank International Debt Statistics (IDS) · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in 49 places. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in 49 places. World Development Indicators · 2015 to 2022. You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself.", @@ -5211,20 +5212,20 @@ } ], "timing_ms": { - "total": 2607, + "total": 2250, "by_step": { "recall": 0, - "shape_arcs": 1, - "shape_probe_coverage": 5, - "shape_probe": 6, - "shape_groups": 17, + "shape_arcs": 0, + "shape_probe_coverage": 3, + "shape_probe": 3, + "shape_groups": 16, "shape_labels": 0, - "shape_admission": 347, - "shape": 1442, - "bind": 1148, - "materialise": 9, - "answer": 6, - "options": 2 + "shape_admission": 431, + "shape": 1214, + "bind": 1016, + "materialise": 10, + "answer": 7, + "options": 3 } }, "restatement": { @@ -10181,7 +10182,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "ab49f41a7e8a4bd3a52698f3b699ebfa" }, "json": { "schema_version": 1, @@ -10191,10 +10193,10 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "404ec2ac166b4737a42231c5569b432c", + "trace_id": "ab49f41a7e8a4bd3a52698f3b699ebfa", "warnings": [], "timing_ms": { - "total": 1684, + "total": 1163, "by_step": { "coverage": 0 } @@ -10207,18 +10209,18 @@ "variable_text": "GNI", "warnings": [], "timing_ms": { - "total": 7, + "total": 8, "by_step": { "validate": 0, "walk": 0, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 1, + "shape": 0, "bind": 0, "where_places": 0, - "materialise": 3, - "answer": 2, + "materialise": 4, + "answer": 3, "options": 1 } }, @@ -11800,16 +11802,16 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1491, + "total": 946, "by_step": { "validate": 0, - "walk": 4, + "walk": 5, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 1467, + "shape": 922, "bind": 0, - "where_places": 1, + "where_places": 0, "materialise": 11, "answer": 7, "options": 1 @@ -16416,7 +16418,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "66f7b92c09b04f4eb11b0cf7c976f2be" }, "json": { "schema_version": 1, @@ -16502,7 +16505,7 @@ } }, "content_version": "cv_18a63cb9e24a4ce6dfcd1c60f0c5a470", - "prepared_at": "2026-10-21T08:59:20Z", + "prepared_at": "2026-10-21T13:07:13Z", "coverage": { "rows": 348, "dimensions": [ @@ -16678,7 +16681,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:59:20.553015+00:00" + "confirmed_at": "2026-10-21T13:07:13.393388+00:00" }, "warnings": [ { @@ -16704,7 +16707,7 @@ }, "bytes": 9453, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:59:20.525876+00:00", + "created_at": "2026-10-21T13:07:13.365418+00:00", "tier": "working", "url": "/api/datasets/spec_bc87ff8e0f29960c38c96a4f4d2b0e20/cv_18a63cb9e24a4ce6dfcd1c60f0c5a470/files/sha256:05184087a3031ed02bb45806f4a6c134b580ace5cada64878fca2aaa75acdb91" }, @@ -16715,7 +16718,7 @@ }, "bytes": 8146, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:59:20.525876+00:00", + "created_at": "2026-10-21T13:07:13.365418+00:00", "tier": "working", "url": "/api/datasets/spec_bc87ff8e0f29960c38c96a4f4d2b0e20/cv_18a63cb9e24a4ce6dfcd1c60f0c5a470/files/sha256:9f6cef75c54026bc957665229b19adb252d00d61f542483166394fa4aa273370" } @@ -16879,7 +16882,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:59:20.525956Z" + "held_until": "2026-11-20T13:07:13.365465Z" } } } @@ -16892,7 +16895,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A05184087a3031ed02bb45806f4a6c134b580ace5cada64878fca2aaa75acdb91?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A05184087a3031ed02bb45806f4a6c134b580ace5cada64878fca2aaa75acdb91?X-Goog-Signature=redacted", + "x-dfo-trace-id": "6ae6fbcb32de433b9c930ccae2a93638" } } }, @@ -16904,7 +16908,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "62a06033b1da44e49a59a3cb04d69bab" }, "body_file": "choose-candidate-two-parts.parquet" } @@ -17031,7 +17036,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "59c41cc22b2c48969e22aa99e323d935" }, "json": { "schema_version": 1, @@ -17139,7 +17145,7 @@ } }, "content_version": "cv_9362a741d742d00a0f4f5d671e0b400c", - "prepared_at": "2026-10-21T08:59:21Z", + "prepared_at": "2026-10-21T13:07:14Z", "coverage": { "rows": 372, "dimensions": [ @@ -17321,7 +17327,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:59:21.291262+00:00" + "confirmed_at": "2026-10-21T13:07:14.106516+00:00" }, "warnings": [], "diagnostics": [ @@ -17341,7 +17347,7 @@ }, "bytes": 10503, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:59:21.265462+00:00", + "created_at": "2026-10-21T13:07:14.069922+00:00", "tier": "working", "url": "/api/datasets/spec_941030940d23f46826acaa0c6fed8bbc/cv_9362a741d742d00a0f4f5d671e0b400c/files/sha256:8fd31163adf485e022515e99d523bd1b93a1274726800598df8583981bc0984d" }, @@ -17352,7 +17358,7 @@ }, "bytes": 8083, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:59:21.265462+00:00", + "created_at": "2026-10-21T13:07:14.069922+00:00", "tier": "working", "url": "/api/datasets/spec_941030940d23f46826acaa0c6fed8bbc/cv_9362a741d742d00a0f4f5d671e0b400c/files/sha256:27b4eefb8edbb7ed613cf134d8df4fba5dfeab885ed8c2f210c26e35032df8bc" } @@ -17603,7 +17609,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:59:21.265858Z" + "held_until": "2026-11-20T13:07:14.070133Z" } } } @@ -17616,7 +17622,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A8fd31163adf485e022515e99d523bd1b93a1274726800598df8583981bc0984d?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A8fd31163adf485e022515e99d523bd1b93a1274726800598df8583981bc0984d?X-Goog-Signature=redacted", + "x-dfo-trace-id": "179d8bf5dffb4f048480c624923bd736" } } }, @@ -17628,7 +17635,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "51d43205f7bd45fb84ad04cf2c329a6d" }, "body_file": "choose-candidate-two-parts-2.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-echoes-separate-and-operations.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-echoes-separate-and-operations.json index eb6706c..41178a4 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-echoes-separate-and-operations.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-echoes-separate-and-operations.json @@ -34,7 +34,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "42c8045fa5264f7ba7622ef7394703ec" }, "json": { "schema_version": 1, @@ -46,19 +47,19 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "36b57c8d82ea4b938e42ca11105ac21c", + "trace_id": "42c8045fa5264f7ba7622ef7394703ec", "warnings": [], "timing_ms": { - "total": 4230, + "total": 4563, "by_step": { "coverage": 0, - "extract": 875 + "extract": 1204 } }, "llm_usage": { "input_tokens": 12972, "output_tokens": 920, - "cached_tokens": 5719 + "cached_tokens": 860 }, "timed_out": false }, @@ -68,20 +69,20 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 2775, + "total": 2905, "by_step": { - "recall": 0, - "shape_arcs": 3, - "shape_probe_coverage": 4, - "shape_probe": 298, - "shape_groups": 17, - "shape_labels": 4, + "recall": 1, + "shape_arcs": 2, + "shape_probe_coverage": 2, + "shape_probe": 243, + "shape_groups": 19, + "shape_labels": 5, "shape_admission": 1, - "shape": 1305, - "bind": 1041, - "materialise": 182, - "answer": 5, - "options": 242 + "shape": 1228, + "bind": 1200, + "materialise": 180, + "answer": 6, + "options": 290 } }, "restatement": { @@ -4203,17 +4204,17 @@ } ], "timing_ms": { - "total": 2694, + "total": 2973, "by_step": { - "recall": 1, + "recall": 495, "shape_arcs": 1, - "shape_probe_coverage": 4, - "shape_probe": 287, + "shape_probe_coverage": 3, + "shape_probe": 190, "shape_groups": 2, "shape_labels": 0, "shape_admission": 0, - "shape": 1117, - "bind": 1576 + "shape": 983, + "bind": 1495 } }, "rendered_sentence": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", @@ -4659,7 +4660,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "5cce61af304d4b7096821150e22e2ad7" }, "json": { "schema_version": 1, @@ -4669,10 +4671,10 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "6bb21f75d7374cb1882111e02c35a590", + "trace_id": "5cce61af304d4b7096821150e22e2ad7", "warnings": [], "timing_ms": { - "total": 2350, + "total": 2558, "by_step": { "coverage": 0 } @@ -4680,7 +4682,7 @@ "llm_usage": { "input_tokens": 4539, "output_tokens": 503, - "cached_tokens": 1544 + "cached_tokens": 0 }, "timed_out": false }, @@ -4690,19 +4692,19 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 1426, + "total": 1289, "by_step": { "validate": 0, "walk": 0, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 952, + "shape": 818, "bind": 0, "where_places": 0, - "materialise": 213, + "materialise": 211, "answer": 1, - "options": 260 + "options": 259 } }, "operations": [], @@ -6924,19 +6926,19 @@ } ], "timing_ms": { - "total": 2327, + "total": 2533, "by_step": { - "recall": 0, + "recall": 1, "shape_arcs": 1, - "shape_probe_coverage": 3, - "shape_probe": 218, - "shape_groups": 1, + "shape_probe_coverage": 4, + "shape_probe": 180, + "shape_groups": 2, "shape_labels": 0, - "shape_admission": 1, - "shape": 817, - "bind": 1494, - "materialise": 5, - "answer": 11 + "shape_admission": 0, + "shape": 856, + "bind": 1659, + "materialise": 4, + "answer": 13 } }, "rendered_sentence": "2 readings. Kenya's outstanding external debt owed to the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 1973 to 2024 · Current US dollars. Commitments of public or publicly guaranteed external debt (debt instrument), by creditor to Kenya from the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 2023 · Current US dollars.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-option-beside-definite.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-beside-definite.json index 27168af..65605d0 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-option-beside-definite.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-beside-definite.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T09:25:52Z" + "recorded_at": "2026-10-21T13:07:18Z" }, "call": [ { @@ -35,7 +35,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "42c8045fa5264f7ba7622ef7394703ec" }, "json": { "schema_version": 1, @@ -47,19 +48,19 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "36b57c8d82ea4b938e42ca11105ac21c", + "trace_id": "42c8045fa5264f7ba7622ef7394703ec", "warnings": [], "timing_ms": { - "total": 4230, + "total": 4563, "by_step": { "coverage": 0, - "extract": 875 + "extract": 1204 } }, "llm_usage": { "input_tokens": 12972, "output_tokens": 920, - "cached_tokens": 5719 + "cached_tokens": 860 }, "timed_out": false }, @@ -69,20 +70,20 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 2775, + "total": 2905, "by_step": { - "recall": 0, - "shape_arcs": 3, - "shape_probe_coverage": 4, - "shape_probe": 298, - "shape_groups": 17, - "shape_labels": 4, + "recall": 1, + "shape_arcs": 2, + "shape_probe_coverage": 2, + "shape_probe": 243, + "shape_groups": 19, + "shape_labels": 5, "shape_admission": 1, - "shape": 1305, - "bind": 1041, - "materialise": 182, - "answer": 5, - "options": 242 + "shape": 1228, + "bind": 1200, + "materialise": 180, + "answer": 6, + "options": 290 } }, "restatement": { @@ -4197,17 +4198,17 @@ } ], "timing_ms": { - "total": 2694, + "total": 2973, "by_step": { - "recall": 1, + "recall": 495, "shape_arcs": 1, - "shape_probe_coverage": 4, - "shape_probe": 287, + "shape_probe_coverage": 3, + "shape_probe": 190, "shape_groups": 2, "shape_labels": 0, "shape_admission": 0, - "shape": 1117, - "bind": 1576 + "shape": 983, + "bind": 1495 } }, "rendered_sentence": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", @@ -4645,7 +4646,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "5cce61af304d4b7096821150e22e2ad7" }, "json": { "schema_version": 1, @@ -4655,10 +4657,10 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "6bb21f75d7374cb1882111e02c35a590", + "trace_id": "5cce61af304d4b7096821150e22e2ad7", "warnings": [], "timing_ms": { - "total": 2350, + "total": 2558, "by_step": { "coverage": 0 } @@ -4666,7 +4668,7 @@ "llm_usage": { "input_tokens": 4539, "output_tokens": 503, - "cached_tokens": 1544 + "cached_tokens": 0 }, "timed_out": false }, @@ -4676,19 +4678,19 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 1426, + "total": 1289, "by_step": { "validate": 0, "walk": 0, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 952, + "shape": 818, "bind": 0, "where_places": 0, - "materialise": 213, + "materialise": 211, "answer": 1, - "options": 260 + "options": 259 } }, "operations": [], @@ -6910,19 +6912,19 @@ } ], "timing_ms": { - "total": 2327, + "total": 2533, "by_step": { - "recall": 0, + "recall": 1, "shape_arcs": 1, - "shape_probe_coverage": 3, - "shape_probe": 218, - "shape_groups": 1, + "shape_probe_coverage": 4, + "shape_probe": 180, + "shape_groups": 2, "shape_labels": 0, - "shape_admission": 1, - "shape": 817, - "bind": 1494, - "materialise": 5, - "answer": 11 + "shape_admission": 0, + "shape": 856, + "bind": 1659, + "materialise": 4, + "answer": 13 } }, "rendered_sentence": "2 readings. Kenya's outstanding external debt owed to the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 1973 to 2024 · Current US dollars. Commitments of public or publicly guaranteed external debt (debt instrument), by creditor to Kenya from the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 2023 · Current US dollars.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-option-two-part-query.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-two-part-query.json index c0e7bbc..e7062d1 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-option-two-part-query.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-two-part-query.json @@ -33,7 +33,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "1ad25aff9f6a4ad7ac21922af623e5e9" }, "json": { "schema_version": 1, @@ -45,7 +46,7 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "9c755dc7ffaf4568afe68d812e56d8fa", + "trace_id": "1ad25aff9f6a4ad7ac21922af623e5e9", "warnings": [], "timing_ms": { "total": 1084, @@ -67,9 +68,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 0, + "total": 1, "by_step": { - "recall": 0 + "recall": 1 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -277,7 +278,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": null + "trace_id": "1ad25aff9f6a4ad7ac21922af623e5e9" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-option-without-data-query.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-without-data-query.json index dcde7b4..d01ef60 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-option-without-data-query.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-without-data-query.json @@ -33,7 +33,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "1ad25aff9f6a4ad7ac21922af623e5e9" }, "json": { "schema_version": 1, @@ -45,7 +46,7 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "9c755dc7ffaf4568afe68d812e56d8fa", + "trace_id": "1ad25aff9f6a4ad7ac21922af623e5e9", "warnings": [], "timing_ms": { "total": 1084, @@ -67,9 +68,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 0, + "total": 1, "by_step": { - "recall": 0 + "recall": 1 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -238,7 +239,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": null + "trace_id": "1ad25aff9f6a4ad7ac21922af623e5e9" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-part-by-mention.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-part-by-mention.json index d24e655..9766448 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-part-by-mention.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-part-by-mention.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:59:01Z" + "recorded_at": "2026-10-21T13:06:53Z" }, "call": [ { @@ -35,7 +35,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "1929173472984df6b31fbc19efa40365" }, "json": { "schema_version": 1, @@ -47,13 +48,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "2ea977c9567e4f2e9c14324b2748a52d", + "trace_id": "1929173472984df6b31fbc19efa40365", "warnings": [], "timing_ms": { - "total": 1645, + "total": 1065, "by_step": { "coverage": 0, - "extract": 1643 + "extract": 1063 } }, "llm_usage": { @@ -69,9 +70,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 0, "by_step": { - "recall": 1 + "recall": 0 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -273,7 +274,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "918df537e4f5439580bee8e871d64d06" }, "json": { "schema_version": 1, @@ -283,12 +285,12 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "f5c1d08be0fc4630b1a1653334f28190", + "trace_id": "918df537e4f5439580bee8e871d64d06", "warnings": [], "timing_ms": { - "total": 2024, + "total": 2076, "by_step": { - "coverage": 1 + "coverage": 0 } }, "llm_usage": { @@ -315,20 +317,20 @@ } ], "timing_ms": { - "total": 1906, + "total": 1942, "by_step": { - "recall": 1, + "recall": 0, "shape_arcs": 0, - "shape_probe_coverage": 3, + "shape_probe_coverage": 2, "shape_probe": 3, - "shape_groups": 16, + "shape_groups": 17, "shape_labels": 0, - "shape_admission": 0, - "shape": 845, - "bind": 1051, - "materialise": 4, + "shape_admission": 1, + "shape": 795, + "bind": 1135, + "materialise": 6, "answer": 4, - "options": 1 + "options": 2 } }, "restatement": { diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-place-one-part.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-place-one-part.json index 0010946..b9b92ba 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-place-one-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-place-one-part.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:58:57Z" + "recorded_at": "2026-10-21T13:06:49Z" }, "call": [ { @@ -34,7 +34,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "1ad25aff9f6a4ad7ac21922af623e5e9" }, "json": { "schema_version": 1, @@ -46,7 +47,7 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "9c755dc7ffaf4568afe68d812e56d8fa", + "trace_id": "1ad25aff9f6a4ad7ac21922af623e5e9", "warnings": [], "timing_ms": { "total": 1084, @@ -68,9 +69,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 0, + "total": 1, "by_step": { - "recall": 0 + "recall": 1 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -272,7 +273,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "11f83a7e47c0452492b5c433c0829ff3" }, "json": { "schema_version": 1, @@ -282,10 +284,10 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "2c9b56f048d44958a65955fad3114ade", + "trace_id": "11f83a7e47c0452492b5c433c0829ff3", "warnings": [], "timing_ms": { - "total": 2145, + "total": 2651, "by_step": { "coverage": 0 } @@ -314,19 +316,19 @@ } ], "timing_ms": { - "total": 2028, + "total": 2337, "by_step": { "recall": 0, - "shape_arcs": 0, + "shape_arcs": 1, "shape_probe_coverage": 3, - "shape_probe": 309, + "shape_probe": 205, "shape_groups": 20, - "shape_labels": 1, + "shape_labels": 2, "shape_admission": 0, - "shape": 1051, - "bind": 967, - "materialise": 4, - "answer": 4, + "shape": 1074, + "bind": 1250, + "materialise": 6, + "answer": 5, "options": 2 } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-place-two-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-place-two-parts.json index 047db53..481f93a 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-place-two-parts.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-place-two-parts.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:59:04Z" + "recorded_at": "2026-10-21T13:06:56Z" }, "call": [ { @@ -35,7 +35,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "69c09616094044ed89eaae3a5ddb6bf3" }, "json": { "schema_version": 1, @@ -47,13 +48,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "1766e66cd8cf4a89be01be85c97b7faa", + "trace_id": "69c09616094044ed89eaae3a5ddb6bf3", "warnings": [], "timing_ms": { - "total": 1165, + "total": 1185, "by_step": { "coverage": 0, - "extract": 1160 + "extract": 1183 } }, "llm_usage": { @@ -69,9 +70,9 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 1, + "total": 0, "by_step": { - "recall": 1 + "recall": 0 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -224,9 +225,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 0, "by_step": { - "recall": 1 + "recall": 0 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -469,7 +470,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "e7ec0fb964854583aff78b27d1df099a" }, "json": { "schema_version": 1, @@ -479,10 +481,10 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "1fff9c87a16c4188ab68dc6df0cd69b3", + "trace_id": "e7ec0fb964854583aff78b27d1df099a", "warnings": [], "timing_ms": { - "total": 2296, + "total": 2313, "by_step": { "coverage": 0 } @@ -506,9 +508,9 @@ } ], "timing_ms": { - "total": 0, + "total": 1, "by_step": { - "recall": 0 + "recall": 1 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -672,17 +674,17 @@ } ], "timing_ms": { - "total": 2151, + "total": 2186, "by_step": { "recall": 0, "shape_arcs": 0, "shape_probe_coverage": 2, - "shape_probe": 366, - "shape_groups": 16, - "shape_labels": 0, - "shape_admission": 1, - "shape": 1139, - "bind": 1000, + "shape_probe": 385, + "shape_groups": 22, + "shape_labels": 1, + "shape_admission": 0, + "shape": 1267, + "bind": 907, "materialise": 6, "answer": 4, "options": 2 diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-posts-unsupported-placeholder.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-posts-unsupported-placeholder.json index 1336e17..670c09f 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-posts-unsupported-placeholder.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-posts-unsupported-placeholder.json @@ -34,7 +34,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "42c8045fa5264f7ba7622ef7394703ec" }, "json": { "schema_version": 1, @@ -46,19 +47,19 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "36b57c8d82ea4b938e42ca11105ac21c", + "trace_id": "42c8045fa5264f7ba7622ef7394703ec", "warnings": [], "timing_ms": { - "total": 4230, + "total": 4563, "by_step": { "coverage": 0, - "extract": 875 + "extract": 1204 } }, "llm_usage": { "input_tokens": 12972, "output_tokens": 920, - "cached_tokens": 5719 + "cached_tokens": 860 }, "timed_out": false }, @@ -68,20 +69,20 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 2775, + "total": 2905, "by_step": { - "recall": 0, - "shape_arcs": 3, - "shape_probe_coverage": 4, - "shape_probe": 298, - "shape_groups": 17, - "shape_labels": 4, + "recall": 1, + "shape_arcs": 2, + "shape_probe_coverage": 2, + "shape_probe": 243, + "shape_groups": 19, + "shape_labels": 5, "shape_admission": 1, - "shape": 1305, - "bind": 1041, - "materialise": 182, - "answer": 5, - "options": 242 + "shape": 1228, + "bind": 1200, + "materialise": 180, + "answer": 6, + "options": 290 } }, "operations": [], @@ -110,17 +111,17 @@ } ], "timing_ms": { - "total": 2694, + "total": 2973, "by_step": { - "recall": 1, + "recall": 495, "shape_arcs": 1, - "shape_probe_coverage": 4, - "shape_probe": 287, + "shape_probe_coverage": 3, + "shape_probe": 190, "shape_groups": 2, "shape_labels": 0, "shape_admission": 0, - "shape": 1117, - "bind": 1576 + "shape": 983, + "bind": 1495 } }, "rendered_sentence": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", @@ -454,7 +455,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "5cce61af304d4b7096821150e22e2ad7" }, "json": { "schema_version": 1, @@ -464,10 +466,10 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "6bb21f75d7374cb1882111e02c35a590", + "trace_id": "5cce61af304d4b7096821150e22e2ad7", "warnings": [], "timing_ms": { - "total": 2350, + "total": 2558, "by_step": { "coverage": 0 } @@ -475,7 +477,7 @@ "llm_usage": { "input_tokens": 4539, "output_tokens": 503, - "cached_tokens": 1544 + "cached_tokens": 0 }, "timed_out": false }, @@ -485,19 +487,19 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 1426, + "total": 1289, "by_step": { "validate": 0, "walk": 0, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 952, + "shape": 818, "bind": 0, "where_places": 0, - "materialise": 213, + "materialise": 211, "answer": 1, - "options": 260 + "options": 259 } }, "operations": [], @@ -2719,19 +2721,19 @@ } ], "timing_ms": { - "total": 2327, + "total": 2533, "by_step": { - "recall": 0, + "recall": 1, "shape_arcs": 1, - "shape_probe_coverage": 3, - "shape_probe": 218, - "shape_groups": 1, + "shape_probe_coverage": 4, + "shape_probe": 180, + "shape_groups": 2, "shape_labels": 0, - "shape_admission": 1, - "shape": 817, - "bind": 1494, - "materialise": 5, - "answer": 11 + "shape_admission": 0, + "shape": 856, + "bind": 1659, + "materialise": 4, + "answer": 13 } }, "rendered_sentence": "2 readings. Kenya's outstanding external debt owed to the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 1973 to 2024 · Current US dollars. Commitments of public or publicly guaranteed external debt (debt instrument), by creditor to Kenya from the 48 countries in Sub-Saharan Africa. World Bank International Debt Statistics (IDS) · 2023 · Current US dollars.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json index 0eb6866..088ef41 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json @@ -34,7 +34,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "3b0a506d6d2a43a0becd94837bafffa1" }, "json": { "schema_version": 1, @@ -46,13 +47,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d0fa88511b064cc6966082b296cd6ea8", + "trace_id": "3b0a506d6d2a43a0becd94837bafffa1", "warnings": [], "timing_ms": { - "total": 4688, + "total": 4692, "by_step": { "coverage": 0, - "extract": 928 + "extract": 1001 } }, "llm_usage": { @@ -68,20 +69,20 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 3547, + "total": 3475, "by_step": { - "recall": 312, - "shape_arcs": 2, - "shape_probe_coverage": 2, - "shape_probe": 192, - "shape_groups": 2, - "shape_labels": 6, + "recall": 434, + "shape_arcs": 3, + "shape_probe_coverage": 4, + "shape_probe": 243, + "shape_groups": 3, + "shape_labels": 9, "shape_admission": 0, - "shape": 912, - "bind": 1643, - "materialise": 3, - "answer": 462, - "options": 215 + "shape": 893, + "bind": 1563, + "materialise": 9, + "answer": 381, + "options": 195 } }, "restatement": { @@ -3250,15 +3251,15 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 502, + "total": 574, "by_step": { - "recall": 307, + "recall": 380, "shape_arcs": 1, "shape_probe": 190, - "shape_groups": 1, + "shape_groups": 0, "shape_labels": 0, "shape_admission": 0, - "shape": 195 + "shape": 194 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json index 5463b8c..398606a 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json @@ -34,7 +34,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "4a421114e5a2429284f5bb99860796e7" }, "json": { "schema_version": 1, @@ -46,13 +47,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "670f1650b70c4616805aa3dd54c4dae8", + "trace_id": "4a421114e5a2429284f5bb99860796e7", "warnings": [], "timing_ms": { - "total": 1333, + "total": 1225, "by_step": { "coverage": 0, - "extract": 1329 + "extract": 1221 } }, "llm_usage": { @@ -223,9 +224,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 2, + "total": 1, "by_step": { - "recall": 2 + "recall": 1 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json index ed37c67..d87f7ad 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json @@ -33,7 +33,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "d09ca5f0ae574410bf93b5d905ea8009" }, "json": { "schema_version": 1, @@ -45,13 +46,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", + "trace_id": "d09ca5f0ae574410bf93b5d905ea8009", "warnings": [], "timing_ms": { - "total": 4556, + "total": 5038, "by_step": { "coverage": 0, - "extract": 889 + "extract": 1141 } }, "llm_usage": { @@ -67,20 +68,20 @@ "variable_text": "basic health care ODA disbursements", "warnings": [], "timing_ms": { - "total": 3505, + "total": 3758, "by_step": { - "recall": 628, + "recall": 694, "shape_arcs": 1, - "shape_probe_coverage": 5, - "shape_probe": 477, - "shape_groups": 22, - "shape_labels": 1, + "shape_probe_coverage": 6, + "shape_probe": 489, + "shape_groups": 16, + "shape_labels": 0, "shape_admission": 1, - "shape": 1283, - "bind": 1188, + "shape": 1365, + "bind": 1248, "materialise": 11, - "answer": 381, - "options": 14 + "answer": 423, + "options": 17 } }, "restatement": { diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json index d11d387..80b86d3 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json @@ -33,7 +33,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d" }, "json": { "schema_version": 1, @@ -45,13 +46,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "trace_id": "95b872cf11e44fffb92260b2bb583f0d", "warnings": [], "timing_ms": { - "total": 1788, + "total": 1697, "by_step": { "coverage": 0, - "extract": 1353 + "extract": 982 } }, "llm_usage": { @@ -67,9 +68,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 434, + "total": 715, "by_step": { - "recall": 434 + "recall": 715 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json index 04e665d..f6878f5 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json @@ -33,7 +33,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "d107dd88e50147378d54464bcdaf9695" }, "json": { "schema_version": 1, @@ -45,13 +46,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "8a56f4a56757466094a49079c6a116c4", + "trace_id": "d107dd88e50147378d54464bcdaf9695", "warnings": [], "timing_ms": { - "total": 4642, + "total": 4075, "by_step": { "coverage": 0, - "extract": 1227 + "extract": 1004 } }, "llm_usage": { @@ -67,19 +68,19 @@ "variable_text": "GNI", "warnings": [], "timing_ms": { - "total": 3202, + "total": 2799, "by_step": { - "recall": 421, - "shape_arcs": 4, - "shape_probe_coverage": 2, - "shape_probe": 211, - "shape_groups": 29, - "shape_labels": 15, + "recall": 381, + "shape_arcs": 2, + "shape_probe_coverage": 1, + "shape_probe": 203, + "shape_groups": 18, + "shape_labels": 5, "shape_admission": 0, - "shape": 1184, - "bind": 1000, - "materialise": 429, - "answer": 168 + "shape": 1186, + "bind": 829, + "materialise": 217, + "answer": 186 } }, "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-part-without-variable-text.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-part-without-variable-text.json index b73e2d7..87f0994 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-part-without-variable-text.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-part-without-variable-text.json @@ -34,7 +34,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "42c8045fa5264f7ba7622ef7394703ec" }, "json": { "schema_version": 1, @@ -46,19 +47,19 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "36b57c8d82ea4b938e42ca11105ac21c", + "trace_id": "42c8045fa5264f7ba7622ef7394703ec", "warnings": [], "timing_ms": { - "total": 4230, + "total": 4563, "by_step": { "coverage": 0, - "extract": 875 + "extract": 1204 } }, "llm_usage": { "input_tokens": 12972, "output_tokens": 920, - "cached_tokens": 5719 + "cached_tokens": 860 }, "timed_out": false }, @@ -67,20 +68,20 @@ { "warnings": [], "timing_ms": { - "total": 2775, + "total": 2905, "by_step": { - "recall": 0, - "shape_arcs": 3, - "shape_probe_coverage": 4, - "shape_probe": 298, - "shape_groups": 17, - "shape_labels": 4, + "recall": 1, + "shape_arcs": 2, + "shape_probe_coverage": 2, + "shape_probe": 243, + "shape_groups": 19, + "shape_labels": 5, "shape_admission": 1, - "shape": 1305, - "bind": 1041, - "materialise": 182, - "answer": 5, - "options": 242 + "shape": 1228, + "bind": 1200, + "materialise": 180, + "answer": 6, + "options": 290 } }, "restatement": { @@ -4195,17 +4196,17 @@ } ], "timing_ms": { - "total": 2694, + "total": 2973, "by_step": { - "recall": 1, + "recall": 495, "shape_arcs": 1, - "shape_probe_coverage": 4, - "shape_probe": 287, + "shape_probe_coverage": 3, + "shape_probe": 190, "shape_groups": 2, "shape_labels": 0, "shape_admission": 0, - "shape": 1117, - "bind": 1576 + "shape": 983, + "bind": 1495 } }, "rendered_sentence": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-label.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-label.json index 958aecf..57c6ca8 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-label.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-label.json @@ -46,7 +46,7 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "9c755dc7ffaf4568afe68d812e56d8fa", + "trace_id": "1ad25aff9f6a4ad7ac21922af623e5e9", "warnings": [], "timing_ms": { "total": 1084, @@ -68,9 +68,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 0, + "total": 1, "by_step": { - "recall": 0 + "recall": 1 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json index 45c6f9d..adaab80 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json @@ -33,7 +33,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "4a421114e5a2429284f5bb99860796e7" }, "json": { "schema_version": 1, @@ -45,13 +46,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "670f1650b70c4616805aa3dd54c4dae8", + "trace_id": "4a421114e5a2429284f5bb99860796e7", "warnings": [], "timing_ms": { - "total": 1333, + "total": 1225, "by_step": { "coverage": 0, - "extract": 1329 + "extract": 1221 } }, "llm_usage": { @@ -222,9 +223,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 2, + "total": 1, "by_step": { - "recall": 2 + "recall": 1 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json index c7c6902..30cab4d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json @@ -33,7 +33,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d" }, "json": { "schema_version": 1, @@ -45,13 +46,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "trace_id": "95b872cf11e44fffb92260b2bb583f0d", "warnings": [], "timing_ms": { - "total": 1788, + "total": 1697, "by_step": { "coverage": 0, - "extract": 1353 + "extract": 982 } }, "llm_usage": { @@ -67,9 +68,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 434, + "total": 715, "by_step": { - "recall": 434 + "recall": 715 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json index e2e4f9c..cb42e8a 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json @@ -34,7 +34,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "3b0a506d6d2a43a0becd94837bafffa1" }, "json": { "schema_version": 1, @@ -46,13 +47,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d0fa88511b064cc6966082b296cd6ea8", + "trace_id": "3b0a506d6d2a43a0becd94837bafffa1", "warnings": [], "timing_ms": { - "total": 4688, + "total": 4692, "by_step": { "coverage": 0, - "extract": 928 + "extract": 1001 } }, "llm_usage": { @@ -68,20 +69,20 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 3547, + "total": 3475, "by_step": { - "recall": 312, - "shape_arcs": 2, - "shape_probe_coverage": 2, - "shape_probe": 192, - "shape_groups": 2, - "shape_labels": 6, + "recall": 434, + "shape_arcs": 3, + "shape_probe_coverage": 4, + "shape_probe": 243, + "shape_groups": 3, + "shape_labels": 9, "shape_admission": 0, - "shape": 912, - "bind": 1643, - "materialise": 3, - "answer": 462, - "options": 215 + "shape": 893, + "bind": 1563, + "materialise": 9, + "answer": 381, + "options": 195 } }, "restatement": { @@ -3250,15 +3251,15 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 502, + "total": 574, "by_step": { - "recall": 307, + "recall": 380, "shape_arcs": 1, "shape_probe": 190, - "shape_groups": 1, + "shape_groups": 0, "shape_labels": 0, "shape_admission": 0, - "shape": 195 + "shape": 194 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-status.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-status.json index f8ce75c..ecb8542 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-status.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-status.json @@ -34,7 +34,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "42c8045fa5264f7ba7622ef7394703ec" }, "json": { "schema_version": 1, @@ -46,19 +47,19 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "36b57c8d82ea4b938e42ca11105ac21c", + "trace_id": "42c8045fa5264f7ba7622ef7394703ec", "warnings": [], "timing_ms": { - "total": 4230, + "total": 4563, "by_step": { "coverage": 0, - "extract": 875 + "extract": 1204 } }, "llm_usage": { "input_tokens": 12972, "output_tokens": 920, - "cached_tokens": 5719 + "cached_tokens": 860 }, "timed_out": false }, @@ -68,20 +69,20 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 2775, + "total": 2905, "by_step": { - "recall": 0, - "shape_arcs": 3, - "shape_probe_coverage": 4, - "shape_probe": 298, - "shape_groups": 17, - "shape_labels": 4, + "recall": 1, + "shape_arcs": 2, + "shape_probe_coverage": 2, + "shape_probe": 243, + "shape_groups": 19, + "shape_labels": 5, "shape_admission": 1, - "shape": 1305, - "bind": 1041, - "materialise": 182, - "answer": 5, - "options": 242 + "shape": 1228, + "bind": 1200, + "materialise": 180, + "answer": 6, + "options": 290 } }, "operations": [], @@ -4183,17 +4184,17 @@ } ], "timing_ms": { - "total": 2694, + "total": 2973, "by_step": { - "recall": 1, + "recall": 495, "shape_arcs": 1, - "shape_probe_coverage": 4, - "shape_probe": 287, + "shape_probe_coverage": 3, + "shape_probe": 190, "shape_groups": 2, "shape_labels": 0, "shape_admission": 0, - "shape": 1117, - "bind": 1576 + "shape": 983, + "bind": 1495 } }, "rendered_sentence": "Could not tell who is giving and who is receiving among \"sub-Saharan Africa\" and \"Kenya\". Put \"from\" or \"to\" before a name.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json index 59b702c..8d9f926 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json @@ -33,7 +33,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "3ceef86d0eac49fa96380d3340878cf1" }, "json": { "schema_version": 1, @@ -45,18 +46,18 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "c354423648a442189d804c35586bd78a", + "trace_id": "3ceef86d0eac49fa96380d3340878cf1", "warnings": [], "timing_ms": { - "total": 5956, + "total": 5613, "by_step": { "coverage": 0, - "extract": 919 + "extract": 1020 } }, "llm_usage": { "input_tokens": 15731, - "output_tokens": 1037, + "output_tokens": 1021, "cached_tokens": 861 }, "timed_out": false @@ -67,20 +68,20 @@ "variable_text": "ODA disbursements for health", "warnings": [], "timing_ms": { - "total": 3227, + "total": 3674, "by_step": { - "recall": 535, + "recall": 773, "shape_arcs": 0, - "shape_probe_coverage": 1, - "shape_probe": 197, - "shape_groups": 16, - "shape_labels": 4, + "shape_probe_coverage": 11, + "shape_probe": 224, + "shape_groups": 26, + "shape_labels": 8, "shape_admission": 0, - "shape": 1071, - "bind": 1345, - "materialise": 157, - "answer": 20, - "options": 99 + "shape": 1251, + "bind": 1411, + "materialise": 115, + "answer": 15, + "options": 109 } }, "restatement": { @@ -3738,20 +3739,20 @@ } ], "timing_ms": { - "total": 3024, + "total": 3542, "by_step": { - "recall": 456, + "recall": 791, "shape_arcs": 0, - "shape_probe_coverage": 1, - "shape_probe": 183, - "shape_groups": 17, - "shape_labels": 4, - "shape_admission": 0, - "shape": 1070, - "bind": 1243, - "materialise": 82, - "answer": 19, - "options": 154 + "shape_probe_coverage": 2, + "shape_probe": 240, + "shape_groups": 39, + "shape_labels": 5, + "shape_admission": 1, + "shape": 1008, + "bind": 1505, + "materialise": 146, + "answer": 13, + "options": 79 } }, "restatement": { @@ -7414,20 +7415,20 @@ } ], "timing_ms": { - "total": 3386, + "total": 3536, "by_step": { - "recall": 579, + "recall": 778, "shape_arcs": 2, - "shape_probe_coverage": 1, - "shape_probe": 263, - "shape_groups": 19, - "shape_labels": 4, - "shape_admission": 0, - "shape": 1015, - "bind": 1274, + "shape_probe_coverage": 2, + "shape_probe": 277, + "shape_groups": 24, + "shape_labels": 5, + "shape_admission": 1, + "shape": 973, + "bind": 1109, "materialise": 1, - "answer": 159, - "options": 358 + "answer": 210, + "options": 465 } }, "restatement": { @@ -9427,7 +9428,50 @@ } ], "measure_label_axes": [], - "measure_axis_values": [] + "measure_axis_values": [], + "related_group": { + "ref": "dc/g/EconomicActivity_ActivitySource-GrossDomesticProduction", + "label": "Economic Activity With Activity Source = Gross Domestic Production" + }, + "related_measures": [ + { + "stat_var": { + "ref": "GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "label": "Gross domestic product growth rate" + }, + "definition": { + "schema_version": 1, + "spec_id": "spec_4535d09baf2bdffef7c19c7796e96687", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "growthRate" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + } + ] } } } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json index 906bbec..790290f 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json @@ -32,7 +32,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "d09ca5f0ae574410bf93b5d905ea8009" }, "json": { "schema_version": 1, @@ -44,13 +45,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", + "trace_id": "d09ca5f0ae574410bf93b5d905ea8009", "warnings": [], "timing_ms": { - "total": 4556, + "total": 5038, "by_step": { "coverage": 0, - "extract": 889 + "extract": 1141 } }, "llm_usage": { @@ -66,20 +67,20 @@ "variable_text": "basic health care ODA disbursements", "warnings": [], "timing_ms": { - "total": 3505, + "total": 3758, "by_step": { - "recall": 628, + "recall": 694, "shape_arcs": 1, - "shape_probe_coverage": 5, - "shape_probe": 477, - "shape_groups": 22, - "shape_labels": 1, + "shape_probe_coverage": 6, + "shape_probe": 489, + "shape_groups": 16, + "shape_labels": 0, "shape_admission": 1, - "shape": 1283, - "bind": 1188, + "shape": 1365, + "bind": 1248, "materialise": 11, - "answer": 381, - "options": 14 + "answer": 423, + "options": 17 } }, "restatement": { @@ -3762,7 +3763,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "90ec74fce6534d0d8e4142b0e1355782" }, "json": { "schema_version": 1, @@ -3834,7 +3836,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-21T08:57:19Z", + "prepared_at": "2026-10-21T13:05:05Z", "coverage": { "rows": 30, "dimensions": [ @@ -4167,7 +4169,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:57:19.628756+00:00" + "confirmed_at": "2026-10-21T13:05:06.336796+00:00" }, "warnings": [], "diagnostics": [ @@ -4187,7 +4189,7 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, @@ -4198,7 +4200,7 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } @@ -4444,7 +4446,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:19.589587Z" + "held_until": "2026-11-20T13:05:06.298810Z" } } } @@ -4457,7 +4459,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted", + "x-dfo-trace-id": "d14640239a5a4ffa8f113140eb5b23a0" } } }, @@ -4469,7 +4472,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "58cc82a3079f4e4298eb45378fdf10db" }, "body_file": "answer-definite-fetch.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json index 3497b90..3741eb3 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json @@ -33,7 +33,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d" }, "json": { "schema_version": 1, @@ -45,13 +46,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "trace_id": "95b872cf11e44fffb92260b2bb583f0d", "warnings": [], "timing_ms": { - "total": 1788, + "total": 1697, "by_step": { "coverage": 0, - "extract": 1353 + "extract": 982 } }, "llm_usage": { @@ -67,9 +68,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 434, + "total": 715, "by_step": { - "recall": 434 + "recall": 715 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -260,7 +261,7 @@ "error": { "class": "IncompleteAnswerError", "code": "answer_incomplete", - "trace_id": null + "trace_id": "95b872cf11e44fffb92260b2bb583f0d" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-artifact-unlisted.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-artifact-unlisted.json new file mode 100644 index 0000000..ad6974c --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-artifact-unlisted.json @@ -0,0 +1,871 @@ +{ + "format_version": 1, + "name": "fetch-ref-artifact-unlisted", + "description": "A ref member whose digest the snapshot manifest does not list asks the file selector in the ref member's own rendering, and bytes that hash to the stored digest give the dataset.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-ref", + "edit": "The snapshot manifest's artifacts no longer list the ref's digest, and the file selector redirects to the parent's signed download." + }, + "call": [ + { + "op": "fetch", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [ + "basic health care ODA disbursements" + ], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + } + }, + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "artifact": { + "digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "rendering": { + "format": "parquet", + "bundle": false + } + } + } + ] + } + } + ], + "exchanges": [ + { + "request": { + "method": "GET", + "path": "/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "62f3f94d818743f89b2e3047c3e737f6" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + }, + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "prepared_at": "2026-10-21T13:05:05Z", + "coverage": { + "rows": 30, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 27 + } + ], + "window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1995 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1995 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 7 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 15 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:ac65501b1aef56a9caaadf063eb0390e8d816198384081e2c1645b04816693b8", + "rendering": { + "format": "frame" + }, + "bytes": 4764, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:06.298931+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:ac65501b1aef56a9caaadf063eb0390e8d816198384081e2c1645b04816693b8" + }, + { + "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", + "rendering": { + "statistics": "series" + }, + "bytes": 5981, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:06.298931+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" + } + ], + "series_count": 5, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 5 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 27 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "stat_var", + "columns": "time_period", + "state": "available", + "width": 28, + "cells": 140 + }, + { + "index": "time_period", + "columns": "stat_var", + "state": "available", + "width": 6, + "cells": 162 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T13:05:06.298810Z" + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/file?format=parquet&bundle=false" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted", + "x-dfo-trace-id": "7dbbbcc2a7bd4cc7a0c5d806e55cc20f" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "81e177c259cc4bca8e9ea1bceb977f3d" + }, + "body_file": "fetch-ref.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 30, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "crsCooperationModality", + "crsCooperationModality_label", + "crsPurpose", + "crsPurpose_label", + "crsTypeOfFinance", + "crsTypeOfFinance_label", + "crsTypeOfFlow", + "crsTypeOfFlow_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [ + "basic health care ODA disbursements" + ], + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." + } + ], + "missing": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-file-selector.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-file-selector.json index b6a9f88..77fd42f 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-file-selector.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-file-selector.json @@ -110,7 +110,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "62f3f94d818743f89b2e3047c3e737f6" }, "json": { "schema_version": 1, @@ -182,7 +183,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-21T08:57:19Z", + "prepared_at": "2026-10-21T13:05:05Z", "coverage": { "rows": 30, "dimensions": [ @@ -533,7 +534,7 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, @@ -544,7 +545,7 @@ }, "bytes": 4764, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:ac65501b1aef56a9caaadf063eb0390e8d816198384081e2c1645b04816693b8" }, @@ -555,7 +556,7 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } @@ -800,7 +801,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:19.589587Z" + "held_until": "2026-11-20T13:05:06.298810Z" } } } @@ -835,7 +836,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted", + "x-dfo-trace-id": "7dbbbcc2a7bd4cc7a0c5d806e55cc20f" } } }, @@ -847,7 +849,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "81e177c259cc4bca8e9ea1bceb977f3d" }, "body_file": "fetch-ref.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json index 0cf5707..9647083 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json @@ -210,7 +210,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "90ec74fce6534d0d8e4142b0e1355782" }, "json": { "schema_version": 1, @@ -282,7 +283,7 @@ } }, "content_version": "cv_11111111111111111111111111111111", - "prepared_at": "2026-10-21T08:57:19Z", + "prepared_at": "2026-10-21T13:05:05Z", "coverage": { "rows": 30, "dimensions": [ @@ -615,7 +616,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:57:19.628756+00:00" + "confirmed_at": "2026-10-21T13:05:06.336796+00:00" }, "warnings": [], "diagnostics": [ @@ -635,7 +636,7 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, @@ -646,7 +647,7 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } @@ -891,7 +892,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:19.589587Z" + "held_until": "2026-11-20T13:05:06.298810Z" } } } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json index c41d811..05ec78d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json @@ -230,7 +230,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "e5ff992e18a94c18866838012ff15862" }, "json": { "schema_version": 1, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-same-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-same-version.json index 86a76d5..0f9d343 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-same-version.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-same-version.json @@ -210,7 +210,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "90ec74fce6534d0d8e4142b0e1355782" }, "json": { "schema_version": 1, @@ -282,7 +283,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-21T08:57:19Z", + "prepared_at": "2026-10-21T13:05:05Z", "coverage": { "rows": 30, "dimensions": [ @@ -615,7 +616,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:57:19.628756+00:00" + "confirmed_at": "2026-10-21T13:05:06.336796+00:00" }, "warnings": [], "diagnostics": [ @@ -635,7 +636,7 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, @@ -646,7 +647,7 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } @@ -891,7 +892,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:19.589587Z" + "held_until": "2026-11-20T13:05:06.298810Z" } } } @@ -904,7 +905,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted", + "x-dfo-trace-id": "d14640239a5a4ffa8f113140eb5b23a0" } } }, @@ -916,7 +918,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "58cc82a3079f4e4298eb45378fdf10db" }, "body_file": "answer-definite-fetch.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-newest-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-newest-version.json index 390f885..7402be9 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-newest-version.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-newest-version.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T09:31:38Z" + "recorded_at": "2026-10-21T13:07:25Z" }, "call": [ { @@ -93,7 +93,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "e5ff992e18a94c18866838012ff15862" }, "json": { "schema_version": 1, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused-twice.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused-twice.json index 4fd7e89..840eeb3 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused-twice.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused-twice.json @@ -110,7 +110,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "62f3f94d818743f89b2e3047c3e737f6" }, "json": { "schema_version": 1, @@ -182,7 +183,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-21T08:57:19Z", + "prepared_at": "2026-10-21T13:05:05Z", "coverage": { "rows": 30, "dimensions": [ @@ -533,7 +534,7 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, @@ -544,7 +545,7 @@ }, "bytes": 4764, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:ac65501b1aef56a9caaadf063eb0390e8d816198384081e2c1645b04816693b8" }, @@ -555,7 +556,7 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } @@ -800,7 +801,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:19.589587Z" + "held_until": "2026-11-20T13:05:06.298810Z" } } } @@ -813,7 +814,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted", + "x-dfo-trace-id": "7dbbbcc2a7bd4cc7a0c5d806e55cc20f" } } }, @@ -837,7 +839,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted", + "x-dfo-trace-id": "7dbbbcc2a7bd4cc7a0c5d806e55cc20f" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused.json index ee41c60..b81b811 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused.json @@ -110,7 +110,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "62f3f94d818743f89b2e3047c3e737f6" }, "json": { "schema_version": 1, @@ -182,7 +183,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-21T08:57:19Z", + "prepared_at": "2026-10-21T13:05:05Z", "coverage": { "rows": 30, "dimensions": [ @@ -533,7 +534,7 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, @@ -544,7 +545,7 @@ }, "bytes": 4764, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:ac65501b1aef56a9caaadf063eb0390e8d816198384081e2c1645b04816693b8" }, @@ -555,7 +556,7 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } @@ -800,7 +801,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:19.589587Z" + "held_until": "2026-11-20T13:05:06.298810Z" } } } @@ -813,7 +814,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted", + "x-dfo-trace-id": "7dbbbcc2a7bd4cc7a0c5d806e55cc20f" } } }, @@ -837,7 +839,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted", + "x-dfo-trace-id": "7dbbbcc2a7bd4cc7a0c5d806e55cc20f" } } }, @@ -849,7 +852,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "81e177c259cc4bca8e9ea1bceb977f3d" }, "body_file": "fetch-ref.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-unknown-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-unknown-version.json index ffbebd5..e27e9b3 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-unknown-version.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-unknown-version.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:58:01Z" + "recorded_at": "2026-10-21T13:05:50Z" }, "call": [ { @@ -111,7 +111,8 @@ "response": { "status": 404, "headers": { - "content-type": "application/problem+json" + "content-type": "application/problem+json", + "x-dfo-trace-id": "30da7e671a9246f8b1c399fe77e0ca9c" }, "json": { "type": "/codes/snapshot_not_found", @@ -119,7 +120,7 @@ "status": 404, "detail": "'spec_774d6c001a6250aa67ca676ab067895e' has no version at content_version 'cv_00000000000000000000000000000000'", "code": "snapshot_not_found", - "trace_id": "a2f44c8df4c642a58f0a2a0723f7e104", + "trace_id": "30da7e671a9246f8b1c399fe77e0ca9c", "capability_version": "dset_88fecfec3c5b89d1", "retryable": false } @@ -131,7 +132,7 @@ "error": { "class": "NotFoundError", "code": "snapshot_not_found", - "trace_id": "a2f44c8df4c642a58f0a2a0723f7e104" + "trace_id": "30da7e671a9246f8b1c399fe77e0ca9c" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref.json index 5afcb7b..007e89a 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:58:01Z" + "recorded_at": "2026-10-21T13:05:50Z" }, "call": [ { @@ -111,7 +111,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "62f3f94d818743f89b2e3047c3e737f6" }, "json": { "schema_version": 1, @@ -183,7 +184,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-21T08:57:19Z", + "prepared_at": "2026-10-21T13:05:05Z", "coverage": { "rows": 30, "dimensions": [ @@ -534,7 +535,7 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, @@ -545,7 +546,7 @@ }, "bytes": 4764, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:ac65501b1aef56a9caaadf063eb0390e8d816198384081e2c1645b04816693b8" }, @@ -556,7 +557,7 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } @@ -801,7 +802,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:19.589587Z" + "held_until": "2026-11-20T13:05:06.298810Z" } } } @@ -814,7 +815,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted", + "x-dfo-trace-id": "7dbbbcc2a7bd4cc7a0c5d806e55cc20f" } } }, @@ -826,7 +828,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "81e177c259cc4bca8e9ea1bceb977f3d" }, "body_file": "fetch-ref.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json index 69122ec..cdf2c56 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json @@ -32,7 +32,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "d09ca5f0ae574410bf93b5d905ea8009" }, "json": { "schema_version": 1, @@ -44,13 +45,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", + "trace_id": "d09ca5f0ae574410bf93b5d905ea8009", "warnings": [], "timing_ms": { - "total": 4556, + "total": 5038, "by_step": { "coverage": 0, - "extract": 889 + "extract": 1141 } }, "llm_usage": { @@ -66,20 +67,20 @@ "variable_text": "basic health care ODA disbursements", "warnings": [], "timing_ms": { - "total": 3505, + "total": 3758, "by_step": { - "recall": 628, + "recall": 694, "shape_arcs": 1, - "shape_probe_coverage": 5, - "shape_probe": 477, - "shape_groups": 22, - "shape_labels": 1, + "shape_probe_coverage": 6, + "shape_probe": 489, + "shape_groups": 16, + "shape_labels": 0, "shape_admission": 1, - "shape": 1283, - "bind": 1188, + "shape": 1365, + "bind": 1248, "materialise": 11, - "answer": 381, - "options": 14 + "answer": 423, + "options": 17 } }, "restatement": { @@ -3762,7 +3763,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "90ec74fce6534d0d8e4142b0e1355782" }, "json": { "schema_version": 1, @@ -3833,7 +3835,7 @@ } } }, - "prepared_at": "2026-10-21T08:57:19Z", + "prepared_at": "2026-10-21T13:05:05Z", "coverage": { "rows": 30, "dimensions": [ @@ -4166,7 +4168,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:57:19.628756+00:00" + "confirmed_at": "2026-10-21T13:05:06.336796+00:00" }, "warnings": [], "diagnostics": [ @@ -4186,7 +4188,7 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, @@ -4197,7 +4199,7 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } @@ -4442,7 +4444,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:19.589587Z" + "held_until": "2026-11-20T13:05:06.298810Z" }, "contentVersion": "cv_b92d94774702c7f05f2075d0b03dd756" } @@ -4466,7 +4468,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": null + "trace_id": "90ec74fce6534d0d8e4142b0e1355782" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json index 740e4d6..571bc2d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json @@ -32,7 +32,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "d09ca5f0ae574410bf93b5d905ea8009" }, "json": { "schema_version": 1, @@ -44,13 +45,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", + "trace_id": "d09ca5f0ae574410bf93b5d905ea8009", "warnings": [], "timing_ms": { - "total": 4556, + "total": 5038, "by_step": { "coverage": 0, - "extract": 889 + "extract": 1141 } }, "llm_usage": { @@ -66,20 +67,20 @@ "variable_text": "basic health care ODA disbursements", "warnings": [], "timing_ms": { - "total": 3505, + "total": 3758, "by_step": { - "recall": 628, + "recall": 694, "shape_arcs": 1, - "shape_probe_coverage": 5, - "shape_probe": 477, - "shape_groups": 22, - "shape_labels": 1, + "shape_probe_coverage": 6, + "shape_probe": 489, + "shape_groups": 16, + "shape_labels": 0, "shape_admission": 1, - "shape": 1283, - "bind": 1188, + "shape": 1365, + "bind": 1248, "materialise": 11, - "answer": 381, - "options": 14 + "answer": 423, + "options": 17 } }, "restatement": { @@ -3862,7 +3863,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "90ec74fce6534d0d8e4142b0e1355782" }, "json": { "schema_version": 1, @@ -3934,7 +3936,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-21T08:57:19Z", + "prepared_at": "2026-10-21T13:05:05Z", "coverage": { "rows": 30, "dimensions": [ @@ -4267,7 +4269,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:57:19.628756+00:00" + "confirmed_at": "2026-10-21T13:05:06.336796+00:00" }, "warnings": [], "diagnostics": [ @@ -4287,7 +4289,7 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, @@ -4298,7 +4300,7 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } @@ -4543,7 +4545,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:19.589587Z" + "held_until": "2026-11-20T13:05:06.298810Z" } } } @@ -4556,7 +4558,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted", + "x-dfo-trace-id": "d14640239a5a4ffa8f113140eb5b23a0" } } }, @@ -4568,7 +4571,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "58cc82a3079f4e4298eb45378fdf10db" }, "body_file": "answer-definite-fetch.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-503-then-504.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-503-then-504.json index 8a18b8e..f7dafde 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-503-then-504.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-503-then-504.json @@ -378,7 +378,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" }, "json": { "schema_version": 1, @@ -452,7 +453,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T08:57:50Z", + "prepared_at": "2026-10-21T13:05:35Z", "coverage": { "rows": 4, "dimensions": [ @@ -785,7 +786,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "head", - "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + "confirmed_at": "2026-10-21T13:05:35.077517+00:00" }, "warnings": [ { @@ -811,7 +812,7 @@ }, "bytes": 9541, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" }, @@ -822,7 +823,7 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } @@ -1052,7 +1053,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:50.451687Z" + "held_until": "2026-11-20T13:05:35.038284Z" } } } @@ -1065,7 +1066,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", + "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" } } }, @@ -1077,7 +1079,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" }, "body_file": "fetch-spec-known-sentence.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-retry-after.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-retry-after.json index 3052299..a9bedd9 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-retry-after.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-retry-after.json @@ -277,7 +277,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" }, "json": { "schema_version": 1, @@ -351,7 +352,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T08:57:50Z", + "prepared_at": "2026-10-21T13:05:35Z", "coverage": { "rows": 4, "dimensions": [ @@ -684,7 +685,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "head", - "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + "confirmed_at": "2026-10-21T13:05:35.077517+00:00" }, "warnings": [ { @@ -710,7 +711,7 @@ }, "bytes": 9541, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" }, @@ -721,7 +722,7 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } @@ -951,7 +952,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:50.451687Z" + "held_until": "2026-11-20T13:05:35.038284Z" } } } @@ -964,7 +965,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", + "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" } } }, @@ -976,7 +978,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" }, "body_file": "fetch-spec-known-sentence.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-async-build.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-async-build.json index 459d801..8313d2b 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-async-build.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-async-build.json @@ -148,7 +148,8 @@ "headers": { "content-type": "application/json", "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" }, "json": { "operation": { @@ -169,7 +170,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "621bdcc038e34f44bec226434f3f7378" }, "json": { "operation": { @@ -194,7 +196,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "1df7b03572044eedaa412f6d2ad6b91f" }, "json": { "operation": { @@ -219,7 +222,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "b5b2e2d98a4047be98aea852117381c7" }, "json": { "operation": { @@ -244,14 +248,15 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "686111d592f3451e8c55691d91a66663" }, "json": { "operation": { "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "status": "running", "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 1516, + "retry_after_ms": 1517, "progress": { "rows_written": 0, "estimate_rows": 108798 @@ -269,7 +274,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "9acc0caab7e143d38b3ecbfbcd225707" }, "json": { "operation": { @@ -278,7 +284,7 @@ "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "retry_after_ms": 1900, "progress": { - "rows_written": 14493, + "rows_written": 16734, "estimate_rows": 108798 } } @@ -294,7 +300,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "3" + "retry-after": "3", + "x-dfo-trace-id": "22c08bbaa1384833bd92f8dd9cc6312d" }, "json": { "operation": { @@ -303,7 +310,7 @@ "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "retry_after_ms": 2377, "progress": { - "rows_written": 41372, + "rows_written": 64341, "estimate_rows": 108798 } } @@ -319,16 +326,17 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "3" + "retry-after": "3", + "x-dfo-trace-id": "227de800033b4185ae9b958d3fa2cec7" }, "json": { "operation": { "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "status": "running", "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 2975, + "retry_after_ms": 2973, "progress": { - "rows_written": 75380, + "rows_written": 106324, "estimate_rows": 108798 } } @@ -344,14 +352,15 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "4" + "retry-after": "4", + "x-dfo-trace-id": "3197d4d8b5094857afb9bbd14c49fcb0" }, "json": { "operation": { "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "status": "running", "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 3755, + "retry_after_ms": 3719, "progress": { "rows_written": 108798, "estimate_rows": 108798 @@ -368,7 +377,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "29f271852cc04f1a8b287274f53105b6" }, "json": { "operation": { @@ -433,7 +443,7 @@ } }, "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "prepared_at": "2026-10-21T08:58:24Z", + "prepared_at": "2026-10-21T13:06:08Z", "coverage": { "rows": 108798, "dimensions": [ @@ -615,7 +625,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:58:25.535416+00:00" + "confirmed_at": "2026-10-21T13:06:09.616741+00:00" }, "warnings": [], "diagnostics": [ @@ -635,7 +645,7 @@ }, "bytes": 913395, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:58:25.500374+00:00", + "created_at": "2026-10-21T13:06:09.573990+00:00", "tier": "working", "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" }, @@ -646,7 +656,7 @@ }, "bytes": 967921, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:58:25.500374+00:00", + "created_at": "2026-10-21T13:06:09.573990+00:00", "tier": "working", "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" } @@ -1117,7 +1127,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:58:25.500506Z" + "held_until": "2026-11-20T13:06:09.573841Z" } } } @@ -1131,7 +1141,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted", + "x-dfo-trace-id": "155fa981459c464482aea52657f99e8b" } } }, @@ -1143,7 +1154,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "228feaabf1f3473cad055088084dc378" }, "body_file": "mint-async-build.parquet" } @@ -1193,11 +1205,11 @@ 1.5, 1.5, 1.5, - 1.516, + 1.517, 1.9, 2.377, - 2.975, - 3.755 + 2.973, + 3.719 ], "resubmissions": 0 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json index e0da9df..e8d5f61 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json @@ -174,7 +174,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" }, "json": { "schema_version": 1, @@ -248,7 +249,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T08:57:50Z", + "prepared_at": "2026-10-21T13:05:35Z", "coverage": { "rows": 4, "dimensions": [ @@ -581,7 +582,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "head", - "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + "confirmed_at": "2026-10-21T13:05:35.077517+00:00" }, "warnings": [ { @@ -607,7 +608,7 @@ }, "bytes": 9541, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" }, @@ -618,7 +619,7 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } @@ -848,7 +849,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:50.451687Z" + "held_until": "2026-11-20T13:05:35.038284Z" } } } @@ -861,7 +862,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", + "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" } } }, @@ -873,7 +875,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" }, "body_file": "fetch-spec-digest-mismatch.bin" } @@ -886,7 +889,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", + "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" } } }, @@ -898,7 +902,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" }, "body_file": "fetch-spec-digest-mismatch.bin" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-empty-narrowing.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-empty-narrowing.json index b91fc2a..36e8750 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-empty-narrowing.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-empty-narrowing.json @@ -176,7 +176,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" }, "json": { "schema_version": 1, @@ -250,7 +251,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T08:57:50Z", + "prepared_at": "2026-10-21T13:05:35Z", "coverage": { "rows": 4, "dimensions": [ @@ -583,7 +584,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "head", - "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + "confirmed_at": "2026-10-21T13:05:35.077517+00:00" }, "warnings": [ { @@ -609,7 +610,7 @@ }, "bytes": 9541, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" }, @@ -620,7 +621,7 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } @@ -850,7 +851,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:50.451687Z" + "held_until": "2026-11-20T13:05:35.038284Z" } } } @@ -863,7 +864,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", + "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" } } }, @@ -875,7 +877,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" }, "body_file": "fetch-spec-known-sentence.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json index 5437487..019164b 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:57:51Z" + "recorded_at": "2026-10-21T13:05:36Z" }, "call": [ { @@ -181,7 +181,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "65233075c02f4a259e853322a41a615e" }, "json": { "schema_version": 1, @@ -250,7 +251,7 @@ } }, "content_version": "cv_1868d697e8e7d56da6a83740a940c2e5", - "prepared_at": "2026-10-21T08:57:52Z", + "prepared_at": "2026-10-21T13:05:38Z", "coverage": { "rows": 309, "dimensions": [ @@ -583,7 +584,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:57:52.666745+00:00" + "confirmed_at": "2026-10-21T13:05:38.830186+00:00" }, "warnings": [], "diagnostics": [ @@ -603,7 +604,7 @@ }, "bytes": 13341, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:52.631622+00:00", + "created_at": "2026-10-21T13:05:38.797066+00:00", "tier": "working", "url": "/api/datasets/spec_4c228c73be6c18efd0939eabb3b3c456/cv_1868d697e8e7d56da6a83740a940c2e5/files/sha256:da9aa46394801d54e23b886528b98b609d8fda2ed46a2eb9e365575ee73ddf3a" }, @@ -614,7 +615,7 @@ }, "bytes": 9074, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:52.631622+00:00", + "created_at": "2026-10-21T13:05:38.797066+00:00", "tier": "working", "url": "/api/datasets/spec_4c228c73be6c18efd0939eabb3b3c456/cv_1868d697e8e7d56da6a83740a940c2e5/files/sha256:ffd0e9eaabfc35d3113188c82648ce0bf809307a01a024b52b0baa133ef63d18" } @@ -977,7 +978,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:52.631891Z" + "held_until": "2026-11-20T13:05:38.797229Z" } } } @@ -1062,7 +1063,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "d1929c3ccdc84f0ab8eb63b2aa22bfce" }, "json": { "schema_version": 1, @@ -1072,10 +1074,10 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "abe8d0c9bf6e4834b93b843fb67a3fb7", + "trace_id": "d1929c3ccdc84f0ab8eb63b2aa22bfce", "warnings": [], "timing_ms": { - "total": 127, + "total": 139, "by_step": { "coverage": 0 } @@ -1094,19 +1096,19 @@ } ], "timing_ms": { - "total": 91, + "total": 99, "by_step": { "validate": 2, - "walk": 64, + "walk": 68, "reread_arcs": 1, "detect_edits": 0, "resolve_survivors": 0, - "shape": 1, + "shape": 2, "bind": 0, "where_places": 0, - "materialise": 11, - "answer": 10, - "options": 2 + "materialise": 12, + "answer": 11, + "options": 3 } }, "operations": [], @@ -4879,7 +4881,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ada9aa46394801d54e23b886528b98b609d8fda2ed46a2eb9e365575ee73ddf3a?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ada9aa46394801d54e23b886528b98b609d8fda2ed46a2eb9e365575ee73ddf3a?X-Goog-Signature=redacted", + "x-dfo-trace-id": "6a47e9cde4fb494da9fa8aa1973d2e55" } } }, @@ -4891,7 +4894,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "74cf2f077d1e4218a74b4913461d26d0" }, "body_file": "fetch-spec-entity-dropped.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json index 5725b10..cef8b0b 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:57:50Z" + "recorded_at": "2026-10-21T13:05:35Z" }, "call": [ { @@ -186,7 +186,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "c62c3fdb28e14a459e5111ba626dd898" }, "json": { "schema_version": 1, @@ -258,7 +259,7 @@ } }, "content_version": "cv_7947f7ed828c0b23b8df4c601d463c09", - "prepared_at": "2026-10-21T08:57:51Z", + "prepared_at": "2026-10-21T13:05:36Z", "coverage": { "rows": 2, "dimensions": [ @@ -591,7 +592,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:57:51.201451+00:00" + "confirmed_at": "2026-10-21T13:05:36.077679+00:00" }, "warnings": [], "diagnostics": [ @@ -611,7 +612,7 @@ }, "bytes": 9059, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:51.176503+00:00", + "created_at": "2026-10-21T13:05:36.037061+00:00", "tier": "working", "url": "/api/datasets/spec_1ee5f6648c9e46ddcc806fa0034bb6a8/cv_7947f7ed828c0b23b8df4c601d463c09/files/sha256:3f42e71fd7f6c7dde3c7294e7eb1eb6525ab0748650d41948ba054114025b297" }, @@ -622,7 +623,7 @@ }, "bytes": 5628, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:51.176503+00:00", + "created_at": "2026-10-21T13:05:36.037061+00:00", "tier": "working", "url": "/api/datasets/spec_1ee5f6648c9e46ddcc806fa0034bb6a8/cv_7947f7ed828c0b23b8df4c601d463c09/files/sha256:36616ef68df33904cc9dfa37fb145d8fd1563b1b3701710dcd8d9e04ed50d79a" } @@ -867,7 +868,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:51.176927Z" + "held_until": "2026-11-20T13:05:36.037239Z" } } } @@ -955,7 +956,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "a59d23d595924f7695a10d939638112b" }, "json": { "schema_version": 1, @@ -965,10 +967,10 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "489a2234e7584dfdac5aad7c27819e90", + "trace_id": "a59d23d595924f7695a10d939638112b", "warnings": [], "timing_ms": { - "total": 608, + "total": 674, "by_step": { "coverage": 0 } @@ -981,18 +983,18 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 587, + "total": 652, "by_step": { "validate": 2, - "walk": 65, - "reread_arcs": 0, + "walk": 76, + "reread_arcs": 1, "detect_edits": 0, "resolve_survivors": 0, - "shape": 2, + "shape": 3, "bind": 0, - "where_places": 329, - "materialise": 5, - "answer": 183, + "where_places": 359, + "materialise": 10, + "answer": 200, "options": 1 } }, @@ -4610,7 +4612,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A3f42e71fd7f6c7dde3c7294e7eb1eb6525ab0748650d41948ba054114025b297?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A3f42e71fd7f6c7dde3c7294e7eb1eb6525ab0748650d41948ba054114025b297?X-Goog-Signature=redacted", + "x-dfo-trace-id": "b94e3c7dd2fe45fdb401820e689a9098" } } }, @@ -4622,7 +4625,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "9e5771b287d64ab18a4a6c98c484570a" }, "body_file": "fetch-spec-entity-rebound.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-no-content.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-no-content.json new file mode 100644 index 0000000..02fc32d --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-no-content.json @@ -0,0 +1,879 @@ +{ + "format_version": 1, + "name": "fetch-spec-files-route-no-content", + "description": "A files route that answers a 2xx other than 200 or 302 raises ContractError unexpected_response, with that response's trace id, and the client fetches nothing.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "The files route answers 204 with no location, and the exchanges after it go." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "prepared_at": "2026-10-21T13:05:35Z", + "coverage": { + "rows": 4, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 4 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "head", + "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal, which hold none at the observation period the other members serve in the requested years." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9541, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:35.038218+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + { + "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", + "rendering": { + "statistics": "series" + }, + "bytes": 5741, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:35.038218+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" + } + ], + "series_count": 1, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 4 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T13:05:35.038284Z" + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + "response": { + "status": 204, + "headers": { + "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" + } + } + } + ], + "expect": [ + { + "error": { + "class": "ContractError", + "code": "unexpected_response", + "trace_id": "0911c16fb4824a499926e24a34069b40" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-foreign-artifact-url.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-foreign-artifact-url.json index a6647fe..a03a5ef 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-foreign-artifact-url.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-foreign-artifact-url.json @@ -174,7 +174,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" }, "json": { "schema_version": 1, @@ -248,7 +249,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T08:57:50Z", + "prepared_at": "2026-10-21T13:05:35Z", "coverage": { "rows": 4, "dimensions": [ @@ -581,7 +582,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "head", - "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + "confirmed_at": "2026-10-21T13:05:35.077517+00:00" }, "warnings": [ { @@ -607,7 +608,7 @@ }, "bytes": 9541, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "https://downloads.example.com/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" }, @@ -618,7 +619,7 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "https://downloads.example.com/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } @@ -848,7 +849,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:50.451687Z" + "held_until": "2026-11-20T13:05:35.038284Z" } } } @@ -859,7 +860,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": null + "trace_id": "72492035a830492dba11a29fa89ded8c" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.json index 8c1ac2d..0d57005 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:58:51Z" + "recorded_at": "2026-10-21T13:06:43Z" }, "call": [ { @@ -173,7 +173,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "af873def265e411b9585fc943fb0100c" }, "json": { "schema_version": 1, @@ -245,7 +246,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-21T08:57:19Z", + "prepared_at": "2026-10-21T13:05:05Z", "coverage": { "rows": 30, "dimensions": [ @@ -578,7 +579,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "head", - "confirmed_at": "2026-10-21T08:57:19.628756+00:00" + "confirmed_at": "2026-10-21T13:05:06.336796+00:00" }, "warnings": [], "diagnostics": [ @@ -598,7 +599,7 @@ }, "bytes": 5627, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:58:51.912379+00:00", + "created_at": "2026-10-21T13:06:43.579496+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:f4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104" }, @@ -609,7 +610,7 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } @@ -854,7 +855,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:19.589587Z" + "held_until": "2026-11-20T13:05:06.298810Z" } } } @@ -867,7 +868,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Af4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Af4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104?X-Goog-Signature=redacted", + "x-dfo-trace-id": "25bfaeae90ea43c18f512793a6337084" } } }, @@ -879,7 +881,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "09f4c71dbf614e94af950a8b6b5bf453" }, "body_file": "fetch-spec-frame-layout.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.json index 7ab13ce..b834d70 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:57:52Z" + "recorded_at": "2026-10-21T13:05:39Z" }, "call": [ { @@ -248,7 +248,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "903874dd8766447b9b7a28b1e2b8fe3e" }, "json": { "schema_version": 1, @@ -352,7 +353,7 @@ } }, "content_version": "cv_daec84e443d4e1b37291242d90fc8fa8", - "prepared_at": "2026-10-21T08:57:57Z", + "prepared_at": "2026-10-21T13:05:46Z", "coverage": { "rows": 170, "dimensions": [ @@ -534,7 +535,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:57:57.507793+00:00" + "confirmed_at": "2026-10-21T13:05:46.277911+00:00" }, "warnings": [ { @@ -560,7 +561,7 @@ }, "bytes": 8716, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:57.481612+00:00", + "created_at": "2026-10-21T13:05:46.238607+00:00", "tier": "working", "url": "/api/datasets/spec_f04936b8378cde70bc6289ac1e45ee9b/cv_daec84e443d4e1b37291242d90fc8fa8/files/sha256:5674a67518081e6d1d436a9ba9ebd4cfe59bb8aec561571b3264522dda1d72b0" }, @@ -571,7 +572,7 @@ }, "bytes": 7768, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:57.481612+00:00", + "created_at": "2026-10-21T13:05:46.238607+00:00", "tier": "working", "url": "/api/datasets/spec_f04936b8378cde70bc6289ac1e45ee9b/cv_daec84e443d4e1b37291242d90fc8fa8/files/sha256:78ad78b09dcc0d40e50f5804d66f3399fa6b851ae4b4ac48b27ce5a6f2124ef0" } @@ -822,7 +823,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:57.481991Z" + "held_until": "2026-11-20T13:05:46.238569Z" } } } @@ -948,7 +949,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "b8966b28738645a9b9ec81828c8e7020" }, "json": { "schema_version": 1, @@ -958,10 +960,10 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "2f2da913d19e45f88486a58418e0d588", + "trace_id": "b8966b28738645a9b9ec81828c8e7020", "warnings": [], "timing_ms": { - "total": 1862, + "total": 1831, "by_step": { "coverage": 0 } @@ -974,18 +976,18 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 1841, + "total": 1803, "by_step": { "validate": 0, "walk": 5, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 1818, + "shape": 1776, "bind": 0, "where_places": 0, - "materialise": 11, - "answer": 6, + "materialise": 14, + "answer": 7, "options": 1 } }, @@ -5258,7 +5260,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A5674a67518081e6d1d436a9ba9ebd4cfe59bb8aec561571b3264522dda1d72b0?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A5674a67518081e6d1d436a9ba9ebd4cfe59bb8aec561571b3264522dda1d72b0?X-Goog-Signature=redacted", + "x-dfo-trace-id": "9d519370377a48769040ee79a5811478" } } }, @@ -5270,7 +5273,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "8c33a7114b194f509a8de63b79b0d683" }, "body_file": "fetch-spec-group-narrowed.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json index d804cb2..5e278f1 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:57:59Z" + "recorded_at": "2026-10-21T13:05:48Z" }, "call": [ { @@ -295,7 +295,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "4f36947ae53548928cf48b3ef6375841" }, "json": { "schema_version": 1, @@ -397,7 +398,7 @@ } }, "content_version": "cv_66a0a4a0331d59b519aa1629dade3d99", - "prepared_at": "2026-10-21T08:58:00Z", + "prepared_at": "2026-10-21T13:05:48Z", "coverage": { "rows": 2114, "dimensions": [ @@ -579,7 +580,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:58:00.100626+00:00" + "confirmed_at": "2026-10-21T13:05:48.882315+00:00" }, "warnings": [], "diagnostics": [ @@ -599,7 +600,7 @@ }, "bytes": 21027, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:58:00.074970+00:00", + "created_at": "2026-10-21T13:05:48.852766+00:00", "tier": "working", "url": "/api/datasets/spec_c2f21170dfa9f31705e47ed60c8fa305/cv_66a0a4a0331d59b519aa1629dade3d99/files/sha256:1ea84fd402e660f640baf08b43a6ef4ed031c01b7dc8a781237c1c3006a3f934" }, @@ -610,7 +611,7 @@ }, "bytes": 8093, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:58:00.074970+00:00", + "created_at": "2026-10-21T13:05:48.852766+00:00", "tier": "working", "url": "/api/datasets/spec_c2f21170dfa9f31705e47ed60c8fa305/cv_66a0a4a0331d59b519aa1629dade3d99/files/sha256:b1f80f2d3df16b6cda3831730ee4749b13e1eb3fff82cdf2f479e71f087bfe2b" } @@ -861,7 +862,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:58:00.075319Z" + "held_until": "2026-11-20T13:05:48.852599Z" } } } @@ -985,7 +986,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "4f01e12f49de482f8674fe65b685601f" }, "json": { "schema_version": 1, @@ -995,10 +997,10 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d797c89c55b74aeda65514aff049c68b", + "trace_id": "4f01e12f49de482f8674fe65b685601f", "warnings": [], "timing_ms": { - "total": 994, + "total": 957, "by_step": { "coverage": 0 } @@ -1011,14 +1013,14 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 973, + "total": 937, "by_step": { - "validate": 0, + "validate": 1, "walk": 5, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 955, + "shape": 918, "bind": 0, "where_places": 0, "materialise": 7, @@ -5257,7 +5259,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A1ea84fd402e660f640baf08b43a6ef4ed031c01b7dc8a781237c1c3006a3f934?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A1ea84fd402e660f640baf08b43a6ef4ed031c01b7dc8a781237c1c3006a3f934?X-Goog-Signature=redacted", + "x-dfo-trace-id": "f00d62be1abb42d9ae15319676c66876" } } }, @@ -5269,7 +5272,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "2c16e3201afc4262a3a2219cafc506b4" }, "body_file": "fetch-spec-group-origin-rebound.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json index c4edfa5..3e103c9 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:58:01Z" + "recorded_at": "2026-10-21T13:05:49Z" }, "call": [ { @@ -175,7 +175,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" }, "json": { "schema_version": 1, @@ -249,7 +250,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T08:57:50Z", + "prepared_at": "2026-10-21T13:05:35Z", "coverage": { "rows": 4, "dimensions": [ @@ -582,7 +583,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "head", - "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + "confirmed_at": "2026-10-21T13:05:35.077517+00:00" }, "warnings": [ { @@ -608,7 +609,7 @@ }, "bytes": 9541, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" }, @@ -619,7 +620,7 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } @@ -849,7 +850,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:50.451687Z" + "held_until": "2026-11-20T13:05:35.038284Z" } } } @@ -862,7 +863,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", + "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" } } }, @@ -874,7 +876,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" }, "body_file": "fetch-spec-known-sentence.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json index f6083d2..8d5f10f 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json @@ -174,7 +174,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" }, "json": { "schema_version": 1, @@ -183,7 +184,7 @@ "spec_id": "spec_cb5baa4161de718f18583060674dbca6" }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T08:57:50Z", + "prepared_at": "2026-10-21T13:05:35Z", "coverage": { "rows": 4, "dimensions": [ @@ -516,7 +517,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "head", - "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + "confirmed_at": "2026-10-21T13:05:35.077517+00:00" }, "warnings": [ { @@ -542,7 +543,7 @@ }, "bytes": 9541, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" }, @@ -553,7 +554,7 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } @@ -783,7 +784,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:50.451687Z" + "held_until": "2026-11-20T13:05:35.038284Z" } } } @@ -794,7 +795,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": null + "trace_id": "72492035a830492dba11a29fa89ded8c" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.json index bc8d9b8..f1f0924 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:57:46Z" + "recorded_at": "2026-10-21T13:05:30Z" }, "call": [ { @@ -182,7 +182,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "a72e52f677934a84bf84cdaee5c6c696" }, "json": { "schema_version": 1, @@ -256,7 +257,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T08:57:50Z", + "prepared_at": "2026-10-21T13:05:35Z", "coverage": { "rows": 4, "dimensions": [ @@ -589,7 +590,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + "confirmed_at": "2026-10-21T13:05:35.077517+00:00" }, "warnings": [ { @@ -615,7 +616,7 @@ }, "bytes": 9541, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" }, @@ -626,7 +627,7 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } @@ -856,7 +857,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:50.451687Z" + "held_until": "2026-11-20T13:05:35.038284Z" } } } @@ -946,7 +947,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "e7b9afd7f94f41eb85716597d0432612" }, "json": { "schema_version": 1, @@ -956,10 +958,10 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "63d251bca9014713ba8769cd3719b880", + "trace_id": "e7b9afd7f94f41eb85716597d0432612", "warnings": [], "timing_ms": { - "total": 104, + "total": 145, "by_step": { "coverage": 0 } @@ -972,18 +974,18 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 83, + "total": 110, "by_step": { - "validate": 2, - "walk": 65, - "reread_arcs": 0, + "validate": 3, + "walk": 81, + "reread_arcs": 2, "detect_edits": 0, "resolve_survivors": 0, - "shape": 1, - "bind": 1, + "shape": 3, + "bind": 0, "where_places": 0, - "materialise": 4, - "answer": 9, + "materialise": 5, + "answer": 15, "options": 1 } }, @@ -4586,7 +4588,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", + "x-dfo-trace-id": "bcb796babc2947ada1b42afa03a19f2a" } } }, @@ -4598,7 +4601,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "a340dab2e965428fa1b99507c6d6dbd4" }, "body_file": "fetch-spec-narrowed.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-operation-failed-resubmitted.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-operation-failed-resubmitted.json index a2565da..bb6f561 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-operation-failed-resubmitted.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-operation-failed-resubmitted.json @@ -148,7 +148,8 @@ "headers": { "content-type": "application/json", "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" }, "json": { "operation": { @@ -169,7 +170,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "621bdcc038e34f44bec226434f3f7378" }, "json": { "operation": { @@ -267,7 +269,8 @@ "headers": { "content-type": "application/json", "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" }, "json": { "operation": { @@ -288,7 +291,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "621bdcc038e34f44bec226434f3f7378" }, "json": { "operation": { @@ -313,7 +317,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "1df7b03572044eedaa412f6d2ad6b91f" }, "json": { "operation": { @@ -338,7 +343,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "b5b2e2d98a4047be98aea852117381c7" }, "json": { "operation": { @@ -363,14 +369,15 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "686111d592f3451e8c55691d91a66663" }, "json": { "operation": { "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "status": "running", "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 1516, + "retry_after_ms": 1517, "progress": { "rows_written": 0, "estimate_rows": 108798 @@ -388,7 +395,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "9acc0caab7e143d38b3ecbfbcd225707" }, "json": { "operation": { @@ -397,7 +405,7 @@ "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "retry_after_ms": 1900, "progress": { - "rows_written": 14493, + "rows_written": 16734, "estimate_rows": 108798 } } @@ -413,7 +421,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "3" + "retry-after": "3", + "x-dfo-trace-id": "22c08bbaa1384833bd92f8dd9cc6312d" }, "json": { "operation": { @@ -422,7 +431,7 @@ "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "retry_after_ms": 2377, "progress": { - "rows_written": 41372, + "rows_written": 64341, "estimate_rows": 108798 } } @@ -438,16 +447,17 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "3" + "retry-after": "3", + "x-dfo-trace-id": "227de800033b4185ae9b958d3fa2cec7" }, "json": { "operation": { "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "status": "running", "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 2975, + "retry_after_ms": 2973, "progress": { - "rows_written": 75380, + "rows_written": 106324, "estimate_rows": 108798 } } @@ -463,14 +473,15 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "4" + "retry-after": "4", + "x-dfo-trace-id": "3197d4d8b5094857afb9bbd14c49fcb0" }, "json": { "operation": { "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "status": "running", "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 3755, + "retry_after_ms": 3719, "progress": { "rows_written": 108798, "estimate_rows": 108798 @@ -487,7 +498,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "29f271852cc04f1a8b287274f53105b6" }, "json": { "operation": { @@ -552,7 +564,7 @@ } }, "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "prepared_at": "2026-10-21T08:58:24Z", + "prepared_at": "2026-10-21T13:06:08Z", "coverage": { "rows": 108798, "dimensions": [ @@ -734,7 +746,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:58:25.535416+00:00" + "confirmed_at": "2026-10-21T13:06:09.616741+00:00" }, "warnings": [], "diagnostics": [ @@ -754,7 +766,7 @@ }, "bytes": 913395, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:58:25.500374+00:00", + "created_at": "2026-10-21T13:06:09.573990+00:00", "tier": "working", "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" }, @@ -765,7 +777,7 @@ }, "bytes": 967921, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:58:25.500374+00:00", + "created_at": "2026-10-21T13:06:09.573990+00:00", "tier": "working", "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" } @@ -1236,7 +1248,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:58:25.500506Z" + "held_until": "2026-11-20T13:06:09.573841Z" } } } @@ -1250,7 +1262,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted", + "x-dfo-trace-id": "155fa981459c464482aea52657f99e8b" } } }, @@ -1262,7 +1275,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "228feaabf1f3473cad055088084dc378" }, "body_file": "mint-async-build.parquet" } @@ -1313,11 +1327,11 @@ 1.5, 1.5, 1.5, - 1.516, + 1.517, 1.9, 2.377, - 2.975, - 3.755 + 2.973, + 3.719 ], "resubmissions": 1 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json index 72285d3..ad8f98a 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json @@ -148,7 +148,8 @@ "headers": { "content-type": "application/json", "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" }, "json": { "operation": { diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited.json index 9e64240..91b20d9 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited.json @@ -148,7 +148,8 @@ "headers": { "content-type": "application/json", "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" }, "json": { "operation": { @@ -181,7 +182,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "621bdcc038e34f44bec226434f3f7378" }, "json": { "operation": { @@ -206,7 +208,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "1df7b03572044eedaa412f6d2ad6b91f" }, "json": { "operation": { @@ -231,7 +234,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "b5b2e2d98a4047be98aea852117381c7" }, "json": { "operation": { @@ -256,14 +260,15 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "686111d592f3451e8c55691d91a66663" }, "json": { "operation": { "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "status": "running", "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 1516, + "retry_after_ms": 1517, "progress": { "rows_written": 0, "estimate_rows": 108798 @@ -281,7 +286,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "9acc0caab7e143d38b3ecbfbcd225707" }, "json": { "operation": { @@ -290,7 +296,7 @@ "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "retry_after_ms": 1900, "progress": { - "rows_written": 14493, + "rows_written": 16734, "estimate_rows": 108798 } } @@ -306,7 +312,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "3" + "retry-after": "3", + "x-dfo-trace-id": "22c08bbaa1384833bd92f8dd9cc6312d" }, "json": { "operation": { @@ -315,7 +322,7 @@ "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "retry_after_ms": 2377, "progress": { - "rows_written": 41372, + "rows_written": 64341, "estimate_rows": 108798 } } @@ -331,16 +338,17 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "3" + "retry-after": "3", + "x-dfo-trace-id": "227de800033b4185ae9b958d3fa2cec7" }, "json": { "operation": { "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "status": "running", "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 2975, + "retry_after_ms": 2973, "progress": { - "rows_written": 75380, + "rows_written": 106324, "estimate_rows": 108798 } } @@ -356,14 +364,15 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "4" + "retry-after": "4", + "x-dfo-trace-id": "3197d4d8b5094857afb9bbd14c49fcb0" }, "json": { "operation": { "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "status": "running", "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 3755, + "retry_after_ms": 3719, "progress": { "rows_written": 108798, "estimate_rows": 108798 @@ -380,7 +389,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "29f271852cc04f1a8b287274f53105b6" }, "json": { "operation": { @@ -445,7 +455,7 @@ } }, "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "prepared_at": "2026-10-21T08:58:24Z", + "prepared_at": "2026-10-21T13:06:08Z", "coverage": { "rows": 108798, "dimensions": [ @@ -627,7 +637,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:58:25.535416+00:00" + "confirmed_at": "2026-10-21T13:06:09.616741+00:00" }, "warnings": [], "diagnostics": [ @@ -647,7 +657,7 @@ }, "bytes": 913395, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:58:25.500374+00:00", + "created_at": "2026-10-21T13:06:09.573990+00:00", "tier": "working", "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" }, @@ -658,7 +668,7 @@ }, "bytes": 967921, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:58:25.500374+00:00", + "created_at": "2026-10-21T13:06:09.573990+00:00", "tier": "working", "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" } @@ -1129,7 +1139,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:58:25.500506Z" + "held_until": "2026-11-20T13:06:09.573841Z" } } } @@ -1143,7 +1153,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted", + "x-dfo-trace-id": "155fa981459c464482aea52657f99e8b" } } }, @@ -1155,7 +1166,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "228feaabf1f3473cad055088084dc378" }, "body_file": "mint-async-build.parquet" } @@ -1206,11 +1218,11 @@ 1.5, 1.5, 1.5, - 1.516, + 1.517, 1.9, 2.377, - 2.975, - 3.755 + 2.973, + 3.719 ], "resubmissions": 0 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-backoff.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-backoff.json new file mode 100644 index 0000000..3ff38ef --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-backoff.json @@ -0,0 +1,1225 @@ +{ + "format_version": 1, + "name": "fetch-spec-poll-refused-backoff", + "description": "With no pacing from the server, each poll waits the next step of the 1, 2, 4, 8 second backoff, and a refused poll uses a step too: the poll after the 503 waits 4 seconds.", + "origin": { + "kind": "synthetic", + "derived_from": "mint-async-build", + "edit": "As fetch-spec-async-build, with no Retry-After and no retry_after_ms on any response, and a 503 service_unavailable with no Retry-After answering the second poll." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + }, + "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 202, + "headers": { + "content-type": "application/json", + "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "pending", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "621bdcc038e34f44bec226434f3f7378" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 503, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/service_unavailable", + "title": "Service Unavailable", + "status": 503, + "detail": "The service is busy.", + "code": "service_unavailable", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": true + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "1df7b03572044eedaa412f6d2ad6b91f" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "b5b2e2d98a4047be98aea852117381c7" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "686111d592f3451e8c55691d91a66663" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "9acc0caab7e143d38b3ecbfbcd225707" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "progress": { + "rows_written": 16734, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "22c08bbaa1384833bd92f8dd9cc6312d" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "progress": { + "rows_written": 64341, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "227de800033b4185ae9b958d3fa2cec7" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "progress": { + "rows_written": 106324, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "3197d4d8b5094857afb9bbd14c49fcb0" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "progress": { + "rows_written": 108798, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "29f271852cc04f1a8b287274f53105b6" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "done" + }, + "manifest": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "ref": "DAC2aAidType206", + "state": "value" + }, + "property": "dac2aAidType" + }, + { + "binding": { + "state": "unbound" + }, + "property": "dacTypeOfFinance" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "facets": { + "provenance": { + "ref": "provenance/OECDDAC2A", + "state": "value" + } + }, + "entities": {}, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2024, + "start_year": 2018 + } + } + }, + "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", + "prepared_at": "2026-10-21T13:06:08Z", + "coverage": { + "rows": 108798, + "dimensions": [ + { + "label": "financingProvider", + "count": 172, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 238, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 7 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 2018 + } + }, + "citation": { + "text": "OECD DAC2A (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=dac2a&pg=0&snb=1&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_DAC2%40DF_DAC2A&df[ag]=OECD.DCD.FSD&df[vs]=1.6&dq=.DPGC.206.USD.Q&lom=LASTNPERIODS&lo=5&to[TIME_PERIOD]=false&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "DAC2A is the OECD Development Assistance Committee's table of ODA disbursements by donor and recipient country or region. It covers bilateral donors and multilateral agencies reporting their own outflows, and includes the OECD's estimate of each donor's core multilateral contributions attributed to recipients.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip", + "attribution": "OECD (2026), OECD DAC2A, OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip (accessed on 2026-10-12)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1960-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The OECD publishes DAC2A in April, June, September and December. The complete table is downloaded from the OECD each time it is republished, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets. The totals DAC2A reports for groups of providers, such as all DAC countries, and for groups of recipients, such as regions and income groups, are included as providers and recipients of their own. Where two provider codes name the same organisation and report the same figures, the figures are counted once. Where two recipient codes name the same organisation, such as IDA and IDA's Multilateral Debt Relief Initiative, their flows are added." + }, + { + "transformation": "Select figures", + "description": "Only figures in current US dollars are included, not constant US dollars. Only flows to recipients on Part I of the DAC List are included: the developing countries, and the multilateral organisations DAC2A reports as recipients, such as development banks and UN agencies. Flows to Part II recipients, the countries in transition, are excluded." + }, + { + "transformation": "Convert to whole units", + "description": "DAC2A reports amounts in millions, which are converted to whole units. ODA per person and ODA as a share of GNI are kept as reported." + }, + { + "transformation": "Select dimensions", + "description": "Each figure is reported by year, provider, recipient and type of aid, such as grants, repayments, interest received, or debt forgiven or rescheduled. DAC2A is a table of disbursements, so every figure, repayments and interest included, is recorded as a disbursement. Figures are marked as gross or net, except where DAC2A does not say which, and as grants or non-grants where the type of aid is wholly one or the other. Imputed multilateral ODA, the OECD's estimate of each provider's share of multilateral organisations' ODA, is marked as modelled. ODA as a share of GNI records the recipient's GNI as its denominator, and ODA per person records the recipient's population." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "ODA disbursements by donor and recipient country or region, including the OECD's imputed multilateral contributions, and ODA per person and as a share of recipient GNI." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDDAC2A", + "axis": "provenance", + "basis": "bound", + "default_policy": null, + "selection_reason": null, + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": null + }, + { + "ref": null, + "axis": "measurementMethod", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 2018 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDDAC2A", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 108798 + } + ], + "family_member_count": 1, + "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "materialise", + "confirmed_at": "2026-10-21T13:06:09.616741+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 913395, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:06:09.573990+00:00", + "tier": "working", + "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + }, + { + "artifact_digest": "sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93", + "rendering": { + "statistics": "series" + }, + "bytes": 967921, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:06:09.573990+00:00", + "tier": "working", + "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" + } + ], + "series_count": 21017, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 172 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 238 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 7 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 172, + "covered": 50 + }, + "missing": [ + { + "ref": "AdaptationFund", + "label": "Adaptation Fund" + }, + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentBankGroup", + "label": "African Development Bank Group" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AndrewCarnegieFoundation", + "label": "Andrew Carnegie Foundation" + }, + { + "ref": "ArabFundForEconomicAndSocialDevelopment", + "label": "Arab Fund for Economic and Social Development" + }, + { + "ref": "Arcadia", + "label": "Arcadia" + }, + { + "ref": "ArcusFoundation", + "label": "Arcus Foundation" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianInfrastructureInvestmentBank", + "label": "Asian Infrastructure Investment Bank" + } + ], + "truncated": true + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 172, + "covered": 50 + }, + "missing": [ + { + "ref": "AdaptationFund", + "label": "Adaptation Fund" + }, + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentBankGroup", + "label": "African Development Bank Group" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AndrewCarnegieFoundation", + "label": "Andrew Carnegie Foundation" + }, + { + "ref": "ArabFundForEconomicAndSocialDevelopment", + "label": "Arab Fund for Economic and Social Development" + }, + { + "ref": "Arcadia", + "label": "Arcadia" + }, + { + "ref": "ArcusFoundation", + "label": "Arcus Foundation" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianInfrastructureInvestmentBank", + "label": "Asian Infrastructure Investment Bank" + } + ], + "truncated": true + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 238, + "covered": 143 + }, + "missing": [ + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianDevelopmentBankSpecialFunds", + "label": "Asian Development Bank Special Funds" + }, + { + "ref": "CaribbeanDevelopmentBank", + "label": "Caribbean Development Bank" + }, + { + "ref": "CentralAmericanBankForEconomicIntegration", + "label": "Central American Bank for Economic Integration" + }, + { + "ref": "DACACPCountries", + "label": "ACP countries (DAC)" + }, + { + "ref": "DACAfrica", + "label": "Africa (DAC)" + }, + { + "ref": "DACAfricaUnallocated", + "label": "Africa, unallocated by country (DAC)" + }, + { + "ref": "DACAllMultilateralRecipients", + "label": "all multilateral recipients (DAC)" + } + ], + "truncated": true + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 238, + "covered": 141 + }, + "missing": [ + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianDevelopmentBankSpecialFunds", + "label": "Asian Development Bank Special Funds" + }, + { + "ref": "CaribbeanDevelopmentBank", + "label": "Caribbean Development Bank" + }, + { + "ref": "CentralAmericanBankForEconomicIntegration", + "label": "Central American Bank for Economic Integration" + }, + { + "ref": "DACACPCountries", + "label": "ACP countries (DAC)" + }, + { + "ref": "DACAfrica", + "label": "Africa (DAC)" + }, + { + "ref": "DACAfricaUnallocated", + "label": "Africa, unallocated by country (DAC)" + }, + { + "ref": "DACAllMultilateralRecipients", + "label": "all multilateral recipients (DAC)" + } + ], + "truncated": true + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "financingProvider", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 7 + } + ] + }, + { + "index": "financingProvider", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 238 + } + ] + }, + { + "index": "financingRecipient", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 7 + } + ] + }, + { + "index": "financingRecipient", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 172 + } + ] + }, + { + "index": "time_period", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 238 + } + ] + }, + { + "index": "time_period", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 172 + } + ] + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T13:06:09.573841Z" + } + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted", + "x-dfo-trace-id": "155fa981459c464482aea52657f99e8b" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "228feaabf1f3473cad055088084dc378" + }, + "body_file": "mint-async-build.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 108798, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "dac2aAidType", + "dac2aAidType_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", + "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + } + ], + "missing": [], + "long_builds": [ + { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll_waits": [ + 1.0, + 2.0, + 4.0, + 8.0, + 8.0, + 8.0, + 8.0, + 8.0, + 8.0, + 8.0 + ], + "resubmissions": 0 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-retry-after.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-retry-after.json new file mode 100644 index 0000000..4fe3f7e --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-retry-after.json @@ -0,0 +1,1244 @@ +{ + "format_version": 1, + "name": "fetch-spec-poll-refused-retry-after", + "description": "The poll after a refused poll waits the refusal's Retry-After whatever its status, as a 429's, and the polls after it keep the server's pacing.", + "origin": { + "kind": "synthetic", + "derived_from": "mint-async-build", + "edit": "As fetch-spec-async-build, with a 503 service_unavailable and Retry-After 5 answering the first poll." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + }, + "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 202, + "headers": { + "content-type": "application/json", + "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry-after": "2", + "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "pending", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500 + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 503, + "headers": { + "content-type": "application/problem+json", + "retry-after": "5" + }, + "json": { + "type": "/codes/service_unavailable", + "title": "Service Unavailable", + "status": 503, + "detail": "The service is busy.", + "code": "service_unavailable", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": true + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2", + "x-dfo-trace-id": "621bdcc038e34f44bec226434f3f7378" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2", + "x-dfo-trace-id": "1df7b03572044eedaa412f6d2ad6b91f" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2", + "x-dfo-trace-id": "b5b2e2d98a4047be98aea852117381c7" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2", + "x-dfo-trace-id": "686111d592f3451e8c55691d91a66663" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1517, + "progress": { + "rows_written": 0, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2", + "x-dfo-trace-id": "9acc0caab7e143d38b3ecbfbcd225707" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1900, + "progress": { + "rows_written": 16734, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "3", + "x-dfo-trace-id": "22c08bbaa1384833bd92f8dd9cc6312d" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 2377, + "progress": { + "rows_written": 64341, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "3", + "x-dfo-trace-id": "227de800033b4185ae9b958d3fa2cec7" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 2973, + "progress": { + "rows_written": 106324, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "4", + "x-dfo-trace-id": "3197d4d8b5094857afb9bbd14c49fcb0" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "running", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 3719, + "progress": { + "rows_written": 108798, + "estimate_rows": 108798 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "29f271852cc04f1a8b287274f53105b6" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "done" + }, + "manifest": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "ref": "DAC2aAidType206", + "state": "value" + }, + "property": "dac2aAidType" + }, + { + "binding": { + "state": "unbound" + }, + "property": "dacTypeOfFinance" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "facets": { + "provenance": { + "ref": "provenance/OECDDAC2A", + "state": "value" + } + }, + "entities": {}, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2024, + "start_year": 2018 + } + } + }, + "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", + "prepared_at": "2026-10-21T13:06:08Z", + "coverage": { + "rows": 108798, + "dimensions": [ + { + "label": "financingProvider", + "count": 172, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 238, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 7 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 2018 + } + }, + "citation": { + "text": "OECD DAC2A (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=dac2a&pg=0&snb=1&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_DAC2%40DF_DAC2A&df[ag]=OECD.DCD.FSD&df[vs]=1.6&dq=.DPGC.206.USD.Q&lom=LASTNPERIODS&lo=5&to[TIME_PERIOD]=false&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "DAC2A is the OECD Development Assistance Committee's table of ODA disbursements by donor and recipient country or region. It covers bilateral donors and multilateral agencies reporting their own outflows, and includes the OECD's estimate of each donor's core multilateral contributions attributed to recipients.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip", + "attribution": "OECD (2026), OECD DAC2A, OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip (accessed on 2026-10-12)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1960-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The OECD publishes DAC2A in April, June, September and December. The complete table is downloaded from the OECD each time it is republished, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets. The totals DAC2A reports for groups of providers, such as all DAC countries, and for groups of recipients, such as regions and income groups, are included as providers and recipients of their own. Where two provider codes name the same organisation and report the same figures, the figures are counted once. Where two recipient codes name the same organisation, such as IDA and IDA's Multilateral Debt Relief Initiative, their flows are added." + }, + { + "transformation": "Select figures", + "description": "Only figures in current US dollars are included, not constant US dollars. Only flows to recipients on Part I of the DAC List are included: the developing countries, and the multilateral organisations DAC2A reports as recipients, such as development banks and UN agencies. Flows to Part II recipients, the countries in transition, are excluded." + }, + { + "transformation": "Convert to whole units", + "description": "DAC2A reports amounts in millions, which are converted to whole units. ODA per person and ODA as a share of GNI are kept as reported." + }, + { + "transformation": "Select dimensions", + "description": "Each figure is reported by year, provider, recipient and type of aid, such as grants, repayments, interest received, or debt forgiven or rescheduled. DAC2A is a table of disbursements, so every figure, repayments and interest included, is recorded as a disbursement. Figures are marked as gross or net, except where DAC2A does not say which, and as grants or non-grants where the type of aid is wholly one or the other. Imputed multilateral ODA, the OECD's estimate of each provider's share of multilateral organisations' ODA, is marked as modelled. ODA as a share of GNI records the recipient's GNI as its denominator, and ODA per person records the recipient's population." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "ODA disbursements by donor and recipient country or region, including the OECD's imputed multilateral contributions, and ODA per person and as a share of recipient GNI." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDDAC2A", + "axis": "provenance", + "basis": "bound", + "default_policy": null, + "selection_reason": null, + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": null + }, + { + "ref": null, + "axis": "measurementMethod", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 2018 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDDAC2A", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 108798 + } + ], + "family_member_count": 1, + "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "materialise", + "confirmed_at": "2026-10-21T13:06:09.616741+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 913395, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:06:09.573990+00:00", + "tier": "working", + "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + }, + { + "artifact_digest": "sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93", + "rendering": { + "statistics": "series" + }, + "bytes": 967921, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:06:09.573990+00:00", + "tier": "working", + "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" + } + ], + "series_count": 21017, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 172 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 238 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 7 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 172, + "covered": 50 + }, + "missing": [ + { + "ref": "AdaptationFund", + "label": "Adaptation Fund" + }, + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentBankGroup", + "label": "African Development Bank Group" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AndrewCarnegieFoundation", + "label": "Andrew Carnegie Foundation" + }, + { + "ref": "ArabFundForEconomicAndSocialDevelopment", + "label": "Arab Fund for Economic and Social Development" + }, + { + "ref": "Arcadia", + "label": "Arcadia" + }, + { + "ref": "ArcusFoundation", + "label": "Arcus Foundation" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianInfrastructureInvestmentBank", + "label": "Asian Infrastructure Investment Bank" + } + ], + "truncated": true + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 172, + "covered": 50 + }, + "missing": [ + { + "ref": "AdaptationFund", + "label": "Adaptation Fund" + }, + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentBankGroup", + "label": "African Development Bank Group" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AndrewCarnegieFoundation", + "label": "Andrew Carnegie Foundation" + }, + { + "ref": "ArabFundForEconomicAndSocialDevelopment", + "label": "Arab Fund for Economic and Social Development" + }, + { + "ref": "Arcadia", + "label": "Arcadia" + }, + { + "ref": "ArcusFoundation", + "label": "Arcus Foundation" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianInfrastructureInvestmentBank", + "label": "Asian Infrastructure Investment Bank" + } + ], + "truncated": true + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 238, + "covered": 143 + }, + "missing": [ + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianDevelopmentBankSpecialFunds", + "label": "Asian Development Bank Special Funds" + }, + { + "ref": "CaribbeanDevelopmentBank", + "label": "Caribbean Development Bank" + }, + { + "ref": "CentralAmericanBankForEconomicIntegration", + "label": "Central American Bank for Economic Integration" + }, + { + "ref": "DACACPCountries", + "label": "ACP countries (DAC)" + }, + { + "ref": "DACAfrica", + "label": "Africa (DAC)" + }, + { + "ref": "DACAfricaUnallocated", + "label": "Africa, unallocated by country (DAC)" + }, + { + "ref": "DACAllMultilateralRecipients", + "label": "all multilateral recipients (DAC)" + } + ], + "truncated": true + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 238, + "covered": 141 + }, + "missing": [ + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianDevelopmentBankSpecialFunds", + "label": "Asian Development Bank Special Funds" + }, + { + "ref": "CaribbeanDevelopmentBank", + "label": "Caribbean Development Bank" + }, + { + "ref": "CentralAmericanBankForEconomicIntegration", + "label": "Central American Bank for Economic Integration" + }, + { + "ref": "DACACPCountries", + "label": "ACP countries (DAC)" + }, + { + "ref": "DACAfrica", + "label": "Africa (DAC)" + }, + { + "ref": "DACAfricaUnallocated", + "label": "Africa, unallocated by country (DAC)" + }, + { + "ref": "DACAllMultilateralRecipients", + "label": "all multilateral recipients (DAC)" + } + ], + "truncated": true + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 238, + "covered": 238 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "financingProvider", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 7 + } + ] + }, + { + "index": "financingProvider", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 238 + } + ] + }, + { + "index": "financingRecipient", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 7 + } + ] + }, + { + "index": "financingRecipient", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 172 + } + ] + }, + { + "index": "time_period", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 238 + } + ] + }, + { + "index": "time_period", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 172 + } + ] + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T13:06:09.573841Z" + } + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted", + "x-dfo-trace-id": "155fa981459c464482aea52657f99e8b" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "228feaabf1f3473cad055088084dc378" + }, + "body_file": "mint-async-build.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 108798, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "dac2aAidType", + "dac2aAidType_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", + "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + } + ], + "missing": [], + "long_builds": [ + { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll_waits": [ + 1.5, + 5.0, + 1.5, + 1.5, + 1.5, + 1.517, + 1.9, + 2.377, + 2.973, + 3.719 + ], + "resubmissions": 0 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused.json index df9163b..4530dea 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused.json @@ -148,7 +148,8 @@ "headers": { "content-type": "application/json", "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" }, "json": { "operation": { @@ -191,7 +192,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "621bdcc038e34f44bec226434f3f7378" }, "json": { "operation": { @@ -216,7 +218,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "1df7b03572044eedaa412f6d2ad6b91f" }, "json": { "operation": { @@ -285,7 +288,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "b5b2e2d98a4047be98aea852117381c7" }, "json": { "operation": { @@ -310,14 +314,15 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "686111d592f3451e8c55691d91a66663" }, "json": { "operation": { "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "status": "running", "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 1516, + "retry_after_ms": 1517, "progress": { "rows_written": 0, "estimate_rows": 108798 @@ -335,7 +340,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "9acc0caab7e143d38b3ecbfbcd225707" }, "json": { "operation": { @@ -344,7 +350,7 @@ "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "retry_after_ms": 1900, "progress": { - "rows_written": 14493, + "rows_written": 16734, "estimate_rows": 108798 } } @@ -360,7 +366,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "3" + "retry-after": "3", + "x-dfo-trace-id": "22c08bbaa1384833bd92f8dd9cc6312d" }, "json": { "operation": { @@ -369,7 +376,7 @@ "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "retry_after_ms": 2377, "progress": { - "rows_written": 41372, + "rows_written": 64341, "estimate_rows": 108798 } } @@ -385,16 +392,17 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "3" + "retry-after": "3", + "x-dfo-trace-id": "227de800033b4185ae9b958d3fa2cec7" }, "json": { "operation": { "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "status": "running", "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 2975, + "retry_after_ms": 2973, "progress": { - "rows_written": 75380, + "rows_written": 106324, "estimate_rows": 108798 } } @@ -410,14 +418,15 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "4" + "retry-after": "4", + "x-dfo-trace-id": "3197d4d8b5094857afb9bbd14c49fcb0" }, "json": { "operation": { "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "status": "running", "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 3755, + "retry_after_ms": 3719, "progress": { "rows_written": 108798, "estimate_rows": 108798 @@ -434,7 +443,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "29f271852cc04f1a8b287274f53105b6" }, "json": { "operation": { @@ -499,7 +509,7 @@ } }, "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "prepared_at": "2026-10-21T08:58:24Z", + "prepared_at": "2026-10-21T13:06:08Z", "coverage": { "rows": 108798, "dimensions": [ @@ -681,7 +691,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:58:25.535416+00:00" + "confirmed_at": "2026-10-21T13:06:09.616741+00:00" }, "warnings": [], "diagnostics": [ @@ -701,7 +711,7 @@ }, "bytes": 913395, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:58:25.500374+00:00", + "created_at": "2026-10-21T13:06:09.573990+00:00", "tier": "working", "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" }, @@ -712,7 +722,7 @@ }, "bytes": 967921, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:58:25.500374+00:00", + "created_at": "2026-10-21T13:06:09.573990+00:00", "tier": "working", "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" } @@ -1183,7 +1193,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:58:25.500506Z" + "held_until": "2026-11-20T13:06:09.573841Z" } } } @@ -1197,7 +1207,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted", + "x-dfo-trace-id": "155fa981459c464482aea52657f99e8b" } } }, @@ -1209,7 +1220,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "228feaabf1f3473cad055088084dc378" }, "body_file": "mint-async-build.parquet" } @@ -1262,11 +1274,11 @@ 1.5, 1.5, 1.5, - 1.516, + 1.517, 1.9, 2.377, - 2.975, - 3.755 + 2.973, + 3.719 ], "resubmissions": 0 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-relative-location.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-relative-location.json index ffb1bb6..ca66cd6 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-relative-location.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-relative-location.json @@ -174,7 +174,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" }, "json": { "schema_version": 1, @@ -248,7 +249,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T08:57:50Z", + "prepared_at": "2026-10-21T13:05:35Z", "coverage": { "rows": 4, "dimensions": [ @@ -581,7 +582,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "head", - "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + "confirmed_at": "2026-10-21T13:05:35.077517+00:00" }, "warnings": [ { @@ -607,7 +608,7 @@ }, "bytes": 9541, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" }, @@ -618,7 +619,7 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } @@ -848,7 +849,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:50.451687Z" + "held_until": "2026-11-20T13:05:35.038284Z" } } } @@ -861,7 +862,8 @@ "response": { "status": 302, "headers": { - "location": "bytes" + "location": "bytes", + "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" } } }, @@ -873,7 +875,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" }, "body_file": "fetch-spec-known-sentence.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json index 3b50acf..010e041 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:58:01Z" + "recorded_at": "2026-10-21T13:05:50Z" }, "call": [ { @@ -181,7 +181,8 @@ "response": { "status": 400, "headers": { - "content-type": "application/problem+json" + "content-type": "application/problem+json", + "x-dfo-trace-id": "b847ea8e841a4560a8ffa3b7f337f361" }, "json": { "type": "/codes/request_invalid", @@ -190,7 +191,7 @@ "detail": "Value error, unknown facet axis/axes: colour", "code": "request_invalid", "pointer": "/input/scope", - "trace_id": "a36e8b07217c4469b8cba617c14c6170", + "trace_id": "b847ea8e841a4560a8ffa3b7f337f361", "capability_version": "dset_88fecfec3c5b89d1", "retryable": false } @@ -202,7 +203,7 @@ "error": { "class": "InvalidRequestError", "code": "request_invalid", - "trace_id": "a36e8b07217c4469b8cba617c14c6170" + "trace_id": "b847ea8e841a4560a8ffa3b7f337f361" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json index dd4cda0..a604bd5 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json @@ -181,7 +181,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "a72e52f677934a84bf84cdaee5c6c696" }, "json": { "schema_version": 1, @@ -255,7 +256,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T08:57:50Z", + "prepared_at": "2026-10-21T13:05:35Z", "coverage": { "rows": 4, "dimensions": [ @@ -588,7 +589,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + "confirmed_at": "2026-10-21T13:05:35.077517+00:00" }, "warnings": [ { @@ -614,7 +615,7 @@ }, "bytes": 9541, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" }, @@ -625,7 +626,7 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } @@ -855,7 +856,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:50.451687Z" + "held_until": "2026-11-20T13:05:35.038284Z" } } } @@ -945,7 +946,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "e7b9afd7f94f41eb85716597d0432612" }, "json": { "schema_version": 1, @@ -955,10 +957,10 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "63d251bca9014713ba8769cd3719b880", + "trace_id": "e7b9afd7f94f41eb85716597d0432612", "warnings": [], "timing_ms": { - "total": 104, + "total": 145, "by_step": { "coverage": 0 } @@ -971,18 +973,18 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 83, + "total": 110, "by_step": { - "validate": 2, - "walk": 65, - "reread_arcs": 0, + "validate": 3, + "walk": 81, + "reread_arcs": 2, "detect_edits": 0, "resolve_survivors": 0, - "shape": 1, - "bind": 1, + "shape": 3, + "bind": 0, "where_places": 0, - "materialise": 4, - "answer": 9, + "materialise": 5, + "answer": 15, "options": 1 } }, @@ -4583,7 +4585,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": null + "trace_id": "e7b9afd7f94f41eb85716597d0432612" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-same-origin-artifact-url.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-same-origin-artifact-url.json index 1ed945b..9750a39 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-same-origin-artifact-url.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-same-origin-artifact-url.json @@ -174,7 +174,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" }, "json": { "schema_version": 1, @@ -248,7 +249,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T08:57:50Z", + "prepared_at": "2026-10-21T13:05:35Z", "coverage": { "rows": 4, "dimensions": [ @@ -581,7 +582,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "head", - "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + "confirmed_at": "2026-10-21T13:05:35.077517+00:00" }, "warnings": [ { @@ -607,7 +608,7 @@ }, "bytes": 9541, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "http://127.0.0.1:19493/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" }, @@ -618,7 +619,7 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "http://127.0.0.1:19493/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } @@ -848,7 +849,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:50.451687Z" + "held_until": "2026-11-20T13:05:35.038284Z" } } } @@ -861,7 +862,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", + "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" } } }, @@ -873,7 +875,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" }, "body_file": "fetch-spec-known-sentence.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-signed-fetch-partial.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-signed-fetch-partial.json new file mode 100644 index 0000000..0b27199 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-signed-fetch-partial.json @@ -0,0 +1,957 @@ +{ + "format_version": 1, + "name": "fetch-spec-signed-fetch-partial", + "description": "A signed fetch that answers anything but 200 is a failed fetch: the client asks the files route once more and fetches again, and the second fetch's 200 gives the dataset.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "The first signed fetch answers 206 with the file's bytes, and the files route is asked again." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "prepared_at": "2026-10-21T13:05:35Z", + "coverage": { + "rows": 4, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 4 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "head", + "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal, which hold none at the observation period the other members serve in the requested years." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9541, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:35.038218+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + { + "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", + "rendering": { + "statistics": "series" + }, + "bytes": 5741, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:35.038218+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" + } + ], + "series_count": 1, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 4 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T13:05:35.038284Z" + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", + "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + }, + "response": { + "status": 206, + "headers": { + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" + }, + "body_file": "fetch-spec-known-sentence.parquet" + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", + "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" + }, + "body_file": "fetch-spec-known-sentence.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 4, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "crsCooperationModality", + "crsCooperationModality_label", + "crsPurpose", + "crsPurpose_label", + "crsTypeOfFinance", + "crsTypeOfFinance_label", + "crsTypeOfFlow", + "crsTypeOfFlow_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + ], + "missing": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json index c8a6696..7f0329e 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json @@ -174,7 +174,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" }, "json": { "schema_version": 1, @@ -248,7 +249,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T08:57:50Z", + "prepared_at": "2026-10-21T13:05:35Z", "coverage": { "rows": 4, "dimensions": [ @@ -581,7 +582,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "head", - "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + "confirmed_at": "2026-10-21T13:05:35.077517+00:00" }, "warnings": [ { @@ -607,7 +608,7 @@ }, "bytes": 9541, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "https://storage.googleapis.com/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" }, @@ -618,7 +619,7 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "https://storage.googleapis.com/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } @@ -848,7 +849,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:50.451687Z" + "held_until": "2026-11-20T13:05:35.038284Z" } } } @@ -859,7 +860,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": null + "trace_id": "72492035a830492dba11a29fa89ded8c" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json index 286a518..d674e42 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json @@ -250,7 +250,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T08:57:50Z", + "prepared_at": "2026-10-21T13:05:35Z", "coverage": { "rows": 4, "dimensions": [ @@ -583,7 +583,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "head", - "confirmed_at": "2026-10-21T08:57:50.475926+00:00" + "confirmed_at": "2026-10-21T13:05:35.077517+00:00" }, "warnings": [ { @@ -609,7 +609,7 @@ }, "bytes": 9541, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" }, @@ -620,7 +620,7 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:50.451120+00:00", + "created_at": "2026-10-21T13:05:35.038218+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } @@ -850,7 +850,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:50.451687Z" + "held_until": "2026-11-20T13:05:35.038284Z" } } } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-strict-info-notice.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-strict-info-notice.json index 4d9ba0a..d552acf 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-strict-info-notice.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-strict-info-notice.json @@ -33,7 +33,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "d09ca5f0ae574410bf93b5d905ea8009" }, "json": { "schema_version": 1, @@ -45,13 +46,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "aa5fbbb0593047b59a36bed2b62cd908", + "trace_id": "d09ca5f0ae574410bf93b5d905ea8009", "warnings": [], "timing_ms": { - "total": 4556, + "total": 5038, "by_step": { "coverage": 0, - "extract": 889 + "extract": 1141 } }, "llm_usage": { @@ -73,20 +74,20 @@ } ], "timing_ms": { - "total": 3505, + "total": 3758, "by_step": { - "recall": 628, + "recall": 694, "shape_arcs": 1, - "shape_probe_coverage": 5, - "shape_probe": 477, - "shape_groups": 22, - "shape_labels": 1, + "shape_probe_coverage": 6, + "shape_probe": 489, + "shape_groups": 16, + "shape_labels": 0, "shape_admission": 1, - "shape": 1283, - "bind": 1188, + "shape": 1365, + "bind": 1248, "materialise": 11, - "answer": 381, - "options": 14 + "answer": 423, + "options": 17 } }, "restatement": { @@ -3769,7 +3770,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "90ec74fce6534d0d8e4142b0e1355782" }, "json": { "schema_version": 1, @@ -3841,7 +3843,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-21T08:57:19Z", + "prepared_at": "2026-10-21T13:05:05Z", "coverage": { "rows": 30, "dimensions": [ @@ -4174,7 +4176,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:57:19.628756+00:00" + "confirmed_at": "2026-10-21T13:05:06.336796+00:00" }, "warnings": [], "diagnostics": [ @@ -4194,7 +4196,7 @@ }, "bytes": 9785, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" }, @@ -4205,7 +4207,7 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:57:19.589654+00:00", + "created_at": "2026-10-21T13:05:06.298931+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } @@ -4450,7 +4452,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:57:19.589587Z" + "held_until": "2026-11-20T13:05:06.298810Z" } } } @@ -4463,7 +4465,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted", + "x-dfo-trace-id": "d14640239a5a4ffa8f113140eb5b23a0" } } }, @@ -4475,7 +4478,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "58cc82a3079f4e4298eb45378fdf10db" }, "body_file": "answer-definite-fetch.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.json b/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.json index 48c39bd..cf3c278 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:58:01Z" + "recorded_at": "2026-10-21T13:05:50Z" }, "call": [ { @@ -152,7 +152,8 @@ "headers": { "content-type": "application/json", "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" }, "json": { "operation": { @@ -173,7 +174,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "621bdcc038e34f44bec226434f3f7378" }, "json": { "operation": { @@ -198,7 +200,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "1df7b03572044eedaa412f6d2ad6b91f" }, "json": { "operation": { @@ -223,7 +226,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "b5b2e2d98a4047be98aea852117381c7" }, "json": { "operation": { @@ -248,14 +252,15 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "686111d592f3451e8c55691d91a66663" }, "json": { "operation": { "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "status": "running", "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 1516, + "retry_after_ms": 1517, "progress": { "rows_written": 0, "estimate_rows": 108798 @@ -273,7 +278,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "9acc0caab7e143d38b3ecbfbcd225707" }, "json": { "operation": { @@ -282,7 +288,7 @@ "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "retry_after_ms": 1900, "progress": { - "rows_written": 14493, + "rows_written": 16734, "estimate_rows": 108798 } } @@ -298,7 +304,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "3" + "retry-after": "3", + "x-dfo-trace-id": "22c08bbaa1384833bd92f8dd9cc6312d" }, "json": { "operation": { @@ -307,7 +314,7 @@ "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "retry_after_ms": 2377, "progress": { - "rows_written": 41372, + "rows_written": 64341, "estimate_rows": 108798 } } @@ -323,16 +330,17 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "3" + "retry-after": "3", + "x-dfo-trace-id": "227de800033b4185ae9b958d3fa2cec7" }, "json": { "operation": { "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "status": "running", "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 2975, + "retry_after_ms": 2973, "progress": { - "rows_written": 75380, + "rows_written": 106324, "estimate_rows": 108798 } } @@ -348,14 +356,15 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "4" + "retry-after": "4", + "x-dfo-trace-id": "3197d4d8b5094857afb9bbd14c49fcb0" }, "json": { "operation": { "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", "status": "running", "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 3755, + "retry_after_ms": 3719, "progress": { "rows_written": 108798, "estimate_rows": 108798 @@ -372,7 +381,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "29f271852cc04f1a8b287274f53105b6" }, "json": { "operation": { @@ -437,7 +447,7 @@ } }, "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "prepared_at": "2026-10-21T08:58:24Z", + "prepared_at": "2026-10-21T13:06:08Z", "coverage": { "rows": 108798, "dimensions": [ @@ -619,7 +629,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:58:25.535416+00:00" + "confirmed_at": "2026-10-21T13:06:09.616741+00:00" }, "warnings": [], "diagnostics": [ @@ -639,7 +649,7 @@ }, "bytes": 913395, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:58:25.500374+00:00", + "created_at": "2026-10-21T13:06:09.573990+00:00", "tier": "working", "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" }, @@ -650,7 +660,7 @@ }, "bytes": 967921, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:58:25.500374+00:00", + "created_at": "2026-10-21T13:06:09.573990+00:00", "tier": "working", "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" } @@ -1121,7 +1131,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:58:25.500506Z" + "held_until": "2026-11-20T13:06:09.573841Z" } } } @@ -1135,7 +1145,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted", + "x-dfo-trace-id": "155fa981459c464482aea52657f99e8b" } } }, @@ -1147,7 +1158,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "228feaabf1f3473cad055088084dc378" }, "body_file": "mint-async-build.parquet" } @@ -1203,11 +1215,11 @@ 1.5, 1.5, 1.5, - 1.516, + 1.517, 1.9, 2.377, - 2.975, - 3.755 + 2.973, + 3.719 ], "resubmissions": 0 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json b/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json index 29fcfc3..587d844 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json @@ -92,7 +92,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "e5ff992e18a94c18866838012ff15862" }, "json": { "schema_version": 1, @@ -116,7 +117,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": null + "trace_id": "e5ff992e18a94c18866838012ff15862" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json b/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json index d4c2725..e4ed5f8 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json @@ -26,7 +26,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "05701162424340a4826f3babe8623497" }, "json": { "operation": { @@ -51,7 +52,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "330e5223958b4f9bb2832079fa1a1bf7" }, "json": { "operation": { @@ -75,7 +77,7 @@ "error": { "class": "ServerError", "code": "operation_failed", - "trace_id": null, + "trace_id": "330e5223958b4f9bb2832079fa1a1bf7", "long_builds": [ { "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.json b/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.json index c45d9bd..6c9afa4 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:58:26Z" + "recorded_at": "2026-10-21T13:06:13Z" }, "call": [ { @@ -27,7 +27,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "05701162424340a4826f3babe8623497" }, "json": { "operation": { @@ -52,7 +53,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "330e5223958b4f9bb2832079fa1a1bf7" }, "json": { "operation": { @@ -77,7 +79,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "0e7e7a314c4e4eb3a93b781968cc2026" }, "json": { "operation": { @@ -102,7 +105,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "d0b0a6aa8f59442bbc225bb043881fbc" }, "json": { "operation": { @@ -127,7 +131,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "a6e1921e93944058a3083758a470bb80" }, "json": { "operation": { @@ -136,7 +141,7 @@ "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", "retry_after_ms": 1518, "progress": { - "rows_written": 2135, + "rows_written": 1876, "estimate_rows": 123015 } } @@ -152,7 +157,8 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2" + "retry-after": "2", + "x-dfo-trace-id": "29c3f42fcb2442d49636e30e36584ced" }, "json": { "operation": { @@ -161,7 +167,7 @@ "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", "retry_after_ms": 1901, "progress": { - "rows_written": 18167, + "rows_written": 16634, "estimate_rows": 123015 } } @@ -177,16 +183,17 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "3" + "retry-after": "3", + "x-dfo-trace-id": "5ae05887ed9e4f10b5771d5af03b45ab" }, "json": { "operation": { "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", "status": "running", "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", - "retry_after_ms": 2379, + "retry_after_ms": 2381, "progress": { - "rows_written": 50948, + "rows_written": 34372, "estimate_rows": 123015 } } @@ -202,16 +209,17 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "3" + "retry-after": "3", + "x-dfo-trace-id": "0bdf8274baba4a90911a519ebcb0a316" }, "json": { "operation": { "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", "status": "running", "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", - "retry_after_ms": 2977, + "retry_after_ms": 2979, "progress": { - "rows_written": 103172, + "rows_written": 64989, "estimate_rows": 123015 } } @@ -227,14 +235,41 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "4" + "retry-after": "4", + "x-dfo-trace-id": "e219ac63111f485a82f419a4257bb933" }, "json": { "operation": { "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", "status": "running", "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", - "retry_after_ms": 3739, + "retry_after_ms": 3729, + "progress": { + "rows_written": 88009, + "estimate_rows": 123015 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "5", + "x-dfo-trace-id": "d81a3a69c6184e75a73cc40c1076576c" + }, + "json": { + "operation": { + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "status": "running", + "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "retry_after_ms": 4696, "progress": { "rows_written": 123015, "estimate_rows": 123015 @@ -251,7 +286,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "babd0944d30042f89412ae971f1e748c" }, "json": { "operation": { @@ -319,7 +355,7 @@ } }, "content_version": "cv_50e17ab9c2e732f13c48cf2028ac5928", - "prepared_at": "2026-10-21T08:58:45Z", + "prepared_at": "2026-10-21T13:06:37Z", "coverage": { "rows": 123015, "dimensions": [ @@ -501,7 +537,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:58:45.913023+00:00" + "confirmed_at": "2026-10-21T13:06:38.298569+00:00" }, "warnings": [], "diagnostics": [ @@ -521,7 +557,7 @@ }, "bytes": 1031059, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:58:45.884058+00:00", + "created_at": "2026-10-21T13:06:38.266212+00:00", "tier": "working", "url": "/api/datasets/spec_8a4676c4abdf43d105aeff9d4ba9299b/cv_50e17ab9c2e732f13c48cf2028ac5928/files/sha256:cf2a4a97cc0fdfeb74ce021502e58c70d87ae4d67dc061a46fa62bb4f106a192" }, @@ -532,7 +568,7 @@ }, "bytes": 984263, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:58:45.884058+00:00", + "created_at": "2026-10-21T13:06:38.266212+00:00", "tier": "working", "url": "/api/datasets/spec_8a4676c4abdf43d105aeff9d4ba9299b/cv_50e17ab9c2e732f13c48cf2028ac5928/files/sha256:1a9852b1499a841264af878b70b999a25b104804e6ae1825dcfaabd5eab989bd" } @@ -1005,7 +1041,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:58:45.884491Z" + "held_until": "2026-11-20T13:06:38.266048Z" } } } @@ -1085,7 +1121,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "7a2237593d79419a816a8040aee2a734" }, "json": { "schema_version": 1, @@ -1095,10 +1132,10 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "66862f73d51a4f6db9b08fca2b8a83cc", + "trace_id": "7a2237593d79419a816a8040aee2a734", "warnings": [], "timing_ms": { - "total": 2543, + "total": 1680, "by_step": { "coverage": 0 } @@ -1122,18 +1159,18 @@ } ], "timing_ms": { - "total": 2118, + "total": 1217, "by_step": { - "validate": 1, - "walk": 4, + "validate": 0, + "walk": 7, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 1921, + "shape": 1003, "bind": 0, "where_places": 0, - "materialise": 174, - "answer": 4, + "materialise": 188, + "answer": 5, "options": 14 } }, @@ -5751,7 +5788,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Acf2a4a97cc0fdfeb74ce021502e58c70d87ae4d67dc061a46fa62bb4f106a192?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3Acf2a4a97cc0fdfeb74ce021502e58c70d87ae4d67dc061a46fa62bb4f106a192?X-Goog-Signature=redacted", + "x-dfo-trace-id": "3bf6929fd74b42ca953c352829d86745" } } }, @@ -5763,7 +5801,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "e9f4912dd1e54c8491dd021b356724c3" }, "body_file": "operation-resume.parquet" } @@ -5821,9 +5860,10 @@ 1.5, 1.518, 1.901, - 2.379, - 2.977, - 3.739 + 2.381, + 2.979, + 3.729, + 4.696 ], "resubmissions": 0 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/resubmit-candidates-sibling.json b/python/client-contract/src/dfo_client_contract/scenarios/resubmit-candidates-sibling.json index 9977104..22deeff 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/resubmit-candidates-sibling.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/resubmit-candidates-sibling.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:59:21Z" + "recorded_at": "2026-10-21T13:07:14Z" }, "call": [ { @@ -35,7 +35,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "7fc0d6eea9ea4a649201c235973bb649" }, "json": { "schema_version": 1, @@ -47,13 +48,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "163938bcd15346ee811708f11f341f1d", + "trace_id": "7fc0d6eea9ea4a649201c235973bb649", "warnings": [], "timing_ms": { - "total": 4002, + "total": 4462, "by_step": { "coverage": 0, - "extract": 1025 + "extract": 992 } }, "llm_usage": { @@ -69,19 +70,19 @@ "variable_text": "GNI", "warnings": [], "timing_ms": { - "total": 1771, + "total": 1879, "by_step": { - "recall": 2, - "shape_arcs": 3, + "recall": 1, + "shape_arcs": 2, "shape_probe_coverage": 3, - "shape_probe": 204, - "shape_groups": 17, - "shape_labels": 5, - "shape_admission": 1, - "shape": 890, - "bind": 874, + "shape_probe": 255, + "shape_groups": 22, + "shape_labels": 7, + "shape_admission": 0, + "shape": 1035, + "bind": 839, "materialise": 1, - "answer": 4 + "answer": 3 } }, "rendered_sentence": "3 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022.", @@ -2073,19 +2074,19 @@ } ], "timing_ms": { - "total": 2810, + "total": 3302, "by_step": { - "recall": 331, + "recall": 797, "shape_arcs": 1, "shape_probe_coverage": 1, - "shape_probe": 159, - "shape_groups": 27, - "shape_labels": 1, + "shape_probe": 211, + "shape_groups": 24, + "shape_labels": 0, "shape_admission": 0, - "shape": 950, - "bind": 802, - "materialise": 219, - "answer": 508 + "shape": 958, + "bind": 891, + "materialise": 152, + "answer": 504 } }, "rendered_sentence": "2 readings. Total government revenue, in local currency in Germany and Kenya. SDG Global Database · 2015 to 2022. Total bugetary revenue of the central government as a proportion of GDP in Germany and Kenya. SDG Global Database · 2015 to 2022.", @@ -3705,7 +3706,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "4763dc6052244fba8ba9aa7f29e3bb61" }, "json": { "schema_version": 1, @@ -3715,10 +3717,10 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "8be99a7590a54b20958e42ed2490a09b", + "trace_id": "4763dc6052244fba8ba9aa7f29e3bb61", "warnings": [], "timing_ms": { - "total": 218, + "total": 173, "by_step": { "coverage": 0 } @@ -4291,7 +4293,7 @@ "variable_text": "tax revenue", "warnings": [], "timing_ms": { - "total": 4, + "total": 3, "by_step": { "validate": 0, "walk": 0, @@ -4303,7 +4305,7 @@ "where_places": 0, "materialise": 1, "answer": 2, - "options": 1 + "options": 0 } }, "rendered_sentence": "2 readings. Total government revenue, in local currency in Germany and Kenya. SDG Global Database · 2015 to 2022. Total bugetary revenue of the central government as a proportion of GDP in Germany and Kenya. SDG Global Database · 2015 to 2022.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/resubmit-placeholder-without-restatement.json b/python/client-contract/src/dfo_client_contract/scenarios/resubmit-placeholder-without-restatement.json index 09d6ae4..44622b5 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/resubmit-placeholder-without-restatement.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/resubmit-placeholder-without-restatement.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:59:30Z" + "recorded_at": "2026-10-21T13:07:30Z" }, "call": [ { @@ -35,7 +35,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "1516d9564a5a493fa7008b64841ffdc1" }, "json": { "schema_version": 1, @@ -47,13 +48,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "2961e5bd14b94abeba99a744e68b1d02", + "trace_id": "1516d9564a5a493fa7008b64841ffdc1", "warnings": [], "timing_ms": { - "total": 3933, + "total": 4391, "by_step": { "coverage": 0, - "extract": 1117 + "extract": 1887 } }, "llm_usage": { @@ -69,19 +70,19 @@ "variable_text": "GNI", "warnings": [], "timing_ms": { - "total": 1762, + "total": 1770, "by_step": { - "recall": 0, + "recall": 2, "shape_arcs": 2, - "shape_probe_coverage": 4, - "shape_probe": 4, - "shape_groups": 24, - "shape_labels": 6, + "shape_probe_coverage": 8, + "shape_probe": 9, + "shape_groups": 28, + "shape_labels": 8, "shape_admission": 1, - "shape": 840, - "bind": 919, - "materialise": 0, - "answer": 3 + "shape": 852, + "bind": 913, + "materialise": 1, + "answer": 2 } }, "rendered_sentence": "3 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022.", @@ -2073,17 +2074,17 @@ } ], "timing_ms": { - "total": 2809, + "total": 2495, "by_step": { - "recall": 290, + "recall": 0, "shape_arcs": 1, - "shape_probe_coverage": 5, - "shape_probe": 207, - "shape_groups": 2, + "shape_probe_coverage": 51, + "shape_probe": 245, + "shape_groups": 3, "shape_labels": 0, - "shape_admission": 1, - "shape": 1017, - "bind": 1502 + "shape_admission": 0, + "shape": 912, + "bind": 1583 } }, "rendered_sentence": "Could not tell who is giving and who is receiving among \"Germany\" and \"Kenya\". Put \"from\" or \"to\" before a name.", @@ -2573,7 +2574,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "92d259a7691d424b9ec4d329f99e63fa" }, "json": { "schema_version": 1, @@ -2583,10 +2585,10 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "769a9afba9da443b89962d16356a9141", + "trace_id": "92d259a7691d424b9ec4d329f99e63fa", "warnings": [], "timing_ms": { - "total": 4, + "total": 3, "by_step": { "coverage": 0 } @@ -2602,14 +2604,14 @@ "total": 1, "by_step": { "validate": 0, - "walk": 0, + "walk": 1, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, "shape": 0, "bind": 0, "where_places": 0, - "materialise": 1, + "materialise": 0, "answer": 0, "options": 0 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json b/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json index c488590..8ee2ace 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json @@ -29,7 +29,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d" }, "json": [ { @@ -42,13 +43,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "trace_id": "95b872cf11e44fffb92260b2bb583f0d", "warnings": [], "timing_ms": { - "total": 1788, + "total": 1697, "by_step": { "coverage": 0, - "extract": 1353 + "extract": 982 } }, "llm_usage": { @@ -64,9 +65,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 434, + "total": 715, "by_step": { - "recall": 434 + "recall": 715 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -242,7 +243,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": null + "trace_id": "95b872cf11e44fffb92260b2bb583f0d" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json b/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json index ca1d6e6..83f93ab 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:58:54Z" + "recorded_at": "2026-10-21T13:06:46Z" }, "call": [ { @@ -30,7 +30,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d" }, "json": { "schema_version": 1, @@ -42,13 +43,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "trace_id": "95b872cf11e44fffb92260b2bb583f0d", "warnings": [], "timing_ms": { - "total": 1788, + "total": 1697, "by_step": { "coverage": 0, - "extract": 1353 + "extract": 982 } }, "llm_usage": { @@ -64,9 +65,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 434, + "total": 715, "by_step": { - "recall": 434 + "recall": 715 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json index 31f2357..9c1e6d7 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json @@ -54,7 +54,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d" }, "json": { "schema_version": 1, @@ -66,13 +67,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "trace_id": "95b872cf11e44fffb92260b2bb583f0d", "warnings": [], "timing_ms": { - "total": 1788, + "total": 1697, "by_step": { "coverage": 0, - "extract": 1353 + "extract": 982 } }, "llm_usage": { @@ -88,9 +89,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 434, + "total": 715, "by_step": { - "recall": 434 + "recall": 715 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json b/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json index 1e330ac..e993fb6 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json @@ -59,7 +59,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d" }, "json": { "schema_version": 1, @@ -71,13 +72,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "trace_id": "95b872cf11e44fffb92260b2bb583f0d", "warnings": [], "timing_ms": { - "total": 1788, + "total": 1697, "by_step": { "coverage": 0, - "extract": 1353 + "extract": 982 } }, "llm_usage": { @@ -93,9 +94,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 434, + "total": 715, "by_step": { - "recall": 434 + "recall": 715 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-server-warning.json b/python/client-contract/src/dfo_client_contract/scenarios/search-server-warning.json index 200f732..1429b59 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-server-warning.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-server-warning.json @@ -38,6 +38,7 @@ "status": 200, "headers": { "content-type": "application/json", + "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d", "x-dfo-warning": "Search runs on a reduced index while it is rebuilt." }, "json": { @@ -50,13 +51,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "trace_id": "95b872cf11e44fffb92260b2bb583f0d", "warnings": [], "timing_ms": { - "total": 1788, + "total": 1697, "by_step": { "coverage": 0, - "extract": 1353 + "extract": 982 } }, "llm_usage": { @@ -72,9 +73,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 434, + "total": 715, "by_step": { - "recall": 434 + "recall": 715 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -259,6 +260,7 @@ "status": 200, "headers": { "content-type": "application/json", + "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d", "x-dfo-warning": "Search runs on a reduced index while it is rebuilt.", "sunset": "Sat, 01 May 2027 00:00:00 GMT" }, @@ -272,13 +274,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "trace_id": "95b872cf11e44fffb92260b2bb583f0d", "warnings": [], "timing_ms": { - "total": 1788, + "total": 1697, "by_step": { "coverage": 0, - "extract": 1353 + "extract": 982 } }, "llm_usage": { @@ -294,9 +296,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 434, + "total": 715, "by_step": { - "recall": 434 + "recall": 715 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -481,6 +483,7 @@ "status": 200, "headers": { "content-type": "application/json", + "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d", "x-dfo-warning": "Search answers from a cached release.", "deprecation": "@1777593600", "sunset": "Sat, 01 May 2027 00:00:00 GMT" @@ -495,13 +498,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "trace_id": "95b872cf11e44fffb92260b2bb583f0d", "warnings": [], "timing_ms": { - "total": 1788, + "total": 1697, "by_step": { "coverage": 0, - "extract": 1353 + "extract": 982 } }, "llm_usage": { @@ -517,9 +520,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 434, + "total": 715, "by_step": { - "recall": 434 + "recall": 715 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-sunset-warning.json b/python/client-contract/src/dfo_client_contract/scenarios/search-sunset-warning.json index 91b7086..13fe4d0 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-sunset-warning.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-sunset-warning.json @@ -34,6 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", + "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d", "sunset": "Sat, 01 May 2027 00:00:00 GMT" }, "json": { @@ -46,13 +47,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "trace_id": "95b872cf11e44fffb92260b2bb583f0d", "warnings": [], "timing_ms": { - "total": 1788, + "total": 1697, "by_step": { "coverage": 0, - "extract": 1353 + "extract": 982 } }, "llm_usage": { @@ -68,9 +69,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 434, + "total": 715, "by_step": { - "recall": 434 + "recall": 715 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -255,6 +256,7 @@ "status": 200, "headers": { "content-type": "application/json", + "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d", "sunset": "Sat, 01 May 2027 00:00:00 GMT" }, "json": { @@ -267,13 +269,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "c197307ca1cc4364a2f31d7fa99aa616", + "trace_id": "95b872cf11e44fffb92260b2bb583f0d", "warnings": [], "timing_ms": { - "total": 1788, + "total": 1697, "by_step": { "coverage": 0, - "extract": 1353 + "extract": 982 } }, "llm_usage": { @@ -289,9 +291,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 434, + "total": 715, "by_step": { - "recall": 434 + "recall": 715 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json b/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json index f8fe217..58073d3 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:58:56Z" + "recorded_at": "2026-10-21T13:06:48Z" }, "call": [ { @@ -30,7 +30,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "4a421114e5a2429284f5bb99860796e7" }, "json": { "schema_version": 1, @@ -42,13 +43,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "670f1650b70c4616805aa3dd54c4dae8", + "trace_id": "4a421114e5a2429284f5bb99860796e7", "warnings": [], "timing_ms": { - "total": 1333, + "total": 1225, "by_step": { "coverage": 0, - "extract": 1329 + "extract": 1221 } }, "llm_usage": { @@ -219,9 +220,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 2, + "total": 1, "by_step": { - "recall": 2 + "recall": 1 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json b/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json index e20d08e..3d8e984 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json @@ -6,7 +6,7 @@ "kind": "recorded", "base_url": "http://127.0.0.1:19493/api", "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T08:59:08Z" + "recorded_at": "2026-10-21T13:06:59Z" }, "call": [ { @@ -37,7 +37,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "2b349555f60d4b9aa5c17d3f59541531" }, "json": { "schema_version": 1, @@ -49,13 +50,13 @@ }, "diagnostics": { "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "b87a5f3d6ed54104885bb9ca8e8e4a73", + "trace_id": "2b349555f60d4b9aa5c17d3f59541531", "warnings": [], "timing_ms": { - "total": 3381, + "total": 4816, "by_step": { "coverage": 0, - "extract": 1159 + "extract": 1848 } }, "llm_usage": { @@ -82,19 +83,19 @@ } ], "timing_ms": { - "total": 2178, + "total": 2929, "by_step": { - "recall": 383, + "recall": 819, "shape_arcs": 2, - "shape_probe_coverage": 3, - "shape_probe": 253, - "shape_groups": 4, - "shape_labels": 1, + "shape_probe_coverage": 2, + "shape_probe": 201, + "shape_groups": 2, + "shape_labels": 0, "shape_admission": 1, - "shape": 846, - "bind": 918, - "materialise": 19, - "answer": 9, + "shape": 935, + "bind": 1152, + "materialise": 12, + "answer": 8, "options": 3 } }, @@ -3367,7 +3368,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/json" + "content-type": "application/json", + "x-dfo-trace-id": "f0557d404d0d4f34aa2ad0fd2784dfac" }, "json": { "schema_version": 1, @@ -3428,7 +3430,7 @@ } }, "content_version": "cv_534dd4c2bf9bdafc837d51a3ba4bcf3e", - "prepared_at": "2026-10-21T08:59:13Z", + "prepared_at": "2026-10-21T13:07:05Z", "coverage": { "rows": 110, "dimensions": [ @@ -3610,7 +3612,7 @@ "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", "capability_version": "dset_88fecfec3c5b89d1", "served_from": "materialise", - "confirmed_at": "2026-10-21T08:59:13.197667+00:00" + "confirmed_at": "2026-10-21T13:07:05.722653+00:00" }, "warnings": [], "diagnostics": [ @@ -3630,7 +3632,7 @@ }, "bytes": 10828, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:59:13.158978+00:00", + "created_at": "2026-10-21T13:07:05.693889+00:00", "tier": "working", "url": "/api/datasets/spec_7778beed72f8433bb7fde4293acfd175/cv_534dd4c2bf9bdafc837d51a3ba4bcf3e/files/sha256:7ca72626eed07dafebc7eaa78713c1c5a36ef05a19d8da96b723dec80d50317f" }, @@ -3641,7 +3643,7 @@ }, "bytes": 10167, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T08:59:13.158978+00:00", + "created_at": "2026-10-21T13:07:05.693889+00:00", "tier": "working", "url": "/api/datasets/spec_7778beed72f8433bb7fde4293acfd175/cv_534dd4c2bf9bdafc837d51a3ba4bcf3e/files/sha256:5b508be6b46ce8e01315f9c89a1837e17ed7b49d7d2554011cfdba9f32203084" } @@ -3957,7 +3959,7 @@ "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", "retention": { "pinned": false, - "held_until": "2026-11-20T08:59:13.158787Z" + "held_until": "2026-11-20T13:07:05.693915Z" } } } @@ -3970,7 +3972,8 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A7ca72626eed07dafebc7eaa78713c1c5a36ef05a19d8da96b723dec80d50317f?X-Goog-Signature=redacted" + "location": "https://storage.googleapis.com/e2e-working/sha256%3A7ca72626eed07dafebc7eaa78713c1c5a36ef05a19d8da96b723dec80d50317f?X-Goog-Signature=redacted", + "x-dfo-trace-id": "5b1ffba527ed4c2b9ae59df39ceb3482" } } }, @@ -3982,7 +3985,8 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet" + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "b1b959d03f9943679a50cfe0f8e1ad5d" }, "body_file": "search-warning-top5.parquet" } @@ -4005,7 +4009,7 @@ "error": { "class": "SearchWarning", "code": null, - "trace_id": null + "trace_id": "2b349555f60d4b9aa5c17d3f59541531" } }, { diff --git a/tools/capture_client_contract.py b/tools/capture_client_contract.py index f41af4c..88c100f 100644 --- a/tools/capture_client_contract.py +++ b/tools/capture_client_contract.py @@ -75,9 +75,13 @@ FILE_EXPIRED, FILE_GONE, NO_VERSIONS, + POLL_BACKOFF_CAP, + POLL_BACKOFF_FIRST, POLL_PATH, REBUILD_REFUSED, + SIGNED_FETCH_STATUS, STORAGE_ORIGIN, + TRACE_HEADER, VERSION_UNAVAILABLE, Answer, ClientError, @@ -96,6 +100,7 @@ digest_of, download_target, failed_operation, + files_route_unexpected, gap_kinds, header_warnings, held_spec, @@ -359,6 +364,14 @@ def _origin(base_url: str) -> str: return f"{parts.scheme}://{parts.netloc}" +def untraced(headers: Mapping[str, str]) -> bool: + """Whether an API response lacks the TRACE_HEADER header the server sends + on every response but one marked `Cache-Control: public`, which a shared + cache replays and so carries no per-request id.""" + directives = headers.get("cache-control", "").lower().replace(" ", "").split(",") + return TRACE_HEADER not in headers and "public" not in directives + + def _is_json(content_type: str) -> bool: media = content_type.split(";", maxsplit=1)[0].strip() return media == "application/json" or media.endswith("+json") @@ -437,6 +450,12 @@ def _send( ) if not bare and "x-dfo-commit" in response.headers: self.commits.add(response.headers["x-dfo-commit"]) + if not bare and untraced(response.headers): + raise SystemExit( + f"{self.name}: {method} {url} answered {response.status} with no " + f"{TRACE_HEADER} header, which the server sends on every response " + "but a shared-cacheable one" + ) kept = self._keep(response) self.exchanges.append({"request": request, "response": kept}) self._traced(kept, bare=bare) @@ -951,8 +970,9 @@ def _download(self, target: str, digest: str, *, origin: bool = True) -> bytes: base URL. The redirect's location is fetched once, where `download_target` places it; a local app's blob URL on the API's origin stands for the storage URL a - deployment signs. A refused fetch or bytes of another digest ask the - route once more.""" + deployment signs. A files route answering a 2xx other than 200 or 302 + raises ContractError `unexpected_response`; a fetch answering other + than 200, or bytes of another digest, ask the route once more.""" base_url = self.recorder.base_url if origin: route_url = _origin(base_url) + target @@ -971,7 +991,8 @@ def _download(self, target: str, digest: str, *, origin: bool = True) -> bytes: ), ) self._raise_problem(files) - require(files.status == 302, f"the files route answered {files.status}") + if files_route_unexpected(files.status): + raise ClientError("unexpected_response") location = files.headers["location"] kind, at = download_target(base_url, route_url, location) if kind == "origin_path" and at.startswith(LOCAL_BLOB_PREFIX): @@ -981,7 +1002,7 @@ def _download(self, target: str, digest: str, *, origin: bool = True) -> bytes: if kind == "url" else self.recorder.origin("GET", at) ) - if data.status >= 400: + if data.status != SIGNED_FETCH_STATUS: failure = ClientError("download_failed") continue if digest_of(data.body) == digest: @@ -1061,7 +1082,6 @@ def _stored(self, member: dict[str, Any]) -> Member: error=VERSION_UNAVAILABLE, newest_version=newest, trace_id=refusal.trace_id if refusal is not None else None, - traced=True, ) def _stored_file( @@ -2344,6 +2364,48 @@ def _poll_busy(exchanges: list[dict[str, Any]], build: dict[str, Any]) -> None: build["poll_waits"] = [waits[0], waits[0], waits[1], *[waits[2]] * 3, *waits[3:]] +def _unpaced(exchanges: list[dict[str, Any]]) -> None: + """Every response loses its Retry-After and every operation resource its + retry_after_ms, so the client paces its polls by its own backoff.""" + for exchange in exchanges: + response = exchange["response"] + response.get("headers", {}).pop("retry-after", None) + body = response.get("json") + if isinstance(body, dict) and isinstance(body.get("operation"), dict): + body["operation"].pop("retry_after_ms", None) + + +def _poll_busy_unpaced(exchanges: list[dict[str, Any]], build: dict[str, Any]) -> None: + """No response paces the polls, and a 503 with no Retry-After answers the + second poll: every poll waits the next step of the backoff, the one after + the 503 included.""" + _unpaced(exchanges) + first = _poll_index(exchanges) + poll = exchanges[first]["request"] + exchanges.insert(first + 1, _refusal(poll, 503, _BUSY)) + polls = sum(1 for e in exchanges if e["request"] == poll) + build["poll_waits"] = [ + min(POLL_BACKOFF_FIRST * 2**step, POLL_BACKOFF_CAP) for step in range(polls) + ] + + +# The Retry-After of the 503 that answers the first poll in +# `fetch-spec-poll-refused-retry-after`. +BUSY_POLL_RETRY_AFTER = 5 + + +def _poll_busy_retry_after( + exchanges: list[dict[str, Any]], build: dict[str, Any] +) -> None: + """A 503 with Retry-After BUSY_POLL_RETRY_AFTER answers the first poll: + the poll after it waits that long, and the polls after keep the server's + pacing.""" + index = _poll_index(exchanges) + headers = {"retry-after": str(BUSY_POLL_RETRY_AFTER)} + exchanges.insert(index, _refusal(exchanges[index]["request"], 503, _BUSY, headers)) + build["poll_waits"].insert(1, float(BUSY_POLL_RETRY_AFTER)) + + _OPERATION_NOT_FOUND = _problem( "operation_not_found", 404, @@ -2384,6 +2446,78 @@ def _signed_url_refused(parent: dict[str, Any], ctx: Context) -> Derived: return _same(parent, exchanges) +def _signed_index(exchanges: Sequence[dict[str, Any]]) -> int: + return next(i for i, e in enumerate(exchanges) if "url" in e["request"]) + + +def _signed_fetch_partial(parent: dict[str, Any], ctx: Context) -> Derived: + """The first signed fetch answers 206 with the file's bytes, and the files + route is asked again.""" + exchanges = copy.deepcopy(parent["exchanges"]) + index = _signed_index(exchanges) + files, signed = exchanges[index - 1], exchanges[index] + partial = copy.deepcopy(signed) + partial["response"]["status"] = 206 + exchanges[index:index] = [partial, copy.deepcopy(files)] + return _same(parent, exchanges) + + +def _files_route_no_content(parent: dict[str, Any], ctx: Context) -> Derived: + """The files route answers 204 with no location, and the exchanges after + it go.""" + index = _signed_index(parent["exchanges"]) - 1 + exchanges = copy.deepcopy(parent["exchanges"][: index + 1]) + response = exchanges[index]["response"] + response["status"] = 204 + response["headers"] = { + name: value + for name, value in response.get("headers", {}).items() + if name not in {"location", "content-type"} + } + error = ctx.raised("unexpected_response", response) + return Derived( + copy.deepcopy(parent["call"]), + exchanges, + [*copy.deepcopy(parent["expect"][:-1]), error], + ) + + +def _specs_an_object(response: dict[str, Any]) -> None: + """Part 0's candidate specs become an object keyed by index.""" + candidates = response["json"]["parts"][0]["candidates"] + candidates["specs"] = {str(i): s for i, s in enumerate(candidates["specs"])} + + +def _operations_an_object(parent: dict[str, Any], ctx: Context) -> Derived: + """Part 0's operations become the one operation GROWTH, as an object.""" + exchanges = copy.deepcopy(parent["exchanges"]) + part = exchanges[0]["response"]["json"]["parts"][0] + require(part.get("operations") == [], "part 0 has no operation") + part["operations"] = dict(GROWTH) + return _same(parent, exchanges) + + +def _artifact_unlisted(parent: dict[str, Any], ctx: Context) -> Derived: + """The snapshot manifest lists no artifact of the ref's digest, and the + file selector, in the ref member's rendering, redirects to the parent's + signed download.""" + exchanges = copy.deepcopy(parent["exchanges"]) + (member,) = parent["call"][0]["ref"]["members"] + manifest = exchanges[0]["response"]["json"] + digest = member["artifact"]["digest"] + manifest["artifacts"] = [ + a for a in manifest["artifacts"] if a["artifact_digest"] != digest + ] + index = next(i for i, e in enumerate(exchanges) if "origin_path" in e["request"]) + path = selector_path( + member["spec"]["spec_id"], + member["content_version"], + member["artifact"]["rendering"], + ) + exchanges[index]["request"] = {"method": "GET", "path": path} + return _same(parent, exchanges) + + def _deferred(body: dict[str, Any]) -> None: body["parts"][1]["status"] = "deferred" @@ -2458,6 +2592,14 @@ def _without_options(body: Any, ctx: Context) -> Any: return body +def _raises(outcome: Mapping[str, Any], code: str, ctx: Context) -> bool: + """Whether `outcome` is the error a client raises itself with `code`, + whatever trace id it carries.""" + error = outcome.get("error", {}) + wanted = ctx.raised(code)["error"]["class"] + return (error.get("class"), error.get("code")) == (wanted, code) + + def _choice_refused( option: int | str, part: int | str | None = None, *, edit: BodyEdit | None = None ) -> Callable[[dict[str, Any], Context], Derived]: @@ -2531,10 +2673,14 @@ def _unknown_kind(parent: dict[str, Any], ctx: Context) -> Derived: def _partial_nothing_answered(parent: dict[str, Any], ctx: Context) -> Derived: require(parent["expect"][0]["answer"]["specs"] == [], "no part has a reading") + (search,) = parent["exchanges"] return Derived( [*copy.deepcopy(parent["call"]), {"op": "fetch", "partial": True}], copy.deepcopy(parent["exchanges"]), - [*copy.deepcopy(parent["expect"]), ctx.raised("answer_incomplete")], + [ + *copy.deepcopy(parent["expect"]), + ctx.raised("answer_incomplete", search["response"]), + ], ) @@ -2660,7 +2806,9 @@ def _failed_without_error(parent: dict[str, Any], ctx: Context) -> Derived: operation["status"] = "failed" operation.pop("progress", None) poll["response"]["json"] = {"operation": operation} - error, _ = failed_operation(poll["response"]["json"], ctx.actions) + error, _ = failed_operation( + poll["response"]["json"], ctx.actions, poll["response"].get("headers") + ) (build,) = parent["expect"][1]["dataset"]["long_builds"] entry = {**build, "poll_waits": build["poll_waits"][:1], "resubmissions": 0} outcome = with_step_notes( @@ -2832,7 +2980,7 @@ def _choice_without_data_query(parent: dict[str, Any], ctx: Context) -> Derived: parent, ctx ) require( - derived.expect[-1] == ctx.raised("contract_violation"), + _raises(derived.expect[-1], "contract_violation", ctx), "the choice raises ContractError", ) return derived @@ -2933,7 +3081,7 @@ def derive(parent: dict[str, Any], ctx: Context) -> Derived: derived = _choice( choose["option"], choose.get("part"), edit=edit, headers=headers )(parent, ctx) - require(derived.expect[-1] == ctx.raised(code), f"the choice raises {code}") + require(_raises(derived.expect[-1], code, ctx), f"the choice raises {code}") return derived return derive @@ -2971,15 +3119,19 @@ def _manifest_without_identity(parent: dict[str, Any], ctx: Context) -> Derived: def _nested_specs_unchecked(parent: dict[str, Any], ctx: Context) -> Derived: - """Each alternative measure of part 0's spec loses its definition's - identity and its resolved, members no client reads.""" + """Each position that holds a Spec no client reads gets the chosen + answer's spec without resolved and without its definition's identity: + the first answer's no_data flagged_match and alternate_match, and the + chosen spec's resolved.equivalent_readings.""" exchanges = copy.deepcopy(parent["exchanges"]) - resolved = exchanges[0]["response"]["json"]["parts"][0]["spec"]["resolved"] - measures = resolved["alternative_measures"] - require(bool(measures), "part 0's spec has alternative measures") - for measure in measures: - measure["definition"].pop("identity") - measure.pop("resolved", None) + asked, chosen = (e["response"]["json"] for e in exchanges[:2]) + no_data = next(p["no_data"] for p in asked["parts"] if p["status"] == "no_data") + spec = chosen["parts"][0]["spec"] + bare = copy.deepcopy(spec) + del bare["resolved"], bare["definition"]["identity"] + no_data["flagged_match"] = copy.deepcopy(bare) + no_data["alternate_match"] = copy.deepcopy(bare) + spec["resolved"]["equivalent_readings"] = [bare] return _same(parent, exchanges) @@ -3188,6 +3340,16 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: "which hashes to the stored digest.", _expired_file_selector, ), + Synthetic( + "fetch-ref-artifact-unlisted", + "fetch-ref", + "The snapshot manifest's artifacts no longer list the ref's digest, and the file " + "selector redirects to the parent's signed download.", + "A ref member whose digest the snapshot manifest does not list asks the file " + "selector in the ref member's own rendering, and bytes that hash to the stored " + "digest give the dataset.", + _artifact_unlisted, + ), Synthetic( "fetch-spec-async-build", "mint-async-build", @@ -3216,6 +3378,26 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: "refused one waited.", _async_fetch(_poll_busy), ), + Synthetic( + "fetch-spec-poll-refused-backoff", + "mint-async-build", + "As fetch-spec-async-build, with no Retry-After and no retry_after_ms on any " + "response, and a 503 service_unavailable with no Retry-After answering the second " + "poll.", + "With no pacing from the server, each poll waits the next step of the 1, 2, 4, 8 " + "second backoff, and a refused poll uses a step too: the poll after the 503 waits " + "4 seconds.", + _async_fetch(_poll_busy_unpaced), + ), + Synthetic( + "fetch-spec-poll-refused-retry-after", + "mint-async-build", + "As fetch-spec-async-build, with a 503 service_unavailable and Retry-After " + f"{BUSY_POLL_RETRY_AFTER} answering the first poll.", + "The poll after a refused poll waits the refusal's Retry-After whatever its status, " + "as a 429's, and the polls after it keep the server's pacing.", + _async_fetch(_poll_busy_retry_after), + ), Synthetic( "fetch-spec-poll-not-found", "mint-async-build", @@ -3233,6 +3415,25 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: "once more and polls the operation it starts; long_builds counts one resubmission.", _async_fetch(_operation_failed), ), + Synthetic( + "fetch-spec-signed-fetch-partial", + "fetch-spec-known-sentence", + "The first signed fetch answers 206 with the file's bytes, and the files route is " + "asked again.", + "A signed fetch that answers anything but 200 is a failed fetch: the client asks " + "the files route once more and fetches again, and the second fetch's 200 gives " + "the dataset.", + _signed_fetch_partial, + ), + Synthetic( + "fetch-spec-files-route-no-content", + "fetch-spec-known-sentence", + "The files route answers 204 with no location, and the exchanges after it go.", + "A files route that answers a 2xx other than 200 or 302 raises ContractError " + "unexpected_response, with that response's trace id, and the client fetches " + "nothing.", + _files_route_no_content, + ), Synthetic( "fetch-ref-signed-url-refused", "fetch-ref", @@ -3369,14 +3570,34 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: ), Synthetic( "answer-nested-specs-unchecked", - "answer-definite-fetch", - "Each alternative measure of part 0's spec loses its definition's identity and its " - "resolved.", - "A client checks strict members only where a rule reads them, so a spec nested in " - "resolved.alternative_measures may lack them, and the fetch reaches the same " - "dataset.", + "choose-place-one-part", + "The no_data part's flagged_match and alternate_match, and the chosen spec's " + "resolved.equivalent_readings, hold the chosen spec without resolved and without " + "its definition's identity.", + "A client checks strict members only where a rule reads them, so a Spec in " + "no_data.flagged_match, no_data.alternate_match or resolved.equivalent_readings may " + "lack resolved and identity, and the search and the choice reach the same answers.", _nested_specs_unchecked, ), + Synthetic( + "answer-candidate-specs-not-a-list", + "answer-candidates-choose-fetch", + "Part 0's candidates.specs becomes an object keyed by index, and the choice and " + "fetch go.", + "A strict member of a JSON type its schema does not admit raises ContractError " + "contract_violation at its pointer, /parts/0/candidates/specs, as a missing one " + "does.", + _search_ends(_specs_an_object, "contract_violation"), + ), + Synthetic( + "answer-operations-not-a-list", + "answer-definite-fetch", + "Part 0's operations becomes one operation object in place of a list.", + "A member a client reads that no strict pointer names, and that holds a JSON type " + "other than its schema's, reads as absent: the part has no operation, and the " + "fetch issues no SearchWarning and reaches the same dataset.", + _operations_an_object, + ), Synthetic( "answer-empty-parts", "search-place-ambiguous", diff --git a/tools/tests/test_capture_client_contract.py b/tools/tests/test_capture_client_contract.py index 41a734e..51e78e0 100644 --- a/tools/tests/test_capture_client_contract.py +++ b/tools/tests/test_capture_client_contract.py @@ -88,7 +88,14 @@ def test_a_recorder_keeps_bodies_redacts_signed_urls_and_names_the_commit() -> N signed = "https://storage.example/bucket/sha256%3Aab?X-Goog-Algorithm=GOOG4&X-Goog-Signature=f00" replies = [ capture.Response( - 302, {"location": signed, "x-dfo-commit": "a" * 40, "server": "x"}, b"" + 302, + { + "location": signed, + "x-dfo-commit": "a" * 40, + "x-dfo-trace-id": "t" * 32, + "server": "x", + }, + b"", ), capture.Response( 200, {"content-type": "application/vnd.apache.parquet"}, b"PAR1" @@ -110,7 +117,7 @@ def transport(method: str, url: str, **kwargs: Any) -> Any: redacted = "https://storage.example/bucket/sha256%3Aab?X-Goog-Signature=redacted" assert recorder.exchanges[0]["response"] == { "status": 302, - "headers": {"location": redacted}, + "headers": {"location": redacted, "x-dfo-trace-id": "t" * 32}, } assert recorder.exchanges[1]["request"] == {"method": "GET", "url": redacted} assert [e["response"]["body_file"] for e in recorder.exchanges[1:]] == [ @@ -125,6 +132,35 @@ def transport(method: str, url: str, **kwargs: Any) -> Any: assert sent[1:] == [{}, {}] +@pytest.mark.parametrize( + ("headers", "refused"), + [ + ({}, True), + ({"cache-control": "no-store"}, True), + ({"cache-control": "public, max-age=60"}, False), + ({"x-dfo-trace-id": "t" * 32}, False), + ], + ids=["untraced", "untraced-private", "shared-cacheable", "traced"], +) +def test_a_recorder_refuses_an_api_response_without_a_trace_id( + headers: dict[str, str], refused: bool +) -> None: + """The server sends x-dfo-trace-id on every API response but a + shared-cacheable one, so a recording that lacks it would hold an + exchange the server did not make.""" + reply = capture.Response( + 200, {"content-type": "application/json", **headers}, b"{}" + ) + recorder = capture.Recorder( + "some-name", "http://127.0.0.1:8000/api", lambda *_, **__: reply + ) + if refused: + with pytest.raises(SystemExit, match="x-dfo-trace-id"): + recorder.api("GET", "/search/healthz") + else: + assert recorder.api("GET", "/search/healthz").status == 200 + + @pytest.mark.parametrize( ("url", "expected"), [ @@ -278,14 +314,15 @@ def transport(method: str, url: str, **kwargs: Any) -> Any: def test_a_renamed_strict_field_ends_the_call_at_the_build() -> None: record = _load("fetch-renamed-strict-field") - manifest = record["exchanges"][-1]["response"]["json"] + response = record["exchanges"][-1]["response"] + manifest = response["json"] assert "content_version" not in manifest assert "contentVersion" in manifest assert record["expect"][-1] == { "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": None, + "trace_id": response["headers"]["x-dfo-trace-id"], } } diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index bc817e0..747e879 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -407,6 +407,19 @@ def change(doc: Any) -> None: return change +def _diagnostics_trace(doc: Any) -> None: + """Step 1's error carries the answer's diagnostics.trace_id, which no + client reads, in place of its response's header.""" + diagnostics = doc["exchanges"][0]["response"]["json"]["diagnostics"] + doc["expect"][1]["error"]["trace_id"] = diagnostics["trace_id"] + + +def _poll_waits(change: Callable[[list[float]], None]) -> Callable[[Any], None]: + return _set_outcome( + 0, lambda o: change(o["dataset"]["long_builds"][0]["poll_waits"]) + ) + + def _ends_in(error: dict[str, Any], keep: int) -> Callable[[Any], None]: """The record keeps its first `keep` exchanges and expects `error`.""" @@ -1369,8 +1382,10 @@ def change(doc: Any) -> None: ), ( "scenarios/answer-nested-specs-unchecked.json", - _first_part(lambda part: part["spec"].pop("resolved")), - "the step follows no answer", + lambda doc: doc["exchanges"][1]["response"]["json"]["parts"][0]["spec"].pop( + "resolved" + ), + "step 1 expects", ), (_SEARCH, _set_body(0, lambda body: body.update(parts=[])), "step 0 expects"), ( @@ -1433,6 +1448,43 @@ def change(doc: Any) -> None: _first_part(_one_part_query), "the record lacks", ), + ("scenarios/answer-timed-out.json", _diagnostics_trace, "step 1 expects"), + ("scenarios/answer-empty-parts.json", _trace(None), "step 0 expects"), + ( + "scenarios/operation-failed-without-error.json", + _trace(None, 1), + "step 1 expects", + ), + ( + "scenarios/choose-option-two-part-query.json", + _trace(None, 1), + "step 1 expects", + ), + ( + "scenarios/fetch-spec-poll-refused-backoff.json", + _poll_waits(lambda waits: waits.__setitem__(2, waits[1])), + "step 0 expects", + ), + ( + "scenarios/fetch-spec-poll-refused-retry-after.json", + _poll_waits(lambda waits: waits.__setitem__(1, waits[0])), + "step 0 expects", + ), + ( + _FETCH, + lambda doc: doc["exchanges"][2]["response"].update(status=206), + "the record lacks", + ), + ( + _FETCH, + lambda doc: doc["exchanges"][1]["response"].update(status=204), + "the steps never make exchanges 2 to 2", + ), + ( + _FETCH, + lambda doc: doc["exchanges"][1]["response"].update(status=201, json={}), + "the steps never make exchanges 2 to 2", + ), ], ids=[ "strict-pointer-unresolved", @@ -1643,6 +1695,15 @@ def change(doc: Any) -> None: "variable-text-refusal-on-a-named-part", "shared-label-refusal-on-distinct-labels", "two-part-query-refusal-on-a-one-part-query", + "trace-id-read-from-diagnostics", + "body-contract-violation-without-its-trace-id", + "failed-operation-without-its-header-trace-id", + "option-contract-violation-without-its-answer-trace-id", + "refused-poll-repeats-its-backoff-wait", + "refused-poll-retry-after-ignored", + "signed-fetch-206-read-as-the-file", + "files-route-204-read-as-a-redirect", + "files-route-201-read-as-a-redirect", ], ) def test_a_broken_contract_is_reported( @@ -1656,6 +1717,23 @@ def test_a_broken_contract_is_reported( assert any(expected in problem for problem in problems), problems +def test_a_record_that_holds_only_under_its_recorded_host_is_reported( + package_dir: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """The second replay moves the recorded origin a response names to the + replay's own; without the move, the manifest of + fetch-spec-same-origin-artifact-url names a host the replay is not on.""" + monkeypatch.setattr( + validator, "relocated", lambda exchanges, *_: [dict(e) for e in exchanges] + ) + problems = validator.validate() + name = "scenarios/fetch-spec-same-origin-artifact-url.json: replayed under" + assert [p for p in problems if "replayed under" in p] == [ + p for p in problems if p.startswith(name) + ] + assert any(p.startswith(name) for p in problems), problems + + def test_a_retired_code_with_a_row_is_reported(package_dir: Path) -> None: _edit(validator.REGISTRY_PATH, _retire("spec_not_found")) problems = validator.validate() diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index b48f9cf..755576a 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -55,7 +55,8 @@ exchanges, with refusals' error classes and gap kinds from `actions.json` and the class of each error the client raises itself from `client-codes.json`, as `expected_outcomes` derives them, the waits - before each poll included; a dataset's rows, columns and per-part row + before each poll included, under the record's base URL and again under + REPLAY_ORIGIN with the recorded origin a response names moved there; a dataset's rows, columns and per-part row counts are left to the Parquet bodies, and each download hashes to its artifact's digest or the outcome says it does not. Each Search request a record holds posts the input the steps derive: the question, a choice's @@ -93,6 +94,7 @@ import sys from collections.abc import Iterator, Mapping, Sequence from dataclasses import dataclass, field, replace +from functools import partial from pathlib import Path from typing import Any from urllib.parse import urljoin, urlsplit, urlunsplit @@ -857,11 +859,12 @@ def header_warnings( @dataclass class PollPacing: - """The wait before each poll of one long build: the `Retry-After` of a 429 - that refused the last poll, else the last operation resource's - `retry_after_ms`, else the `Retry-After` of the response that carried that - resource, else a backoff that doubles from 1 to 8 seconds and advances - only when it is used.""" + """The wait before each poll of one long build: the `Retry-After` of the + refusal that answered the last poll, whatever its status, else the last + operation resource's `retry_after_ms`, else the `Retry-After` of the + response that carried that resource, else a backoff that doubles from 1 + to 8 seconds and advances one step each time it is used, a poll after a + refusal included.""" paced: float | None = None header: float | None = None @@ -875,8 +878,8 @@ def took(self, operation: Mapping[str, Any], headers: Mapping[str, str]) -> None self.paced = ms / 1000 if number and ms >= 0 else None self.header = retry_after(headers) - def rate_limited(self, headers: Mapping[str, str]) -> None: - """A 429 refused the last poll; it spends no retry.""" + def refused_poll(self, headers: Mapping[str, str]) -> None: + """A refusal the client polls past answered the last poll.""" self.refused = retry_after(headers) def next_wait(self) -> float: @@ -908,14 +911,22 @@ def error_outcome(error: str, code: str | None, **members: Any) -> dict[str, Any VERSION_UNAVAILABLE = "VersionUnavailableError" +class _Unset: + """The type of UNSET.""" + + +# The trace id of an error raised without one, which `read_from` settles. +UNSET = _Unset() + + class ClientError(Exception): """A step ends in an error a client raises. A refusal names its class, the server's code and its trace id, a SearchWarning or DataWarning names the server's warning, departure or operation code, and any other error names a code from `client-codes.json`, whose row gives its class. A VersionUnavailableError also names the newest version, or None, and the - trace id of the refusal that gave its code. `traced` says the trace id is - settled; an error raised without one takes it as `read_from` gives.""" + trace id of the refusal that gave its code. An error raised with no + `trace_id` holds UNSET and takes its id as `read_from` gives.""" def __init__( self, @@ -923,15 +934,13 @@ def __init__( *, error: str | None = None, newest_version: str | None = None, - trace_id: str | None = None, - traced: bool = False, + trace_id: str | None | _Unset = UNSET, ) -> None: super().__init__(f"{error or 'client'} {code}") self.code = code self.error = error self.newest_version = newest_version self.trace_id = trace_id - self.traced = traced or trace_id is not None def error_class(self, client_codes: Mapping[str, Mapping[str, Any]]) -> str: """The error class: the one it names, else its client code's. @@ -956,22 +965,25 @@ def outcome(self, client_codes: Mapping[str, Mapping[str, Any]]) -> dict[str, An ValueError: The code is not a client code of one class. """ error = self.error_class(client_codes) + trace = None if isinstance(self.trace_id, _Unset) else self.trace_id if error == VERSION_UNAVAILABLE: return error_outcome( error, self.code, - trace_id=self.trace_id, + trace_id=trace, newest_version=self.newest_version, ) - return error_outcome(error, self.code, trace_id=self.trace_id) + return error_outcome(error, self.code, trace_id=trace) TRACE_HEADER = "x-dfo-trace-id" def trace_id(body: Any, headers: Mapping[str, str] | None) -> str | None: - """A refusal's trace id: its body's `trace_id`, else its TRACE_HEADER - header, else None.""" + """A response's trace id: the top-level `trace_id` of `body` when it is + an object holding one, a problem document or any other body, else its + TRACE_HEADER header, else None. A Search answer's `diagnostics.trace_id` + is not read.""" found = body.get("trace_id") if isinstance(body, dict) else None if isinstance(found, str) and found: return found @@ -994,7 +1006,6 @@ def refusal_error( code or REFUSAL_WITHOUT_CODE, error=error_class(status, code, actions), trace_id=trace_id(body, headers), - traced=True, ) @@ -1014,12 +1025,11 @@ def refusal_error( def read_from(error: ClientError, trace: str | None) -> ClientError: """`error`, raised on the API response whose trace id is `trace`: an error that describes a response, a RESPONSE_ERRORS code, SearchWarning - or DataWarning, takes `trace` unless it is traced already; an error that + or DataWarning, takes `trace` unless its trace id is settled; an error that describes the caller's input, or a storage-host fetch, keeps null.""" - reads = error.code in RESPONSE_ERRORS or error.error in WARNING_CLASSES - if not error.traced and reads: - error.trace_id = trace - error.traced = True + if isinstance(error.trace_id, _Unset): + reads = error.code in RESPONSE_ERRORS or error.error in WARNING_CLASSES + error.trace_id = trace if reads else None return error @@ -1273,6 +1283,13 @@ def _identity(spec: dict[str, Any], assumptions: Any = None) -> dict[str, Any]: return item +def listed(holder: Mapping[str, Any], name: str) -> list[Any]: + """A member a client reads as a list, and that no strict pointer names: + a member of another type reads as absent, as an empty list.""" + value = holder.get(name) + return value if isinstance(value, list) else [] + + def _echo(part: dict[str, Any], **members: Any) -> dict[str, Any]: """An entry with the members every entry but a parsed one echoes from its part: variable_text, separate when true, and operations when any.""" @@ -1281,8 +1298,8 @@ def _echo(part: dict[str, Any], **members: Any) -> dict[str, Any]: entry: dict[str, Any] = {**members, "variable_text": part["variable_text"]} if part.get("separate") is True: entry["separate"] = True - if part.get("operations"): - entry["operations"] = part["operations"] + if operations := listed(part, "operations"): + entry["operations"] = operations return entry @@ -1294,21 +1311,21 @@ def reading_hints(answer: Answer) -> dict[str, str]: warnings follow. An `info` warning gives nothing.""" hints: dict[str, str] = {} - def notices(warnings: Any) -> None: - for warning in warnings or []: + def notices(warnings: list[Any]) -> None: + for warning in warnings: if warning.get("severity") in SHOWN_SEVERITIES and warning.get("message"): hints.setdefault(f"Note: {warning['message']}", warning["code"]) for part in answer.parts: if part.get("status") != "definite": continue - for operation in part.get("operations") or []: + for operation in listed(part, "operations"): line = f"Not done: {operation['verb']} ({json.dumps(operation['phrase'])})" hints.setdefault(line, operation["verb"]) - for departure in part.get("departures") or []: + for departure in listed(part, "departures"): hints.setdefault(departure["text"], departure["code"]) - notices(part.get("warnings")) - notices(answer.body.get("diagnostics", {}).get("warnings")) + notices(listed(part, "warnings")) + notices(listed(answer.body.get("diagnostics", {}), "warnings")) return hints @@ -1440,6 +1457,42 @@ def _strict_members(strict: dict[str, Any]) -> dict[str, list[str]]: return members +def json_type(value: Any) -> str: + """The JSON type of a parsed value, an integer's as `integer`.""" + if isinstance(value, bool): + return "boolean" + if isinstance(value, int): + return "integer" + for kind, name in ((dict, "object"), (list, "array"), (str, "string")): + if isinstance(value, kind): + return name + return "number" if isinstance(value, float) else "null" + + +def schema_types(openapi: dict[str, Any], schema: Any) -> set[str] | None: + """The JSON types `schema` admits, through `$ref`, `anyOf`, `oneOf` and + `allOf`, with `number` admitting an integer; None when it names none.""" + if not isinstance(schema, dict): + return None + ref = schema.get("$ref") + if isinstance(ref, str) and ref.startswith("#/"): + return schema_types(openapi, _resolve(openapi, ref[1:])) + if "type" in schema: + named = schema["type"] + types = set(named) if isinstance(named, list) else {named} + return types | {"integer"} if "number" in types else types + for keyword in ("anyOf", "oneOf"): + if keyword in schema: + branches = [schema_types(openapi, b) for b in schema[keyword]] + if any(b is None for b in branches): + return None + return set().union(*(b for b in branches if b is not None)) + for branch in schema.get("allOf", []): + if (types := schema_types(openapi, branch)) is not None: + return types + return {"object"} if "properties" in schema else None + + def strict_gaps( openapi: dict[str, Any], members: Mapping[str, Sequence[str]], @@ -1448,8 +1501,9 @@ def strict_gaps( where: str = "", component: str | None = None, ) -> list[str]: - """The strict members `body` lacks or holds as null, read through - `schema`: each component schema it reaches names its own, and a + """The strict members `body` lacks, holds as null, or holds as a JSON + type their schema does not admit, read through `schema`: each component + schema it reaches names its own, and a discriminated union whose discriminator `body` lacks is a gap. The walk goes down only through strict members, the ones a client reads, so a member no client reads, such as a spec's `resolved.equivalent_readings`, @@ -1492,10 +1546,15 @@ def strict_gaps( if isinstance(body, dict): read = members.get(component, ()) if component is not None else () for name, member in schema.get("properties", {}).items(): - if name in body and name in read: - gaps.extend( - strict_gaps(openapi, members, member, body[name], f"{where}/{name}") - ) + if name not in body or name not in read or body[name] is None: + continue + types = schema_types(openapi, member) + if types is not None and json_type(body[name]) not in types: + gaps.append(f"{where}/{name}") + continue + gaps.extend( + strict_gaps(openapi, members, member, body[name], f"{where}/{name}") + ) if isinstance(body, list) and "items" in schema: for index, item in enumerate(body): gaps.extend( @@ -1647,6 +1706,17 @@ def selector_path( # client fetches from, and the query every signed URL in a record carries. STORAGE_ORIGIN = "https://storage.googleapis.com" REDACTED_QUERY = "X-Goog-Signature=redacted" +# The successes a files route answers with the file's `location`; any other +# 2xx raises ContractError `unexpected_response`. A signed fetch that answers +# other than SIGNED_FETCH_STATUS is a failed fetch. +FILES_ROUTE_STATUSES = frozenset({200, 302}) +SIGNED_FETCH_STATUS = 200 + + +def files_route_unexpected(status: int) -> bool: + """Whether a files route's answer is a 2xx other than those of + FILES_ROUTE_STATUSES, which raises ContractError `unexpected_response`.""" + return 200 <= status < 300 and status not in FILES_ROUTE_STATUSES def download_target(base_url: str, route_url: str, location: str) -> tuple[str, str]: @@ -1754,7 +1824,6 @@ def failed_operation( OPERATION_FAILED, error=error_class(500, OPERATION_FAILED, actions), trace_id=trace_id(None, headers), - traced=True, ) return error, retryable(500, None) status = problem.get("status") @@ -1767,7 +1836,7 @@ class LongBuild: """A build the server runs on, followed the way a client polls it. Each wait before a poll is `PollPacing`'s. A 429 poll spends no retry, any other retryable refused poll one of MAX_RETRIES, and any other refused - poll raises. A poll answering a failed operation, retryable by its + poll raises; the poll after a refusal waits as `PollPacing` gives. A poll answering a failed operation, retryable by its error, posts the build again once when the client holds its request; otherwise, and for an operation that failed before the client polled it, the operation's error raises. `entry` is the build's `long_builds` @@ -1826,12 +1895,11 @@ def polled(self, status: int, headers: Mapping[str, str], body: Any) -> bool: error = refusal_error(status, body, self.actions, headers) again = retryable(status, body) if error.code != OPERATION_FAILED: - if status == 429: - self.pacing.rate_limited(headers) - elif again and self.retries < MAX_RETRIES: + if status != 429: + if not again or self.retries >= MAX_RETRIES: + raise error self.retries += 1 - else: - raise error + self.pacing.refused_poll(headers) return False if not again or self.request is None or self.entry["resubmissions"]: raise error @@ -1999,10 +2067,12 @@ def body(self, response: dict[str, Any]) -> bytes: def download(self, target: str, digest: str, *, origin: bool) -> None: """A file through the route that redirects to its signed URL: an `origin_path`, as `artifact_route` places an artifact's `url`, when - `origin`, else a path under the base URL. The client fetches once the URL the route's `location` - names, as `download_target` places it. A refused fetch, or bytes that - do not hash to `digest`, ask the route once more, and a second - failure raises.""" + `origin`, else a path under the base URL. A route answering a 2xx + other than 200 or 302 raises ContractError `unexpected_response`. + The client fetches once the URL the route's `location` names, as + `download_target` places it. A fetch answering other than 200, or + bytes that do not hash to `digest`, ask the route once more, and a + second failure raises.""" failure = ClientError("download_failed") base = urlsplit(self.base_url) route_url = ( @@ -2014,12 +2084,14 @@ def download(self, target: str, digest: str, *, origin: bool) -> None: kind = "origin_path" if origin else "path" exchange = self.call("GET", target, kind=kind) self.acted_on(exchange) + if files_route_unexpected(exchange["response"]["status"]): + raise ClientError("unexpected_response") location = exchange["response"].get("headers", {}).get("location") if not isinstance(location, str): raise _UnfitError(f"the redirect from {target} names no location") fetched, at = download_target(self.base_url, route_url, location) signed = self.call("GET", at, kind=fetched, retries=False)["response"] - if signed["status"] >= 400: + if signed["status"] != SIGNED_FETCH_STATUS: failure = ClientError("download_failed") continue if digest_of(self.body(signed)) == digest: @@ -2207,7 +2279,6 @@ def stored_version(self, member: dict[str, Any]) -> dict[str, Any]: error=VERSION_UNAVAILABLE, newest_version=newest, trace_id=refusal.trace_id if refusal is not None else None, - traced=True, ) def stored_file( @@ -2454,6 +2525,39 @@ def expected_outcomes( return outcomes +# The origin of the second base URL the validator replays each scenario +# under, on a host no record names. +REPLAY_ORIGIN = "https://replay.example.org" + + +def origin_of(url: str) -> str: + parts = urlsplit(url) + return f"{parts.scheme}://{parts.netloc}" + + +def relocated( + exchanges: Sequence[Mapping[str, Any]], recorded: str, origin: str +) -> list[dict[str, Any]]: + """`exchanges` as a replay under a base URL on `origin` serves them: the + `recorded` origin, the one the record's `origin.base_url` names, becomes + `origin` wherever a response names it, in its JSON body and its + headers.""" + + def moved(value: Any) -> Any: + if isinstance(value, str): + return value.replace(recorded, origin) + if isinstance(value, list): + return [moved(item) for item in value] + if isinstance(value, dict): + return {key: moved(item) for key, item in value.items()} + return value + + return [ + {"request": exchange["request"], "response": moved(exchange["response"])} + for exchange in exchanges + ] + + def owns_body_file(name: str, body_file: str) -> bool: """Whether `body_file` is one the scenario `name` writes: `.`, or `-.` for its n-th body.""" @@ -2694,20 +2798,33 @@ def _check_scenarios( proxy_codes, ) ) + replay = partial( + expected_outcomes, + routes=routes, + strict=strict, + actions=actions, + client_codes=client_codes, + body_dir=directory, + ) try: - derived = expected_outcomes( - record, - routes=routes, - base_url=base_url, - strict=strict, - actions=actions, - client_codes=client_codes, - body_dir=directory, - ) + derived = replay(record, base_url=base_url) except ValueError as exc: problems.append(f"scenarios/{file_name}: {exc}") continue problems.extend(_check_expect(file_name, record, derived)) + elsewhere = REPLAY_ORIGIN + urlsplit(base_url).path + exchanges = relocated(record["exchanges"], origin_of(base_url), REPLAY_ORIGIN) + try: + moved = replay({**record, "exchanges": exchanges}, base_url=elsewhere) + except ValueError as exc: + moved = [{"unfit": str(exc)}] + if moved != derived: + problems.append( + f"scenarios/{file_name}: replayed under {elsewhere}, with the " + f"recorded origin replaced by its own, it gives " + f"{json.dumps(moved)[:300]}, not the outcomes it gives under " + f"{base_url}" + ) problems.extend( f"scenarios/{p.name}: no scenario names this body file" From daea49c6149d9792b33958f62f7d27738652a0b1 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Wed, 21 Oct 2026 15:56:18 +0200 Subject: [PATCH 23/39] fix(client-contract): read malformed members through typed accessors, and pin the files route and 429 polls The validator reads every non-strict member through one set of typed accessors, so a member or item of another JSON type reads as absent and no malformed body crashes it. A strict list's items must be objects, and one of another type raises contract_violation at its index pointer. A files route answers 302, which the client follows, or 200, whose body is the file; any other status but a refusal raises unexpected_response. A 429 poll whose problem document says retryable false raises at once. A definite part whose variable_text is absent or empty adds nothing to its member's parts. The validator reports a recorded API response without x-dfo-trace-id unless it is Cache-Control: public, and a body trace_id must be a non-empty string. New scenarios pin a 307 and a 200 from the files route, a non-retryable 429 poll and folded parts without names. 112 scenarios, 31 recorded and 81 synthetic. --- python/client-contract/README.md | 12 +- .../answer-folded-parts-unnamed.json | 15436 ++++++++++++++++ .../fetch-spec-files-route-no-content.json | 2 +- .../fetch-spec-files-route-serves-file.json | 917 + ...h-spec-files-route-temporary-redirect.json | 880 + ...-spec-poll-rate-limited-not-retryable.json | 202 + tools/capture_client_contract.py | 235 +- tools/tests/test_validate_client_contract.py | 76 + tools/validate_client_contract.py | 245 +- 9 files changed, 17844 insertions(+), 161 deletions(-) create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/answer-folded-parts-unnamed.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-serves-file.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-temporary-redirect.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited-not-retryable.json diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 61f464a..4e77c07 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -73,7 +73,7 @@ uv run ty check src/dfo_client_contract ## Strict fields -`strict-fields.json` lists the members a client cannot act without. Each pointer names one property of one component schema, `/components/schemas//properties/`. A `required` entry stays in its schema's `required` list and admits no null, so a client raises `ContractError` when one is missing or null. Every entry is a member some client rule acts on, and a client checks a body only along them: from the body's root it goes down through strict members alone, so a member no client reads goes unchecked, however deep. A `Spec` where no rule reads it, in `resolved.equivalent_readings`, `no_data.flagged_match` or `no_data.alternate_match`, may lack `resolved` or its definition's `identity` and raises nothing, which `answer-nested-specs-unchecked` pins at all three. A strict member that holds a JSON type its schema does not admit raises `ContractError` `contract_violation` at its pointer, as a missing one does, which `answer-candidate-specs-not-a-list` pins with `candidates.specs` as an object. A member a client reads that no strict pointer names, and that holds a JSON type its schema does not admit, reads as absent, which `answer-operations-not-a-list` pins with a definite part's `operations` as an object. An `enums` entry keeps every listed value, the values a client branches on: the answer kinds, the part statuses and the operation statuses. A client still accepts a value no entry lists. +`strict-fields.json` lists the members a client cannot act without. Each pointer names one property of one component schema, `/components/schemas//properties/`. A `required` entry stays in its schema's `required` list and admits no null, so a client raises `ContractError` when one is missing or null. Every entry is a member some client rule acts on, and a client checks a body only along them: from the body's root it goes down through strict members alone, so a member no client reads goes unchecked, however deep. A `Spec` where no rule reads it, in `resolved.equivalent_readings`, `no_data.flagged_match` or `no_data.alternate_match`, may lack `resolved` or its definition's `identity` and raises nothing, which `answer-nested-specs-unchecked` pins at all three. A strict member that holds a JSON type its schema does not admit raises `ContractError` `contract_violation` at its pointer, as a missing one does, which `answer-candidate-specs-not-a-list` pins with `candidates.specs` as an object. Each item of a strict list, `parts`, `candidates.specs` or `artifacts`, must be an object, and an item of another type raises `contract_violation` at its index pointer, such as `/parts/0/candidates/specs/0`. A member a client reads that no strict pointer names, and that holds a JSON type other than the list, object or string its rule reads, reads as absent, and so does every member of a holder that is not an object; an item of another type in such a list reads as absent too. So `no_data.options` as an object or null offers no option, `mentions` as a string mentions nothing, and a `diagnostics` that is not an object holds no `timed_out` and no warnings. `answer-operations-not-a-list` pins a definite part's `operations` as an object. An `enums` entry keeps every listed value, the values a client branches on: the answer kinds, the part statuses and the operation statuses. A client still accepts a value no entry lists. The answer's `kind` and each part's `status` are the discriminators of their unions in the served document. A search response with no `kind` raises `ContractError`, as a part with no `status` does, although the served document gives `kind` a default and leaves it out of `required`. A part `status` a client does not know raises nothing and makes the part an `unknown` gap. An answer `kind` a client does not know raises `ContractError`, because the client cannot read the answer. A Search response body that is not an object, a `resolution` answer whose `parts` is empty, at pointer `/parts`, since the served schema gives it at least one item, a part whose `status` is not a string, at pointer `/parts//status`, and a definite or candidate spec whose `definition.spec_id` differs from its `spec_id` raise `ContractError` `contract_violation`, in a Search response as in a ref; `search-body-not-an-object`, `answer-empty-parts`, `answer-part-status-not-a-string` and `answer-definition-spec-id-mismatch` pin the four. @@ -138,7 +138,7 @@ A step that acts on an earlier result follows one: `choose` follows `search` or An exchange's request names its target in one of three ways. `path` is a path the client composes under the base URL, such as `/search/resolve`. `origin_path` is a root-relative URL the server returned, such as an artifact's `url`, or the path and query of an absolute one on the API's origin, which resolves against the base URL's origin and never against its path. `url` is an absolute URL outside the API, such as the signed storage URL a files route redirects to, which the client fetches with a bare request carrying no client header and no key. `json` holds the request body members that must match; a recorded scenario lists every member the client sent. The response gives `status`, the `headers` a client reads, and a `json` body or a `body_file`, a binary body in `scenarios/`. A scenario's own body files are named `.` and `-.`; a synthetic scenario may instead name a body file its parent names. -A `newest_version` outcome gives the `content_version` the step found, or null. An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a warning's code, which for a `SearchWarning` may be null, or for any other error the client raises itself its code in `client-codes.json`. Every error outcome gives its `trace_id`: a refusal's, as the refusal rules below give it; a failed operation's, its error document's `trace_id`, else the `x-dfo-trace-id` header of the response that carried the failed resource; a `VersionUnavailableError`'s, its first refusal's, or null when nothing refused. An error the client raises itself follows one rule: an error that describes a response carries that response's trace id, and an error that describes the caller's input carries null. The trace id is the one a user quotes to find the fault in the server's logs. The errors that describe a response are `unexpected_response`, `contract_violation` on a body, `answer_declined`, `answer_incomplete`, and a strict fetch's `SearchWarning` or `DataWarning`. A response's trace id is the top-level `trace_id` member of its body when the body is a JSON object holding one, a problem document or any other body, else its `x-dfo-trace-id` header, else null. A Search answer's `diagnostics.trace_id` is not read, and `answer-timed-out` pins the header's winning over a `diagnostics.trace_id` that differs from it. `answer_declined`, `answer_incomplete`, a `SearchWarning`, and a `contract_violation` a choice raises on an option describe the held answer, so they carry the trace id of the Search response that answered it. The errors that describe the caller's input, `choice_invalid`, `invalid_argument` and the key-lookup reasons, carry null, and so do `digest_mismatch` and `download_failed`, which describe a storage-host fetch, and `deadline_exceeded`, `network_error` and `offline`, which describe no response. `search-no-json-body`, `fetch-spec-strict-warning`, `answer-timed-out`, `answer-empty-parts`, `fetch-spec-files-route-no-content` and `choose-option-two-part-query` pin a trace id on an error that describes a response, `operation-failed-without-error` the header of the response that carried a failed resource with no error, and `choose-refused-shared-label` a null one on a choice whose answer's response carries a trace id. A `VersionUnavailableError` also gives `newest_version`, the version the lookup found, or null. A dataset or error outcome of a step that made a long build gives `long_builds`, one entry per build the server ran on, in order: the `operation_id` the client polled last, the `poll_waits` in seconds before each poll, and the number of `resubmissions`. Any outcome of a step that retried a refused request gives `retry_waits`, the seconds before each retry in order, and any outcome of a step whose API responses issued warnings gives `warnings`, their codes from `warning-codes.json` in order. +A `newest_version` outcome gives the `content_version` the step found, or null. An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a warning's code, which for a `SearchWarning` may be null, or for any other error the client raises itself its code in `client-codes.json`. Every error outcome gives its `trace_id`: a refusal's, as the refusal rules below give it; a failed operation's, its error document's `trace_id`, else the `x-dfo-trace-id` header of the response that carried the failed resource; a `VersionUnavailableError`'s, its first refusal's, or null when nothing refused. An error the client raises itself follows one rule: an error that describes a response carries that response's trace id, and an error that describes the caller's input carries null. The trace id is the one a user quotes to find the fault in the server's logs. The errors that describe a response are `unexpected_response`, `contract_violation` on a body, `answer_declined`, `answer_incomplete`, and a strict fetch's `SearchWarning` or `DataWarning`. A response's trace id is the top-level `trace_id` member of its body when the body is a JSON object holding one as a non-empty string, a problem document or any other body, else its `x-dfo-trace-id` header, else null. A Search answer's `diagnostics.trace_id` is not read, and `answer-timed-out` pins the header's winning over a `diagnostics.trace_id` that differs from it. `answer_declined`, `answer_incomplete`, a `SearchWarning`, and a `contract_violation` a choice raises on an option describe the held answer, so they carry the trace id of the Search response that answered it. The errors that describe the caller's input, `choice_invalid`, `invalid_argument` and the key-lookup reasons, carry null, and so do `digest_mismatch` and `download_failed`, which describe a storage-host fetch, and `deadline_exceeded`, `network_error` and `offline`, which describe no response. `search-no-json-body`, `fetch-spec-strict-warning`, `answer-timed-out`, `answer-empty-parts`, `fetch-spec-files-route-no-content` and `choose-option-two-part-query` pin a trace id on an error that describes a response, `operation-failed-without-error` the header of the response that carried a failed resource with no error, and `choose-refused-shared-label` a null one on a choice whose answer's response carries a trace id. A `VersionUnavailableError` also gives `newest_version`, the version the lookup found, or null. A dataset or error outcome of a step that made a long build gives `long_builds`, one entry per build the server ran on, in order: the `operation_id` the client polled last, the `poll_waits` in seconds before each poll, and the number of `resubmissions`. Any outcome of a step that retried a refused request gives `retry_waits`, the seconds before each retry in order, and any outcome of a step whose API responses issued warnings gives `warnings`, their codes from `warning-codes.json` in order. Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry where the retry rules allow one, except on a poll, where the long-build rules count retries, and a record that ends a run of retries while the rules allow another does not fit, since the client makes it, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, each POST carries its body, each build posts the body the rules give for the spec it builds, so the builds' order and spec_ids are checked, each Search request posts the whole body `{"schema_version": 1, "input": ...}` with the input the rules give: the question, a choice's input, or a member's identity, each poll names the operation the client holds, each files route is the one the artifact's `url` names, each signed download is the URL the files route's `location` names, each retry waits the wait the retry rules give, and each response's warning headers issue the warnings the warning rules give. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. @@ -159,7 +159,7 @@ The records also fix these client rules: - A fetch builds each distinct `spec_id` once, in part order, and finishes one member (build, the sentence when the client lacks it, files, download) before the next. - A fetch of a spec posts its narrowing as the build's `input.scope`, and posts no `scope` when it narrows nothing. A mint takes a layout and no narrowing, so it posts no `scope`. `window` posts `{"kind": "range", "start_year", "end_year"}` for a pair of years, or `{"kind": "all"}` or `{"kind": "latest"}`, and `facets` posts each axis as `{"ref": ...}`, and `facets: {}` names no axis and posts no `facets`. The server's `scope.entities` replaces the spec's whole entity binding, so `entities` posts a whole map: the roles the spec's `definition.identity.entities` binds, with each role the caller names replaced by its refs and each role the caller binds to null dropped. Naming `origin` alone on a spec bound to `origin` and `destination` keeps `destination`. A fetch that names no role, `entities: {}` included, posts no `entities`, so a fetch whose narrowing is all empty posts no `scope`; `fetch-spec-empty-narrowing` pins it. - A built `spec_id` that differs from the posted one, or a spec with no sentence, takes its sentence from Search: the client posts the built definition's `identity` as one `dataset_resubmit` identity entry, with the member's first part as `variable_text`, or `"dataset"` when no answer part names it, and checks the answer's `spec_id` equals the built one. The entry's `entity_groups` holds the spec's `resolved.entity_groups` for each role the built identity binds to the same entities as the spec's definition, so a window or facets narrowing keeps every group and a role the narrowing rebound or dropped loses its group. The entry leaves `entity_groups` out when it keeps no group, as for a resumed operation, whose spec the client does not hold. The server reads a role posted without its group as its members, so a narrowed spec of flows to the least developed countries would read "44 recipients" in place of "the 44 Least Developed Countries". -- A dataset of several members puts the `part` column first, then each member's columns in member order, each column once. A column that members hold in different types widens as pyarrow's permissive promotion widens it, and a pair that cannot widen raises `ContractError` `contract_violation`; a member file that already holds a `part` column raises `contract_violation` when members stack. Rows and columns are not derived, so no scenario pins these. The `part` value on a member's rows is the member's `parts` joined by `"; "`, so a member that answers two folded parts reads `"health ODA disbursements; education ODA disbursements"`, or the member's sentence when `parts` is empty. A definite part without `variable_text` adds nothing to its member's `parts`. +- A dataset of several members puts the `part` column first, then each member's columns in member order, each column once. A column that members hold in different types widens as pyarrow's permissive promotion widens it, and a pair that cannot widen raises `ContractError` `contract_violation`; a member file that already holds a `part` column raises `contract_violation` when members stack. Rows and columns are not derived, so no scenario pins these. The `part` value on a member's rows is the member's `parts` joined by `"; "`, so a member that answers two folded parts reads `"health ODA disbursements; education ODA disbursements"`, or the member's sentence when `parts` is empty. A definite part whose `variable_text` is absent or empty adds nothing to its member's `parts`, which `answer-folded-parts-unnamed` pins. - A choice names its part by index, by variable text, or by a word that one gap's options mention, and its option by index or label; a candidate is named by index. A candidate with neither a heading nor a sentence has a null label; no scenario pins it. A label is matched among the options that mention the word the part was named by. With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. - A choice raises `InvalidRequestError` `choice_invalid` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is out of range or matches no label or several. It raises the same when an entry it would post cannot be built: a part with no `variable_text`, or a part of a status the client does not know that has no `restatement`. A chosen option whose `data_query` holds other than one part raises `ContractError`, and so does a chosen option with no `data_query`, in a one-part answer as in a several-part one, before any request. `choose-refused-shared-label`, `choose-refused-part-without-variable-text`, `choose-refused-unknown-status`, `choose-option-two-part-query` and `choose-option-without-data-query` pin these. - Every pick of a candidate asks Search for the picked answer, and no client builds it locally. In a one-part answer the pick posts `dataset_resubmit`, without `raw_query`, with one identity entry: the candidate's identity and `entity_groups`, and the part's `variable_text`, `separate` and `operations` as below. The picked answer, its sentence with any "Assumed: …" clause, and its assumptions are Search's response. A choice of a no_data option in a one-part answer posts the option's `data_query` as the input. @@ -168,7 +168,7 @@ The records also fix these client rules: - A strict fetch raises the manifest's first warning above `info` severity as a `DataWarning` with that warning's code, before the sentence lookup and the download. - An identity resubmit whose answer is not one definite part of the built `spec_id`, with a sentence, raises `ContractError`. - The `frame` layout posts `{"format": "parquet", "bundle": false, "layout": "frame"}` as the build's `options` and downloads the artifact whose rendering's `layout` is `frame`; the `long` layout posts `{"format": "parquet", "bundle": false}` and downloads the bare Parquet artifact with any other layout. A fetch of an answer with several members in the `frame` layout raises `InvalidRequestError` before any build. -- A download asks the route that redirects to the signed URL, an artifact's `url` or the file selector, and fetches the URL its `location` names once. A route that answers a 2xx other than 200 or 302 raises `ContractError` `unexpected_response` with that response's trace id, which `fetch-spec-files-route-no-content` pins with a 204. The route ask is an API request and follows the retry rules below, so a retryable refusal is retried within the budget and any other refusal, `artifact_expired` among them, raises at once. A failed fetch gets exactly one more round: a fetch that answers anything but 200, which `fetch-spec-signed-fetch-partial` pins with a 206, or bytes that do not hash to the artifact's digest ask the route again, under the same retry rules, and fetch again, with no wait between rounds. A second failure raises `ServerError` with `download_failed`, or `digest_mismatch` when the bytes are wrong. A network error or timeout on the fetch is retryable, so it starts the second round too, and when the second round fails the same way the client raises that failure as itself, `network_error` or `deadline_exceeded`. The replay holds no network failure, so no scenario pins that case. +- A download asks the route that redirects to the signed URL, an artifact's `url` or the file selector, and fetches the URL its `location` names once. A files route answers 302 with the `location` the client fetches, or 200 with the file as its body, which the client hashes with no further request, which `fetch-spec-files-route-serves-file` pins. A refusal reads by the refusal rules, and any other status, another 2xx or another 3xx included, raises `ContractError` `unexpected_response` with that response's trace id, which `fetch-spec-files-route-no-content` pins with a 204 and `fetch-spec-files-route-temporary-redirect` with a 307. The route ask is an API request and follows the retry rules below, so a retryable refusal is retried within the budget and any other refusal, `artifact_expired` among them, raises at once. A failed fetch gets exactly one more round: a fetch that answers anything but 200, which `fetch-spec-signed-fetch-partial` pins with a 206, or bytes that do not hash to the artifact's digest ask the route again, under the same retry rules, and fetch again, with no wait between rounds. A second failure raises `ServerError` with `download_failed`, or `digest_mismatch` when the bytes are wrong. A network error or timeout on the fetch is retryable, so it starts the second round too, and when the second round fails the same way the client raises that failure as itself, `network_error` or `deadline_exceeded`. The replay holds no network failure, so no scenario pins that case. - A manifest artifact's `url` names its files route on the API's origin: a root-relative `url` resolves against the base URL's origin, and an absolute one on that origin is asked as its path and query, so both make the same `origin_path` request, which `fetch-spec-same-origin-artifact-url` pins. An artifact `url` on any other origin, the storage host's included, raises `ContractError` `contract_violation` before the sentence lookup and any request for the file, which `fetch-spec-foreign-artifact-url` and `fetch-spec-storage-artifact-url` pin. - A relative `location` resolves against the files route's URL, and the client fetches it on the API's origin as an `origin_path` request. A `location` on an origin other than the API's or `https://storage.googleapis.com` raises `ContractError` `contract_violation` before any fetch. A fetch on the storage host is bare and carries no API key. `fetch-spec-relative-location` pins the relative case. - A declined or catalogue answer is not complete, and fetching it raises `DeclinedError`. @@ -176,7 +176,7 @@ The records also fix these client rules: - A fetch of an answer issues one `SearchWarning` when a definite part has an operation Search did not run, a departure, or a warning at severity `warn` or `degraded` with a `message`, or the answer's `diagnostics.warnings` holds such a warning. An `info` warning, and a warning with no `message`, issue nothing. Each way is one line a client shows: `Not done: ()` coded by the verb, the departure's `text` coded by its code, or `Note: ` coded by the warning's code, in part order with the diagnostics warnings last, and ways that show the same line count once, under the first one's code. A strict fetch raises the `SearchWarning` before any build, with the code of its one line, or a null code when there are several lines. A strict fetch raises it before the `frame` layout's several-member check. - A ref's version is found in this order: the snapshot route and the files route at the stored digest; the file selector, `GET /datasets/{id}/{content_version}/file` with the ref's rendering as the query; and a build of the ref's spec in the ref's rendering, which must answer the same `content_version`. A snapshot refusal other than `artifact_expired` ends the lookup, so `snapshot_not_found` raises `NotFoundError` with no further request. A files route or selector refusal of `artifact_expired`, `artifact_not_found` or `not_found` takes the next step, and a selector file of another digest is not the stored file. A snapshot manifest whose artifacts list no artifact of the ref member's digest sends the client to the selector in the ref member's own rendering, and a file that hashes to that digest gives the dataset, which `fetch-ref-artifact-unlisted` pins. A rebuild that answers another version, or that raises `InvalidRequestError`, `NotFoundError` or `VersionUnavailableError`, ends in `VersionUnavailableError` with the first refusal's code, or `version_unavailable` when nothing refused. Its `newest_version` is the version the rebuild answered, or else the newest stored version, which `GET /datasets/{id}/versions?limit=1` lists alone, as a `newest_version` step finds it, since the route lists versions newest first and needs no key; or null when that route lists none or refuses with `NotFoundError`. Any other refusal of the versions route raises, and a page whose `versions` is not a list of versions each with a `content_version` raises `ContractError` `contract_violation`, which `newest-version-unreadable-page` pins. - A build answers 200 with the manifest, or 202 with an operation the client polls at `/datasets/operations/{operation_id}`, the id of the operation it holds. A mint's build answers 202; a record whose mint answers 200 fits no mint step. Before each poll it waits the `Retry-After` of the refusal that answered the last poll, whatever its status, as every retry of a refused request waits; else the last operation resource's `retry_after_ms`, else the `Retry-After` of the last answered poll, the response that carried that resource, else a backoff of 1, 2, 4 and then 8 seconds that advances one step each time it is used, a poll after a refusal included. -- A 429 poll spends no retry. Any other retryable refused poll spends one of the two retries, which a poll that answers restores, and a refusal that is not retryable raises. `fetch-spec-poll-refused` pins two 503s polled again after an answered poll, `fetch-spec-poll-refused-backoff` a 503 with no `Retry-After` among polls no response paces, after which the backoff advances, `fetch-spec-poll-refused-retry-after` a 503 whose `Retry-After` paces the next poll, and `fetch-spec-poll-not-found` a 404 that raises at once. A poll that answers a failed operation whose error is retryable posts the same build once more and polls the operation it starts; a second failure, an error that is not retryable, and a resumed operation, whose build request the client does not hold, raise the operation's error. A refused poll whose code is `operation_failed` is a failed operation with that error. A failed operation whose resource carries no `error` raises `ServerError` with `operation_failed`, retryable by status 500 as a refusal without a document is, which `operation-failed-without-error` pins. A 202 or resumed operation that already reads `failed` raises its error before any poll. +- A retryable 429 poll spends no retry, and a 429 whose body says it is not retryable raises at once, as a refusal's `retryable` outranks its status, which `fetch-spec-poll-rate-limited-not-retryable` pins. Any other retryable refused poll spends one of the two retries, which a poll that answers restores, and a refusal that is not retryable raises. `fetch-spec-poll-refused` pins two 503s polled again after an answered poll, `fetch-spec-poll-refused-backoff` a 503 with no `Retry-After` among polls no response paces, after which the backoff advances, `fetch-spec-poll-refused-retry-after` a 503 whose `Retry-After` paces the next poll, and `fetch-spec-poll-not-found` a 404 that raises at once. A poll that answers a failed operation whose error is retryable posts the same build once more and polls the operation it starts; a second failure, an error that is not retryable, and a resumed operation, whose build request the client does not hold, raise the operation's error. A refused poll whose code is `operation_failed` is a failed operation with that error. A failed operation whose resource carries no `error` raises `ServerError` with `operation_failed`, retryable by status 500 as a refusal without a document is, which `operation-failed-without-error` pins. A 202 or resumed operation that already reads `failed` raises its error before any poll. - Any other refusal is retried when it is retryable: as a problem document's `retryable` says, or the website proxy's `retry` of `retry_after_delay`, else when its status is 408, 429, 500, 502, 503 or 504. A client makes two retries by default, and the scenarios assume that default. A build's POST shares those two retries with every other refusal of it, and once a 504 cuts the build off the client posts it once more only, whatever that post answers: a build refused 504 then 503 raises the 503, a build refused 503 then 504 is posted once more after the 504, and a second 504 raises. `fetch-spec-504-then-503`, `fetch-spec-503-then-504` and `fetch-spec-504-twice` pin the three. A refusal that is not retryable, or one past the retries, raises its error. - Each retry waits the refusal's `Retry-After` when it carries one, and otherwise the client's backoff for that attempt: 0.5 seconds before the first retry, doubling to at most 8. The build's 504 cut-off retry follows the same rule. `retry_waits` pins these waits, and `fetch-spec-504-retry-after` pins a cut-off that carries `Retry-After`. - A 401 resolves the key again by the key-lookup rule. When the key changed, the client sends the request once more at once, with no wait and spending no retry; when it did not, or the second answer is a 401 too, the 401 raises `AuthenticationError`. A replay's key never changes, so `search-unauthorized` pins the second case and no scenario the first. @@ -194,7 +194,7 @@ uv sync --directory ../dfo-apis --extra eval --extra api --extra engine --extra uv run tools/capture_client_contract.py openapi --dfo-apis ../dfo-apis ``` -Its `record` command runs every scenario against a base URL, dev's Cloud Run URL by default, checks each live answer still has the shape its scenario names, derives the synthetic scenarios from the fresh records with no request, and then runs the validator. A recorded scenario holds only exchanges the server made, and the run refuses one that a canned exchange answered, and an API response without the `x-dfo-trace-id` header the server sends on every response but a shared-cacheable one, marked `Cache-Control: public`; the record names the commit the server's responses name. It fails when the validator reports a problem or the binary bodies pass 5 MB. `--only` records the scenarios it names. `--offline` makes no request: each recorded scenario's steps run again over its own exchanges and rewrite its `expect`, and each synthetic scenario is derived again from its parent, so a change to the outcome rules or to `client-codes.json` reaches the records without a recording: +Its `record` command runs every scenario against a base URL, dev's Cloud Run URL by default, checks each live answer still has the shape its scenario names, derives the synthetic scenarios from the fresh records with no request, and then runs the validator. A recorded scenario holds only exchanges the server made, and the run refuses one that a canned exchange answered, and an API response without the `x-dfo-trace-id` header the server sends on every response but a shared-cacheable one, marked `Cache-Control: public`, whose `cache-control` header the record then keeps. The validator refuses a recorded API response with neither; the record names the commit the server's responses name. It fails when the validator reports a problem or the binary bodies pass 5 MB. `--only` records the scenarios it names. `--offline` makes no request: each recorded scenario's steps run again over its own exchanges and rewrite its `expect`, and each synthetic scenario is derived again from its parent, so a change to the outcome rules or to `client-codes.json` reaches the records without a recording: ```bash uv run tools/capture_client_contract.py record --offline --only answer-declined choose-refused-no-choice diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-folded-parts-unnamed.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-folded-parts-unnamed.json new file mode 100644 index 0000000..6432111 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-folded-parts-unnamed.json @@ -0,0 +1,15436 @@ +{ + "format_version": 1, + "name": "answer-folded-parts-unnamed", + "description": "A definite part whose variable_text is absent or empty adds nothing to its member's parts, so the member that answers both names no part and its rows' part value is its sentence.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-several-readings-folded", + "edit": "The first folded part loses its variable_text and the second's becomes an empty string." + }, + "call": [ + { + "op": "search", + "question": "ODA disbursements for health and for education from Germany to Kenya, and GDP of Kenya" + }, + { + "op": "fetch" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "ODA disbursements for health and for education from Germany to Kenya, and GDP of Kenya" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "3ceef86d0eac49fa96380d3340878cf1" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "ODA disbursements for health and for education from Germany to Kenya, and GDP of Kenya", + "normalized_query": "ODA disbursements for health and for education from Germany to Kenya, and GDP of Kenya", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "3ceef86d0eac49fa96380d3340878cf1", + "warnings": [], + "timing_ms": { + "total": 5613, + "by_step": { + "coverage": 0, + "extract": 1020 + } + }, + "llm_usage": { + "input_tokens": 15731, + "output_tokens": 1021, + "cached_tokens": 861 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "warnings": [], + "timing_ms": { + "total": 3674, + "by_step": { + "recall": 773, + "shape_arcs": 0, + "shape_probe_coverage": 11, + "shape_probe": 224, + "shape_groups": 26, + "shape_labels": 8, + "shape_admission": 0, + "shape": 1251, + "bind": 1411, + "materialise": 115, + "answer": 15, + "options": 109 + } + }, + "restatement": { + "variable_text": "ODA disbursements for health", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "definition": { + "schema_version": 1, + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal", + "label": "gross disbursements (official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 545, + "member_digest": "0c7508fd1997d6cdc896f2eab0f092a4915cfca9e2400eb9577bb22b527fe882", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "CRSPurposeCode110", + "label": "education" + }, + "value_kind": "enum_value" + }, + { + "ref": { + "ref": "CRSPurposeCode120", + "label": "health" + }, + "value_kind": "enum_value" + } + ] + }, + "expansion": { + "added": [ + { + "ref": "CRSPurposeCode121", + "label": "general health" + }, + { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + { + "ref": "CRSPurposeCode123", + "label": "noncommunicable disease" + }, + { + "ref": "CRSPurposeCode12110", + "label": "health policy and administrative management" + }, + { + "ref": "CRSPurposeCode12181", + "label": "medical education and training" + }, + { + "ref": "CRSPurposeCode12182", + "label": "medical research" + }, + { + "ref": "CRSPurposeCode12191", + "label": "medical service" + }, + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + }, + { + "ref": "CRSPurposeCode12230", + "label": "basic health infrastructure" + }, + { + "ref": "CRSPurposeCode12240", + "label": "basic nutrition" + }, + { + "ref": "CRSPurposeCode12250", + "label": "infectious disease control" + }, + { + "ref": "CRSPurposeCode12261", + "label": "health education" + }, + { + "ref": "CRSPurposeCode12262", + "label": "malaria control" + }, + { + "ref": "CRSPurposeCode12263", + "label": "tuberculosis control" + }, + { + "ref": "CRSPurposeCode12264", + "label": "COVID-19 control" + }, + { + "ref": "CRSPurposeCode12281", + "label": "health personnel development" + }, + { + "ref": "CRSPurposeCode12310", + "label": "general noncommunicable disease control" + }, + { + "ref": "CRSPurposeCode12320", + "label": "tobacco use control" + }, + { + "ref": "CRSPurposeCode12330", + "label": "control of harmful use of alcohol and drugs" + }, + { + "ref": "CRSPurposeCode12340", + "label": "mental health and well-being promotion" + }, + { + "ref": "CRSPurposeCode12350", + "label": "other noncommunicable disease prevention and treatment" + }, + { + "ref": "CRSPurposeCode12382", + "label": "research for noncommunicable disease prevention and control" + } + ] + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "financialObligationType" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 108, + "member_count_exact": true, + "served_count": 545, + "data_date_range": { + "start": "1997", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "breadth", + "has_data": true, + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 12 + }, + { + "label": "variables", + "count": 51 + } + ] + }, + "facets": { + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + }, + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", + "account": "provider" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 104, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1606, + "served_rows": 21, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 83, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 136, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 136, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 111, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 1600, + "served_rows": 84, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 976, + "served_rows": 27, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE", + "label": "scholarship and student cost in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 38, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 819, + "served_rows": 19, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 315, + "served_rows": 19, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode121", + "label": "general health" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 6, + "served_rows": 82, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 108, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode123", + "label": "noncommunicable disease" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 3, + "served_rows": 4, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode100", + "label": "social infrastructure and services" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "member_count": 13, + "served_rows": 1214, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode111", + "label": "unspecified-level education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 6, + "served_rows": 78, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode112", + "label": "basic education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 6, + "served_rows": 77, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode113", + "label": "upper secondary education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 5, + "served_rows": 69, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode114", + "label": "post-secondary education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 4, + "served_rows": 94, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 501, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 501, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance420", + "label": "debt instrument" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 11, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance421", + "label": "standard loan" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance420", + "member_count": 4620, + "served_rows": 11, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 512, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Kenya for education and health, 1997 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "education and health", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1997 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "CRSPurposeCode110", + "label": "education" + }, + { + "ref": "CRSPurposeCode120", + "label": "health" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "measure_elected" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [ + { + "text": "ODA", + "named": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "slot": "crsTypeOfFlow", + "disposition": "bound", + "selected": [] + }, + { + "text": "health", + "named": [ + { + "ref": "CRSPurposeCode120", + "label": "health" + } + ], + "slot": "crsPurpose", + "disposition": "bound", + "selected": [] + }, + { + "text": "education", + "named": [ + { + "ref": "CRSPurposeCode110", + "label": "education" + } + ], + "slot": "crsPurpose", + "disposition": "bound", + "selected": [] + } + ], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_b438dc000255d174bcc13eb675e603f7", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 512, + "served_rows_exact": true + }, + { + "definition": { + "schema_version": 1, + "spec_id": "spec_e348565295de394da8ddaa23ec5fa475", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialObligation", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialObligationType", + "binding": { + "state": "value", + "ref": "Commitment" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "commitments", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialObligation", + "label": "financial obligation" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialObligationType", + "value": { + "ref": "Commitment", + "label": "commitment" + } + } + ], + "served_rows": 519, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "open_axis_facts": [ + { + "property": "crsTypeOfFinance", + "varies": true, + "distinct_count": 2, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "count": 105 + }, + { + "value": { + "ref": "CRSTypeOfFinance421", + "label": "standard loan" + }, + "count": 3 + } + ] + }, + { + "property": "crsCooperationModality", + "varies": true, + "distinct_count": 7, + "undeclared_count": 19, + "values": [ + { + "value": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "count": 27 + }, + { + "value": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "count": 21 + }, + { + "value": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "count": 16 + }, + { + "value": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "count": 15 + }, + { + "value": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "count": 8 + }, + { + "value": { + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "count": 1 + } + ] + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1991, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1985, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1986, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1991, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1992, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1973, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1994, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1986, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1987, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1989, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1987, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1961, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 1985, + "end_year": 1990 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1991, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "KES", + "origin": "EUR" + } + } + } + } + }, + { + "variable_text": "", + "warnings": [ + { + "code": "binding_folded", + "severity": "info", + "message": "'ODA disbursements for education' resolved to the same shape as an earlier part; folded into that part's spec." + } + ], + "timing_ms": { + "total": 3542, + "by_step": { + "recall": 791, + "shape_arcs": 0, + "shape_probe_coverage": 2, + "shape_probe": 240, + "shape_groups": 39, + "shape_labels": 5, + "shape_admission": 1, + "shape": 1008, + "bind": 1505, + "materialise": 146, + "answer": 13, + "options": 79 + } + }, + "restatement": { + "variable_text": "ODA disbursements for education", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "definition": { + "schema_version": 1, + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal", + "label": "gross disbursements (official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 545, + "member_digest": "0c7508fd1997d6cdc896f2eab0f092a4915cfca9e2400eb9577bb22b527fe882", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "CRSPurposeCode110", + "label": "education" + }, + "value_kind": "enum_value" + }, + { + "ref": { + "ref": "CRSPurposeCode120", + "label": "health" + }, + "value_kind": "enum_value" + } + ] + }, + "expansion": { + "added": [ + { + "ref": "CRSPurposeCode121", + "label": "general health" + }, + { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + { + "ref": "CRSPurposeCode123", + "label": "noncommunicable disease" + }, + { + "ref": "CRSPurposeCode12110", + "label": "health policy and administrative management" + }, + { + "ref": "CRSPurposeCode12181", + "label": "medical education and training" + }, + { + "ref": "CRSPurposeCode12182", + "label": "medical research" + }, + { + "ref": "CRSPurposeCode12191", + "label": "medical service" + }, + { + "ref": "CRSPurposeCode12220", + "label": "basic health care" + }, + { + "ref": "CRSPurposeCode12230", + "label": "basic health infrastructure" + }, + { + "ref": "CRSPurposeCode12240", + "label": "basic nutrition" + }, + { + "ref": "CRSPurposeCode12250", + "label": "infectious disease control" + }, + { + "ref": "CRSPurposeCode12261", + "label": "health education" + }, + { + "ref": "CRSPurposeCode12262", + "label": "malaria control" + }, + { + "ref": "CRSPurposeCode12263", + "label": "tuberculosis control" + }, + { + "ref": "CRSPurposeCode12264", + "label": "COVID-19 control" + }, + { + "ref": "CRSPurposeCode12281", + "label": "health personnel development" + }, + { + "ref": "CRSPurposeCode12310", + "label": "general noncommunicable disease control" + }, + { + "ref": "CRSPurposeCode12320", + "label": "tobacco use control" + }, + { + "ref": "CRSPurposeCode12330", + "label": "control of harmful use of alcohol and drugs" + }, + { + "ref": "CRSPurposeCode12340", + "label": "mental health and well-being promotion" + }, + { + "ref": "CRSPurposeCode12350", + "label": "other noncommunicable disease prevention and treatment" + }, + { + "ref": "CRSPurposeCode12382", + "label": "research for noncommunicable disease prevention and control" + } + ] + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": true + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "financialObligationType" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 108, + "member_count_exact": true, + "served_count": 545, + "data_date_range": { + "start": "1997", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "breadth", + "has_data": true, + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 12 + }, + { + "label": "variables", + "count": 51 + } + ] + }, + "facets": { + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + }, + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", + "account": "provider" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 104, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1606, + "served_rows": 21, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 83, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 136, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 136, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 111, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 1600, + "served_rows": 84, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 976, + "served_rows": 27, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE", + "label": "scholarship and student cost in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 38, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 819, + "served_rows": 19, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 315, + "served_rows": 19, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode121", + "label": "general health" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 6, + "served_rows": 82, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 108, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode123", + "label": "noncommunicable disease" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 3, + "served_rows": 4, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode100", + "label": "social infrastructure and services" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "member_count": 13, + "served_rows": 1214, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode111", + "label": "unspecified-level education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 6, + "served_rows": 78, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode112", + "label": "basic education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 6, + "served_rows": 77, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode113", + "label": "upper secondary education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 5, + "served_rows": 69, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSPurposeCode114", + "label": "post-secondary education" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 4, + "served_rows": 94, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 501, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 501, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance420", + "label": "debt instrument" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 11, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance421", + "label": "standard loan" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance420", + "member_count": 4620, + "served_rows": 11, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 512, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Kenya for education and health, 1997 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "education and health", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1997 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "CRSPurposeCode110", + "label": "education" + }, + { + "ref": "CRSPurposeCode120", + "label": "health" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "text_recognized" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "measure_elected" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [ + { + "text": "ODA", + "named": [ + { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + } + ], + "slot": "crsTypeOfFlow", + "disposition": "bound", + "selected": [] + }, + { + "text": "health", + "named": [ + { + "ref": "CRSPurposeCode120", + "label": "health" + } + ], + "slot": "crsPurpose", + "disposition": "bound", + "selected": [] + }, + { + "text": "education", + "named": [ + { + "ref": "CRSPurposeCode110", + "label": "education" + } + ], + "slot": "crsPurpose", + "disposition": "bound", + "selected": [] + } + ], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_b438dc000255d174bcc13eb675e603f7", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 512, + "served_rows_exact": true + }, + { + "definition": { + "schema_version": 1, + "spec_id": "spec_e348565295de394da8ddaa23ec5fa475", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialObligation", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialObligationType", + "binding": { + "state": "value", + "ref": "Commitment" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "commitments", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialObligation", + "label": "financial obligation" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialObligationType", + "value": { + "ref": "Commitment", + "label": "commitment" + } + } + ], + "served_rows": 519, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "open_axis_facts": [ + { + "property": "crsTypeOfFinance", + "varies": true, + "distinct_count": 2, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "count": 105 + }, + { + "value": { + "ref": "CRSTypeOfFinance421", + "label": "standard loan" + }, + "count": 3 + } + ] + }, + { + "property": "crsCooperationModality", + "varies": true, + "distinct_count": 7, + "undeclared_count": 19, + "values": [ + { + "value": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "count": 27 + }, + { + "value": { + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" + }, + "count": 21 + }, + { + "value": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "count": 16 + }, + { + "value": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "count": 15 + }, + { + "value": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "count": 8 + }, + { + "value": { + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" + }, + "count": 1 + }, + { + "value": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "count": 1 + } + ] + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1991, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1985, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1986, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1991, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1992, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1973, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1994, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1986, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1987, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1989, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1987, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1961, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 1985, + "end_year": 1990 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1990, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1991, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1960, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1992, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2025 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2025 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "KES", + "origin": "EUR" + } + } + } + } + }, + { + "variable_text": "GDP", + "warnings": [ + { + "code": "direction_discarded", + "severity": "warn", + "message": "Germany was named as the provider; this shape reports the place as its own subject, so the direction was dropped." + }, + { + "code": "direction_discarded", + "severity": "warn", + "message": "Kenya was named as the recipient; this shape reports the place as its own subject, so the direction was dropped." + } + ], + "timing_ms": { + "total": 3536, + "by_step": { + "recall": 778, + "shape_arcs": 2, + "shape_probe_coverage": 2, + "shape_probe": 277, + "shape_groups": 24, + "shape_labels": 5, + "shape_admission": 1, + "shape": 973, + "bind": 1109, + "materialise": 1, + "answer": 210, + "options": 465 + } + }, + "restatement": { + "variable_text": "GDP", + "entities": [ + { + "text": "Germany", + "role_text": "from" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [ + { + "code": "direction_discarded", + "binding_ref": "where:", + "asked": "Germany", + "text": "You named Germany as a provider. This measure has no providers, so this shows the place itself." + }, + { + "code": "direction_discarded", + "binding_ref": "where:", + "asked": "Kenya", + "text": "You named Kenya as a recipient. This measure has no recipients, so this shows the place itself." + } + ], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_f8dea3052d1ef6ba5667628815d1a663", + "definition": { + "schema_version": 1, + "spec_id": "spec_f8dea3052d1ef6ba5667628815d1a663", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + }, + { + "property": "economicSector", + "binding": { + "state": "unbound" + } + }, + { + "property": "naics", + "binding": { + "state": "unbound" + } + }, + { + "property": "schoolGradeLevel", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "USDollar" + } + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_nominal", + "label": "Nominal gross domestic product", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 65, + "member_digest": "73519eeb75639bdae33042fc844830cd46becc08e4f9122dfcd0886e9875f657", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "economicSector", + "naics", + "schoolGradeLevel" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 41, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 132, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 2 + }, + { + "label": "observations", + "count": 66 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 132, + "rows_exact": true, + "series": 2, + "window": { + "start_year": 1960, + "end_year": 2025 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "bound", + "ref": "USDollar", + "label": "USDollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossValueAdded", + "label": "GrossValueAdded" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NetDomesticProduction", + "label": "Net Domestic Production" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NetValueAdded", + "label": "Net Value Added" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "AgricultureForestryFishingSector", + "label": "Agriculture,Forestry and Fishing Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ConstructionSector", + "label": "Construction Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ElectricityGasSteamAirConditionSupply", + "label": "Electric Gas Steam Air Condition Supply" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinanceService", + "label": "Finance Service" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MOSPI_OtherService", + "label": "MOSPI Other Service" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ManufacturingSector", + "label": "Manufacturing Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MiningQuarrying", + "label": "Mining quarrying" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TradeSector", + "label": "Trade Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AccommodationAndFoodSector", + "label": "Accommodation and food sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AdministrativeAndSupportServices", + "label": "Administrative and support services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AgriculturalSupportActivities", + "label": "Agricultural support activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Agriculture", + "label": "Agriculture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AirTransportAndSupportServices", + "label": "Air transport and support services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AllEconomicActivities", + "label": "All economic activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "AnimalProduction", + "label": "Animal production" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ArtsEntertainmentRecreation", + "label": "Arts entertainment recreation" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Education", + "label": "Education" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ElectricitySupply", + "label": "Electricity supply" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EmployerHouseholdActivities", + "label": "Employer household activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialActivities", + "label": "FinancialActivities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialAndInsuranceActivities", + "label": "Financial and insurance activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialIntermediationServicesIndirectlyMeasured", + "label": "Financial intermediation services indirectly measured" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FishingAquaculture", + "label": "Fishing aquaculture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FoodBeveragesTobaccoManufacture", + "label": "Food beverages tobacco manufacture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ForestryLogging", + "label": "Forestry logging" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "HumanHealthAndSocialWork", + "label": "Human health and social work" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "InformationAndCommunication", + "label": "Information and communication" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "InsuranceActivities", + "label": "Insurance activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "LandTransport", + "label": "Land transport" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherManufacturingAndRepair", + "label": "Other manufacturing and repair" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherServiceSector", + "label": "Other service sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "OtherTransportPostalCourierActivities", + "label": "Other transport postal courier activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ProductTaxes", + "label": "Product taxes" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ProfessionalScientificTechnicalActivities", + "label": "Professional scientific technical activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PublicAdministrationAndDefence", + "label": "Public administration and defence" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PublishingBroadcastingInformationActivities", + "label": "Publishing Broadcasting Information Activities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "RealEstate", + "label": "Real estate" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Telecommunications", + "label": "Telecommunications" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TransportStorageSector", + "label": "Transport and Storage" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "WaterSupplySewerageWasteManagement", + "label": "Water supply sewerage waste management" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "WholesaleRetailTradeAndRepair", + "label": "Wholesale retail trade and repair" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "BankingAndInsuranceSector", + "label": "Banking And Insurance Sector" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Construction", + "label": "Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "FinancialServices", + "label": "Financial Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Industry", + "label": "Industry" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Services", + "label": "Services" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "options": [ + { + "value": { + "ref": { + "ref": "NAICS/23", + "label": "Construction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/44-45", + "label": "Retail trade" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/53", + "label": "Real estate and rental and leasing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/22", + "label": "Utilities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/55", + "label": "Management of companies and enterprises" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/48-49", + "label": "Transportation and warehousing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/61", + "label": "Educational services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/51", + "label": "Information" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/42", + "label": "Wholesale trade" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/21", + "label": "Mining, quarrying, and oil and gas extraction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/11", + "label": "Agriculture, forestry, fishing and hunting" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/72", + "label": "Accommodation and food services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/52", + "label": "Finance and insurance" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/54", + "label": "Professional, Scientific, and Technical Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/71", + "label": "Arts, entertainment, and recreation" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/311-316_322-326", + "label": "Durable Goods Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/31-33", + "label": "Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/321_327-339", + "label": "Durable Goods Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/56", + "label": "Administrative and Support and Waste Management Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/62", + "label": "Health care and social assistance" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/81", + "label": "Other services, except public administration" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/92", + "label": "Public administration" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "options": [ + { + "value": { + "ref": { + "ref": "HigherSecondaryEducation", + "label": "Higher Secondary Education" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PrePrimaryAndPrimaryEducation", + "label": "PrePrimary and Primary" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SecondaryEducation", + "label": "SecondaryEducation" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "USDollar", + "label": "USDollar" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Euro", + "label": "Euro" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NationalCurrency", + "label": "NationalCurrency" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PurchasingPowerStandard", + "label": "PurchasingPowerStandard" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "GDP in Germany and Kenya, 1960 to 2025. Current US dollars · World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Germany and Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAccommodationFoodServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSFinanceInsurance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSMiningQuarryingOilGasExtraction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSProfessionalScientificTechnicalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSWholesaleTrade_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826", + "dc/zz6gwv838v9w" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "equivalent_readings": [ + { + "spec_id": "spec_2a65bb3dc1332b16173c540e3392b139", + "definition": { + "schema_version": 1, + "spec_id": "spec_2a65bb3dc1332b16173c540e3392b139", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicProduction", + "measured_property": "valueAdded", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "currencyConversionBasis", + "binding": { + "state": "unbound" + } + }, + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + }, + { + "property": "productTaxBasis", + "binding": { + "state": "value", + "ref": "IncludingProductTaxes" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "CurrencyUSD" + } + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicproduction_valueadded_measuredvalue_nominal", + "label": "Gross domestic product (GDP)", + "population_type": { + "ref": "EconomicProduction", + "label": "economic production" + }, + "measured_property": { + "ref": "valueAdded", + "label": "value added" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 2, + "member_digest": "ef9c4356618ed98aab762248e68799d78c74ad249a6041dad0e8a345c85ee02f", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "currencyConversionBasis" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 2, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1980", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 92, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 2 + }, + { + "label": "observations", + "count": 46 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 92, + "rows_exact": true, + "series": 2, + "window": { + "start_year": 1980, + "end_year": 2025 + }, + "licence": { + "label": "IMF Copyright and Usage" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/IMFWorldEconomicOutlook", + "label": "IMF World Economic Outlook (WEO)", + "source": { + "ref": "source/InternationalMonetaryFund", + "label": "International Monetary Fund (IMF)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/IMFWorldEconomicOutlook" + }, + "unit": { + "basis": "bound", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "PurchasingPowerParityRate", + "label": "purchasing power parity rate" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "resolved_sources": [ + { + "ref": "provenance/IMFWorldEconomicOutlook", + "label": "IMF World Economic Outlook (WEO)", + "source": { + "ref": "source/InternationalMonetaryFund", + "label": "International Monetary Fund (IMF)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/IMFWorldEconomicOutlook" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAccommodationFoodServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSFinanceInsurance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSMiningQuarryingOilGasExtraction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSProfessionalScientificTechnicalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSWholesaleTrade_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826", + "dc/zz6gwv838v9w" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "measure_label_axes": [], + "measure_axis_values": [], + "related_group": { + "ref": "dc/g/EconomicActivity_ActivitySource-GrossDomesticProduction", + "label": "Economic Activity With Activity Source = Gross Domestic Production" + }, + "related_measures": [ + { + "stat_var": { + "ref": "GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "label": "Gross domestic product growth rate" + }, + "definition": { + "schema_version": 1, + "spec_id": "spec_4535d09baf2bdffef7c19c7796e96687", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "growthRate" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + } + ] + } + } + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Kenya for education and health, 1997 to 2024. Current US dollars · OECD Creditor Reporting System (CRS). GDP in Germany and Kenya, 1960 to 2025. Current US dollars · World Development Indicators. You named Germany as a provider. This measure has no providers, so this shows the place itself. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross ODA disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:crsTypeOfFlow", + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "education and health", + "axis": "how", + "segment": "heading", + "property_dcid": "crsPurpose", + "binding_ref": "how:crsPurpose", + "entity_refs": [], + "states": [ + "how:crsPurpose" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsCooperationModality", + "binding_ref": "how:crsCooperationModality", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFinance", + "binding_ref": "how:crsTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "crsTypeOfFlow", + "binding_ref": "how:crsTypeOfFlow", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1997 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD Creditor Reporting System (CRS)", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ], + "part_index": 2 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "Germany and Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 2 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 2 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 2 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 2 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "text", + "text": "You named Germany as a provider. This measure has no providers, so this shows the place itself.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 2 + }, + { + "kind": "text", + "text": "You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 2 + } + ], + "status": "definite" + } + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "definition": { + "schema_version": 1, + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "set", + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ] + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "ee49afa94b0440c9b557ce3413d538a5" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "refs": [ + "CRSPurposeCode110", + "CRSPurposeCode120" + ], + "state": "set" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/KEN" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + }, + "content_version": "cv_d6ce435ea267b46680c94eae9423d420", + "prepared_at": "2026-10-21T13:05:29Z", + "coverage": { + "rows": 512, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 28 + } + ], + "window": { + "kind": "all", + "start_year": 1997, + "end_year": 2024, + "origin": "default" + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "applied_window": { + "kind": "all", + "start_year": 1997, + "end_year": 2024, + "origin": "default" + }, + "graph_revision": null, + "code_index_stamp": { + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", + "graph_endpoint": "graph_release" + }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11260_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 3 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 5 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11232_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 3 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11260_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 10 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 5 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 8 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12340_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12350_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12382_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11260_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12340_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12350_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12382_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12340_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12350_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12382_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11232_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11260_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12340_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12350_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12382_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11232_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11260_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12340_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 18 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11232_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11260_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 10 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 13 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 5 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 5 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 11 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 7 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 5 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 3 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 3 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 3 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12340_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12350_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12382_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 7 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11232_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11260_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12340_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12350_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12382_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 3 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 14 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 12 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 5 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11232_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11260_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 11 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 8 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 7 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 3 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12340_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12350_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12382_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11232_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 19 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12340_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12382_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 19 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12382_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH01_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityH02_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 8 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 8 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 3 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 8 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 2 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 9 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 8 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 12 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12350_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityB031_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityB031_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityB03_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityB03_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityB04_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityB04_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityB04_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11231_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11260_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12262_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12263_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12310_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12350_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityE01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11130_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11330_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12181_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12250_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12261_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12264_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12281_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance422_CRSCooperationModalityE01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode11120_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode11182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode11320_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode11430_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSPurposeCode12230_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode11110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode11420_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12110_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12182_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12191_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance610_CRSCooperationModalityC01_CRSPurposeCode12240_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_digest": "0c7508fd1997d6cdc896f2eab0f092a4915cfca9e2400eb9577bb22b527fe882", + "family_member_count": 545, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDCreditorReportingSystem", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + } + ], + "normalisations": [], + "frame_grammar_version": "1.1.0", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T13:05:29.417660+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 16150, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:29.374895+00:00", + "tier": "working", + "url": "/api/datasets/spec_25f482395c5d012ec278118f38dff29c/cv_d6ce435ea267b46680c94eae9423d420/files/sha256:20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d" + }, + { + "artifact_digest": "sha256:a5d2d7627c8fe1357519ca0ac021c791182ab08c76f44e8055b4bb50a6059179", + "rendering": { + "statistics": "series" + }, + "bytes": 11612, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:29.374895+00:00", + "tier": "working", + "url": "/api/datasets/spec_25f482395c5d012ec278118f38dff29c/cv_d6ce435ea267b46680c94eae9423d420/files/sha256:a5d2d7627c8fe1357519ca0ac021c791182ab08c76f44e8055b4bb50a6059179" + } + ], + "series_count": 108, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 108 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 28 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "stat_var", + "columns": "time_period", + "state": "available", + "width": 29, + "cells": 3132 + }, + { + "index": "time_period", + "columns": "stat_var", + "state": "available", + "width": 109, + "cells": 3052 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T13:05:29.374859Z" + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_25f482395c5d012ec278118f38dff29c/cv_d6ce435ea267b46680c94eae9423d420/files/sha256:20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3A20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d?X-Goog-Signature=redacted", + "x-dfo-trace-id": "cee84dbe25214a0f8ea3f0a28ce10adc" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3A20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "c3f031f1d3724d2ea9b19e58197e4f03" + }, + "body_file": "answer-several-readings-folded.parquet" + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_f8dea3052d1ef6ba5667628815d1a663", + "definition": { + "schema_version": 1, + "spec_id": "spec_f8dea3052d1ef6ba5667628815d1a663", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } + }, + { + "property": "economicSector", + "binding": { + "state": "unbound" + } + }, + { + "property": "naics", + "binding": { + "state": "unbound" + } + }, + { + "property": "schoolGradeLevel", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + }, + "facets": { + "unit": { + "state": "value", + "ref": "USDollar" + } + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "e043b83fa1f8472e814c68afde278ab8" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_f8dea3052d1ef6ba5667628815d1a663", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "EconomicActivity", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "ref": "GrossDomesticProduction", + "state": "value" + }, + "property": "activitySource" + }, + { + "binding": { + "state": "unbound" + }, + "property": "economicSector" + }, + { + "binding": { + "state": "unbound" + }, + "property": "naics" + }, + { + "binding": { + "state": "unbound" + }, + "property": "schoolGradeLevel" + } + ], + "facets": { + "unit": { + "ref": "USDollar", + "state": "value" + } + }, + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + }, + "content_version": "cv_91f57bfc5bbc5f09983596996238787d", + "prepared_at": "2026-10-21T13:05:30Z", + "coverage": { + "rows": 132, + "dimensions": [ + { + "label": "observationAbout", + "count": 2 + }, + { + "label": "years", + "count": 66 + } + ], + "window": { + "kind": "all", + "start_year": 1960, + "end_year": 2025, + "origin": "default" + } + }, + "citation": { + "text": "World Development Indicators (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "license": "Creative Commons Attribution License", + "license_type": "CreativeCommonsAttributionLicense", + "license_url": "https://datacatalog.worldbank.org/search/dataset/0037712", + "url": "https://datatopics.worldbank.org/world-development-indicators/", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": { + "publisher": "World Bank", + "description": "The primary World Bank collection of development indicators encompassing global economic and social data.", + "source_data_url": "http://api.worldbank.org/v2/en/country/AFG?downloadformat=csv", + "update_cadence": "Monthly", + "last_update": "2026-10-13", + "currencies": [], + "transformation_log": [], + "version_history": [] + } + } + ] + }, + "trace": { + "applied_window": { + "kind": "all", + "start_year": 1960, + "end_year": 2025, + "origin": "default" + }, + "graph_revision": null, + "code_index_stamp": { + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", + "graph_endpoint": "graph_release" + }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "source_revisions": [ + { + "source": "dc/base/WorldDevelopmentIndicators", + "revision": "2026-10-13" + } + ], + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_EconomicActivity_GrossDomesticProduction_Nominal", + "roles": [ + "observationAbout" + ], + "observation_count": 132 + } + ], + "family_member_digest": "73519eeb75639bdae33042fc844830cd46becc08e4f9122dfcd0886e9875f657", + "family_member_count": 65, + "facets": [ + { + "axis": "provenance", + "ref": "dc/base/WorldDevelopmentIndicators", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "8535402560764839853" + }, + { + "axis": "measurementMethod", + "ref": null, + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "8535402560764839853" + }, + { + "axis": "unit", + "ref": "USDollar", + "basis": "bound", + "default_policy": null, + "default_policy_version": null, + "selection_reason": null, + "dispatch_facet_id": "8535402560764839853" + } + ], + "normalisations": [], + "frame_grammar_version": "1.1.0", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T13:05:30.811140+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 6545, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:30.778158+00:00", + "tier": "working", + "url": "/api/datasets/spec_f8dea3052d1ef6ba5667628815d1a663/cv_91f57bfc5bbc5f09983596996238787d/files/sha256:9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839" + }, + { + "artifact_digest": "sha256:8eecb62c1741271464d6d66841353d96f7e36aa9c3915f7948ea7c78c7dbc9e7", + "rendering": { + "statistics": "series" + }, + "bytes": 5379, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:30.778158+00:00", + "tier": "working", + "url": "/api/datasets/spec_f8dea3052d1ef6ba5667628815d1a663/cv_91f57bfc5bbc5f09983596996238787d/files/sha256:8eecb62c1741271464d6d66841353d96f7e36aa9c3915f7948ea7c78c7dbc9e7" + } + ], + "series_count": 2, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "observationAbout", + "kind": "role", + "droppable": false, + "distinct": 2 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 66 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "observationAbout", + "field": "iso3", + "token": "observationAbout_iso3", + "state": "available", + "coverage": { + "entities": 2, + "covered": 2 + }, + "missing": [], + "truncated": false + }, + { + "column": "observationAbout", + "field": "iso2", + "token": "observationAbout_iso2", + "state": "available", + "coverage": { + "entities": 2, + "covered": 2 + }, + "missing": [], + "truncated": false + }, + { + "column": "observationAbout", + "field": "label", + "token": "observationAbout_label", + "state": "available", + "coverage": { + "entities": 2, + "covered": 2 + }, + "missing": [], + "truncated": false + }, + { + "column": "observationAbout", + "field": "type", + "token": "observationAbout_type", + "state": "available", + "coverage": { + "entities": 2, + "covered": 2 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "observationAbout_label" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "observationAbout", + "columns": "time_period", + "state": "available", + "width": 67, + "cells": 134 + }, + { + "index": "time_period", + "columns": "observationAbout", + "state": "available", + "width": 3, + "cells": 198 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T13:05:30.778009Z" + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_f8dea3052d1ef6ba5667628815d1a663/cv_91f57bfc5bbc5f09983596996238787d/files/sha256:9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3A9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839?X-Goog-Signature=redacted", + "x-dfo-trace-id": "8bf21c550f584bcaa21bcb8d69498a7d" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3A9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet", + "x-dfo-trace-id": "8072bc19c0fc4a5aa825d37c5956317c" + }, + "body_file": "answer-several-readings-folded-2.parquet" + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "definite", + "sentence": "Germany's gross ODA disbursements to Kenya for education and health, 1997 to 2024. Current US dollars · OECD Creditor Reporting System (CRS). GDP in Germany and Kenya, 1960 to 2025. Current US dollars · World Development Indicators. You named Germany as a provider. This measure has no providers, so this shows the place itself. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", + "complete": true, + "specs": [ + "spec_25f482395c5d012ec278118f38dff29c", + "spec_f8dea3052d1ef6ba5667628815d1a663" + ], + "gaps": [] + } + }, + { + "dataset": { + "rows": 644, + "columns": [ + "part", + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "crsCooperationModality", + "crsCooperationModality_label", + "crsPurpose", + "crsPurpose_label", + "crsTypeOfFinance", + "crsTypeOfFinance_label", + "crsTypeOfFlow", + "crsTypeOfFlow_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label", + "stat_var_label", + "observationAbout", + "observationAbout_label" + ], + "part_rows": [ + { + "part": "Germany's gross ODA disbursements to Kenya for education and health, 1997 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "rows": 512 + }, + { + "part": "GDP", + "rows": 132 + } + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_25f482395c5d012ec278118f38dff29c", + "content_version": "cv_d6ce435ea267b46680c94eae9423d420", + "sentence": "Germany's gross ODA disbursements to Kenya for education and health, 1997 to 2024. Current US dollars · OECD Creditor Reporting System (CRS)." + }, + { + "parts": [ + "GDP" + ], + "spec_id": "spec_f8dea3052d1ef6ba5667628815d1a663", + "content_version": "cv_91f57bfc5bbc5f09983596996238787d", + "sentence": "GDP in Germany and Kenya, 1960 to 2025. Current US dollars · World Development Indicators." + } + ], + "missing": [], + "search_warning": true + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-no-content.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-no-content.json index 02fc32d..68fd02f 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-no-content.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-no-content.json @@ -1,7 +1,7 @@ { "format_version": 1, "name": "fetch-spec-files-route-no-content", - "description": "A files route that answers a 2xx other than 200 or 302 raises ContractError unexpected_response, with that response's trace id, and the client fetches nothing.", + "description": "A files route that answers a status other than 302, 200 or a refusal raises ContractError unexpected_response, with that response's trace id, and the client fetches nothing.", "origin": { "kind": "synthetic", "derived_from": "fetch-spec-known-sentence", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-serves-file.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-serves-file.json new file mode 100644 index 0000000..26184e1 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-serves-file.json @@ -0,0 +1,917 @@ +{ + "format_version": 1, + "name": "fetch-spec-files-route-serves-file", + "description": "A files route that answers 200 holds the file as its body, which the client hashes against the artifact's digest with no further request.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "The files route answers 200 with the file the signed URL served, and the signed fetch goes." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "prepared_at": "2026-10-21T13:05:35Z", + "coverage": { + "rows": 4, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 4 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "head", + "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal, which hold none at the observation period the other members serve in the requested years." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9541, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:35.038218+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + { + "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", + "rendering": { + "statistics": "series" + }, + "bytes": 5741, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:35.038218+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" + } + ], + "series_count": 1, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 4 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T13:05:35.038284Z" + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + "response": { + "status": 200, + "headers": { + "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40", + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "fetch-spec-known-sentence.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 4, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "crsCooperationModality", + "crsCooperationModality_label", + "crsPurpose", + "crsPurpose_label", + "crsTypeOfFinance", + "crsTypeOfFinance_label", + "crsTypeOfFlow", + "crsTypeOfFlow_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + ], + "missing": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-temporary-redirect.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-temporary-redirect.json new file mode 100644 index 0000000..dfff971 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-temporary-redirect.json @@ -0,0 +1,880 @@ +{ + "format_version": 1, + "name": "fetch-spec-files-route-temporary-redirect", + "description": "A files route redirects with 302 only: a 307, as any 3xx other than 302, raises ContractError unexpected_response, and the client does not follow its location.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "The files route answers 307 with the parent's location, and the exchanges after it go." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "prepared_at": "2026-10-21T13:05:35Z", + "coverage": { + "rows": 4, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 4 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "head", + "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal, which hold none at the observation period the other members serve in the requested years." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9541, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:35.038218+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + { + "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", + "rendering": { + "statistics": "series" + }, + "bytes": 5741, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:35.038218+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" + } + ], + "series_count": 1, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 4 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T13:05:35.038284Z" + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + "response": { + "status": 307, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", + "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" + } + } + } + ], + "expect": [ + { + "error": { + "class": "ContractError", + "code": "unexpected_response", + "trace_id": "0911c16fb4824a499926e24a34069b40" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited-not-retryable.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited-not-retryable.json new file mode 100644 index 0000000..e1d7cee --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited-not-retryable.json @@ -0,0 +1,202 @@ +{ + "format_version": 1, + "name": "fetch-spec-poll-rate-limited-not-retryable", + "description": "A refusal's retryable outranks its status on a poll too: a 429 that says it is not retryable raises RateLimitError at once, where a retryable 429 is polled again without spending a retry.", + "origin": { + "kind": "synthetic", + "derived_from": "mint-async-build", + "edit": "As fetch-spec-async-build, with a 429 problem document with no code and retryable false answering the first poll, and the exchanges after it go." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + }, + "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "definition": { + "schema_version": 1, + "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2018, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 202, + "headers": { + "content-type": "application/json", + "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry-after": "2", + "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" + }, + "json": { + "operation": { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "status": "pending", + "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "retry_after_ms": 1500 + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + }, + "response": { + "status": 429, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "title": "Too Many Requests", + "status": 429, + "detail": "This key has used its requests for the day.", + "trace_id": "00000000000000000000000000000000", + "retryable": false + } + } + } + ], + "expect": [ + { + "error": { + "class": "RateLimitError", + "code": "refusal_without_code", + "trace_id": "00000000000000000000000000000000", + "long_builds": [ + { + "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll_waits": [ + 1.5 + ], + "resubmissions": 0 + } + ] + } + } + ] +} diff --git a/tools/capture_client_contract.py b/tools/capture_client_contract.py index 88c100f..bca8a94 100644 --- a/tools/capture_client_contract.py +++ b/tools/capture_client_contract.py @@ -74,6 +74,8 @@ from validate_client_contract import ( FILE_EXPIRED, FILE_GONE, + FILES_ROUTE_FILE, + FILES_ROUTE_REDIRECT, NO_VERSIONS, POLL_BACKOFF_CAP, POLL_BACKOFF_FIRST, @@ -100,7 +102,6 @@ digest_of, download_target, failed_operation, - files_route_unexpected, gap_kinds, header_warnings, held_spec, @@ -121,8 +122,10 @@ search_warns, selector_path, sentence_entry, + shared_cacheable, surface_problems, trace_id, + untraced, versions_path, with_step_notes, ) @@ -136,7 +139,9 @@ # The rendering both clients ask for: bare long Parquet. RENDERING = {"format": "parquet", "bundle": False} -# The response headers a client reads, and so the ones a record keeps. +# The response headers a client reads, and so the ones a record keeps, beside +# a `cache-control` that marks the response shared-cacheable, which excuses it +# from carrying `x-dfo-trace-id`. KEPT_HEADERS = ( "content-type", "location", @@ -364,14 +369,6 @@ def _origin(base_url: str) -> str: return f"{parts.scheme}://{parts.netloc}" -def untraced(headers: Mapping[str, str]) -> bool: - """Whether an API response lacks the TRACE_HEADER header the server sends - on every response but one marked `Cache-Control: public`, which a shared - cache replays and so carries no per-request id.""" - directives = headers.get("cache-control", "").lower().replace(" ", "").split(",") - return TRACE_HEADER not in headers and "public" not in directives - - def _is_json(content_type: str) -> bool: media = content_type.split(";", maxsplit=1)[0].strip() return media == "application/json" or media.endswith("+json") @@ -482,6 +479,8 @@ def _keep(self, response: Response) -> dict[str, Any]: for name in KEPT_HEADERS if name in response.headers } + if shared_cacheable(response.headers): + headers["cache-control"] = response.headers["cache-control"] if headers: kept["headers"] = headers content_type = response.headers.get("content-type", "") @@ -965,14 +964,14 @@ def _identity_sentence( return resubmitted_sentence(answer, definition["spec_id"]) def _download(self, target: str, digest: str, *, origin: bool = True) -> bytes: - """A file through the route that redirects to it: an `origin_path`, - as `artifact_route` places an artifact's url, or a path under the - base URL. The redirect's - location is fetched once, where `download_target` places it; a local - app's blob URL on the API's origin stands for the storage URL a - deployment signs. A files route answering a 2xx other than 200 or 302 - raises ContractError `unexpected_response`; a fetch answering other - than 200, or bytes of another digest, ask the route once more.""" + """A file through its files route: an `origin_path`, as + `artifact_route` places an artifact's url, or a path under the base + URL. A 302's location is fetched once, where `download_target` places + it, a local app's blob URL on the API's origin standing for the + storage URL a deployment signs; a 200 holds the file; any other + success raises ContractError `unexpected_response`. A fetch answering + other than 200, or bytes of another digest, ask the route once + more.""" base_url = self.recorder.base_url if origin: route_url = _origin(base_url) + target @@ -991,20 +990,23 @@ def _download(self, target: str, digest: str, *, origin: bool = True) -> bytes: ), ) self._raise_problem(files) - if files_route_unexpected(files.status): + if files.status == FILES_ROUTE_FILE: + data = files + elif files.status == FILES_ROUTE_REDIRECT: + location = files.headers["location"] + kind, at = download_target(base_url, route_url, location) + if kind == "origin_path" and at.startswith(LOCAL_BLOB_PREFIX): + kind = "url" + data = ( + self.recorder.external(urljoin(route_url, location)) + if kind == "url" + else self.recorder.origin("GET", at) + ) + if data.status != SIGNED_FETCH_STATUS: + failure = ClientError("download_failed") + continue + else: raise ClientError("unexpected_response") - location = files.headers["location"] - kind, at = download_target(base_url, route_url, location) - if kind == "origin_path" and at.startswith(LOCAL_BLOB_PREFIX): - kind = "url" - data = ( - self.recorder.external(urljoin(route_url, location)) - if kind == "url" - else self.recorder.origin("GET", at) - ) - if data.status != SIGNED_FETCH_STATUS: - failure = ClientError("download_failed") - continue if digest_of(data.body) == digest: return data.body failure = ClientError("digest_mismatch") @@ -2415,23 +2417,38 @@ def _poll_busy_retry_after( ) -def _poll_not_found(parent: dict[str, Any], ctx: Context) -> Derived: - """A 404 operation_not_found, which is not retryable, answers the first - poll, and the exchanges after it go.""" - derived = _async_fetch()(parent, ctx) - index = _poll_index(derived.exchanges) - refused = _refusal(derived.exchanges[index]["request"], 404, _OPERATION_NOT_FOUND) - (outcome,) = derived.expect - (build,) = outcome["dataset"]["long_builds"] - error = refusal_error(404, _OPERATION_NOT_FOUND, ctx.actions).outcome( - ctx.client_codes - ) - entry = {**build, "poll_waits": build["poll_waits"][:1]} - return Derived( - derived.call, - [*derived.exchanges[:index], refused], - [with_step_notes(error, long_builds=[entry], retry_waits=(), warnings=())], - ) +# The codeless problem document of a 429 that says it is not retryable, which +# answers the first poll of `fetch-spec-poll-rate-limited-not-retryable`. +_RATE_LIMITED_FOR_GOOD = { + "title": "Too Many Requests", + "status": 429, + "detail": "This key has used its requests for the day.", + "trace_id": "0" * 32, + "retryable": False, +} + + +def _poll_refused_at_once( + status: int, body: dict[str, Any] +) -> Callable[[dict[str, Any], Context], Derived]: + """A refusal of `status` with the not-retryable `body` answers the first + poll, which raises it, and the exchanges after it go.""" + + def derive(parent: dict[str, Any], ctx: Context) -> Derived: + derived = _async_fetch()(parent, ctx) + index = _poll_index(derived.exchanges) + refused = _refusal(derived.exchanges[index]["request"], status, body) + (outcome,) = derived.expect + (build,) = outcome["dataset"]["long_builds"] + error = refusal_error(status, body, ctx.actions).outcome(ctx.client_codes) + entry = {**build, "poll_waits": build["poll_waits"][:1]} + return Derived( + derived.call, + [*derived.exchanges[:index], refused], + [with_step_notes(error, long_builds=[entry], retry_waits=(), warnings=())], + ) + + return derive def _signed_url_refused(parent: dict[str, Any], ctx: Context) -> Derived: @@ -2462,24 +2479,66 @@ def _signed_fetch_partial(parent: dict[str, Any], ctx: Context) -> Derived: return _same(parent, exchanges) -def _files_route_no_content(parent: dict[str, Any], ctx: Context) -> Derived: - """The files route answers 204 with no location, and the exchanges after - it go.""" - index = _signed_index(parent["exchanges"]) - 1 - exchanges = copy.deepcopy(parent["exchanges"][: index + 1]) - response = exchanges[index]["response"] - response["status"] = 204 - response["headers"] = { +def _files_route_answers( + status: int, *, keep_location: bool +) -> Callable[[dict[str, Any], Context], Derived]: + """The files route answers `status`, with its location when + `keep_location`, and raises ContractError unexpected_response; the + exchanges after it go.""" + + def derive(parent: dict[str, Any], ctx: Context) -> Derived: + index = _signed_index(parent["exchanges"]) - 1 + exchanges = copy.deepcopy(parent["exchanges"][: index + 1]) + response = exchanges[index]["response"] + response["status"] = status + dropped = {"content-type"} if keep_location else {"location", "content-type"} + response["headers"] = { + name: value + for name, value in response.get("headers", {}).items() + if name not in dropped + } + error = ctx.raised("unexpected_response", response) + return Derived( + copy.deepcopy(parent["call"]), + exchanges, + [*copy.deepcopy(parent["expect"][:-1]), error], + ) + + return derive + + +def _files_route_serves_file(parent: dict[str, Any], ctx: Context) -> Derived: + """The files route answers 200 with the file the parent's signed URL + served, and no signed fetch follows.""" + exchanges = copy.deepcopy(parent["exchanges"]) + index = _signed_index(exchanges) + files, signed = exchanges[index - 1], exchanges[index] + headers = { name: value - for name, value in response.get("headers", {}).items() - if name not in {"location", "content-type"} + for name, value in files["response"].get("headers", {}).items() + if name != "location" } - error = ctx.raised("unexpected_response", response) - return Derived( - copy.deepcopy(parent["call"]), - exchanges, - [*copy.deepcopy(parent["expect"][:-1]), error], - ) + headers["content-type"] = signed["response"]["headers"]["content-type"] + files["response"] = {**signed["response"], "headers": headers} + del exchanges[index] + return _same(parent, exchanges) + + +def _folded_parts_unnamed(parent: dict[str, Any], ctx: Context) -> Derived: + """The two folded parts of the first member lose their variable_text, + the first its member and the second to an empty string, so that member + names no part and its part value is its sentence.""" + exchanges = copy.deepcopy(parent["exchanges"]) + parts = exchanges[0]["response"]["json"]["parts"] + require(parts[0]["spec"]["spec_id"] == parts[1]["spec"]["spec_id"], "folded parts") + del parts[0]["variable_text"] + parts[1]["variable_text"] = "" + derived = _same(parent, exchanges) + dataset = derived.expect[-1]["dataset"] + member = dataset["members"][0] + member["parts"] = [] + dataset["part_rows"][0]["part"] = part_label(member) + return derived def _specs_an_object(response: dict[str, Any]) -> None: @@ -3398,6 +3457,16 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: "as a 429's, and the polls after it keep the server's pacing.", _async_fetch(_poll_busy_retry_after), ), + Synthetic( + "fetch-spec-poll-rate-limited-not-retryable", + "mint-async-build", + "As fetch-spec-async-build, with a 429 problem document with no code and " + "retryable false answering the first poll, and the exchanges after it go.", + "A refusal's retryable outranks its status on a poll too: a 429 that says it is " + "not retryable raises RateLimitError at once, where a retryable 429 is polled " + "again without spending a retry.", + _poll_refused_at_once(429, _RATE_LIMITED_FOR_GOOD), + ), Synthetic( "fetch-spec-poll-not-found", "mint-async-build", @@ -3405,7 +3474,7 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: "and the exchanges after it go.", "A refused poll that is not retryable raises its error at once, with the one poll " "made in long_builds.", - _poll_not_found, + _poll_refused_at_once(404, _OPERATION_NOT_FOUND), ), Synthetic( "fetch-spec-operation-failed-resubmitted", @@ -3429,10 +3498,28 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: "fetch-spec-files-route-no-content", "fetch-spec-known-sentence", "The files route answers 204 with no location, and the exchanges after it go.", - "A files route that answers a 2xx other than 200 or 302 raises ContractError " - "unexpected_response, with that response's trace id, and the client fetches " - "nothing.", - _files_route_no_content, + "A files route that answers a status other than 302, 200 or a refusal raises " + "ContractError unexpected_response, with that response's trace id, and the " + "client fetches nothing.", + _files_route_answers(204, keep_location=False), + ), + Synthetic( + "fetch-spec-files-route-temporary-redirect", + "fetch-spec-known-sentence", + "The files route answers 307 with the parent's location, and the exchanges after " + "it go.", + "A files route redirects with 302 only: a 307, as any 3xx other than 302, raises " + "ContractError unexpected_response, and the client does not follow its location.", + _files_route_answers(307, keep_location=True), + ), + Synthetic( + "fetch-spec-files-route-serves-file", + "fetch-spec-known-sentence", + "The files route answers 200 with the file the signed URL served, and the signed " + "fetch goes.", + "A files route that answers 200 holds the file as its body, which the client " + "hashes against the artifact's digest with no further request.", + _files_route_serves_file, ), Synthetic( "fetch-ref-signed-url-refused", @@ -3579,6 +3666,16 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: "lack resolved and identity, and the search and the choice reach the same answers.", _nested_specs_unchecked, ), + Synthetic( + "answer-folded-parts-unnamed", + "answer-several-readings-folded", + "The first folded part loses its variable_text and the second's becomes an empty " + "string.", + "A definite part whose variable_text is absent or empty adds nothing to its " + "member's parts, so the member that answers both names no part and its rows' part " + "value is its sentence.", + _folded_parts_unnamed, + ), Synthetic( "answer-candidate-specs-not-a-list", "answer-candidates-choose-fetch", diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index 747e879..11f9113 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -414,6 +414,24 @@ def _diagnostics_trace(doc: Any) -> None: doc["expect"][1]["error"]["trace_id"] = diagnostics["trace_id"] +def _no_data_options(change: Callable[[Any], Any]) -> Callable[[Any], None]: + """Part 0's no_data options become what `change` makes of them.""" + + def edit(doc: Any) -> None: + no_data = doc["exchanges"][0]["response"]["json"]["parts"][0]["no_data"] + no_data["options"] = change(no_data["options"]) + + return edit + + +def _mentions_a_string(doc: Any) -> None: + """Each no_data option of the first answer mentions one string, its + words joined, in place of a list of words.""" + for part in doc["exchanges"][0]["response"]["json"]["parts"]: + for option in part.get("no_data", {}).get("options", []): + option["mentions"] = " and ".join(option.get("mentions", [])) + + def _poll_waits(change: Callable[[list[float]], None]) -> Callable[[Any], None]: return _set_outcome( 0, lambda o: change(o["dataset"]["long_builds"][0]["poll_waits"]) @@ -1485,6 +1503,32 @@ def change(doc: Any) -> None: lambda doc: doc["exchanges"][1]["response"].update(status=201, json={}), "the steps never make exchanges 2 to 2", ), + ( + _SEARCH, + _no_data_options(lambda options: dict(enumerate(options))), + "expects", + ), + (_SEARCH, _no_data_options(lambda options: None), "step 0 expects"), + ( + "scenarios/choose-part-by-mention.json", + _mentions_a_string, + "the steps never make exchanges 1 to 1", + ), + ( + "scenarios/answer-timed-out.json", + _set_body(0, lambda body: body.update(diagnostics="timed out")), + "step 0 expects", + ), + ( + "scenarios/answer-candidates-choose-fetch.json", + _set_body( + 0, + lambda body: body["parts"][0]["candidates"]["specs"].__setitem__( + 0, "x" + ), + ), + "the step follows no answer", + ), ], ids=[ "strict-pointer-unresolved", @@ -1704,6 +1748,11 @@ def change(doc: Any) -> None: "signed-fetch-206-read-as-the-file", "files-route-204-read-as-a-redirect", "files-route-201-read-as-a-redirect", + "no-data-options-as-an-object-counted", + "no-data-options-null-counted", + "mentions-as-a-string-matched", + "diagnostics-not-an-object-read", + "candidate-spec-not-an-object-read", ], ) def test_a_broken_contract_is_reported( @@ -1734,6 +1783,33 @@ def test_a_record_that_holds_only_under_its_recorded_host_is_reported( assert any(p.startswith(name) for p in problems), problems +@pytest.mark.parametrize( + ("headers", "reported"), + [ + ({}, True), + ({"cache-control": "no-store"}, True), + ({"cache-control": "public, max-age=60"}, False), + ], + ids=["untraced", "untraced-private", "shared-cacheable"], +) +def test_a_recorded_response_without_a_trace_id_is_reported( + package_dir: Path, headers: dict[str, str], reported: bool +) -> None: + """The server sends x-dfo-trace-id on every API response but one marked + Cache-Control: public, so a recorded response without it is one the + server did not send.""" + + def change(doc: Any) -> None: + kept = doc["exchanges"][0]["response"]["headers"] + del kept["x-dfo-trace-id"] + kept.update(headers) + + _edit(package_dir / _FETCH, change) + problems = validator.validate() + found = [p for p in problems if "carries no x-dfo-trace-id" in p] + assert bool(found) is reported, problems + + def test_a_retired_code_with_a_row_is_reported(package_dir: Path) -> None: _edit(validator.REGISTRY_PATH, _retire("spec_not_found")) problems = validator.validate() diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index 755576a..66c9fda 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -56,9 +56,10 @@ and the class of each error the client raises itself from `client-codes.json`, as `expected_outcomes` derives them, the waits before each poll included, under the record's base URL and again under - REPLAY_ORIGIN with the recorded origin a response names moved there; a dataset's rows, columns and per-part row - counts are left to the Parquet bodies, and each download hashes to its - artifact's digest or the outcome says it does not. Each Search request a + REPLAY_ORIGIN with the recorded origin a response names moved there; a + dataset's rows, columns and per-part row counts are left to the Parquet + bodies, and each download hashes to its artifact's digest or the outcome + says it does not. Each Search request a record holds posts the input the steps derive: the question, a choice's data_query or dataset_resubmit entries, or a member's identity with the entity groups of the roles its build left bound as they were, and each @@ -991,6 +992,19 @@ def trace_id(body: Any, headers: Mapping[str, str] | None) -> str | None: return header or None +def shared_cacheable(headers: Mapping[str, str]) -> bool: + """Whether a response is marked `Cache-Control: public`: a shared cache + replays it, so it carries no per-request trace id.""" + directives = headers.get("cache-control", "").lower().replace(" ", "").split(",") + return "public" in directives + + +def untraced(headers: Mapping[str, str]) -> bool: + """Whether an API response lacks the TRACE_HEADER header the server sends + on every response but a shared-cacheable one.""" + return TRACE_HEADER not in headers and not shared_cacheable(headers) + + def refusal_error( status: int, body: Any, @@ -1033,6 +1047,39 @@ def read_from(error: ClientError, trace: str | None) -> ClientError: return error +# --- reading members no strict pointer names --------------------------------- +# +# A member a client reads that no strict pointer names, and that holds a JSON +# type other than the one its rule reads, reads as absent; so does every +# member of a holder that is not an object. Each read of such a member goes +# through one of these. + + +def read_object(holder: Any, name: str) -> dict[str, Any] | None: + """`holder`'s member `name` when it is an object, else None.""" + value = holder.get(name) if isinstance(holder, dict) else None + return value if isinstance(value, dict) else None + + +def read_list(holder: Any, name: str) -> list[Any] | None: + """`holder`'s member `name` when it is a list, else None.""" + value = holder.get(name) if isinstance(holder, dict) else None + return value if isinstance(value, list) else None + + +def read_objects(holder: Any, name: str) -> list[dict[str, Any]]: + """The object items of `holder`'s list member `name`: an absent list, or + one of another type, holds none, and an item of another type reads as + absent.""" + return [item for item in read_list(holder, name) or [] if isinstance(item, dict)] + + +def read_string(holder: Any, name: str) -> str | None: + """`holder`'s member `name` when it is a string, else None.""" + value = holder.get(name) if isinstance(holder, dict) else None + return value if isinstance(value, str) else None + + # The answer kinds a client reads. Any other kind raises ContractError. ANSWER_KINDS = ("resolution", "catalogue", "declined") RESOLUTION = "resolution" @@ -1066,7 +1113,9 @@ def answer_from_body(body: Any) -> Answer: raise ClientError("contract_violation") if body["kind"] == RESOLUTION and not parts: raise ClientError("contract_violation") - return Answer(body, parts, body.get("rendered_sentence"), body.get("status")) + return Answer( + body, parts, read_string(body, "rendered_sentence"), read_string(body, "status") + ) def _readable(part: Any) -> bool: @@ -1076,7 +1125,7 @@ def _readable(part: Any) -> bool: return False specs = [part.get("spec")] if part["status"] == "definite" else [] if part["status"] == "candidates": - specs = (part.get("candidates") or {}).get("specs") or [] + specs = read_list(read_object(part, "candidates"), "specs") or [] return all( not isinstance(spec, dict) or not isinstance(spec.get("definition"), dict) @@ -1125,14 +1174,16 @@ def choice_for( index = part else: named = [ - i for i, p in enumerate(answer.parts) if p.get("variable_text") == part + i + for i, p in enumerate(answer.parts) + if read_string(p, "variable_text") == part ] if not named: mention = part named = [ i for i in sorted(gap_parts) - if any(part in o.get("mentions", []) for o in _options(answer, i)) + if any(part in mentions(o) for o in _options(answer, i)) ] if len(named) != 1: raise _refuse() @@ -1155,8 +1206,8 @@ def choice_for( found = [ o for o in options - if o.get("label") == option - and (mention is None or mention in o.get("mentions", [])) + if read_string(o, "label") == option + and (mention is None or mention in mentions(o)) ] if len(found) != 1: raise _refuse() @@ -1164,7 +1215,13 @@ def choice_for( def _options(answer: Answer, index: int) -> list[dict[str, Any]]: - return answer.parts[index].get("no_data", {}).get("options", []) + """A part's no_data options, as `read_objects` reads them.""" + return read_objects(read_object(answer.parts[index], "no_data"), "options") + + +def mentions(option: Mapping[str, Any]) -> list[str]: + """The words a no_data option mentions, its string items.""" + return [w for w in read_list(option, "mentions") or [] if isinstance(w, str)] def choice_input(answer: Answer, choice: Choice) -> dict[str, Any]: @@ -1211,7 +1268,7 @@ def resubmit_entry(part: dict[str, Any], choice: Choice | None) -> dict[str, Any return _echo( part, entry_kind="candidates", - ordering=candidates.get("ordering"), + ordering=read_string(candidates, "ordering"), truncated=candidates.get("truncated") is True, candidates=[ _identity(spec, reading_echo(part, spec)) @@ -1247,8 +1304,8 @@ def reading_echo(part: Mapping[str, Any], spec: Mapping[str, Any]) -> Any: no `assumptions`, and Search reads the reading as a fresh request does; `[]` states none.""" if part.get("status") == "candidates": - return (part.get("reading_assumptions") or {}).get(spec["spec_id"]) - return part.get("assumptions") + return read_list(read_object(part, "reading_assumptions"), spec["spec_id"]) + return read_list(part, "assumptions") def _restated_entry(part: dict[str, Any]) -> dict[str, Any]: @@ -1275,7 +1332,7 @@ def _identity(spec: dict[str, Any], assumptions: Any = None) -> dict[str, Any]: """A spec's identity, its entity groups when it has any, and the reading's `assumptions` echo unless it is None.""" item: dict[str, Any] = {"identity": spec["definition"]["identity"]} - groups = spec.get("resolved", {}).get("entity_groups") + groups = read_object(spec.get("resolved"), "entity_groups") if groups: item["entity_groups"] = groups if assumptions is not None: @@ -1283,27 +1340,21 @@ def _identity(spec: dict[str, Any], assumptions: Any = None) -> dict[str, Any]: return item -def listed(holder: Mapping[str, Any], name: str) -> list[Any]: - """A member a client reads as a list, and that no strict pointer names: - a member of another type reads as absent, as an empty list.""" - value = holder.get(name) - return value if isinstance(value, list) else [] - - def _echo(part: dict[str, Any], **members: Any) -> dict[str, Any]: """An entry with the members every entry but a parsed one echoes from its part: variable_text, separate when true, and operations when any.""" - if not part.get("variable_text"): + variable_text = read_string(part, "variable_text") + if not variable_text: raise _refuse() - entry: dict[str, Any] = {**members, "variable_text": part["variable_text"]} + entry: dict[str, Any] = {**members, "variable_text": variable_text} if part.get("separate") is True: entry["separate"] = True - if operations := listed(part, "operations"): + if operations := read_list(part, "operations"): entry["operations"] = operations return entry -def reading_hints(answer: Answer) -> dict[str, str]: +def reading_hints(answer: Answer) -> dict[str, str | None]: """How `answer`'s readings differ from the question, each line a client shows once, with its code. In part order, each definite part gives each operation Search did not run, coded by its verb, each departure, and each @@ -1311,21 +1362,24 @@ def reading_hints(answer: Answer) -> dict[str, str]: warnings follow. An `info` warning gives nothing.""" hints: dict[str, str] = {} - def notices(warnings: list[Any]) -> None: - for warning in warnings: - if warning.get("severity") in SHOWN_SEVERITIES and warning.get("message"): - hints.setdefault(f"Note: {warning['message']}", warning["code"]) + def notices(holder: Any) -> None: + for warning in read_objects(holder, "warnings"): + message = read_string(warning, "message") + if read_string(warning, "severity") in SHOWN_SEVERITIES and message: + hints.setdefault(f"Note: {message}", read_string(warning, "code")) for part in answer.parts: if part.get("status") != "definite": continue - for operation in listed(part, "operations"): - line = f"Not done: {operation['verb']} ({json.dumps(operation['phrase'])})" - hints.setdefault(line, operation["verb"]) - for departure in listed(part, "departures"): - hints.setdefault(departure["text"], departure["code"]) - notices(listed(part, "warnings")) - notices(listed(answer.body.get("diagnostics", {}), "warnings")) + for operation in read_objects(part, "operations"): + if verb := read_string(operation, "verb"): + phrase = json.dumps(operation.get("phrase")) + hints.setdefault(f"Not done: {verb} ({phrase})", verb) + for departure in read_objects(part, "departures"): + if text := read_string(departure, "text"): + hints.setdefault(text, read_string(departure, "code")) + notices(part) + notices(read_object(answer.body, "diagnostics")) return hints @@ -1346,7 +1400,8 @@ def answer_gaps(answer: Answer, kinds: Mapping[str, str]) -> list[dict[str, Any] """Each part without a reading: a candidates part is a choice among its specs; a no_data part takes its reason's gap kind, or `timed_out` when the answer timed out; a part of unknown status is an `unknown` gap.""" - timed_out = answer.body.get("diagnostics", {}).get("timed_out") is True + diagnostics = read_object(answer.body, "diagnostics") + timed_out = diagnostics is not None and diagnostics.get("timed_out") is True gaps = [] for index, part in enumerate(answer.parts): match part.get("status"): @@ -1361,7 +1416,7 @@ def answer_gaps(answer: Answer, kinds: Mapping[str, str]) -> list[dict[str, Any] if timed_out else kinds.get(no_data["reason"], "no_data") ) - options = len(no_data.get("options", [])) + options = len(read_objects(no_data, "options")) case "unsupported": kind, options = "unsupported", 0 case _: @@ -1380,8 +1435,8 @@ def answer_members(answer: Answer) -> list[tuple[list[str], dict[str, Any]]]: continue spec = part["spec"] named = members.setdefault(spec["spec_id"], ([], spec))[0] - if part.get("variable_text"): - named.append(part["variable_text"]) + if variable_text := read_string(part, "variable_text"): + named.append(variable_text) return list(members.values()) @@ -1393,9 +1448,9 @@ def held_spec(spec: Mapping[str, Any]) -> dict[str, Any]: held = { "spec_id": spec["spec_id"], "definition": spec["definition"], - "sentence": resolved["rendered_sentence"], + "sentence": read_string(resolved, "rendered_sentence"), } - if groups := resolved.get("entity_groups"): + if groups := read_object(resolved, "entity_groups"): held["entity_groups"] = groups return held @@ -1502,7 +1557,8 @@ def strict_gaps( component: str | None = None, ) -> list[str]: """The strict members `body` lacks, holds as null, or holds as a JSON - type their schema does not admit, read through `schema`: each component + type their schema does not admit, and each item of a strict list of a + type its item schema does not admit, read through `schema`: each component schema it reaches names its own, and a discriminated union whose discriminator `body` lacks is a gap. The walk goes down only through strict members, the ones a client reads, so a @@ -1556,7 +1612,11 @@ def strict_gaps( strict_gaps(openapi, members, member, body[name], f"{where}/{name}") ) if isinstance(body, list) and "items" in schema: + types = schema_types(openapi, schema["items"]) for index, item in enumerate(body): + if types is not None and json_type(item) not in types: + gaps.append(f"{where}/{index}") + continue gaps.extend( strict_gaps(openapi, members, schema["items"], item, f"{where}/{index}") ) @@ -1706,19 +1766,16 @@ def selector_path( # client fetches from, and the query every signed URL in a record carries. STORAGE_ORIGIN = "https://storage.googleapis.com" REDACTED_QUERY = "X-Goog-Signature=redacted" -# The successes a files route answers with the file's `location`; any other -# 2xx raises ContractError `unexpected_response`. A signed fetch that answers +# A files route answers FILES_ROUTE_REDIRECT with the `location` the client +# fetches, or FILES_ROUTE_FILE with the file as its body; a refusal reads by +# the refusal rules, and any other status, another 2xx or 3xx included, +# raises ContractError `unexpected_response`. A signed fetch that answers # other than SIGNED_FETCH_STATUS is a failed fetch. -FILES_ROUTE_STATUSES = frozenset({200, 302}) +FILES_ROUTE_REDIRECT = 302 +FILES_ROUTE_FILE = 200 SIGNED_FETCH_STATUS = 200 -def files_route_unexpected(status: int) -> bool: - """Whether a files route's answer is a 2xx other than those of - FILES_ROUTE_STATUSES, which raises ContractError `unexpected_response`.""" - return 200 <= status < 300 and status not in FILES_ROUTE_STATUSES - - def download_target(base_url: str, route_url: str, location: str) -> tuple[str, str]: """Where a client fetches the file a files route's `location` names, as `(kind, target)`: a URL on the storage host as `url`, fetched bare; @@ -1751,9 +1808,9 @@ def artifact_route(base_url: str, url: str) -> str: def data_warning(manifest: Mapping[str, Any]) -> ClientError | None: """The DataWarning a strict fetch raises for a manifest: its first warning above `info` severity, with that warning's code; None when it has none.""" - for warning in manifest.get("warnings") or []: - if isinstance(warning, dict) and warning.get("severity") != "info": - return ClientError(warning.get("code"), error="DataWarning") + for warning in read_objects(manifest, "warnings"): + if read_string(warning, "severity") != "info": + return ClientError(read_string(warning, "code"), error="DataWarning") return None @@ -1782,11 +1839,12 @@ def kept_entity_groups( if held is None or not (groups := held.get("entity_groups")): return {} before = held["definition"]["identity"].get("entities", {}) - after = built["identity"].get("entities", {}) + after = read_object(built["identity"], "entities") or {} return { role: group for role, group in groups.items() - if role in after and set(after[role]) == set(before.get(role, ())) + if isinstance(after.get(role), list) + and set(after[role]) == set(before.get(role, ())) } @@ -1834,13 +1892,15 @@ def failed_operation( class LongBuild: """A build the server runs on, followed the way a client polls it. Each - wait before a poll is `PollPacing`'s. A 429 poll spends no retry, any - other retryable refused poll one of MAX_RETRIES, and any other refused - poll raises; the poll after a refusal waits as `PollPacing` gives. A poll answering a failed operation, retryable by its - error, posts the build again once when the client holds its request; - otherwise, and for an operation that failed before the client polled - it, the operation's error raises. `entry` is the build's `long_builds` - entry, and `result` its manifest once it is done.""" + wait before a poll is `PollPacing`'s. A retryable 429 poll spends no + retry, any other retryable refused poll one of MAX_RETRIES, and a refused + poll that is not retryable raises, a 429 included; the poll after a + refusal waits as `PollPacing` gives. A poll answering a failed + operation, retryable by its error, posts the build again once when the + client holds its request; otherwise, and for an operation that failed + before the client polled it, the operation's error raises. `entry` is + the build's `long_builds` entry, and `result` its manifest once it is + done.""" def __init__( self, @@ -1895,8 +1955,10 @@ def polled(self, status: int, headers: Mapping[str, str], body: Any) -> bool: error = refusal_error(status, body, self.actions, headers) again = retryable(status, body) if error.code != OPERATION_FAILED: + if not again: + raise error if status != 429: - if not again or self.retries >= MAX_RETRIES: + if self.retries >= MAX_RETRIES: raise error self.retries += 1 self.pacing.refused_poll(headers) @@ -2065,14 +2127,14 @@ def body(self, response: dict[str, Any]) -> bytes: return b"" def download(self, target: str, digest: str, *, origin: bool) -> None: - """A file through the route that redirects to its signed URL: an - `origin_path`, as `artifact_route` places an artifact's `url`, when - `origin`, else a path under the base URL. A route answering a 2xx - other than 200 or 302 raises ContractError `unexpected_response`. - The client fetches once the URL the route's `location` names, as - `download_target` places it. A fetch answering other than 200, or - bytes that do not hash to `digest`, ask the route once more, and a - second failure raises.""" + """A file through its files route: an `origin_path`, as + `artifact_route` places an artifact's `url`, when `origin`, else a + path under the base URL. A 302 names the signed URL in its + `location`, which the client fetches once where `download_target` + places it; a 200 holds the file; a refusal raises; any other status + raises ContractError `unexpected_response`. A fetch answering other + than 200, or bytes that do not hash to `digest`, ask the route once + more, and a second failure raises.""" failure = ClientError("download_failed") base = urlsplit(self.base_url) route_url = ( @@ -2082,19 +2144,26 @@ def download(self, target: str, digest: str, *, origin: bool) -> None: ) for _ in range(2): kind = "origin_path" if origin else "path" - exchange = self.call("GET", target, kind=kind) - self.acted_on(exchange) - if files_route_unexpected(exchange["response"]["status"]): + files = self.call("GET", target, kind=kind)["response"] + status = files["status"] + if status >= 400: + raise refusal_error( + status, problem_body(files), self.actions, files.get("headers") + ) + if status == FILES_ROUTE_FILE: + file = files + elif status == FILES_ROUTE_REDIRECT: + location = files.get("headers", {}).get("location") + if not isinstance(location, str): + raise _UnfitError(f"the redirect from {target} names no location") + fetched, at = download_target(self.base_url, route_url, location) + file = self.call("GET", at, kind=fetched, retries=False)["response"] + if file["status"] != SIGNED_FETCH_STATUS: + failure = ClientError("download_failed") + continue + else: raise ClientError("unexpected_response") - location = exchange["response"].get("headers", {}).get("location") - if not isinstance(location, str): - raise _UnfitError(f"the redirect from {target} names no location") - fetched, at = download_target(self.base_url, route_url, location) - signed = self.call("GET", at, kind=fetched, retries=False)["response"] - if signed["status"] != SIGNED_FETCH_STATUS: - failure = ClientError("download_failed") - continue - if digest_of(self.body(signed)) == digest: + if digest_of(self.body(file)) == digest: return failure = ClientError("digest_mismatch") raise failure @@ -2778,6 +2847,12 @@ def _check_scenarios( label, exchange, base_path, routes, registry, proxy_codes ) ) + headers = exchange["response"].get("headers", {}) + if "url" not in exchange["request"] and untraced(headers): + problems.append( + f"{label}: the API response carries no {TRACE_HEADER} " + "header and is not marked Cache-Control: public" + ) else: problems.extend( _check_problem_code( From 677e52372ffad671145c19bf03980ed4478dbc1f Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Wed, 21 Oct 2026 16:13:13 +0200 Subject: [PATCH 24/39] fix(client-contract): read entity bindings through the typed accessors, and report a crashing derivation against its record kept_entity_groups reads entity_groups, the identity and its entities through read_object and compares only the string refs a role binds, so a malformed binding reads as absent. An exception while deriving one record's outcomes is reported against that record, and the other records are still checked. A body trace_id that is empty or not a string reads as absent, and a test pins it. The scenario schema's headers description names the cache-control header that excuses a shared-cacheable response from x-dfo-trace-id. --- python/client-contract/README.md | 4 +- .../dfo_client_contract/scenario.schema.json | 2 +- tools/tests/test_validate_client_contract.py | 47 +++++++++++++++++++ tools/validate_client_contract.py | 24 +++++++--- 4 files changed, 68 insertions(+), 9 deletions(-) diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 4e77c07..82b0aed 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -138,9 +138,9 @@ A step that acts on an earlier result follows one: `choose` follows `search` or An exchange's request names its target in one of three ways. `path` is a path the client composes under the base URL, such as `/search/resolve`. `origin_path` is a root-relative URL the server returned, such as an artifact's `url`, or the path and query of an absolute one on the API's origin, which resolves against the base URL's origin and never against its path. `url` is an absolute URL outside the API, such as the signed storage URL a files route redirects to, which the client fetches with a bare request carrying no client header and no key. `json` holds the request body members that must match; a recorded scenario lists every member the client sent. The response gives `status`, the `headers` a client reads, and a `json` body or a `body_file`, a binary body in `scenarios/`. A scenario's own body files are named `.` and `-.`; a synthetic scenario may instead name a body file its parent names. -A `newest_version` outcome gives the `content_version` the step found, or null. An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a warning's code, which for a `SearchWarning` may be null, or for any other error the client raises itself its code in `client-codes.json`. Every error outcome gives its `trace_id`: a refusal's, as the refusal rules below give it; a failed operation's, its error document's `trace_id`, else the `x-dfo-trace-id` header of the response that carried the failed resource; a `VersionUnavailableError`'s, its first refusal's, or null when nothing refused. An error the client raises itself follows one rule: an error that describes a response carries that response's trace id, and an error that describes the caller's input carries null. The trace id is the one a user quotes to find the fault in the server's logs. The errors that describe a response are `unexpected_response`, `contract_violation` on a body, `answer_declined`, `answer_incomplete`, and a strict fetch's `SearchWarning` or `DataWarning`. A response's trace id is the top-level `trace_id` member of its body when the body is a JSON object holding one as a non-empty string, a problem document or any other body, else its `x-dfo-trace-id` header, else null. A Search answer's `diagnostics.trace_id` is not read, and `answer-timed-out` pins the header's winning over a `diagnostics.trace_id` that differs from it. `answer_declined`, `answer_incomplete`, a `SearchWarning`, and a `contract_violation` a choice raises on an option describe the held answer, so they carry the trace id of the Search response that answered it. The errors that describe the caller's input, `choice_invalid`, `invalid_argument` and the key-lookup reasons, carry null, and so do `digest_mismatch` and `download_failed`, which describe a storage-host fetch, and `deadline_exceeded`, `network_error` and `offline`, which describe no response. `search-no-json-body`, `fetch-spec-strict-warning`, `answer-timed-out`, `answer-empty-parts`, `fetch-spec-files-route-no-content` and `choose-option-two-part-query` pin a trace id on an error that describes a response, `operation-failed-without-error` the header of the response that carried a failed resource with no error, and `choose-refused-shared-label` a null one on a choice whose answer's response carries a trace id. A `VersionUnavailableError` also gives `newest_version`, the version the lookup found, or null. A dataset or error outcome of a step that made a long build gives `long_builds`, one entry per build the server ran on, in order: the `operation_id` the client polled last, the `poll_waits` in seconds before each poll, and the number of `resubmissions`. Any outcome of a step that retried a refused request gives `retry_waits`, the seconds before each retry in order, and any outcome of a step whose API responses issued warnings gives `warnings`, their codes from `warning-codes.json` in order. +A `newest_version` outcome gives the `content_version` the step found, or null. An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a warning's code, which for a `SearchWarning` may be null, or for any other error the client raises itself its code in `client-codes.json`. Every error outcome gives its `trace_id`: a refusal's, as the refusal rules below give it; a failed operation's, its error document's `trace_id`, else the `x-dfo-trace-id` header of the response that carried the failed resource; a `VersionUnavailableError`'s, its first refusal's, or null when nothing refused. An error the client raises itself follows one rule: an error that describes a response carries that response's trace id, and an error that describes the caller's input carries null. The trace id is the one a user quotes to find the fault in the server's logs. The errors that describe a response are `unexpected_response`, `contract_violation` on a body, `answer_declined`, `answer_incomplete`, and a strict fetch's `SearchWarning` or `DataWarning`. A response's trace id is the top-level `trace_id` member of its body when the body is a JSON object holding one as a non-empty string, a problem document or any other body, else its `x-dfo-trace-id` header, else null. A body `trace_id` that is empty or not a string reads as absent, so the header applies; no scenario holds one, and the validator's tests pin it. A Search answer's `diagnostics.trace_id` is not read, and `answer-timed-out` pins the header's winning over a `diagnostics.trace_id` that differs from it. `answer_declined`, `answer_incomplete`, a `SearchWarning`, and a `contract_violation` a choice raises on an option describe the held answer, so they carry the trace id of the Search response that answered it. The errors that describe the caller's input, `choice_invalid`, `invalid_argument` and the key-lookup reasons, carry null, and so do `digest_mismatch` and `download_failed`, which describe a storage-host fetch, and `deadline_exceeded`, `network_error` and `offline`, which describe no response. `search-no-json-body`, `fetch-spec-strict-warning`, `answer-timed-out`, `answer-empty-parts`, `fetch-spec-files-route-no-content` and `choose-option-two-part-query` pin a trace id on an error that describes a response, `operation-failed-without-error` the header of the response that carried a failed resource with no error, and `choose-refused-shared-label` a null one on a choice whose answer's response carries a trace id. A `VersionUnavailableError` also gives `newest_version`, the version the lookup found, or null. A dataset or error outcome of a step that made a long build gives `long_builds`, one entry per build the server ran on, in order: the `operation_id` the client polled last, the `poll_waits` in seconds before each poll, and the number of `resubmissions`. Any outcome of a step that retried a refused request gives `retry_waits`, the seconds before each retry in order, and any outcome of a step whose API responses issued warnings gives `warnings`, their codes from `warning-codes.json` in order. -Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry where the retry rules allow one, except on a poll, where the long-build rules count retries, and a record that ends a run of retries while the rules allow another does not fit, since the client makes it, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, each POST carries its body, each build posts the body the rules give for the spec it builds, so the builds' order and spec_ids are checked, each Search request posts the whole body `{"schema_version": 1, "input": ...}` with the input the rules give: the question, a choice's input, or a member's identity, each poll names the operation the client holds, each files route is the one the artifact's `url` names, each signed download is the URL the files route's `location` names, each retry waits the wait the retry rules give, and each response's warning headers issue the warnings the warning rules give. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. +Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. A record whose outcomes it cannot derive, because its exchanges do not fit its steps or a malformed member raises while it reads them, is reported as that record's problem, and the other records are still checked. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry where the retry rules allow one, except on a poll, where the long-build rules count retries, and a record that ends a run of retries while the rules allow another does not fit, since the client makes it, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, each POST carries its body, each build posts the body the rules give for the spec it builds, so the builds' order and spec_ids are checked, each Search request posts the whole body `{"schema_version": 1, "input": ...}` with the input the rules give: the question, a choice's input, or a member's identity, each poll names the operation the client holds, each files route is the one the artifact's `url` names, each signed download is the URL the files route's `location` names, each retry waits the wait the retry rules give, and each response's warning headers issue the warnings the warning rules give. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. A recorded scenario's request and response bodies validate against their route's schemas in `served/openapi.json`. A required member stays required when its schema admits null: the body carries it, as null or a value. A member the schema leaves optional may be absent or null, and a client reads both as null. diff --git a/python/client-contract/src/dfo_client_contract/scenario.schema.json b/python/client-contract/src/dfo_client_contract/scenario.schema.json index b0af29b..d1c6481 100644 --- a/python/client-contract/src/dfo_client_contract/scenario.schema.json +++ b/python/client-contract/src/dfo_client_contract/scenario.schema.json @@ -544,7 +544,7 @@ "maximum": 599 }, "headers": { - "description": "The response headers a client reads, by lower-case name.", + "description": "The response headers a client reads, by lower-case name, and a cache-control header that marks the response shared-cacheable, which excuses it from carrying x-dfo-trace-id.", "type": "object", "propertyNames": { "pattern": "^[a-z0-9-]+$", diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index 11f9113..a5e468b 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -424,6 +424,15 @@ def edit(doc: Any) -> None: return edit +def _built_destination_as_objects(doc: Any) -> None: + """The built manifest binds destination to objects, not refs, so the + build keeps no destination group and the sentence lookup posts none.""" + entities = doc["exchanges"][0]["response"]["json"]["definition"]["identity"][ + "entities" + ] + entities["destination"] = [{"dcid": ref} for ref in entities["destination"]] + + def _mentions_a_string(doc: Any) -> None: """Each no_data option of the first answer mentions one string, its words joined, in place of a list of words.""" @@ -1509,6 +1518,7 @@ def change(doc: Any) -> None: "expects", ), (_SEARCH, _no_data_options(lambda options: None), "step 0 expects"), + (_GROUP_NARROWED, _built_destination_as_objects, "where the rules post"), ( "scenarios/choose-part-by-mention.json", _mentions_a_string, @@ -1750,6 +1760,7 @@ def change(doc: Any) -> None: "files-route-201-read-as-a-redirect", "no-data-options-as-an-object-counted", "no-data-options-null-counted", + "bound-entities-as-objects-compared", "mentions-as-a-string-matched", "diagnostics-not-an-object-read", "candidate-spec-not-an-object-read", @@ -1783,6 +1794,42 @@ def test_a_record_that_holds_only_under_its_recorded_host_is_reported( assert any(p.startswith(name) for p in problems), problems +@pytest.mark.parametrize("body_trace", ["", 7], ids=["empty", "a-number"]) +def test_a_body_trace_id_that_is_not_a_non_empty_string_reads_as_absent( + package_dir: Path, body_trace: Any +) -> None: + """A problem document's trace_id that is empty or not a string reads as + absent, so the refusal carries its x-dfo-trace-id header.""" + + def change(doc: Any) -> None: + response = doc["exchanges"][0]["response"] + response["json"]["trace_id"] = body_trace + doc["expect"][0]["error"]["trace_id"] = response["headers"]["x-dfo-trace-id"] + + _edit(package_dir / _CODELESS, change) + problems = validator.validate() + assert not [p for p in problems if _CODELESS in p], problems + + +def test_one_record_that_crashes_its_derivation_is_its_own_problem( + package_dir: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """An exception while deriving one record's outcomes is that record's + problem, and every other record is still checked.""" + step = validator._Replay.step + + def crashing(self: Any, chosen: dict[str, Any]) -> dict[str, Any]: + if chosen.get("question") == "should donors give more aid to Kenya?": + raise TypeError("a malformed member the rules missed") + return step(self, chosen) + + monkeypatch.setattr(validator._Replay, "step", crashing) + _edit(package_dir / _FETCH, _set_outcome(0, lambda o: o.update(dataset={}))) + problems = validator.validate() + assert any(p.startswith(_DECLINED) and "TypeError" in p for p in problems), problems + assert any(p.startswith(_FETCH) for p in problems), problems + + @pytest.mark.parametrize( ("headers", "reported"), [ diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index 66c9fda..14ec369 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -1836,18 +1836,24 @@ def kept_entity_groups( each role the built identity binds to the same entities the held definition binds it to. A role the narrowing rebound or dropped loses its group; a window or facets narrowing keeps every group.""" - if held is None or not (groups := held.get("entity_groups")): + if held is None or not (groups := read_object(held, "entity_groups")): return {} - before = held["definition"]["identity"].get("entities", {}) - after = read_object(built["identity"], "entities") or {} + before = read_object(read_object(held["definition"], "identity"), "entities") + after = read_object(built["identity"], "entities") return { role: group for role, group in groups.items() - if isinstance(after.get(role), list) - and set(after[role]) == set(before.get(role, ())) + if read_list(after, role) is not None + and bound_refs(after, role) == bound_refs(before, role) } +def bound_refs(entities: dict[str, Any] | None, role: str) -> set[str]: + """The refs an identity's `entities` binds `role` to, its string items; + a binding of another type, or an item of one, reads as absent.""" + return {ref for ref in read_list(entities, role) or [] if isinstance(ref, str)} + + def sentence_entry( parts: list[str], built: Mapping[str, Any], held: Mapping[str, Any] | None ) -> dict[str, Any]: @@ -2571,7 +2577,9 @@ def expected_outcomes( columns. Raises: - ValueError: The exchanges do not fit the steps. + ValueError: The exchanges do not fit the steps, or deriving an + outcome raised, so the record names its own problem and the + other records are still checked. """ replay = _Replay( record["exchanges"], @@ -2586,6 +2594,10 @@ def expected_outcomes( outcomes = [replay.step(step) for step in record["call"]] except (_UnfitError, KeyError, IndexError, StopIteration, ValueError) as exc: raise ValueError(f"the exchanges do not fit the steps: {exc!r}") from exc + # Any other exception is a malformed record the rules missed: it is this + # record's problem, and the other records are still checked. + except Exception as exc: + raise ValueError(f"deriving its outcomes raised {exc!r}") from exc if replay.cursor != len(replay.exchanges): raise ValueError( f"the steps never make exchanges {replay.cursor} to " From f2c102bce513fc7cee68d0322d39cd2790b14f17 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Wed, 21 Oct 2026 16:53:44 +0200 Subject: [PATCH 25/39] docs(client-contract): tighten the contract README, rules and tools prose Split clause-joining semicolons and mid-sentence colons into sentences and state facts positively in the package README, the rules README, tools/README.md and the capture and validate tools. Every rule keeps its cases and codes; the tools keep their help text. No code changes. --- python/client-contract/README.md | 26 ++-- .../src/dfo_client_contract/rules/README.md | 4 +- tools/README.md | 2 +- tools/capture_client_contract.py | 106 +++++++------- tools/validate_client_contract.py | 137 +++++++++--------- 5 files changed, 138 insertions(+), 137 deletions(-) diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 82b0aed..1d97269 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -118,7 +118,7 @@ An answer's gaps follow from its parts. A candidates part is a `choice` gap, its ## Client codes -`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, `retryable`, and a one-line `condition`. `retryable` is the flag both clients generate onto the error: `deadline_exceeded`, `download_failed` and `network_error` are retryable, `digest_mismatch` and the rest are not, and `refusal_without_code` is retryable as its status is, which its row gives as `by_status`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps the server's code: the problem document's `code`, or the website proxy's `error`. A refusal whose body carries neither raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`; no other row does. A problem document without a code still gives the error its `retryable` and `trace_id`, so a 503 whose body says `retryable: false` raises at once, which `search-refused-without-code` pins. Every refusal's trace id is the response's trace id, as the trace-id rule under Scenarios gives it: `search-refused-without-code` pins the body's winning over the header, and `search-unauthorized` the header's for a refusal with no body. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. Each reason the key-lookup rule raises, `key_empty`, `profile_not_found`, `profile_without_key` and `credentials_file_invalid`, is a row of class `AuthenticationError`. The list holds no warning. `warning-codes.json` lists, sorted by code, each code a client sets on a warning it issues itself, with its class and condition: `route_deprecated`, a `DfoDeprecationWarning`, for a `Deprecation` or `Sunset` header; `server_warning`, a `DfoWarning`, for an `x-dfo-warning` header; and `key_checksum_mismatch`, `key_not_base62` and `key_unknown_prefix`, each a `DfoWarning`, for a key that fails the key-format rule with that reason. Both clients generate their warning codes from it and issue no other. No warning code is a code in another table or in `registries/codes.json`. A `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and a null code when they differ in several ways. A `DataWarning` carries the manifest warning's code. +`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, `retryable`, and a one-line `condition`. `retryable` is the flag both clients generate onto the error: `deadline_exceeded`, `download_failed` and `network_error` are retryable, `digest_mismatch` and the rest are not, and `refusal_without_code` is retryable as its status is, which its row gives as `by_status`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps the server's code: the problem document's `code`, or the website proxy's `error`. A refusal whose body carries neither raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`. No other row does. A problem document without a code still gives the error its `retryable` and `trace_id`, so a 503 whose body says `retryable: false` raises at once, which `search-refused-without-code` pins. Every refusal's trace id is the response's trace id, as the trace-id rule under Scenarios gives it. `search-refused-without-code` pins the body's winning over the header, and `search-unauthorized` the header's for a refusal with no body. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. Each reason the key-lookup rule raises, `key_empty`, `profile_not_found`, `profile_without_key` and `credentials_file_invalid`, is a row of class `AuthenticationError`. The list holds no warning. `warning-codes.json` lists, sorted by code, each code a client sets on a warning it issues itself, with its class and condition: `route_deprecated`, a `DfoDeprecationWarning`, for a `Deprecation` or `Sunset` header; `server_warning`, a `DfoWarning`, for an `x-dfo-warning` header; and `key_checksum_mismatch`, `key_not_base62` and `key_unknown_prefix`, each a `DfoWarning`, for a key that fails the key-format rule with that reason. Both clients generate their warning codes from it and issue no other. No warning code is a code in another table or in `registries/codes.json`. A `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and a null code when they differ in several ways. A `DataWarning` carries the manifest warning's code. ## Scenarios @@ -136,11 +136,11 @@ A scenario is one client-level call, the HTTP exchanges it makes, and the outcom A step that acts on an earlier result follows one: `choose` follows `search` or `choose`, a `fetch` with no target follows `search`, `choose` or another `fetch` with no target and acts on the last answer, and `result` follows `mint` or `operation`. A `fetch` of an answer or a spec, `mint` and `operation` take a `layout`, `long` by default or `frame`, and a `fetch` of an answer or a spec takes `strict`. A `spec` in a step holds `spec_id`, the server's unmodified `definition`, the `sentence` when the client knows it, and the server's `resolved.entity_groups` as `entity_groups` when it names any. -An exchange's request names its target in one of three ways. `path` is a path the client composes under the base URL, such as `/search/resolve`. `origin_path` is a root-relative URL the server returned, such as an artifact's `url`, or the path and query of an absolute one on the API's origin, which resolves against the base URL's origin and never against its path. `url` is an absolute URL outside the API, such as the signed storage URL a files route redirects to, which the client fetches with a bare request carrying no client header and no key. `json` holds the request body members that must match; a recorded scenario lists every member the client sent. The response gives `status`, the `headers` a client reads, and a `json` body or a `body_file`, a binary body in `scenarios/`. A scenario's own body files are named `.` and `-.`; a synthetic scenario may instead name a body file its parent names. +An exchange's request names its target in one of three ways. `path` is a path the client composes under the base URL, such as `/search/resolve`. `origin_path` is a root-relative URL the server returned, such as an artifact's `url`, or the path and query of an absolute one on the API's origin, which resolves against the base URL's origin, whatever path that URL has. `url` is an absolute URL outside the API, such as the signed storage URL a files route redirects to, which the client fetches with a bare request carrying no client header and no key. `json` holds the request body members that must match; a recorded scenario lists every member the client sent. The response gives `status`, the `headers` a client reads, and a `json` body or a `body_file`, a binary body in `scenarios/`. A scenario's own body files are named `.` and `-.`; a synthetic scenario may instead name a body file its parent names. -A `newest_version` outcome gives the `content_version` the step found, or null. An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a warning's code, which for a `SearchWarning` may be null, or for any other error the client raises itself its code in `client-codes.json`. Every error outcome gives its `trace_id`: a refusal's, as the refusal rules below give it; a failed operation's, its error document's `trace_id`, else the `x-dfo-trace-id` header of the response that carried the failed resource; a `VersionUnavailableError`'s, its first refusal's, or null when nothing refused. An error the client raises itself follows one rule: an error that describes a response carries that response's trace id, and an error that describes the caller's input carries null. The trace id is the one a user quotes to find the fault in the server's logs. The errors that describe a response are `unexpected_response`, `contract_violation` on a body, `answer_declined`, `answer_incomplete`, and a strict fetch's `SearchWarning` or `DataWarning`. A response's trace id is the top-level `trace_id` member of its body when the body is a JSON object holding one as a non-empty string, a problem document or any other body, else its `x-dfo-trace-id` header, else null. A body `trace_id` that is empty or not a string reads as absent, so the header applies; no scenario holds one, and the validator's tests pin it. A Search answer's `diagnostics.trace_id` is not read, and `answer-timed-out` pins the header's winning over a `diagnostics.trace_id` that differs from it. `answer_declined`, `answer_incomplete`, a `SearchWarning`, and a `contract_violation` a choice raises on an option describe the held answer, so they carry the trace id of the Search response that answered it. The errors that describe the caller's input, `choice_invalid`, `invalid_argument` and the key-lookup reasons, carry null, and so do `digest_mismatch` and `download_failed`, which describe a storage-host fetch, and `deadline_exceeded`, `network_error` and `offline`, which describe no response. `search-no-json-body`, `fetch-spec-strict-warning`, `answer-timed-out`, `answer-empty-parts`, `fetch-spec-files-route-no-content` and `choose-option-two-part-query` pin a trace id on an error that describes a response, `operation-failed-without-error` the header of the response that carried a failed resource with no error, and `choose-refused-shared-label` a null one on a choice whose answer's response carries a trace id. A `VersionUnavailableError` also gives `newest_version`, the version the lookup found, or null. A dataset or error outcome of a step that made a long build gives `long_builds`, one entry per build the server ran on, in order: the `operation_id` the client polled last, the `poll_waits` in seconds before each poll, and the number of `resubmissions`. Any outcome of a step that retried a refused request gives `retry_waits`, the seconds before each retry in order, and any outcome of a step whose API responses issued warnings gives `warnings`, their codes from `warning-codes.json` in order. +A `newest_version` outcome gives the `content_version` the step found, or null. An answer outcome gives `kind`, `status`, `sentence`, `complete`, the distinct `specs` of its definite parts, and its `gaps`, each with the `part` index, the gap `kind` and the number of `options`. A dataset outcome gives `rows`, `columns`, `complete`, its `members`, each with `parts`, `spec_id`, `content_version` and `sentence`, and the `missing` gaps. For one member the columns are the artifact's columns; a dataset of several members adds a `part` column and gives `part_rows`, one entry per member in member order with the `part` value of that member's rows and their number. A fetch of an answer also gives `search_warning`, whether the fetch issued a `SearchWarning`. An error outcome gives the error `class` and its `code`: a refusal's code, a warning's code, which for a `SearchWarning` may be null, or for any other error the client raises itself its code in `client-codes.json`. Every error outcome gives its `trace_id`: a refusal's, as the refusal rules below give it; a failed operation's, its error document's `trace_id`, else the `x-dfo-trace-id` header of the response that carried the failed resource; a `VersionUnavailableError`'s, its first refusal's, or null when nothing refused. An error the client raises itself follows one rule. An error that describes a response carries that response's trace id, and an error that describes the caller's input carries null. The trace id is the one a user quotes to find the fault in the server's logs. The errors that describe a response are `unexpected_response`, `contract_violation` on a body, `answer_declined`, `answer_incomplete`, and a strict fetch's `SearchWarning` or `DataWarning`. A response's trace id is the top-level `trace_id` member of its body when the body is a JSON object holding one as a non-empty string, a problem document or any other body, else its `x-dfo-trace-id` header, else null. A body `trace_id` that is empty or not a string reads as absent, so the header applies. No scenario holds one, and the validator's tests pin it. A Search answer's `diagnostics.trace_id` is not read, and `answer-timed-out` pins the header's winning over a `diagnostics.trace_id` that differs from it. `answer_declined`, `answer_incomplete`, a `SearchWarning`, and a `contract_violation` a choice raises on an option describe the held answer, so they carry the trace id of the Search response that answered it. The errors that describe the caller's input, `choice_invalid`, `invalid_argument` and the key-lookup reasons, carry null, and so do `digest_mismatch` and `download_failed`, which describe a storage-host fetch, and `deadline_exceeded`, `network_error` and `offline`, which describe no response. `search-no-json-body`, `fetch-spec-strict-warning`, `answer-timed-out`, `answer-empty-parts`, `fetch-spec-files-route-no-content` and `choose-option-two-part-query` pin a trace id on an error that describes a response, `operation-failed-without-error` the header of the response that carried a failed resource with no error, and `choose-refused-shared-label` a null one on a choice whose answer's response carries a trace id. A `VersionUnavailableError` also gives `newest_version`, the version the lookup found, or null. A dataset or error outcome of a step that made a long build gives `long_builds`, one entry per build the server ran on, in order: the `operation_id` the client polled last, the `poll_waits` in seconds before each poll, and the number of `resubmissions`. Any outcome of a step that retried a refused request gives `retry_waits`, the seconds before each retry in order, and any outcome of a step whose API responses issued warnings gives `warnings`, their codes from `warning-codes.json` in order. -Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. A record whose outcomes it cannot derive, because its exchanges do not fit its steps or a malformed member raises while it reads them, is reported as that record's problem, and the other records are still checked. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry where the retry rules allow one, except on a poll, where the long-build rules count retries, and a record that ends a run of retries while the rules allow another does not fit, since the client makes it, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, each POST carries its body, each build posts the body the rules give for the spec it builds, so the builds' order and spec_ids are checked, each Search request posts the whole body `{"schema_version": 1, "input": ...}` with the input the rules give: the question, a choice's input, or a member's identity, each poll names the operation the client holds, each files route is the one the artifact's `url` names, each signed download is the URL the files route's `location` names, each retry waits the wait the retry rules give, and each response's warning headers issue the warnings the warning rules give. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. +Each outcome follows from the exchanges and `actions.json`, and `tools/validate_client_contract.py` fails a record whose `expect` says otherwise. A record whose outcomes it cannot derive, because its exchanges do not fit its steps or a malformed member raises while it reads them, is reported as that record's problem, and the other records are checked. It runs the steps over the exchanges by the rules below: a refusal followed by the same request is a retry where the retry rules allow one, except on a poll, where the long-build rules count retries, and a record that ends a run of retries while the rules allow another does not fit, since the client makes it, a refusal's class is its code's action or else its status, the class of an error the client raises itself is its code's row in `client-codes.json`, a gap's kind is its reason's `gap_kind`, option and candidate counts are those the bodies hold, a dataset's members, `complete`, `missing` and `search_warning` follow from the answer and the manifests, each POST carries its body, each build posts the body the rules give for the spec it builds, so the builds' order and spec_ids are checked, each Search request posts the whole body `{"schema_version": 1, "input": ...}` with the input the rules give: the question, a choice's input, or a member's identity, each poll names the operation the client holds, each files route is the one the artifact's `url` names, each signed download is the URL the files route's `location` names, each retry waits the wait the retry rules give, and each response's warning headers issue the warnings the warning rules give. A dataset's `rows`, `columns` and `part_rows` row counts are the Parquet bodies' and are not derived, except that `part` comes first and `part_rows` is given exactly when the dataset has several members, each entry's `part` is its member's value and their rows sum to `rows`. A recorded scenario's request and response bodies validate against their route's schemas in `served/openapi.json`. A required member stays required when its schema admits null: the body carries it, as null or a value. A member the schema leaves optional may be absent or null, and a client reads both as null. @@ -150,7 +150,7 @@ A client replays a scenario by serving the exchanges in order: - A request with no exchange left, or one that matches none, fails the scenario, and so does an exchange the call never makes. - `path` resolves against the base URL the replay gives the client, and `origin_path` against that base URL's origin, so a replay can run under any base URL form. - A replay substitutes its own base URL's origin for the origin of the record's `origin.base_url`, a synthetic record's parent's, wherever a response names it, in its JSON body and its headers. `fetch-spec-same-origin-artifact-url` names the recorded origin in its manifest's artifact `url`s, and the validator replays every scenario under its recorded base URL and again under `https://replay.example.org` with the same path, so a record that holds only under its recorded host fails. -- Sleeps are not replayed: the replay injects the client's clock and sleep, and each wait the client asks for advances the clock at once. The waits before polls are the outcome's `poll_waits`, and the waits before retries its `retry_waits`. +- Sleeps are not replayed. The replay injects the client's clock and sleep, and each wait the client asks for advances the clock at once. The waits before polls are the outcome's `poll_waits`, and the waits before retries its `retry_waits`. - A replay runs each scenario as a fresh process, so no warning has been issued when it starts. - Every absolute URL a record holds, a `url` request or a `location` header, is a signed URL on `https://storage.googleapis.com` with its path kept and its query `X-Goog-Signature=redacted`, whatever signed it; a `location` may also name a route under the base URL. The validator compares hostnames and refuses any other host, a local app's under any name or port included. @@ -159,29 +159,29 @@ The records also fix these client rules: - A fetch builds each distinct `spec_id` once, in part order, and finishes one member (build, the sentence when the client lacks it, files, download) before the next. - A fetch of a spec posts its narrowing as the build's `input.scope`, and posts no `scope` when it narrows nothing. A mint takes a layout and no narrowing, so it posts no `scope`. `window` posts `{"kind": "range", "start_year", "end_year"}` for a pair of years, or `{"kind": "all"}` or `{"kind": "latest"}`, and `facets` posts each axis as `{"ref": ...}`, and `facets: {}` names no axis and posts no `facets`. The server's `scope.entities` replaces the spec's whole entity binding, so `entities` posts a whole map: the roles the spec's `definition.identity.entities` binds, with each role the caller names replaced by its refs and each role the caller binds to null dropped. Naming `origin` alone on a spec bound to `origin` and `destination` keeps `destination`. A fetch that names no role, `entities: {}` included, posts no `entities`, so a fetch whose narrowing is all empty posts no `scope`; `fetch-spec-empty-narrowing` pins it. - A built `spec_id` that differs from the posted one, or a spec with no sentence, takes its sentence from Search: the client posts the built definition's `identity` as one `dataset_resubmit` identity entry, with the member's first part as `variable_text`, or `"dataset"` when no answer part names it, and checks the answer's `spec_id` equals the built one. The entry's `entity_groups` holds the spec's `resolved.entity_groups` for each role the built identity binds to the same entities as the spec's definition, so a window or facets narrowing keeps every group and a role the narrowing rebound or dropped loses its group. The entry leaves `entity_groups` out when it keeps no group, as for a resumed operation, whose spec the client does not hold. The server reads a role posted without its group as its members, so a narrowed spec of flows to the least developed countries would read "44 recipients" in place of "the 44 Least Developed Countries". -- A dataset of several members puts the `part` column first, then each member's columns in member order, each column once. A column that members hold in different types widens as pyarrow's permissive promotion widens it, and a pair that cannot widen raises `ContractError` `contract_violation`; a member file that already holds a `part` column raises `contract_violation` when members stack. Rows and columns are not derived, so no scenario pins these. The `part` value on a member's rows is the member's `parts` joined by `"; "`, so a member that answers two folded parts reads `"health ODA disbursements; education ODA disbursements"`, or the member's sentence when `parts` is empty. A definite part whose `variable_text` is absent or empty adds nothing to its member's `parts`, which `answer-folded-parts-unnamed` pins. +- A dataset of several members puts the `part` column first, then each member's columns in member order, each column once. A column that members hold in different types widens as pyarrow's permissive promotion widens it, and a pair that cannot widen raises `ContractError` `contract_violation`. A member file that already holds a `part` column raises `contract_violation` when members stack. Rows and columns are not derived, so no scenario pins these. The `part` value on a member's rows is the member's `parts` joined by `"; "`, so a member that answers two folded parts reads `"health ODA disbursements; education ODA disbursements"`, or the member's sentence when `parts` is empty. A definite part whose `variable_text` is absent or empty adds nothing to its member's `parts`, which `answer-folded-parts-unnamed` pins. - A choice names its part by index, by variable text, or by a word that one gap's options mention, and its option by index or label; a candidate is named by index. A candidate with neither a heading nor a sentence has a null label; no scenario pins it. A label is matched among the options that mention the word the part was named by. With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. - A choice raises `InvalidRequestError` `choice_invalid` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is out of range or matches no label or several. It raises the same when an entry it would post cannot be built: a part with no `variable_text`, or a part of a status the client does not know that has no `restatement`. A chosen option whose `data_query` holds other than one part raises `ContractError`, and so does a chosen option with no `data_query`, in a one-part answer as in a several-part one, before any request. `choose-refused-shared-label`, `choose-refused-part-without-variable-text`, `choose-refused-unknown-status`, `choose-option-two-part-query` and `choose-option-without-data-query` pin these. - Every pick of a candidate asks Search for the picked answer, and no client builds it locally. In a one-part answer the pick posts `dataset_resubmit`, without `raw_query`, with one identity entry: the candidate's identity and `entity_groups`, and the part's `variable_text`, `separate` and `operations` as below. The picked answer, its sentence with any "Assumed: …" clause, and its assumptions are Search's response. A choice of a no_data option in a one-part answer posts the option's `data_query` as the input. -- In a several-part answer a choice posts `dataset_resubmit`, without `raw_query`, with one entry per part in part order. The chosen candidate posts an identity entry with its identity and `entity_groups`, and the chosen option its `data_query`'s one part as a parsed entry. A definite part posts an identity entry with its spec's identity and `entity_groups`. A candidates part left alone posts a `candidates` entry: its candidate set in the server's order, each with its identity and `entity_groups`, and its `ordering` and `truncated` echoed. The server cannot recompute that order, because it rests on the first answer's bind election and availability reads, and a parsed entry would cost an LLM bind. Any other part posts its `restatement` as a parsed entry, or a placeholder entry with its no_data `reason` or unsupported `code` when it has none. Every entry but a parsed one carries the part's `variable_text`, `separate` when true and `operations` when the part has any; `entity_groups` is left out when the spec has none. `choose-echoes-separate-and-operations` pins the echo on a definite part's entry, and `choose-posts-unsupported-placeholder` an unsupported part's placeholder. +- In a several-part answer a choice posts `dataset_resubmit`, without `raw_query`, with one entry per part in part order. The chosen candidate posts an identity entry with its identity and `entity_groups`, and the chosen option its `data_query`'s one part as a parsed entry. A definite part posts an identity entry with its spec's identity and `entity_groups`. A candidates part left alone posts a `candidates` entry: its candidate set in the server's order, each with its identity and `entity_groups`, and its `ordering` and `truncated` echoed. The server cannot recompute that order, because it rests on the first answer's bind election and availability reads, and a parsed entry would cost an LLM bind. Any other part posts its `restatement` as a parsed entry, or a placeholder entry with its no_data `reason` or unsupported `code` when it has none. Every entry but a parsed one carries the part's `variable_text`, `separate` when true and `operations` when the part has any. `entity_groups` is left out when the spec has none. `choose-echoes-separate-and-operations` pins the echo on a definite part's entry, and `choose-posts-unsupported-placeholder` an unsupported part's placeholder. - Each identity a choice posts echoes its reading's assumptions as `assumptions`: the chosen candidate's entry carries its part's `reading_assumptions` under the candidate's `spec_id`, a definite part's entry carries the part's `assumptions`, and each candidate of a `candidates` entry carries its own `reading_assumptions` entry. Search then states the echoed items that still hold, so the picked answer states what that reading assumed. `[]` states none. An identity with no `assumptions` reads as a fresh request, so a client that holds no list for a reading, from a part that carries no `assumptions` or `reading_assumptions`, posts none. The identity entry that asks for a built sentence posts no `assumptions`, since it reads only the spec's own `rendered_sentence`. - A strict fetch raises the manifest's first warning above `info` severity as a `DataWarning` with that warning's code, before the sentence lookup and the download. - An identity resubmit whose answer is not one definite part of the built `spec_id`, with a sentence, raises `ContractError`. - The `frame` layout posts `{"format": "parquet", "bundle": false, "layout": "frame"}` as the build's `options` and downloads the artifact whose rendering's `layout` is `frame`; the `long` layout posts `{"format": "parquet", "bundle": false}` and downloads the bare Parquet artifact with any other layout. A fetch of an answer with several members in the `frame` layout raises `InvalidRequestError` before any build. -- A download asks the route that redirects to the signed URL, an artifact's `url` or the file selector, and fetches the URL its `location` names once. A files route answers 302 with the `location` the client fetches, or 200 with the file as its body, which the client hashes with no further request, which `fetch-spec-files-route-serves-file` pins. A refusal reads by the refusal rules, and any other status, another 2xx or another 3xx included, raises `ContractError` `unexpected_response` with that response's trace id, which `fetch-spec-files-route-no-content` pins with a 204 and `fetch-spec-files-route-temporary-redirect` with a 307. The route ask is an API request and follows the retry rules below, so a retryable refusal is retried within the budget and any other refusal, `artifact_expired` among them, raises at once. A failed fetch gets exactly one more round: a fetch that answers anything but 200, which `fetch-spec-signed-fetch-partial` pins with a 206, or bytes that do not hash to the artifact's digest ask the route again, under the same retry rules, and fetch again, with no wait between rounds. A second failure raises `ServerError` with `download_failed`, or `digest_mismatch` when the bytes are wrong. A network error or timeout on the fetch is retryable, so it starts the second round too, and when the second round fails the same way the client raises that failure as itself, `network_error` or `deadline_exceeded`. The replay holds no network failure, so no scenario pins that case. -- A manifest artifact's `url` names its files route on the API's origin: a root-relative `url` resolves against the base URL's origin, and an absolute one on that origin is asked as its path and query, so both make the same `origin_path` request, which `fetch-spec-same-origin-artifact-url` pins. An artifact `url` on any other origin, the storage host's included, raises `ContractError` `contract_violation` before the sentence lookup and any request for the file, which `fetch-spec-foreign-artifact-url` and `fetch-spec-storage-artifact-url` pin. +- A download asks the route that redirects to the signed URL, an artifact's `url` or the file selector, and fetches the URL its `location` names once. A files route answers 302 with the `location` the client fetches, or 200 with the file as its body, which the client hashes with no further request, which `fetch-spec-files-route-serves-file` pins. A refusal reads by the refusal rules, and any other status, another 2xx or another 3xx included, raises `ContractError` `unexpected_response` with that response's trace id, which `fetch-spec-files-route-no-content` pins with a 204 and `fetch-spec-files-route-temporary-redirect` with a 307. The route ask is an API request and follows the retry rules below, so a retryable refusal is retried within the budget and any other refusal, `artifact_expired` among them, raises at once. A failed fetch gets exactly one more round. A fetch that answers anything but 200, which `fetch-spec-signed-fetch-partial` pins with a 206, or bytes that do not hash to the artifact's digest ask the route again, under the same retry rules, and fetch again, with no wait between rounds. A second failure raises `ServerError` with `download_failed`, or `digest_mismatch` when the bytes are wrong. A network error or timeout on the fetch is retryable, so it starts the second round too, and when the second round fails the same way the client raises that failure as itself, `network_error` or `deadline_exceeded`. The replay holds no network failure, so no scenario pins that case. +- A manifest artifact's `url` names its files route on the API's origin. A root-relative `url` resolves against the base URL's origin, and an absolute one on that origin is asked as its path and query, so both make the same `origin_path` request, which `fetch-spec-same-origin-artifact-url` pins. An artifact `url` on any other origin, the storage host's included, raises `ContractError` `contract_violation` before the sentence lookup and any request for the file, which `fetch-spec-foreign-artifact-url` and `fetch-spec-storage-artifact-url` pin. - A relative `location` resolves against the files route's URL, and the client fetches it on the API's origin as an `origin_path` request. A `location` on an origin other than the API's or `https://storage.googleapis.com` raises `ContractError` `contract_violation` before any fetch. A fetch on the storage host is bare and carries no API key. `fetch-spec-relative-location` pins the relative case. - A declined or catalogue answer is not complete, and fetching it raises `DeclinedError`. - Fetching an answer with a gap raises `IncompleteAnswerError` before any request, unless the fetch is partial and some part has a reading. - A fetch of an answer issues one `SearchWarning` when a definite part has an operation Search did not run, a departure, or a warning at severity `warn` or `degraded` with a `message`, or the answer's `diagnostics.warnings` holds such a warning. An `info` warning, and a warning with no `message`, issue nothing. Each way is one line a client shows: `Not done: ()` coded by the verb, the departure's `text` coded by its code, or `Note: ` coded by the warning's code, in part order with the diagnostics warnings last, and ways that show the same line count once, under the first one's code. A strict fetch raises the `SearchWarning` before any build, with the code of its one line, or a null code when there are several lines. A strict fetch raises it before the `frame` layout's several-member check. - A ref's version is found in this order: the snapshot route and the files route at the stored digest; the file selector, `GET /datasets/{id}/{content_version}/file` with the ref's rendering as the query; and a build of the ref's spec in the ref's rendering, which must answer the same `content_version`. A snapshot refusal other than `artifact_expired` ends the lookup, so `snapshot_not_found` raises `NotFoundError` with no further request. A files route or selector refusal of `artifact_expired`, `artifact_not_found` or `not_found` takes the next step, and a selector file of another digest is not the stored file. A snapshot manifest whose artifacts list no artifact of the ref member's digest sends the client to the selector in the ref member's own rendering, and a file that hashes to that digest gives the dataset, which `fetch-ref-artifact-unlisted` pins. A rebuild that answers another version, or that raises `InvalidRequestError`, `NotFoundError` or `VersionUnavailableError`, ends in `VersionUnavailableError` with the first refusal's code, or `version_unavailable` when nothing refused. Its `newest_version` is the version the rebuild answered, or else the newest stored version, which `GET /datasets/{id}/versions?limit=1` lists alone, as a `newest_version` step finds it, since the route lists versions newest first and needs no key; or null when that route lists none or refuses with `NotFoundError`. Any other refusal of the versions route raises, and a page whose `versions` is not a list of versions each with a `content_version` raises `ContractError` `contract_violation`, which `newest-version-unreadable-page` pins. -- A build answers 200 with the manifest, or 202 with an operation the client polls at `/datasets/operations/{operation_id}`, the id of the operation it holds. A mint's build answers 202; a record whose mint answers 200 fits no mint step. Before each poll it waits the `Retry-After` of the refusal that answered the last poll, whatever its status, as every retry of a refused request waits; else the last operation resource's `retry_after_ms`, else the `Retry-After` of the last answered poll, the response that carried that resource, else a backoff of 1, 2, 4 and then 8 seconds that advances one step each time it is used, a poll after a refusal included. +- A build answers 200 with the manifest, or 202 with an operation the client polls at `/datasets/operations/{operation_id}`, the id of the operation it holds. A mint's build answers 202. A record whose mint answers 200 fits no mint step. Before each poll it waits the `Retry-After` of the refusal that answered the last poll, whatever its status, as every retry of a refused request waits; else the last operation resource's `retry_after_ms`, else the `Retry-After` of the last answered poll, the response that carried that resource, else a backoff of 1, 2, 4 and then 8 seconds that advances one step each time it is used, a poll after a refusal included. - A retryable 429 poll spends no retry, and a 429 whose body says it is not retryable raises at once, as a refusal's `retryable` outranks its status, which `fetch-spec-poll-rate-limited-not-retryable` pins. Any other retryable refused poll spends one of the two retries, which a poll that answers restores, and a refusal that is not retryable raises. `fetch-spec-poll-refused` pins two 503s polled again after an answered poll, `fetch-spec-poll-refused-backoff` a 503 with no `Retry-After` among polls no response paces, after which the backoff advances, `fetch-spec-poll-refused-retry-after` a 503 whose `Retry-After` paces the next poll, and `fetch-spec-poll-not-found` a 404 that raises at once. A poll that answers a failed operation whose error is retryable posts the same build once more and polls the operation it starts; a second failure, an error that is not retryable, and a resumed operation, whose build request the client does not hold, raise the operation's error. A refused poll whose code is `operation_failed` is a failed operation with that error. A failed operation whose resource carries no `error` raises `ServerError` with `operation_failed`, retryable by status 500 as a refusal without a document is, which `operation-failed-without-error` pins. A 202 or resumed operation that already reads `failed` raises its error before any poll. - Any other refusal is retried when it is retryable: as a problem document's `retryable` says, or the website proxy's `retry` of `retry_after_delay`, else when its status is 408, 429, 500, 502, 503 or 504. A client makes two retries by default, and the scenarios assume that default. A build's POST shares those two retries with every other refusal of it, and once a 504 cuts the build off the client posts it once more only, whatever that post answers: a build refused 504 then 503 raises the 503, a build refused 503 then 504 is posted once more after the 504, and a second 504 raises. `fetch-spec-504-then-503`, `fetch-spec-503-then-504` and `fetch-spec-504-twice` pin the three. A refusal that is not retryable, or one past the retries, raises its error. - Each retry waits the refusal's `Retry-After` when it carries one, and otherwise the client's backoff for that attempt: 0.5 seconds before the first retry, doubling to at most 8. The build's 504 cut-off retry follows the same rule. `retry_waits` pins these waits, and `fetch-spec-504-retry-after` pins a cut-off that carries `Retry-After`. -- A 401 resolves the key again by the key-lookup rule. When the key changed, the client sends the request once more at once, with no wait and spending no retry; when it did not, or the second answer is a 401 too, the 401 raises `AuthenticationError`. A replay's key never changes, so `search-unauthorized` pins the second case and no scenario the first. +- A 401 resolves the key again by the key-lookup rule. When the key changed, the client sends the request once more at once, with no wait and spending no retry. When it did not, or the second answer is a 401 too, the 401 raises `AuthenticationError`. A replay's key never changes, so `search-unauthorized` pins the second case and no scenario the first. - A `request(method, path)` whose `path` is not a path on the base URL, because it starts with `//` or names a scheme, raises `InvalidRequestError` `invalid_argument` before any request. No scenario step makes such a request. -- A 2xx response of a JSON route with no JSON body raises `ContractError` `unexpected_response`; `search-no-json-body` pins it for Search. +- A 2xx response of a JSON route with no JSON body raises `ContractError` `unexpected_response`. `search-no-json-body` pins it for Search. - A `Deprecation` or `Sunset` header on an API response, either alone, issues `route_deprecated` once per process per distinct pair of their values, and an `x-dfo-warning` header issues `server_warning` once per process per message. A signed fetch's headers issue nothing. `search-sunset-warning` pins a Sunset header alone, issued once over two responses that carry the same value, and `search-server-warning` pins a repeated `x-dfo-warning` message issued once, a new message issued again, and a Deprecation beside the same Sunset issued as a new pair. - Timeouts follow the clients' design and are not replayed, since the replay advances the clock only by the waits the client asks for: the client's `timeout`, 30 s by default, bounds one request attempt; `search(timeout=60)` bounds the whole search, each attempt reading until that deadline, and None means no limit; `fetch(timeout=1800)` bounds the whole fetch, each download getting the time left on the fetch's deadline; a synchronous build POST, and mint's POST, read for up to 150 s within any outer deadline; `result(timeout=1800)` bounds the wait, and None means no limit. A poll attempt that hangs past the per-attempt timeout spends a retry, and a deadline that passes during a body read raises `DfoTimeoutError` `deadline_exceeded`. In TypeScript an infinite remaining time arms no timer, and a finite one above 2^31-1 ms is clamped. No scenario step takes a timeout. @@ -194,7 +194,7 @@ uv sync --directory ../dfo-apis --extra eval --extra api --extra engine --extra uv run tools/capture_client_contract.py openapi --dfo-apis ../dfo-apis ``` -Its `record` command runs every scenario against a base URL, dev's Cloud Run URL by default, checks each live answer still has the shape its scenario names, derives the synthetic scenarios from the fresh records with no request, and then runs the validator. A recorded scenario holds only exchanges the server made, and the run refuses one that a canned exchange answered, and an API response without the `x-dfo-trace-id` header the server sends on every response but a shared-cacheable one, marked `Cache-Control: public`, whose `cache-control` header the record then keeps. The validator refuses a recorded API response with neither; the record names the commit the server's responses name. It fails when the validator reports a problem or the binary bodies pass 5 MB. `--only` records the scenarios it names. `--offline` makes no request: each recorded scenario's steps run again over its own exchanges and rewrite its `expect`, and each synthetic scenario is derived again from its parent, so a change to the outcome rules or to `client-codes.json` reaches the records without a recording: +Its `record` command runs every scenario against a base URL, dev's Cloud Run URL by default, checks each live answer still has the shape its scenario names, derives the synthetic scenarios from the fresh records with no request, and then runs the validator. A recorded scenario holds only exchanges the server made, and the run refuses one that a canned exchange answered, and an API response without the `x-dfo-trace-id` header the server sends on every response but a shared-cacheable one, marked `Cache-Control: public`, whose `cache-control` header the record then keeps. The validator refuses a recorded API response with neither. The record names the commit the server's responses name. It fails when the validator reports a problem or the binary bodies pass 5 MB. `--only` records the scenarios it names. `--offline` makes no request. Each recorded scenario's steps run again over its own exchanges and rewrite its `expect`, and each synthetic scenario is derived again from its parent, so a change to the outcome rules or to `client-codes.json` reaches the records without a recording: ```bash uv run tools/capture_client_contract.py record --offline --only answer-declined choose-refused-no-choice diff --git a/python/client-contract/src/dfo_client_contract/rules/README.md b/python/client-contract/src/dfo_client_contract/rules/README.md index cfd440a..8257f50 100644 --- a/python/client-contract/src/dfo_client_contract/rules/README.md +++ b/python/client-contract/src/dfo_client_contract/rules/README.md @@ -32,11 +32,11 @@ A client resolves its key when it is built, and again after a 401. The first sou 1. inside Colab, a notebook secret named `DFO_API_KEY`; 1. otherwise, anonymous. -A missing file goes on to the next source, and so does a missing `default` profile. A file that fails to parse raises `credentials_file_invalid`, a profile named by `DFO_PROFILE` that the file lacks raises `profile_not_found`, and a chosen profile with no `key`, or an empty one, raises `profile_without_key`. The file is read only when no earlier source wins. The argument may also be a callable or a key object, called or unwrapped when the client resolves the key; vectors pass strings, and the Colab source has none. +A missing file goes on to the next source, and so does a missing `default` profile. A file that fails to parse raises `credentials_file_invalid`, a profile named by `DFO_PROFILE` that the file lacks raises `profile_not_found`, and a chosen profile with no `key`, or an empty one, raises `profile_without_key`. The file is read only when no earlier source wins. The argument may also be a callable or a key object, called or unwrapped when the client resolves the key. The vectors pass strings, and the Colab source has no vectors. ## Key format (`key-format`) -A secret key is `dfo_k_`, then a base62 body, then a 6-character checksum; `dfo_p_` marks a browser-safe key. Base62 is `0-9A-Za-z` in that order. The checksum is the CRC32 (ISO-HDLC, as zlib computes it) of the body's ASCII bytes, written in base62 and left-padded with `0` to six characters. Issued keys have a 32-character body, 44 characters in all, but the check ignores length: the last six characters after the prefix are the checksum and the rest is the body. +A secret key is `dfo_k_`, then a base62 body, then a 6-character checksum; `dfo_p_` marks a browser-safe key. Base62 is `0-9A-Za-z` in that order. The checksum is the CRC32 (ISO-HDLC, as zlib computes it) of the body's ASCII bytes, written in base62 and left-padded with `0` to six characters. Issued keys have a 32-character body, 44 characters in all, but the check ignores length. The last six characters after the prefix are the checksum and the rest is the body. The check runs in order and reports the first failure: `unknown_prefix` when the key starts with neither prefix, `not_base62` when a character after the prefix is outside base62, and `checksum_mismatch` when the body is empty or its checksum differs. A failure warns with the code `key_` from `warning-codes.json`, such as `key_checksum_mismatch`, and the client sends the key anyway, so a change of key format forces no upgrade. diff --git a/tools/README.md b/tools/README.md index 9b795ea..2d0404f 100644 --- a/tools/README.md +++ b/tools/README.md @@ -44,7 +44,7 @@ uv run tools/validate_descriptions_vectors.py uv run tools/validate_client_contract.py ``` -`capture_client_contract.py` refreshes the client contract from dfo-apis. `openapi --dfo-apis PATH` builds the composed app in that checkout's environment, in process, and writes `served/openapi.json` and `served/SOURCE.json`, refusing a checkout with uncommitted changes or untracked files and an environment out of step with its `uv.lock`; `record` runs the contract's scenarios against a base URL, dev by default, writes the records with every absolute URL's query redacted and a local app's signed URLs written as storage URLs, refusing a record that still names any other host, derives the synthetic ones and validates the result, and `record --offline` derives the outcomes again from the records with no request. A recorded scenario holds only exchanges the server made: `record` refuses a recorded scenario that a canned exchange answered, and a synthetic derivation makes no request. Nothing in a record marks an exchange as canned, so `validate_client_contract.py` cannot check this rule and the capture enforces it. It imports its outcome rules from `validate_client_contract.py`. `python/client-contract/README.md` has the recipe. A PEP 723 script; its tests run without network or pyarrow: +`capture_client_contract.py` refreshes the client contract from dfo-apis. `openapi --dfo-apis PATH` builds the composed app in that checkout's environment, in process, and writes `served/openapi.json` and `served/SOURCE.json`, refusing a checkout with uncommitted changes or untracked files and an environment out of step with its `uv.lock`; `record` runs the contract's scenarios against a base URL, dev by default, writes the records with every absolute URL's query redacted and a local app's signed URLs written as storage URLs, refusing a record that still names any other host, derives the synthetic ones and validates the result, and `record --offline` derives the outcomes again from the records with no request. A recorded scenario holds only exchanges the server made. `record` refuses a recorded scenario that a canned exchange answered, and a synthetic derivation makes no request. Nothing in a record marks an exchange as canned, so `validate_client_contract.py` cannot check this rule and the capture enforces it. It imports its outcome rules from `validate_client_contract.py`. `python/client-contract/README.md` has the recipe. A PEP 723 script whose tests run without network or pyarrow: ```bash uv run tools/capture_client_contract.py record diff --git a/tools/capture_client_contract.py b/tools/capture_client_contract.py index bca8a94..ae74779 100644 --- a/tools/capture_client_contract.py +++ b/tools/capture_client_contract.py @@ -14,33 +14,33 @@ `openapi` builds the composed dfo-apis app from the checkout at PATH, with the deployed surfaces (Search, Datasets, Graph and Presentation), by -calling `dfo_apis.app.create_app()` in that checkout's environment, and -writes `app.openapi()` to `served/openapi.json` and the -checkout's commit to `served/SOURCE.json`. No server runs. The surfaces load -an origin catalogue and a graph release when they are built, so the capture -publishes the checkout's own test catalogue and test release into a temporary -directory; the document does not depend on the data they hold. A checkout with uncommitted changes to tracked files is -refused, because the commit would not describe the document. +calling `dfo_apis.app.create_app()` in that checkout's environment. It +writes `app.openapi()` to `served/openapi.json` and the checkout's commit to +`served/SOURCE.json`. No server runs. The surfaces load an origin catalogue +and a graph release when they are built, so the capture publishes the +checkout's own test catalogue and test release into a temporary directory. +The document does not depend on the data they hold. A checkout with +uncommitted changes to tracked files is refused, because the commit would +not describe the document. `record` runs every scenario this file defines against the API at the base -URL (dev by default; a local app at `http://127.0.0.1:8083/api`), the way a -client would, and writes each record and its binary bodies to `scenarios/`. -Each recorded scenario checks that its live answer still has the shape the -scenario is named for and refuses to write one that does not. With -`--offline` no request is made: each recorded scenario's steps run again +URL (dev by default, or a local app at `http://127.0.0.1:8083/api`), the way +a client would, and writes each record and its binary bodies to `scenarios/`. +Each recorded scenario checks that its live answer has the shape the +scenario is named for, and the run refuses to write one that does not. With +`--offline` no request is made. Each recorded scenario's steps run again over its own exchanges and rewrite its `expect`, and each synthetic scenario is derived again from its parent. A synthetic derivation makes no request -in either mode. Synthetic -scenarios are derived from the recorded records after them, so a recording -refreshes both, and a synthetic record names its parent's body files rather -than copies. Every absolute URL a record keeps, a signed download or a -`location` header, keeps its path, and its query becomes -`X-Goog-Signature=redacted`, and a local app's blob URL becomes the storage -URL a deployment signs; a record holding any other absolute URL, outside a -`location` under the base URL, is refused. The -long builds need two specs the server has not built, so a local recording -starts on a fresh datasets database. `--scenarios-dir` writes outside the -package, unvalidated. The run ends by validating the whole contract with +in either mode. Synthetic scenarios are derived from the recorded records +after them, so a recording refreshes both, and a synthetic record names its +parent's body files and holds no copies. Every absolute URL a record keeps, +a signed download or a `location` header, keeps its path and has its query +replaced by `X-Goog-Signature=redacted`. A local app's blob URL becomes the +storage URL a deployment signs. A record holding any other absolute URL, +outside a `location` under the base URL, is refused. The long builds need +two specs the server has not built, so a local recording starts on a fresh +datasets database. `--scenarios-dir` writes outside the package, +unvalidated. The run ends by validating the whole contract with `tools/validate_client_contract.py`, and fails when it reports a problem or the binary bodies pass 5 MB. @@ -137,7 +137,7 @@ REPOSITORY = "DevelopmentFinanceObservatory/apis" BINARY_BUDGET = 5_000_000 -# The rendering both clients ask for: bare long Parquet. +# The rendering both clients ask for, bare long Parquet. RENDERING = {"format": "parquet", "bundle": False} # The response headers a client reads, and so the ones a record keeps, beside # a `cache-control` that marks the response shared-cacheable, which excuses it @@ -314,7 +314,7 @@ def __call__( class _NoRedirect(urllib.request.HTTPRedirectHandler): - """Leaves a redirect to the caller: the files route's 302 is read by hand.""" + """Leaves a redirect to the caller, since the files route's 302 is read by hand.""" def redirect_request(self, *_: Any, **__: Any) -> None: return None @@ -343,7 +343,7 @@ def _lower(items: Any) -> dict[str, str]: return {name.lower(): value for name, value in items} -# A local composed app signs no URL: its launcher serves each file at +# A local composed app signs no URL. Its launcher serves each file at # `/__e2e__/blob/{bucket}/{object}` on the API's own origin. A record states # such a URL as the storage URL a deployment signs for the same object. LOCAL_BLOB_PREFIX = "/__e2e__/blob/" @@ -353,7 +353,7 @@ def redact_external_url(url: str) -> str: """An absolute `url` with its query, whatever signs it, replaced by `X-Goog-Signature=redacted`, and a local app's blob URL rewritten to `STORAGE_ORIGIN/{bucket}/{object}`, the object name percent-encoded as - storage signs it; a root-relative URL as it stands.""" + storage signs it. A root-relative URL is returned as it stands.""" parts = urlsplit(url) if not parts.netloc: return url @@ -382,7 +382,7 @@ class Recorder: """Sends requests the way a client does and keeps each exchange. `canned` exchanges answer the first requests, in order, before the - network; a request that is not the next canned one ends the run.""" + network. A request that is not the next canned one ends the run.""" name: str base_url: str @@ -610,14 +610,14 @@ def parquet_shape(data: bytes) -> tuple[int, list[str]]: def _reached[T](results: list[T], step: str) -> T: - """The result a step produced; a step that refused cannot be acted on.""" + """The result a step produced. A step that refused cannot be acted on.""" if not results: raise ShapeError(f"{step} refused, so the steps after it cannot run") return results[0] class ShapeError(Exception): - """The live answer no longer has the shape the scenario is named for.""" + """The live answer lacks the shape the scenario is named for.""" def require(condition: bool, message: str) -> None: @@ -964,14 +964,14 @@ def _identity_sentence( return resubmitted_sentence(answer, definition["spec_id"]) def _download(self, target: str, digest: str, *, origin: bool = True) -> bytes: - """A file through its files route: an `origin_path`, as - `artifact_route` places an artifact's url, or a path under the base + """A file through its files route, named by an `origin_path`, as + `artifact_route` places an artifact's url, or by a path under the base URL. A 302's location is fetched once, where `download_target` places it, a local app's blob URL on the API's origin standing for the - storage URL a deployment signs; a 200 holds the file; any other - success raises ContractError `unexpected_response`. A fetch answering - other than 200, or bytes of another digest, ask the route once - more.""" + storage URL a deployment signs. A 200 holds the file. Any other + success raises ContractError `unexpected_response`. A fetch that + answers with a status other than 200, or returns bytes of another + digest, asks the route once more.""" base_url = self.recorder.base_url if origin: route_url = _origin(base_url) + target @@ -1126,7 +1126,7 @@ def _newest(self, spec_id: str) -> str | None: return newest_listed(body) def _acted(self, response: Response) -> Any: - """The JSON body of a success; a refusal raises its error, and a + """The JSON body of a success. A refusal raises its error, and a success without a JSON body raises ContractError `unexpected_response`.""" self._raise_problem(response) @@ -1382,7 +1382,7 @@ def _fetch_spec_grouped( entities: Mapping[str, list[str] | None] | None = None, ) -> Callable[[Session, Context], None]: """Fetches the GROUPED_FLOW spec, whose destination is a named group, with - the narrowing given, and checks the built sentence still names the group.""" + the narrowing given, and checks the built sentence names the group.""" def run(s: Session, ctx: Context) -> None: spec = ctx.definite_spec(GROUPED_FLOW) @@ -1888,7 +1888,7 @@ class Derived: @dataclass(frozen=True) class Synthetic: - """A scenario derived from a recorded one, with no request: its + """A scenario derived from a recorded one, with no request. Its derivation runs over a context whose transport refuses every request.""" name: str @@ -2135,8 +2135,8 @@ def derive(parent: dict[str, Any], ctx: Context) -> Derived: def _resubmit_other_spec(parent: dict[str, Any], ctx: Context) -> Derived: - """Search answers the built identity with the spec the fetch posted - rather than the one the build answered.""" + """Search answers the built identity with the spec the fetch posted, + which differs from the one the build answered.""" index = next( i for i, e in enumerate(parent["exchanges"]) @@ -2301,7 +2301,7 @@ def _async_fetch( change: Callable[[list[dict[str, Any]], dict[str, Any]], None] | None = None, ) -> Callable[[dict[str, Any], Context], Derived]: """The parent's mint and result as one fetch of its spec, which makes the - same exchanges; `change` edits the exchanges and the fetch's outcome.""" + same exchanges. `change` edits the exchanges and the fetch's outcome.""" def derive(parent: dict[str, Any], ctx: Context) -> Derived: mint, result = parent["call"] @@ -2355,7 +2355,7 @@ def _operation_failed(exchanges: list[dict[str, Any]], build: dict[str, Any]) -> def _poll_busy(exchanges: list[dict[str, Any]], build: dict[str, Any]) -> None: """A 503 answers the first poll, and two more answer the third, after - the second answered: each spends a retry, the answer between restores + the second answered. Each spends a retry, the answer between restores both, and each poll after a 503 waits the wait the 503's poll waited.""" first = _poll_index(exchanges) poll = exchanges[first]["request"] @@ -2379,7 +2379,7 @@ def _unpaced(exchanges: list[dict[str, Any]]) -> None: def _poll_busy_unpaced(exchanges: list[dict[str, Any]], build: dict[str, Any]) -> None: """No response paces the polls, and a 503 with no Retry-After answers the - second poll: every poll waits the next step of the backoff, the one after + second poll. Every poll waits the next step of the backoff, the one after the 503 included.""" _unpaced(exchanges) first = _poll_index(exchanges) @@ -2399,8 +2399,8 @@ def _poll_busy_unpaced(exchanges: list[dict[str, Any]], build: dict[str, Any]) - def _poll_busy_retry_after( exchanges: list[dict[str, Any]], build: dict[str, Any] ) -> None: - """A 503 with Retry-After BUSY_POLL_RETRY_AFTER answers the first poll: - the poll after it waits that long, and the polls after keep the server's + """A 503 with Retry-After BUSY_POLL_RETRY_AFTER answers the first poll. + The poll after it waits that long, and the polls after keep the server's pacing.""" index = _poll_index(exchanges) headers = {"retry-after": str(BUSY_POLL_RETRY_AFTER)} @@ -2483,7 +2483,7 @@ def _files_route_answers( status: int, *, keep_location: bool ) -> Callable[[dict[str, Any], Context], Derived]: """The files route answers `status`, with its location when - `keep_location`, and raises ContractError unexpected_response; the + `keep_location`, and raises ContractError unexpected_response. The exchanges after it go.""" def derive(parent: dict[str, Any], ctx: Context) -> Derived: @@ -2702,7 +2702,7 @@ def derive(parent: dict[str, Any], ctx: Context) -> Derived: # The x-dfo-trace-id header the Search responses of `answer-timed-out` and -# `choose-refused-shared-label` carry: the first's answer_incomplete carries +# `choose-refused-shared-label` carry. The first's answer_incomplete carries # it, and the second's choice_invalid, which describes the caller's choice, # does not. ANSWER_TRACE_ID = "5" * 32 @@ -2785,7 +2785,7 @@ def token(text: str) -> dict[str, Any]: def _picked_reading_assumes(parent: dict[str, Any], ctx: Context) -> Derived: """The parent's search and pick, with the picked reading's - reading_assumptions entry holding one declared default: the resubmit + reading_assumptions entry holding one declared default. The resubmit echoes it unchanged, and Search's answer states it.""" exchanges = copy.deepcopy(parent["exchanges"][:2]) search, resubmit = exchanges @@ -2897,7 +2897,7 @@ def _versions_renamed(parent: dict[str, Any], ctx: Context) -> Derived: def _sunset_twice(parent: dict[str, Any], ctx: Context) -> Derived: - """The parent's search made twice, each response carrying SUNSET: the + """The parent's search made twice, each response carrying SUNSET. The first warns, and the second, with the same value, does not.""" exchange = copy.deepcopy(parent["exchanges"][0]) exchange["response"]["headers"]["sunset"] = SUNSET @@ -2925,7 +2925,7 @@ def _artifact_urls_on( origin: Callable[[dict[str, Any]], str], ) -> Callable[[dict[str, Any], Context], Derived]: """Every artifact `url` of the parent's build becomes absolute on the - origin `origin` gives for the parent: on the API's own origin the record + origin `origin` gives for the parent. On the API's own origin the record stands, and on any other the build raises ContractError and the exchanges after it go.""" @@ -2956,7 +2956,7 @@ def derive(parent: dict[str, Any], ctx: Context) -> Derived: def _server_warnings(parent: dict[str, Any], ctx: Context) -> Derived: """The parent's search made three times. The first response carries - SERVER_MESSAGE; the second the same message and SUNSET; the third + SERVER_MESSAGE, the second the same message and SUNSET, and the third OTHER_SERVER_MESSAGE, DEPRECATION and SUNSET. The warnings each step issues are written out, so a change to the warning rules fails the record.""" @@ -4004,7 +4004,7 @@ def write_record( def _refuse_local_host(record: dict[str, Any], base_url: str) -> None: """Refuses a record holding an absolute URL other than a redacted signed URL on the storage host, or a `location` under `base_url`, as - `absolute_url_problems` finds them: a local app's host, under any name + `absolute_url_problems` finds them. A local app's host, under any name or port, is one no deployed client can fetch.""" if problems := absolute_url_problems(record, base_url): raise SystemExit("\n".join(problems)) diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index 14ec369..20206b1 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -18,13 +18,13 @@ outside them and PLATFORM_PREFIXES. - Every `strict-fields.json` pointer resolves in `served/openapi.json` and names each property once. A required entry's property stays in its schema's - `required` list and admits no null; an enum entry's property admits every + `required` list and admits no null. An enum entry's property admits every value listed. - `actions.json` lists codes in order, each once. Every active refusal code in `registries/codes.json` with a `problem_details` or `no_data_reason` mapping has a row, and no row names another code. A row carries `gap_kind` exactly - when its code has a `no_data_reason` mapping; `choose` goes with the - `choice` gap kind and only with it; and a code with a `problem_details` + when its code has a `no_data_reason` mapping. The `choose` action goes with + the `choice` gap kind and only with it. A code with a `problem_details` mapping takes an action a problem document can carry. - `client-codes.json` lists codes in order, each once, none of them a code in `actions.json` or `registries/codes.json`. Each row's class is one a @@ -56,7 +56,7 @@ and the class of each error the client raises itself from `client-codes.json`, as `expected_outcomes` derives them, the waits before each poll included, under the record's base URL and again under - REPLAY_ORIGIN with the recorded origin a response names moved there; a + REPLAY_ORIGIN with the recorded origin a response names moved there. A dataset's rows, columns and per-part row counts are left to the Parquet bodies, and each download hashes to its artifact's digest or the outcome says it does not. Each Search request a @@ -183,7 +183,7 @@ def _contract_validators() -> dict[str, jsonschema.Draft202012Validator]: def _resolve(document: Any, pointer: str) -> Any: - """The value at an RFC 6901 `pointer` in `document`; raises `KeyError`.""" + """The value at an RFC 6901 `pointer` in `document`. Raises `KeyError`.""" node = document for raw in pointer.split("/")[1:]: token = raw.replace("~1", "/").replace("~0", "~") @@ -545,7 +545,7 @@ def operation( self, base_path: str, request: dict[str, Any] ) -> tuple[str, str, dict[str, Any] | None] | None: """The route template an API request matches, its method's JSON - pointer under `/paths`, and the operation it serves; None for a + pointer under `/paths`, and the operation it serves. None for a request outside the API or one that matches no route.""" if "url" in request: return None @@ -696,7 +696,7 @@ def _check_problem_code( # --- outcomes --------------------------------------------------------------- # # A client's outcome for each step follows from the exchanges and from -# `actions.json`. The functions here derive it; the validator checks each +# `actions.json`. The functions here derive it. The validator checks each # record's `expect` against them, and `tools/capture_client_contract.py` # imports them to write `expect` when it records. @@ -762,7 +762,7 @@ def may_retry( def problem_body(response: Mapping[str, Any]) -> Any: """A refusal's JSON body when its content type is one of PROBLEM_MEDIA, - else None: a body in any other type reads as no body.""" + else None. A body in any other type reads as no body.""" content_type = response.get("headers", {}).get("content-type", "") media = content_type.split(";", maxsplit=1)[0].strip().lower() return response.get("json") if media in PROBLEM_MEDIA else None @@ -907,7 +907,7 @@ def error_outcome(error: str, code: str | None, **members: Any) -> dict[str, Any # The warnings a client raises as errors under strict, which carry the -# server's code rather than a client code. +# server's code. WARNING_CLASSES = ("SearchWarning", "DataWarning") VERSION_UNAVAILABLE = "VersionUnavailableError" @@ -993,7 +993,7 @@ def trace_id(body: Any, headers: Mapping[str, str] | None) -> str | None: def shared_cacheable(headers: Mapping[str, str]) -> bool: - """Whether a response is marked `Cache-Control: public`: a shared cache + """Whether a response is marked `Cache-Control: public`. A shared cache replays it, so it carries no per-request trace id.""" directives = headers.get("cache-control", "").lower().replace(" ", "").split(",") return "public" in directives @@ -1024,7 +1024,7 @@ def refusal_error( # The codes of the errors a client raises itself that describe a response, -# beside the warnings it raises under strict; every other client code +# beside the warnings it raises under strict. Every other client code # describes the caller's input or a storage-host fetch. RESPONSE_ERRORS = frozenset( { @@ -1037,9 +1037,9 @@ def refusal_error( def read_from(error: ClientError, trace: str | None) -> ClientError: - """`error`, raised on the API response whose trace id is `trace`: an + """`error`, raised on the API response whose trace id is `trace`. An error that describes a response, a RESPONSE_ERRORS code, SearchWarning - or DataWarning, takes `trace` unless its trace id is settled; an error that + or DataWarning, takes `trace` unless its trace id is settled. An error that describes the caller's input, or a storage-host fetch, keeps null.""" if isinstance(error.trace_id, _Unset): reads = error.code in RESPONSE_ERRORS or error.error in WARNING_CLASSES @@ -1050,7 +1050,7 @@ def read_from(error: ClientError, trace: str | None) -> ClientError: # --- reading members no strict pointer names --------------------------------- # # A member a client reads that no strict pointer names, and that holds a JSON -# type other than the one its rule reads, reads as absent; so does every +# type other than the one its rule reads, reads as absent. So does every # member of a holder that is not an object. Each read of such a member goes # through one of these. @@ -1085,7 +1085,7 @@ def read_string(holder: Any, name: str) -> str | None: RESOLUTION = "resolution" # The variable text an identity resubmit sends for a member no answer part names. UNNAMED_VARIABLE_TEXT = "dataset" -# The warning severities a fetch reports in its SearchWarning; `info` stays quiet. +# The warning severities a fetch reports in its SearchWarning. `info` stays quiet. SHOWN_SEVERITIES = ("warn", "degraded") @@ -1159,7 +1159,7 @@ def choice_for( With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. A part is named by its index, its variable text, or a word that one gap's options mention, and must be a gap. A - candidates part's options are its candidates, chosen by index; any other + candidates part's options are its candidates, chosen by index. Any other gap's are its no_data options, chosen by index or label, a label scoped to the options that mention the word the part was named by.""" gaps = answer_gaps(answer, kinds) @@ -1226,7 +1226,7 @@ def mentions(option: Mapping[str, Any]) -> list[str]: def choice_input(answer: Answer, choice: Choice) -> dict[str, Any]: """The Search input a choice posts. In a one-part answer an option posts - its data_query; any other choice posts dataset_resubmit with one entry + its data_query. Any other choice posts dataset_resubmit with one entry per part, in part order, so a picked candidate in a one-part answer posts its identity as the one entry, and Search answers the picked reading.""" if len(answer.parts) == 1 and choice.option is not None: @@ -1288,7 +1288,7 @@ def _data_query(option: Mapping[str, Any]) -> dict[str, Any]: def _option_part(option: Mapping[str, Any]) -> Any: - """The one part a no_data option's `data_query` holds; a query of other + """The one part a no_data option's `data_query` holds. A query of other than one part raises ContractError, in a one-part answer as in a several-part one.""" parts = _data_query(option).get("parts") @@ -1301,7 +1301,7 @@ def reading_echo(part: Mapping[str, Any], spec: Mapping[str, Any]) -> Any: """The assumptions a resubmitted reading of `part` echoes: a definite part's `assumptions`, or a candidates part's `reading_assumptions` under the reading's spec_id. None, when the part carries no such member, posts - no `assumptions`, and Search reads the reading as a fresh request does; + no `assumptions`, and Search reads the reading as a fresh request does. `[]` states none.""" if part.get("status") == "candidates": return read_list(read_object(part, "reading_assumptions"), spec["spec_id"]) @@ -1397,9 +1397,10 @@ def search_warning_code(answer: Answer) -> str | None: def answer_gaps(answer: Answer, kinds: Mapping[str, str]) -> list[dict[str, Any]]: - """Each part without a reading: a candidates part is a choice among its - specs; a no_data part takes its reason's gap kind, or `timed_out` when the - answer timed out; a part of unknown status is an `unknown` gap.""" + """Each part without a reading. A candidates part is a choice among its + specs, a no_data part takes its reason's gap kind, or `timed_out` when the + answer timed out, an unsupported part is an `unsupported` gap, and a part + of unknown status is an `unknown` gap.""" diagnostics = read_object(answer.body, "diagnostics") timed_out = diagnostics is not None and diagnostics.get("timed_out") is True gaps = [] @@ -1456,7 +1457,7 @@ def held_spec(spec: Mapping[str, Any]) -> dict[str, Any]: def answer_outcome(answer: Answer, kinds: Mapping[str, str]) -> dict[str, Any]: - """An answer outcome. A declined or catalogue answer is never complete.""" + """An answer outcome. A declined or catalogue answer is incomplete.""" gaps = answer_gaps(answer, kinds) outcome: dict[str, Any] = {"kind": answer.body["kind"]} if answer.status is not None: @@ -1470,7 +1471,7 @@ def answer_outcome(answer: Answer, kinds: Mapping[str, str]) -> dict[str, Any]: def part_label(member: Mapping[str, Any]) -> str: """The `part` column's value on a member's rows in a dataset of several - members: the member's parts joined by `; `, or its sentence when it + members. It is the member's parts joined by `; `, or its sentence when it answers no part.""" return "; ".join(member["parts"]) or member["sentence"] @@ -1526,7 +1527,7 @@ def json_type(value: Any) -> str: def schema_types(openapi: dict[str, Any], schema: Any) -> set[str] | None: """The JSON types `schema` admits, through `$ref`, `anyOf`, `oneOf` and - `allOf`, with `number` admitting an integer; None when it names none.""" + `allOf`, with `number` admitting an integer. None when it names none.""" if not isinstance(schema, dict): return None ref = schema.get("$ref") @@ -1558,12 +1559,12 @@ def strict_gaps( ) -> list[str]: """The strict members `body` lacks, holds as null, or holds as a JSON type their schema does not admit, and each item of a strict list of a - type its item schema does not admit, read through `schema`: each component + type its item schema does not admit, read through `schema`. Each component schema it reaches names its own, and a discriminated union whose discriminator `body` lacks is a gap. The walk goes down only through strict members, the ones a client reads, so a member no client reads, such as a spec's `resolved.equivalent_readings`, - is never checked. A discriminator value the union does not map, and a + goes unchecked. A discriminator value the union does not map, and a union without a discriminator that offers more than one object branch, reach nothing. `component` is the component schema `schema` belongs to.""" if not isinstance(schema, dict): @@ -1638,8 +1639,8 @@ class _UnfitError(Exception): "long": {"format": "parquet", "bundle": False}, "frame": {"format": "parquet", "bundle": False, "layout": "frame"}, } -# The snapshot refusal after which a stored version's lookup builds it again: -# the version exists, but its file has expired. Any other refusal ends it. +# The snapshot refusal after which a stored version's lookup builds it again. +# The version exists, but its file has expired. Any other refusal ends it. FILE_EXPIRED = "artifact_expired" # The file route refusals after which the lookup takes its next step. FILE_GONE = frozenset({FILE_EXPIRED, "artifact_not_found", "not_found"}) @@ -1686,7 +1687,7 @@ def posted_scope(step: Mapping[str, Any]) -> dict[str, Any] | None: def versions_path(spec_id: str) -> str: - """The versions route asked for the newest stored version alone: the + """The versions route asked for the newest stored version alone. The route lists versions newest first, so `limit=1` returns just it.""" return f"/datasets/{spec_id}/versions?limit=1" @@ -1714,9 +1715,9 @@ def build_body( scope: Mapping[str, Any] | None, rendering: Mapping[str, Any], ) -> dict[str, Any]: - """The body a client posts to build `spec`, a step's `spec` or a ref's: - its spec_id and unmodified definition, `scope` when it narrows anything, - and `rendering` as the options.""" + """The body a client posts to build `spec`, a step's `spec` or a ref's. + It holds the spec_id and unmodified definition, `scope` when it narrows + anything, and `rendering` as the options.""" input_: dict[str, Any] = { "kind": "spec_id", "spec_id": spec["spec_id"], @@ -1767,7 +1768,7 @@ def selector_path( STORAGE_ORIGIN = "https://storage.googleapis.com" REDACTED_QUERY = "X-Goog-Signature=redacted" # A files route answers FILES_ROUTE_REDIRECT with the `location` the client -# fetches, or FILES_ROUTE_FILE with the file as its body; a refusal reads by +# fetches, or FILES_ROUTE_FILE with the file as its body. A refusal reads by # the refusal rules, and any other status, another 2xx or 3xx included, # raises ContractError `unexpected_response`. A signed fetch that answers # other than SIGNED_FETCH_STATUS is a failed fetch. @@ -1807,7 +1808,7 @@ def artifact_route(base_url: str, url: str) -> str: def data_warning(manifest: Mapping[str, Any]) -> ClientError | None: """The DataWarning a strict fetch raises for a manifest: its first warning - above `info` severity, with that warning's code; None when it has none.""" + above `info` severity, with that warning's code. None when it has none.""" for warning in read_objects(manifest, "warnings"): if read_string(warning, "severity") != "info": return ClientError(read_string(warning, "code"), error="DataWarning") @@ -1815,7 +1816,7 @@ def data_warning(manifest: Mapping[str, Any]) -> ClientError | None: def resubmitted_sentence(answer: Answer, spec_id: str) -> str: - """The sentence Search gives a built identity it was posted: the answer + """The sentence Search gives a built identity it was posted. The answer must be one definite part of `spec_id`, with a sentence, or the client raises ContractError.""" found = answer.parts[0] if len(answer.parts) == 1 else {} @@ -1832,10 +1833,10 @@ def resubmitted_sentence(answer: Answer, spec_id: str) -> str: def kept_entity_groups( held: Mapping[str, Any] | None, built: Mapping[str, Any] ) -> dict[str, Any]: - """The held spec's entity groups a built definition keeps: the group of - each role the built identity binds to the same entities the held + """The held spec's entity groups a built definition keeps, which are the + group of each role the built identity binds to the same entities the held definition binds it to. A role the narrowing rebound or dropped loses its - group; a window or facets narrowing keeps every group.""" + group, and a window or facets narrowing keeps every group.""" if held is None or not (groups := read_object(held, "entity_groups")): return {} before = read_object(read_object(held["definition"], "identity"), "entities") @@ -1849,8 +1850,8 @@ def kept_entity_groups( def bound_refs(entities: dict[str, Any] | None, role: str) -> set[str]: - """The refs an identity's `entities` binds `role` to, its string items; - a binding of another type, or an item of one, reads as absent.""" + """The refs an identity's `entities` binds `role` to, its string items. + A binding of another type, or an item of one, reads as absent.""" return {ref for ref in read_list(entities, role) or [] if isinstance(ref, str)} @@ -1900,10 +1901,10 @@ class LongBuild: """A build the server runs on, followed the way a client polls it. Each wait before a poll is `PollPacing`'s. A retryable 429 poll spends no retry, any other retryable refused poll one of MAX_RETRIES, and a refused - poll that is not retryable raises, a 429 included; the poll after a + poll that is not retryable raises, a 429 included. The poll after a refusal waits as `PollPacing` gives. A poll answering a failed operation, retryable by its error, posts the build again once when the - client holds its request; otherwise, and for an operation that failed + client holds its request. Otherwise, and for an operation that failed before the client polled it, the operation's error raises. `entry` is the build's `long_builds` entry, and `result` its manifest once it is done.""" @@ -2038,8 +2039,8 @@ def call( `path`, `origin_path` or `url`, is exactly `target`. With `retries`, a refusal followed by the same request is retried as `may_retry` allows, each retry after the wait `retry_wait` gives, and the last - exchange of the run is the one acted on; a run that ends while - `may_retry` still holds lacks a retry the client makes. Each API + exchange of the run is the one acted on. A run that ends while + `may_retry` holds lacks a retry the client makes. Each API response issues the warnings its headers carry.""" if self.cursor >= len(self.exchanges): raise _UnfitError(f"the steps make a {method} {target} the record lacks") @@ -2133,14 +2134,14 @@ def body(self, response: dict[str, Any]) -> bytes: return b"" def download(self, target: str, digest: str, *, origin: bool) -> None: - """A file through its files route: an `origin_path`, as - `artifact_route` places an artifact's `url`, when `origin`, else a + """A file through its files route, named by an `origin_path`, as + `artifact_route` places an artifact's `url`, when `origin`, else by a path under the base URL. A 302 names the signed URL in its `location`, which the client fetches once where `download_target` - places it; a 200 holds the file; a refusal raises; any other status - raises ContractError `unexpected_response`. A fetch answering other - than 200, or bytes that do not hash to `digest`, ask the route once - more, and a second failure raises.""" + places it. A 200 holds the file, a refusal raises, and any other + status raises ContractError `unexpected_response`. A fetch that + answers other than 200, or bytes that do not hash to `digest`, asks + the route once more, and a second failure raises.""" failure = ClientError("download_failed") base = urlsplit(self.base_url) route_url = ( @@ -2211,8 +2212,8 @@ def build( scope: dict[str, Any] | None = None, ) -> dict[str, Any]: """A build of `spec`'s latest version, posting `rendering` as its - options and `scope` as its input's scope: the manifest it answers, - through a long build when it answers 202.""" + options and `scope` as its input's scope. It returns the manifest the + build answers, through a long build when it answers 202.""" exchange = self.posted_build(spec, rendering, scope) if exchange["response"]["status"] != 202: return self.acted_on(exchange) @@ -2309,10 +2310,10 @@ def stored_version(self, member: dict[str, Any]) -> dict[str, Any]: """One version a ref names, through the lookup order: the snapshot route and the files route at the stored digest, then the file selector, then a build that must answer the same version. A snapshot - refusal other than artifact_expired ends the lookup; otherwise a + refusal other than artifact_expired ends the lookup. Otherwise a lookup that finds no file raises VersionUnavailableError with the - first refusal's code, or version_unavailable, and the newest version: - the one the build answered, or the versions route's first.""" + first refusal's code, or version_unavailable, and the newest version, + either the one the build answered or the versions route's first.""" spec = member["spec"] spec_id, version = spec["spec_id"], member["content_version"] rendering = member["artifact"]["rendering"] @@ -2362,7 +2363,7 @@ def stored_file( """Whether the files route at the stored digest, or else the file selector, served the stored file, and the files route's refusal when it refused. A selector refusal outside FILE_GONE, and a files route - one, raise; a selector file of another digest is not the stored one.""" + one, raise. A selector file of another digest is not the stored one.""" digest = member["artifact"]["digest"] refusal = None artifact = next( @@ -2395,7 +2396,7 @@ def stored_file( def newest(self, spec_id: str) -> str | None: """The newest stored version, the one the versions route lists first, - or None when it lists none or refuses the spec as unknown; a page + or None when it lists none or refuses the spec as unknown. A page that lists no versions in the form `newest_listed` reads raises.""" try: body = self.acted_on(self.call("GET", versions_path(spec_id))) @@ -2454,11 +2455,11 @@ def _choose(self, step: dict[str, Any]) -> dict[str, Any]: return answer_outcome(chosen, self.kinds) def _fetch(self, step: dict[str, Any]) -> dict[str, Any]: - """A fetch of the answer: a declined or catalogue answer raises - DeclinedError; a gap raises IncompleteAnswerError unless the fetch is - partial and some part has a reading; a strict fetch whose readings - depart from the question raises SearchWarning; the frame layout with - several members raises InvalidRequestError; all before any request.""" + """A fetch of the answer. Before any request, a declined or catalogue + answer raises DeclinedError, a gap raises IncompleteAnswerError unless + the fetch is partial and some part has a reading, a strict fetch whose + readings depart from the question raises SearchWarning, and the frame + layout with several members raises InvalidRequestError.""" answer = self._answered() if answer.body.get("kind") != "resolution": raise read_from(ClientError("answer_declined"), answer.trace_id) @@ -2579,7 +2580,7 @@ def expected_outcomes( Raises: ValueError: The exchanges do not fit the steps, or deriving an outcome raised, so the record names its own problem and the - other records are still checked. + other records are checked. """ replay = _Replay( record["exchanges"], @@ -2594,8 +2595,8 @@ def expected_outcomes( outcomes = [replay.step(step) for step in record["call"]] except (_UnfitError, KeyError, IndexError, StopIteration, ValueError) as exc: raise ValueError(f"the exchanges do not fit the steps: {exc!r}") from exc - # Any other exception is a malformed record the rules missed: it is this - # record's problem, and the other records are still checked. + # Any other exception is a malformed record the rules missed. It is this + # record's problem, and the other records are checked as before. except Exception as exc: raise ValueError(f"deriving its outcomes raised {exc!r}") from exc if replay.cursor != len(replay.exchanges): @@ -2662,7 +2663,7 @@ def _under(url: str, base_url: str) -> bool: def absolute_url_problems(record: Mapping[str, Any], base_url: str) -> list[str]: """Each absolute URL a record holds, a `url` request or a `location` header, that is not a signed URL on the storage host, over https and - with the redacted query; a `location` may also name a route under + with the redacted query. A `location` may also name a route under `base_url`. A local app's host, or any other, is refused by name.""" storage = urlsplit(STORAGE_ORIGIN) problems = [] @@ -2760,7 +2761,7 @@ def _part_problems( ) -> list[str]: """A dataset of several members has the `part` column first and a `part_rows` entry per member, in member order, whose `part` is that - member's `part_label` and whose rows sum to the dataset's; a dataset of + member's `part_label` and whose rows sum to the dataset's. A dataset of one member has neither.""" several = len(members) > 1 problems = [] From 8ed610a5edc8b1db7786ceef6b0e6d9b234cd568 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Thu, 22 Oct 2026 17:18:45 +0200 Subject: [PATCH 26/39] docs(contract): clarify conformance, capabilities and timeout scope Describe the API gate as schema and registry validation of recorded exchanges. Scope disk-cache rules to clients implementing that capability and state the synchronous platform DNS timeout exception. --- python/client-contract/README.md | 6 +++--- .../client-contract/src/dfo_client_contract/rules/README.md | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 1d97269..4546fc6 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -1,6 +1,6 @@ # dfo-spec-kit-client-contract (Python) -This package holds the contract the DFO clients are built to: the Python client `development-finance` and the TypeScript client `@developmentfinance/client`. The clients generate their wire types, strict checks and error maps from these files and replay the scenarios. dfo-apis CI checks its app against the same files, so a server change that breaks a client fails there first. The files below are normative; where this README and the files disagree, the files win and the disagreement is a bug. See the [repo README](../../README.md) for how this package fits with the rest of `dfo-spec-kit`. +This package holds the contract the DFO clients are built to: the Python client `development-finance` and the TypeScript client `@developmentfinance/client`. The clients generate their wire types, strict checks and error maps from these files and replay the scenarios. dfo-apis CI validates the recorded exchanges against the app's current OpenAPI document, strict fields and code registry. The SDK's scheduled live journeys check deployed server behavior; a change that preserves the schema can pass the API gate. The files below are normative; where this README and the files disagree, the files win and the disagreement is a bug. See the [repo README](../../README.md) for how this package fits with the rest of `dfo-spec-kit`. The import name is `dfo_client_contract`. It depends on the standard library only. @@ -183,7 +183,7 @@ The records also fix these client rules: - A `request(method, path)` whose `path` is not a path on the base URL, because it starts with `//` or names a scheme, raises `InvalidRequestError` `invalid_argument` before any request. No scenario step makes such a request. - A 2xx response of a JSON route with no JSON body raises `ContractError` `unexpected_response`. `search-no-json-body` pins it for Search. - A `Deprecation` or `Sunset` header on an API response, either alone, issues `route_deprecated` once per process per distinct pair of their values, and an `x-dfo-warning` header issues `server_warning` once per process per message. A signed fetch's headers issue nothing. `search-sunset-warning` pins a Sunset header alone, issued once over two responses that carry the same value, and `search-server-warning` pins a repeated `x-dfo-warning` message issued once, a new message issued again, and a Deprecation beside the same Sunset issued as a new pair. -- Timeouts follow the clients' design and are not replayed, since the replay advances the clock only by the waits the client asks for: the client's `timeout`, 30 s by default, bounds one request attempt; `search(timeout=60)` bounds the whole search, each attempt reading until that deadline, and None means no limit; `fetch(timeout=1800)` bounds the whole fetch, each download getting the time left on the fetch's deadline; a synchronous build POST, and mint's POST, read for up to 150 s within any outer deadline; `result(timeout=1800)` bounds the wait, and None means no limit. A poll attempt that hangs past the per-attempt timeout spends a retry, and a deadline that passes during a body read raises `DfoTimeoutError` `deadline_exceeded`. In TypeScript an infinite remaining time arms no timer, and a finite one above 2^31-1 ms is clamped. No scenario step takes a timeout. +- Python synchronous platform name resolution can exceed the following timeout and deadline limits. Asynchronous name resolution is cancellable. Timeouts follow the clients' design and are not replayed, since the replay advances the clock only by the waits the client asks for: the client's `timeout`, 30 s by default, bounds one request attempt; `search(timeout=60)` bounds the whole search, each attempt reading until that deadline, and None means no limit; `fetch(timeout=1800)` bounds the whole fetch, each download getting the time left on the fetch's deadline; a synchronous build POST, and mint's POST, read for up to 150 s within any outer deadline; `result(timeout=1800)` bounds the wait, and None means no limit. A poll attempt that hangs past the per-attempt timeout spends a retry, and a deadline that passes during a body read raises `DfoTimeoutError` `deadline_exceeded`. In TypeScript an infinite remaining time arms no timer, and a finite one above 2^31-1 ms is clamped. No scenario step takes a timeout. ## Recording @@ -214,7 +214,7 @@ A record's `origin.base_url` is the base URL the run was given, a local app's in ## Rules -`rules/README.md` states the rules every client implements the same way: the credentials path and file format, the key lookup order, the key format check, and the cache directory and layout. Each rule's vectors are in `rules/.json`. +`rules/README.md` states the shared rules for credentials, key lookup and format, and disk caching. A rule applies where the client and runtime implement its capability. Python implements disk caching; TypeScript currently keeps no disk cache, so `cache-dir` and `cache-layout` apply to Python. Credentials-file rules apply to runtimes with local credentials support. Each rule's vectors are in `rules/.json`. ## Validation diff --git a/python/client-contract/src/dfo_client_contract/rules/README.md b/python/client-contract/src/dfo_client_contract/rules/README.md index 8257f50..17d91bd 100644 --- a/python/client-contract/src/dfo_client_contract/rules/README.md +++ b/python/client-contract/src/dfo_client_contract/rules/README.md @@ -1,6 +1,6 @@ # Client rules -Every DFO client implements these rules the same way, so a key, a credentials file and a cache directory work across languages. Each rule's vectors are in `.json`, validated by `rules.schema.json`. In a vector, `env` lists the environment variables set, and an empty value counts as unset everywhere below. +Clients implement these rules for the capabilities available in their runtime. Python implements every rule. TypeScript implements the key and credentials rules in Node; browser runtimes use the key sources available there. TypeScript currently keeps no disk cache, so `cache-dir` and `cache-layout` apply to Python. Clients implementing the same capability use the same rules and formats. Each rule's vectors are in `.json`, validated by `rules.schema.json`. In a vector, `env` lists the environment variables set, and an empty value counts as unset everywhere below. ## Credentials path (`credentials-path`) @@ -49,7 +49,7 @@ The cache root is the first of, as readerkit's `resolve_cache_dir(app="dfo", ... 1. `BBLOCKS_CACHE_DIR`; 1. the platform cache directory for `readerkit`: on Linux `$XDG_CACHE_HOME/readerkit`, else `~/.cache/readerkit`; on macOS `~/Library/Caches/readerkit`; on Windows `\readerkit\Cache`, which the vectors give as `LOCALAPPDATA`. -A leading `~` expands to the home directory. The cache directory is `/v1/dfo/cache1`: `v1` is readerkit's own layout version, `dfo` the app, and `cache1` the client cache's layout version, shared by every client and every client release. +A leading `~` expands to the home directory. The cache directory is `/v1/dfo/cache1`: `v1` is readerkit's own layout version, `dfo` the app, and `cache1` the client cache's layout version. Clients and releases implementing `cache1` share this layout. ## Cache layout (`cache-layout`) From c1a9966d6c445d39f1bfc9824fa83cc3b2affd73 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Thu, 22 Oct 2026 17:32:44 +0200 Subject: [PATCH 27/39] docs(contract): scope concurrent cache write guarantees Distinguish content-addressed byte entries from replaceable manifests. Concurrent manifest writes can reduce cache availability while artifact digest verification continues to protect data identity. --- python/client-contract/src/dfo_client_contract/rules/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/client-contract/src/dfo_client_contract/rules/README.md b/python/client-contract/src/dfo_client_contract/rules/README.md index 17d91bd..fdd4a5e 100644 --- a/python/client-contract/src/dfo_client_contract/rules/README.md +++ b/python/client-contract/src/dfo_client_contract/rules/README.md @@ -58,4 +58,4 @@ Inside the cache directory: - a downloaded artifact is `files/sha256/`, keyed by its digest; - a manifest is `manifests///.json`, where `` is the format, then `-bundle` for a bundle, then `-frame` for the frame layout: `parquet`, `parquet-frame`, `csv-bundle`. -A client writes an entry to a temporary name in the same directory and renames it into place, so a reader never sees a partial entry, and concurrent writers of one entry write identical bytes. A read re-hashes an artifact, and a mismatch counts as a miss. +A client writes an entry to a temporary name in the same directory and renames it into place, so a reader sees a complete entry. Concurrent writers of one content-addressed artifact write identical bytes. Manifest updates can replace another complete manifest and lose a cache candidate, so cache availability is best-effort. A read re-hashes an artifact, and a mismatch counts as a miss. From 94ed5a2e0ea2de590752d47462123ae93f886382 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Fri, 23 Oct 2026 09:17:00 +0200 Subject: [PATCH 28/39] fix(contract): close the review's body-file, ref, echo, choice and recovery gaps Capture and the validator refuse a symlinked or out-of-directory body file before reading or writing it. A ref's `definition` requires the `schema_version` and `identity` the served `CanonicalDefinition` needs, with three rejected examples. The resubmit echo posts the object items of `operations` and `assumptions` alone, a candidate may be chosen by its label as well as its index, and a rebuild that answers another `spec_id` raises `contract_violation`. The README states the browser redirect rule the TypeScript client follows. Five synthetic scenarios pin the new rules (117 in all). --- python/client-contract/CHANGELOG.md | 2 +- python/client-contract/README.md | 29 +- .../dataset-ref.schema.json | 12 +- .../refs/ref-bare-definition-rejected.json | 31 + ...-definition-without-identity-rejected.json | 32 + ...ition-without-schema-version-rejected.json | 96 + .../scenarios/choose-candidate-by-label.json | 3133 ++++++ .../choose-echo-drops-malformed-items.json | 9008 +++++++++++++++++ ...choose-refused-shared-candidate-label.json | 2402 +++++ ...hoose-refused-unknown-candidate-label.json | 2393 +++++ .../fetch-ref-expired-rebuild-other-spec.json | 910 ++ tools/README.md | 4 +- tools/capture_client_contract.py | 163 +- tools/tests/test_capture_client_contract.py | 48 + tools/tests/test_validate_client_contract.py | 13 + tools/validate_client_contract.py | 89 +- 16 files changed, 18324 insertions(+), 41 deletions(-) create mode 100644 python/client-contract/src/dfo_client_contract/refs/ref-bare-definition-rejected.json create mode 100644 python/client-contract/src/dfo_client_contract/refs/ref-definition-without-identity-rejected.json create mode 100644 python/client-contract/src/dfo_client_contract/refs/ref-definition-without-schema-version-rejected.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-by-label.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-echo-drops-malformed-items.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-candidate-label.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-candidate-label.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-other-spec.json diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index 92c3c21..561952b 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -11,7 +11,7 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be - `strict-fields.json` and its schema: 28 members that stay required and non-nullable, each one a client reads, and the answer kinds, part statuses and operation statuses the clients branch on. - `actions.json` and its schema: the caller's next step for each of the 101 active refusal codes on `problem_details` or `no_data_reason`, with the gap kind of each no_data reason. - The status fallback for a refusal whose code has no row: 400 and 422 to `InvalidRequestError`, 401 to `AuthenticationError`, 403 to `PermissionDeniedError`, 404 and 410 to `NotFoundError`, 408 to `DfoTimeoutError`, 429 to `RateLimitError`, and any other 4xx or 5xx to `InvalidRequestError` or `ServerError`. -- `scenario.schema.json`, the scenario record, and 101 scenarios: 31 recorded against the composed dfo-apis app at `635943e03`, and 70 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 2,105,201 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, a part without variable_text, an unknown status without a restatement, a shared label, a one-part option whose data_query holds two parts, the separate and operations echo, an unsupported part's placeholder, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a cut-off build retried after its Retry-After, a build refused 504 then 503 and one refused 503 then 504, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, a signed URL refused on both rounds, a relative files-route Location, an artifact url on a foreign origin, on the storage host and absolute on the API's origin, a manifest definition without identity, a Search spec without identity or resolved, nested specs no rule reads, an empty parts list, a Search body that is not an object, a codeless 503 problem document that is not retryable, a 401, an identity resubmit answering another spec, a part whose status is not a string, a Search spec whose definition names another spec_id, a Search response with no JSON body, an option with no data_query, empty entities and facets, a Sunset header issued once, `x-dfo-warning` messages and a Deprecation and Sunset pair, an unreadable versions page, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, 503 polls retried within the budget an answered poll restores, a 404 poll that raises, a failed operation posted again, a failed operation with no error, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route. +- `scenario.schema.json`, the scenario record, and 117 scenarios: 31 recorded against the composed dfo-apis app at `635943e03`, and 86 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 2,105,201 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, a part without variable_text, an unknown status without a restatement, a shared label, a one-part option whose data_query holds two parts, the separate and operations echo, an unsupported part's placeholder, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a cut-off build retried after its Retry-After, a build refused 504 then 503 and one refused 503 then 504, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, a signed URL refused on both rounds, a relative files-route Location, an artifact url on a foreign origin, on the storage host and absolute on the API's origin, a manifest definition without identity, a Search spec without identity or resolved, nested specs no rule reads, an empty parts list, a Search body that is not an object, a codeless 503 problem document that is not retryable, a 401, an identity resubmit answering another spec, a part whose status is not a string, a Search spec whose definition names another spec_id, a Search response with no JSON body, an option with no data_query, empty entities and facets, a Sunset header issued once, `x-dfo-warning` messages and a Deprecation and Sunset pair, an unreadable versions page, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, 503 polls retried within the budget an answered poll restores, a 404 poll that raises, a failed operation posted again, a failed operation with no error, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route. - `client-codes.json` and its schema: the 17 codes a client sets on the errors it raises itself, each with its error class, retryable flag and condition, disjoint from `actions.json` and `registries/codes.json`, and the `client_codes()` and `client_codes_schema()` accessors. Every scenario error the client raises itself carries its code, and `refusal_without_code` names a refusal whose body carries no code. - `proxy-codes.json` and its schema, the website proxy's `rate_limited` and `transient_unavailable` codes with their statuses, and `warning-codes.json` and its schema, the 5 codes a client sets on the warnings it issues itself, with the `proxy_codes()` and `warning_codes()` accessors. - Error outcomes give the error's `trace_id`, the body's, else the `x-dfo-trace-id` header's, else null. Scenario outcomes give `retry_waits`, the waits before each retry, and `warnings`, the warning codes a step's responses issued. Scenario steps take no `timeout`. diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 4546fc6..2cf9c20 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -124,15 +124,15 @@ An answer's gaps follow from its parts. A candidates part is a `choice` gap, its A scenario is one client-level call, the HTTP exchanges it makes, and the outcome each step reaches. Each record is one file, `scenarios/.json`, validated by `scenario.schema.json`. -| Member | Holds | -| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `format_version` | `1` | -| `name` | The kebab-case name, equal to the file name's stem | -| `description` | One or two sentences on what the scenario proves | -| `origin` | `recorded`, with the `base_url`, the deployed `dfo_commit` and `recorded_at`; or `synthetic`, with the recorded scenario it is `derived_from` and a one-line `edit` | +| Member | Holds | +| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `format_version` | `1` | +| `name` | The kebab-case name, equal to the file name's stem | +| `description` | One or two sentences on what the scenario proves | +| `origin` | `recorded`, with the `base_url`, the deployed `dfo_commit` and `recorded_at`; or `synthetic`, with the recorded scenario it is `derived_from` and a one-line `edit` | | `call` | The steps, in order: `search`; `choose`; `fetch` of the previous answer, of a `spec` with `window`, `entities` and `facets`, or of a `ref`; `mint`; `operation`, which resumes a long build by its `operation_id`; `result`; `newest_version` of a `spec` | -| `exchanges` | The requests the call makes, in order, each with the response to give | -| `expect` | One outcome per step: an `answer`, a `dataset`, an `operation`, a `newest_version` or an `error` | +| `exchanges` | The requests the call makes, in order, each with the response to give | +| `expect` | One outcome per step: an `answer`, a `dataset`, an `operation`, a `newest_version` or an `error` | A step that acts on an earlier result follows one: `choose` follows `search` or `choose`, a `fetch` with no target follows `search`, `choose` or another `fetch` with no target and acts on the last answer, and `result` follows `mint` or `operation`. A `fetch` of an answer or a spec, `mint` and `operation` take a `layout`, `long` by default or `frame`, and a `fetch` of an answer or a spec takes `strict`. A `spec` in a step holds `spec_id`, the server's unmodified `definition`, the `sentence` when the client knows it, and the server's `resolved.entity_groups` as `entity_groups` when it names any. @@ -160,21 +160,22 @@ The records also fix these client rules: - A fetch of a spec posts its narrowing as the build's `input.scope`, and posts no `scope` when it narrows nothing. A mint takes a layout and no narrowing, so it posts no `scope`. `window` posts `{"kind": "range", "start_year", "end_year"}` for a pair of years, or `{"kind": "all"}` or `{"kind": "latest"}`, and `facets` posts each axis as `{"ref": ...}`, and `facets: {}` names no axis and posts no `facets`. The server's `scope.entities` replaces the spec's whole entity binding, so `entities` posts a whole map: the roles the spec's `definition.identity.entities` binds, with each role the caller names replaced by its refs and each role the caller binds to null dropped. Naming `origin` alone on a spec bound to `origin` and `destination` keeps `destination`. A fetch that names no role, `entities: {}` included, posts no `entities`, so a fetch whose narrowing is all empty posts no `scope`; `fetch-spec-empty-narrowing` pins it. - A built `spec_id` that differs from the posted one, or a spec with no sentence, takes its sentence from Search: the client posts the built definition's `identity` as one `dataset_resubmit` identity entry, with the member's first part as `variable_text`, or `"dataset"` when no answer part names it, and checks the answer's `spec_id` equals the built one. The entry's `entity_groups` holds the spec's `resolved.entity_groups` for each role the built identity binds to the same entities as the spec's definition, so a window or facets narrowing keeps every group and a role the narrowing rebound or dropped loses its group. The entry leaves `entity_groups` out when it keeps no group, as for a resumed operation, whose spec the client does not hold. The server reads a role posted without its group as its members, so a narrowed spec of flows to the least developed countries would read "44 recipients" in place of "the 44 Least Developed Countries". - A dataset of several members puts the `part` column first, then each member's columns in member order, each column once. A column that members hold in different types widens as pyarrow's permissive promotion widens it, and a pair that cannot widen raises `ContractError` `contract_violation`. A member file that already holds a `part` column raises `contract_violation` when members stack. Rows and columns are not derived, so no scenario pins these. The `part` value on a member's rows is the member's `parts` joined by `"; "`, so a member that answers two folded parts reads `"health ODA disbursements; education ODA disbursements"`, or the member's sentence when `parts` is empty. A definite part whose `variable_text` is absent or empty adds nothing to its member's `parts`, which `answer-folded-parts-unnamed` pins. -- A choice names its part by index, by variable text, or by a word that one gap's options mention, and its option by index or label; a candidate is named by index. A candidate with neither a heading nor a sentence has a null label; no scenario pins it. A label is matched among the options that mention the word the part was named by. With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. -- A choice raises `InvalidRequestError` `choice_invalid` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is out of range or matches no label or several. It raises the same when an entry it would post cannot be built: a part with no `variable_text`, or a part of a status the client does not know that has no `restatement`. A chosen option whose `data_query` holds other than one part raises `ContractError`, and so does a chosen option with no `data_query`, in a one-part answer as in a several-part one, before any request. `choose-refused-shared-label`, `choose-refused-part-without-variable-text`, `choose-refused-unknown-status`, `choose-option-two-part-query` and `choose-option-without-data-query` pin these. +- A choice names its part by index, by variable text, or by a word that one gap's options mention, and its option, a candidate among them, by index or label. A candidate's label is the `text` of its spec's `resolved.sentence_plan` tokens in the `heading` segment, a token whose `segment` is not a string counted in it, joined and stripped of surrounding white space, or else its `resolved.rendered_sentence`. A candidate with neither a heading nor a sentence has a null label; no scenario pins it. A no_data option's label is matched among the options that mention the word the part was named by. With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. +- A choice raises `InvalidRequestError` `choice_invalid` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is out of range or matches no label or several. It raises the same when an entry it would post cannot be built: a part with no `variable_text`, or a part of a status the client does not know that has no `restatement`. A chosen option whose `data_query` holds other than one part raises `ContractError`, and so does a chosen option with no `data_query`, in a one-part answer as in a several-part one, before any request. `choose-refused-shared-label`, `choose-refused-unknown-candidate-label`, `choose-refused-shared-candidate-label`, `choose-refused-part-without-variable-text`, `choose-refused-unknown-status`, `choose-option-two-part-query` and `choose-option-without-data-query` pin these, and `choose-candidate-by-label` pins a candidate chosen by its label. - Every pick of a candidate asks Search for the picked answer, and no client builds it locally. In a one-part answer the pick posts `dataset_resubmit`, without `raw_query`, with one identity entry: the candidate's identity and `entity_groups`, and the part's `variable_text`, `separate` and `operations` as below. The picked answer, its sentence with any "Assumed: …" clause, and its assumptions are Search's response. A choice of a no_data option in a one-part answer posts the option's `data_query` as the input. -- In a several-part answer a choice posts `dataset_resubmit`, without `raw_query`, with one entry per part in part order. The chosen candidate posts an identity entry with its identity and `entity_groups`, and the chosen option its `data_query`'s one part as a parsed entry. A definite part posts an identity entry with its spec's identity and `entity_groups`. A candidates part left alone posts a `candidates` entry: its candidate set in the server's order, each with its identity and `entity_groups`, and its `ordering` and `truncated` echoed. The server cannot recompute that order, because it rests on the first answer's bind election and availability reads, and a parsed entry would cost an LLM bind. Any other part posts its `restatement` as a parsed entry, or a placeholder entry with its no_data `reason` or unsupported `code` when it has none. Every entry but a parsed one carries the part's `variable_text`, `separate` when true and `operations` when the part has any. `entity_groups` is left out when the spec has none. `choose-echoes-separate-and-operations` pins the echo on a definite part's entry, and `choose-posts-unsupported-placeholder` an unsupported part's placeholder. -- Each identity a choice posts echoes its reading's assumptions as `assumptions`: the chosen candidate's entry carries its part's `reading_assumptions` under the candidate's `spec_id`, a definite part's entry carries the part's `assumptions`, and each candidate of a `candidates` entry carries its own `reading_assumptions` entry. Search then states the echoed items that still hold, so the picked answer states what that reading assumed. `[]` states none. An identity with no `assumptions` reads as a fresh request, so a client that holds no list for a reading, from a part that carries no `assumptions` or `reading_assumptions`, posts none. The identity entry that asks for a built sentence posts no `assumptions`, since it reads only the spec's own `rendered_sentence`. +- In a several-part answer a choice posts `dataset_resubmit`, without `raw_query`, with one entry per part in part order. The chosen candidate posts an identity entry with its identity and `entity_groups`, and the chosen option its `data_query`'s one part as a parsed entry. A definite part posts an identity entry with its spec's identity and `entity_groups`. A candidates part left alone posts a `candidates` entry: its candidate set in the server's order, each with its identity and `entity_groups`, and its `ordering` and `truncated` echoed. The server cannot recompute that order, because it rests on the first answer's bind election and availability reads, and a parsed entry would cost an LLM bind. Any other part posts its `restatement` as a parsed entry, or a placeholder entry with its no_data `reason` or unsupported `code` when it has none. Every entry but a parsed one carries the part's `variable_text`, `separate` when true and `operations` when the part has any that are objects, posting those alone. `entity_groups` is left out when the spec has none. `choose-echoes-separate-and-operations` pins the echo on a definite part's entry, and `choose-posts-unsupported-placeholder` an unsupported part's placeholder. +- Each identity a choice posts echoes its reading's assumptions as `assumptions`: the chosen candidate's entry carries its part's `reading_assumptions` under the candidate's `spec_id`, a definite part's entry carries the part's `assumptions`, and each candidate of a `candidates` entry carries its own `reading_assumptions` entry. Search then states the echoed items that still hold, so the picked answer states what that reading assumed. `[]` states none. An identity with no `assumptions` reads as a fresh request, so a client that holds no list for a reading, from a part that carries no `assumptions` or `reading_assumptions`, posts none. The identity entry that asks for a built sentence posts no `assumptions`, since it reads only the spec's own `rendered_sentence`. An echoed `operations` or `assumptions` list posts its object items alone: by the absent-value rule under Strict fields an item of another type reads as absent, so the echo drops it, and an `assumptions` list with no object item posts `[]`. `choose-echo-drops-malformed-items` pins both lists. - A strict fetch raises the manifest's first warning above `info` severity as a `DataWarning` with that warning's code, before the sentence lookup and the download. - An identity resubmit whose answer is not one definite part of the built `spec_id`, with a sentence, raises `ContractError`. - The `frame` layout posts `{"format": "parquet", "bundle": false, "layout": "frame"}` as the build's `options` and downloads the artifact whose rendering's `layout` is `frame`; the `long` layout posts `{"format": "parquet", "bundle": false}` and downloads the bare Parquet artifact with any other layout. A fetch of an answer with several members in the `frame` layout raises `InvalidRequestError` before any build. - A download asks the route that redirects to the signed URL, an artifact's `url` or the file selector, and fetches the URL its `location` names once. A files route answers 302 with the `location` the client fetches, or 200 with the file as its body, which the client hashes with no further request, which `fetch-spec-files-route-serves-file` pins. A refusal reads by the refusal rules, and any other status, another 2xx or another 3xx included, raises `ContractError` `unexpected_response` with that response's trace id, which `fetch-spec-files-route-no-content` pins with a 204 and `fetch-spec-files-route-temporary-redirect` with a 307. The route ask is an API request and follows the retry rules below, so a retryable refusal is retried within the budget and any other refusal, `artifact_expired` among them, raises at once. A failed fetch gets exactly one more round. A fetch that answers anything but 200, which `fetch-spec-signed-fetch-partial` pins with a 206, or bytes that do not hash to the artifact's digest ask the route again, under the same retry rules, and fetch again, with no wait between rounds. A second failure raises `ServerError` with `download_failed`, or `digest_mismatch` when the bytes are wrong. A network error or timeout on the fetch is retryable, so it starts the second round too, and when the second round fails the same way the client raises that failure as itself, `network_error` or `deadline_exceeded`. The replay holds no network failure, so no scenario pins that case. - A manifest artifact's `url` names its files route on the API's origin. A root-relative `url` resolves against the base URL's origin, and an absolute one on that origin is asked as its path and query, so both make the same `origin_path` request, which `fetch-spec-same-origin-artifact-url` pins. An artifact `url` on any other origin, the storage host's included, raises `ContractError` `contract_violation` before the sentence lookup and any request for the file, which `fetch-spec-foreign-artifact-url` and `fetch-spec-storage-artifact-url` pin. - A relative `location` resolves against the files route's URL, and the client fetches it on the API's origin as an `origin_path` request. A `location` on an origin other than the API's or `https://storage.googleapis.com` raises `ContractError` `contract_violation` before any fetch. A fetch on the storage host is bare and carries no API key. `fetch-spec-relative-location` pins the relative case. +- The redirect rules above hold where a client reads the files route's response itself: the Python client, and the TypeScript client in Node. A browser page or worker cannot, because a `fetch` with `redirect: "manual"` answers an opaque redirect with no status and no `location`. There the TypeScript client asks the files route again with `redirect: "follow"`, sending the API key alone, which the browser drops on the way to another origin, and the followed request is the round's one fetch. The response must end on the API's origin or `https://storage.googleapis.com`, and any other host raises `ContractError` `contract_violation` after the fetch. So in a browser a files route answering 301, 303, 307 or 308 is followed as a 302 is. The refusal rules, the retry rules, the rounds and the digest check hold in every runtime. The scenario format names no runtime, so the scenarios fix the Python and Node behaviour, and the TypeScript client's own tests check the browser's. - A declined or catalogue answer is not complete, and fetching it raises `DeclinedError`. - Fetching an answer with a gap raises `IncompleteAnswerError` before any request, unless the fetch is partial and some part has a reading. - A fetch of an answer issues one `SearchWarning` when a definite part has an operation Search did not run, a departure, or a warning at severity `warn` or `degraded` with a `message`, or the answer's `diagnostics.warnings` holds such a warning. An `info` warning, and a warning with no `message`, issue nothing. Each way is one line a client shows: `Not done: ()` coded by the verb, the departure's `text` coded by its code, or `Note: ` coded by the warning's code, in part order with the diagnostics warnings last, and ways that show the same line count once, under the first one's code. A strict fetch raises the `SearchWarning` before any build, with the code of its one line, or a null code when there are several lines. A strict fetch raises it before the `frame` layout's several-member check. -- A ref's version is found in this order: the snapshot route and the files route at the stored digest; the file selector, `GET /datasets/{id}/{content_version}/file` with the ref's rendering as the query; and a build of the ref's spec in the ref's rendering, which must answer the same `content_version`. A snapshot refusal other than `artifact_expired` ends the lookup, so `snapshot_not_found` raises `NotFoundError` with no further request. A files route or selector refusal of `artifact_expired`, `artifact_not_found` or `not_found` takes the next step, and a selector file of another digest is not the stored file. A snapshot manifest whose artifacts list no artifact of the ref member's digest sends the client to the selector in the ref member's own rendering, and a file that hashes to that digest gives the dataset, which `fetch-ref-artifact-unlisted` pins. A rebuild that answers another version, or that raises `InvalidRequestError`, `NotFoundError` or `VersionUnavailableError`, ends in `VersionUnavailableError` with the first refusal's code, or `version_unavailable` when nothing refused. Its `newest_version` is the version the rebuild answered, or else the newest stored version, which `GET /datasets/{id}/versions?limit=1` lists alone, as a `newest_version` step finds it, since the route lists versions newest first and needs no key; or null when that route lists none or refuses with `NotFoundError`. Any other refusal of the versions route raises, and a page whose `versions` is not a list of versions each with a `content_version` raises `ContractError` `contract_violation`, which `newest-version-unreadable-page` pins. +- A ref's version is found in this order: the snapshot route and the files route at the stored digest; the file selector, `GET /datasets/{id}/{content_version}/file` with the ref's rendering as the query; and a build of the ref's spec in the ref's rendering, which must answer the ref's `spec_id` and the same `content_version`. Both recovery steps keep the ref's identity, so a recovered member carries the ref's `spec_id` and `content_version`: a snapshot manifest whose `definition.spec_id` or `content_version` is not the ref's, or a rebuild manifest whose `definition.spec_id` is not the ref's, raises `ContractError` `contract_violation` before any download, which `fetch-ref-expired-rebuild-other-spec` pins for the rebuild. A snapshot refusal other than `artifact_expired` ends the lookup, so `snapshot_not_found` raises `NotFoundError` with no further request. A files route or selector refusal of `artifact_expired`, `artifact_not_found` or `not_found` takes the next step, and a selector file of another digest is not the stored file. A snapshot manifest whose artifacts list no artifact of the ref member's digest sends the client to the selector in the ref member's own rendering, and a file that hashes to that digest gives the dataset, which `fetch-ref-artifact-unlisted` pins. A rebuild that answers another version, or that raises `InvalidRequestError`, `NotFoundError` or `VersionUnavailableError`, ends in `VersionUnavailableError` with the first refusal's code, or `version_unavailable` when nothing refused. Its `newest_version` is the version the rebuild answered, or else the newest stored version, which `GET /datasets/{id}/versions?limit=1` lists alone, as a `newest_version` step finds it, since the route lists versions newest first and needs no key; or null when that route lists none or refuses with `NotFoundError`. Any other refusal of the versions route raises, and a page whose `versions` is not a list of versions each with a `content_version` raises `ContractError` `contract_violation`, which `newest-version-unreadable-page` pins. - A build answers 200 with the manifest, or 202 with an operation the client polls at `/datasets/operations/{operation_id}`, the id of the operation it holds. A mint's build answers 202. A record whose mint answers 200 fits no mint step. Before each poll it waits the `Retry-After` of the refusal that answered the last poll, whatever its status, as every retry of a refused request waits; else the last operation resource's `retry_after_ms`, else the `Retry-After` of the last answered poll, the response that carried that resource, else a backoff of 1, 2, 4 and then 8 seconds that advances one step each time it is used, a poll after a refusal included. - A retryable 429 poll spends no retry, and a 429 whose body says it is not retryable raises at once, as a refusal's `retryable` outranks its status, which `fetch-spec-poll-rate-limited-not-retryable` pins. Any other retryable refused poll spends one of the two retries, which a poll that answers restores, and a refusal that is not retryable raises. `fetch-spec-poll-refused` pins two 503s polled again after an answered poll, `fetch-spec-poll-refused-backoff` a 503 with no `Retry-After` among polls no response paces, after which the backoff advances, `fetch-spec-poll-refused-retry-after` a 503 whose `Retry-After` paces the next poll, and `fetch-spec-poll-not-found` a 404 that raises at once. A poll that answers a failed operation whose error is retryable posts the same build once more and polls the operation it starts; a second failure, an error that is not retryable, and a resumed operation, whose build request the client does not hold, raise the operation's error. A refused poll whose code is `operation_failed` is a failed operation with that error. A failed operation whose resource carries no `error` raises `ServerError` with `operation_failed`, retryable by status 500 as a refusal without a document is, which `operation-failed-without-error` pins. A 202 or resumed operation that already reads `failed` raises its error before any poll. - Any other refusal is retried when it is retryable: as a problem document's `retryable` says, or the website proxy's `retry` of `retry_after_delay`, else when its status is 408, 429, 500, 502, 503 or 504. A client makes two retries by default, and the scenarios assume that default. A build's POST shares those two retries with every other refusal of it, and once a 504 cuts the build off the client posts it once more only, whatever that post answers: a build refused 504 then 503 raises the 503, a build refused 503 then 504 is posted once more after the 504, and a second 504 raises. `fetch-spec-504-then-503`, `fetch-spec-503-then-504` and `fetch-spec-504-twice` pin the three. A refusal that is not retryable, or one past the retries, raises its error. @@ -210,7 +211,7 @@ A record's `origin.base_url` is the base URL the run was given, a local app's in ## DatasetRef -`dataset-ref.schema.json` is the frozen format a client writes for `data.ref` and reads back in any language: `format_version: 1` and one or more `members`, each `{parts, sentence, spec: {spec_id, definition}, content_version, artifact: {digest, rendering}}`. `parts` holds the variable text of each answer part the member answers, in query order, and is empty for a spec fetched outside an answer. `rendering` is the selector a client matches an artifact on, `{format, bundle}` with `layout: "frame"` for the frame layout, never the server's rendering object. Beyond the schema, each member's `definition.spec_id` equals its `spec.spec_id`, and members hold distinct `spec_id`s. `refs/` holds accepted examples and rejected ones, each `{format_version, name, description, ref}` with `expect: "accept"` or `error`, `{by: "schema"}` or `{by: "rule", reason}`, the reason `definition_spec_id_mismatch` or `repeated_spec_id`. +`dataset-ref.schema.json` is the frozen format a client writes for `data.ref` and reads back in any language: `format_version: 1` and one or more `members`, each `{parts, sentence, spec: {spec_id, definition}, content_version, artifact: {digest, rendering}}`. `parts` holds the variable text of each answer part the member answers, in query order, and is empty for a spec fetched outside an answer. `definition` is the server's definition unmodified, so it holds the `schema_version`, `spec_id` and `identity` the served `CanonicalDefinition` requires, and a rebuild posts it as it is. `rendering` is the selector a client matches an artifact on, `{format, bundle}` with `layout: "frame"` for the frame layout, never the server's rendering object. Beyond the schema, each member's `definition.spec_id` equals its `spec.spec_id`, and members hold distinct `spec_id`s. `ref-bare-definition-rejected`, `ref-definition-without-identity-rejected` and `ref-definition-without-schema-version-rejected` pin the definition's required members. `refs/` holds accepted examples and rejected ones, each `{format_version, name, description, ref}` with `expect: "accept"` or `error`, `{by: "schema"}` or `{by: "rule", reason}`, the reason `definition_spec_id_mismatch` or `repeated_spec_id`. ## Rules diff --git a/python/client-contract/src/dfo_client_contract/dataset-ref.schema.json b/python/client-contract/src/dfo_client_contract/dataset-ref.schema.json index b9d7e0b..382e739 100644 --- a/python/client-contract/src/dfo_client_contract/dataset-ref.schema.json +++ b/python/client-contract/src/dfo_client_contract/dataset-ref.schema.json @@ -58,14 +58,22 @@ "$ref": "#/$defs/spec_id" }, "definition": { - "description": "The server's definition for spec_id, unmodified.", + "description": "The server's definition for spec_id, unmodified. It holds the members the served CanonicalDefinition requires, so a rebuild can post it as it is.", "type": "object", "required": [ - "spec_id" + "schema_version", + "spec_id", + "identity" ], "properties": { + "schema_version": { + "const": 1 + }, "spec_id": { "$ref": "#/$defs/spec_id" + }, + "identity": { + "type": "object" } } } diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-bare-definition-rejected.json b/python/client-contract/src/dfo_client_contract/refs/ref-bare-definition-rejected.json new file mode 100644 index 0000000..232a9f8 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/refs/ref-bare-definition-rejected.json @@ -0,0 +1,31 @@ +{ + "format_version": 1, + "name": "ref-bare-definition-rejected", + "description": "A member's definition is the server's whole definition, with its schema_version and identity beside its spec_id.", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6" + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "artifact": { + "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "format": "parquet", + "bundle": false + } + } + } + ] + }, + "error": { + "by": "schema" + } +} diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-definition-without-identity-rejected.json b/python/client-contract/src/dfo_client_contract/refs/ref-definition-without-identity-rejected.json new file mode 100644 index 0000000..b2b93fd --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/refs/ref-definition-without-identity-rejected.json @@ -0,0 +1,32 @@ +{ + "format_version": 1, + "name": "ref-definition-without-identity-rejected", + "description": "A member's definition holds its identity.", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6" + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "artifact": { + "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "format": "parquet", + "bundle": false + } + } + } + ] + }, + "error": { + "by": "schema" + } +} diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-definition-without-schema-version-rejected.json b/python/client-contract/src/dfo_client_contract/refs/ref-definition-without-schema-version-rejected.json new file mode 100644 index 0000000..9cc8ed9 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/refs/ref-definition-without-schema-version-rejected.json @@ -0,0 +1,96 @@ +{ + "format_version": 1, + "name": "ref-definition-without-schema-version-rejected", + "description": "A member's definition holds its schema_version.", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "artifact": { + "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "format": "parquet", + "bundle": false + } + } + } + ] + }, + "error": { + "by": "schema" + } +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-by-label.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-by-label.json new file mode 100644 index 0000000..8e3295c --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-by-label.json @@ -0,0 +1,3133 @@ +{ + "format_version": 1, + "name": "choose-candidate-by-label", + "description": "A candidate is chosen by its label, the heading of its sentence plan, as by its index: the choice posts the same identity entry and reaches the same answer.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-candidates-choose-fetch", + "edit": "The choice names candidate 0 by its label, and the fetch goes." + }, + "call": [ + { + "op": "search", + "question": "GNI of Germany from 2015 to 2022" + }, + { + "op": "choose", + "option": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022." + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "GNI of Germany from 2015 to 2022" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "d107dd88e50147378d54464bcdaf9695" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "GNI of Germany from 2015 to 2022", + "normalized_query": "GNI of Germany from 2015 to 2022", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "d107dd88e50147378d54464bcdaf9695", + "warnings": [], + "timing_ms": { + "total": 4075, + "by_step": { + "coverage": 0, + "extract": 1004 + } + }, + "llm_usage": { + "input_tokens": 7300, + "output_tokens": 300, + "cached_tokens": 861 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GNI", + "warnings": [], + "timing_ms": { + "total": 2799, + "by_step": { + "recall": 381, + "shape_arcs": 2, + "shape_probe_coverage": 1, + "shape_probe": 203, + "shape_groups": 18, + "shape_labels": 5, + "shape_admission": 0, + "shape": 1186, + "bind": 829, + "materialise": 217, + "answer": 186 + } + }, + "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "sentence_plan": [ + { + "kind": "text", + "text": "3 readings.", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "primary income", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross of fixed capital consumption", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "OECD DAC1", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity per capita", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "GNI", + "entities": [ + { + "text": "Germany" + } + ], + "time_text": "2015 to 2022", + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "candidates", + "candidates": { + "ordering": "intent_rank", + "max_candidates": 6, + "specs": [ + { + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "definition": { + "schema_version": 1, + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicunit_primaryincome_measuredvalue_nominal", + "label": "Gross national income", + "population_type": { + "ref": "EconomicUnit", + "label": "economic unit" + }, + "measured_property": { + "ref": "primaryIncome", + "label": "primary income" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "distinguishes": true + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + }, + { + "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "definition": { + "schema_version": 1, + "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "PurchasingPowerParity" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossNationalIncome" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity", + "label": "Gross National Income Based on Purchasing Power Parity", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "PurchasingPowerParity", + "label": "PurchasingPowerParity" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "833b9da89613fa6c1775652daac2388f38204c6c9f9929ca113deed9a0d08369", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ], + "upstream": { + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + } + } + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "fallback", + "ref": "InternationalDollar", + "label": "InternationalDollar" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "InternationalDollar", + "label": "InternationalDollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross national income based on purchasing power parity in international dollars, 2015 to 2022. World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross national income based on purchasing power parity", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "in international dollars", + "axis": "unit", + "segment": "heading", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + }, + { + "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", + "definition": { + "schema_version": 1, + "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "PurchasingPowerParity", + "measurement_denominator": { + "unresolved": true + } + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossNationalIncome" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity_per_unresolved", + "label": "Gross National Income Based on Purchasing Power Parity Per Capita", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "PurchasingPowerParity", + "label": "PurchasingPowerParity" + }, + "measurement_denominator": { + "ref": "PerCapita", + "label": "PerCapita" + }, + "measurement_denominator_unresolved": true, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "7b2d5b0fc09cfc0215c8d7c6c21a5195fa21e79f2a148a6bca9ce6c3af8bbb9f", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ], + "upstream": { + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + } + } + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "fallback", + "ref": "InternationalDollar", + "label": "InternationalDollar" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "InternationalDollar", + "label": "InternationalDollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross national income based on purchasing power parity per capita in international dollars, 2015 to 2022. World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross national income based on purchasing power parity per capita", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "in international dollars", + "axis": "unit", + "segment": "heading", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "truncated": false + }, + "reading_assumptions": { + "spec_c0f61f3ca3558aac184973441a67601e": [], + "spec_403a96317ee8b97f1d8569c71015e5ce": [], + "spec_d94656e5d53b7b6c6b0c683145a1cd98": [] + } + } + ], + "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "sentence_plan": [ + { + "kind": "text", + "text": "3 readings.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "primary income", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross of fixed capital consumption", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "OECD DAC1", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity per capita", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "candidates" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "dataset_resubmit", + "entries": [ + { + "entry_kind": "identity", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + }, + "assumptions": [], + "variable_text": "GNI" + } + ] + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "4386e87708a64f078f39a795faeb0100" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "dataset_resubmit", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "4386e87708a64f078f39a795faeb0100", + "warnings": [], + "timing_ms": { + "total": 9, + "by_step": { + "coverage": 0 + } + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GNI", + "warnings": [], + "timing_ms": { + "total": 8, + "by_step": { + "validate": 0, + "walk": 5, + "reread_arcs": 0, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 0, + "bind": 0, + "where_places": 1, + "materialise": 0, + "answer": 1, + "options": 1 + } + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "definition": { + "schema_version": 1, + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicunit_primaryincome_measuredvalue_nominal", + "label": "Gross national income", + "population_type": { + "ref": "EconomicUnit", + "label": "economic unit" + }, + "measured_property": { + "ref": "primaryIncome", + "label": "primary income" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_347a470e04c97eec" + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [], + "related_measures": [] + } + } + } + ], + "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "status": "definite" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "candidates", + "sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 3 + } + ] + } + }, + { + "answer": { + "kind": "resolution", + "status": "definite", + "sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "complete": true, + "specs": [ + "spec_c0f61f3ca3558aac184973441a67601e" + ], + "gaps": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-echo-drops-malformed-items.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-echo-drops-malformed-items.json new file mode 100644 index 0000000..0579b1e --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-echo-drops-malformed-items.json @@ -0,0 +1,9008 @@ +{ + "format_version": 1, + "name": "choose-echo-drops-malformed-items", + "description": "An item that is not an object reads as absent, so each echoed operations and assumptions list posts only its object items: the definite part's one operation and its own assumptions, and the chosen candidate's empty list.", + "origin": { + "kind": "synthetic", + "derived_from": "choose-candidate-echoes-assumptions", + "edit": "The definite part's operations hold 42 before an operation and its assumptions end with a string, and the chosen candidate's reading_assumptions end with 7." + }, + "call": [ + { + "op": "search", + "question": "GNI of Germany and aid flows to Kenya" + }, + { + "op": "choose", + "part": 0, + "option": 0 + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "GNI of Germany and aid flows to Kenya" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "810e4170976b4e69aade88273e59e8c2" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "GNI of Germany and aid flows to Kenya", + "normalized_query": "GNI of Germany and aid flows to Kenya", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "810e4170976b4e69aade88273e59e8c2", + "warnings": [], + "timing_ms": { + "total": 3563, + "by_step": { + "coverage": 0, + "extract": 915 + } + }, + "llm_usage": { + "input_tokens": 11874, + "output_tokens": 489, + "cached_tokens": 860 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GNI", + "warnings": [ + { + "code": "direction_discarded", + "severity": "warn", + "message": "Kenya was named as the recipient; this shape reports the place as its own subject, so the direction was dropped." + } + ], + "timing_ms": { + "total": 2206, + "by_step": { + "recall": 1, + "shape_arcs": 1, + "shape_probe_coverage": 3, + "shape_probe": 270, + "shape_groups": 201, + "shape_labels": 6, + "shape_admission": 0, + "shape": 1165, + "bind": 1038, + "materialise": 1, + "answer": 1 + } + }, + "rendered_sentence": "2 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 1960 to 2025 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 1990 to 2025. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", + "sentence_plan": [ + { + "kind": "text", + "text": "2 readings.", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Primary income", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross of fixed capital consumption", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany and Kenya", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "OECD DAC1", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "1960 to 2025", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Gross national income based on purchasing power parity", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany and Kenya", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "1990 to 2025", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", + "segment": "departure", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "GNI", + "entities": [ + { + "text": "Germany" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [ + { + "code": "direction_discarded", + "binding_ref": "where:", + "asked": "Kenya", + "text": "You named Kenya as a recipient. This measure has no recipients, so this shows the place itself." + } + ], + "assumptions": [], + "status": "candidates", + "candidates": { + "ordering": "intent_rank", + "max_candidates": 6, + "specs": [ + { + "spec_id": "spec_f0d0bb4841c0e55d6d4a353e45dcd52c", + "definition": { + "schema_version": 1, + "spec_id": "spec_f0d0bb4841c0e55d6d4a353e45dcd52c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicunit_primaryincome_measuredvalue_nominal", + "label": "Gross national income", + "population_type": { + "ref": "EconomicUnit", + "label": "economic unit" + }, + "measured_property": { + "ref": "primaryIncome", + "label": "primary income" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 66, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 1 + }, + { + "label": "observations", + "count": 66 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 66, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 1960, + "end_year": 2025 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1" + }, + "value_kind": "source" + } + }, + { + "value": { + "ref": { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 1960 to 2025. Current US dollars · OECD DAC1.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "distinguishes": true + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Germany and Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + }, + { + "spec_id": "spec_c024875e07eee23ed7cb8d18b4436df1", + "definition": { + "schema_version": 1, + "spec_id": "spec_c024875e07eee23ed7cb8d18b4436df1", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "PurchasingPowerParity" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossNationalIncome" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity", + "label": "Gross National Income Based on Purchasing Power Parity", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "PurchasingPowerParity", + "label": "PurchasingPowerParity" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "833b9da89613fa6c1775652daac2388f38204c6c9f9929ca113deed9a0d08369", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ], + "upstream": { + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + } + } + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "1990", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 72, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 2 + }, + { + "label": "observations", + "count": 36 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 72, + "rows_exact": true, + "series": 2, + "window": { + "start_year": 1990, + "end_year": 2025 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "fallback", + "ref": "InternationalDollar", + "label": "InternationalDollar" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "InternationalDollar", + "label": "InternationalDollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Gross national income based on purchasing power parity in international dollars in Germany and Kenya, 1990 to 2025. World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Gross national income based on purchasing power parity", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "in international dollars", + "axis": "unit", + "segment": "heading", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Germany and Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1990 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "truncated": false + }, + "reading_assumptions": { + "spec_f0d0bb4841c0e55d6d4a353e45dcd52c": [ + 7 + ], + "spec_c024875e07eee23ed7cb8d18b4436df1": [] + } + }, + { + "variable_text": "aid flows", + "warnings": [ + { + "code": "retrieval_score_weak", + "severity": "info", + "message": "the chosen reading's match to the query is weak; treat it with less confidence than a strong match." + }, + { + "code": "slot_defaulted", + "severity": "warn", + "message": "No aid type was named, so the answer covers official development assistance." + } + ], + "timing_ms": { + "total": 2564, + "by_step": { + "recall": 607, + "shape_arcs": 1, + "shape_probe_coverage": 3, + "shape_probe": 218, + "shape_groups": 18, + "shape_labels": 0, + "shape_admission": 0, + "shape": 930, + "bind": 1014, + "materialise": 6, + "answer": 4, + "options": 3 + } + }, + "restatement": { + "variable_text": "aid flows", + "entities": [ + { + "text": "Germany" + }, + { + "text": "Kenya", + "role_text": "to" + } + ], + "sources": [], + "operations": [] + }, + "operations": [ + 42, + { + "verb": "growth", + "phrase": "growth of GDP", + "over": "year" + } + ], + "departures": [ + { + "code": "closest_match", + "asked": "aid flows", + "shown": "gross disbursements", + "text": "You asked for aid flows. This shows gross disbursements, the closest measure the data holds." + }, + { + "code": "direction_inferred", + "binding_ref": "where:", + "asked": "Germany", + "text": "You named Germany without a direction. Only the data with Germany as the provider holds values, so this reads it as the provider." + } + ], + "assumptions": [ + { + "kind": "declared_default", + "binding_ref": "how:dac2aAidType", + "text": "official development assistance", + "refs": [ + "DAC2aAidType206" + ] + }, + "assumed" + ], + "status": "definite", + "spec": { + "spec_id": "spec_473682ae7e62be173cac86a13815f0fa", + "definition": { + "schema_version": 1, + "spec_id": "spec_473682ae7e62be173cac86a13815f0fa", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal_family_f096b1ba", + "label": "gross disbursements (official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "DAC2aAidType206", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "dacTypeOfFinance", + "financialObligationType" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 65, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 65 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2024, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + } + ] + }, + "download": { + "rows": 65, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 1960, + "end_year": 2024 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "DAC2aAidType218", + "label": "ODA loans and other long-term capital" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 2, + "served_rows": 61, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType201", + "label": "ODA grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 1, + "served_rows": 65, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType207", + "label": "free-standing technical co-operation" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 59, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType213", + "label": "developmental food aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 44, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType216", + "label": "humanitarian aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 29, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross disbursements to Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2a", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "DAC2aAidType206", + "label": "official development assistance" + } + ], + "provenance": "declared_default" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "measure_elected" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "measure_elected" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "high", + "available_at_place": true, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_433a5ca3b9aa482f8f332201570ef664", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 65, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1985, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1992, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1973, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1994, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1987, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1989, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1987, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1961, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 1985, + "end_year": 1990 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "KES", + "origin": "EUR" + } + } + } + } + } + ], + "rendered_sentence": "Answered 1 of 2 parts. GNI has 2 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 1960 to 2025 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 1990 to 2025. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself. Germany's gross disbursements to Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a. You asked for aid flows. This shows gross disbursements, the closest measure the data holds. You named Germany without a direction. Only the data with Germany as the provider holds values, so this reads it as the provider. Assumed: official development assistance.", + "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "GNI", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " has 2 readings.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Primary income", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross of fixed capital consumption", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany and Kenya", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "OECD DAC1", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "1960 to 2025", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Gross national income based on purchasing power parity", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany and Kenya", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "1990 to 2025", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "1960 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "You asked for aid flows. This shows gross disbursements, the closest measure the data holds.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "You named Germany without a direction. Only the data with Germany as the provider holds values, so this reads it as the provider.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "Assumed: ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "official development assistance", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 1 + } + ], + "status": "mixed" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "dataset_resubmit", + "entries": [ + { + "entry_kind": "identity", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + } + }, + "assumptions": [], + "variable_text": "GNI" + }, + { + "entry_kind": "identity", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + }, + "assumptions": [ + { + "kind": "declared_default", + "binding_ref": "how:dac2aAidType", + "text": "official development assistance", + "refs": [ + "DAC2aAidType206" + ] + } + ], + "variable_text": "aid flows", + "operations": [ + { + "verb": "growth", + "phrase": "growth of GDP", + "over": "year" + } + ] + } + ] + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "2e151fcdeb6f40b3be7b3da99c277765" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "dataset_resubmit", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "2e151fcdeb6f40b3be7b3da99c277765", + "warnings": [], + "timing_ms": { + "total": 947, + "by_step": { + "coverage": 0 + } + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GNI", + "warnings": [], + "timing_ms": { + "total": 2, + "by_step": { + "validate": 0, + "walk": 0, + "reread_arcs": 1, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 0, + "bind": 0, + "where_places": 0, + "materialise": 0, + "answer": 1, + "options": 0 + } + }, + "operations": [], + "departures": [ + { + "code": "entity_unavailable", + "binding_ref": "where:", + "text": "You asked for Kenya. The data holds no values for it." + } + ], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_f0d0bb4841c0e55d6d4a353e45dcd52c", + "definition": { + "schema_version": 1, + "spec_id": "spec_f0d0bb4841c0e55d6d4a353e45dcd52c", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU", + "country/KEN" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicunit_primaryincome_measuredvalue_nominal", + "label": "Gross national income", + "population_type": { + "ref": "EconomicUnit", + "label": "economic unit" + }, + "measured_property": { + "ref": "primaryIncome", + "label": "primary income" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2025" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 66, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 1 + }, + { + "label": "observations", + "count": 66 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "download": { + "rows": 66, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 1960, + "end_year": 2025 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1" + }, + "value_kind": "source" + } + }, + { + "value": { + "ref": { + "ref": "provenance/WorldBankInternationalDebtStatistics", + "label": "World Bank International Debt Statistics (IDS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 1960 to 2025. Current US dollars · OECD DAC1.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Germany and Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec" + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [], + "related_measures": [] + } + } + }, + { + "variable_text": "aid flows", + "warnings": [], + "timing_ms": { + "total": 924, + "by_step": { + "validate": 0, + "walk": 5, + "reread_arcs": 0, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 909, + "bind": 0, + "where_places": 0, + "materialise": 4, + "answer": 5, + "options": 1 + } + }, + "operations": [], + "departures": [], + "assumptions": [ + { + "kind": "declared_default", + "binding_ref": "how:dac2aAidType", + "text": "official development assistance", + "refs": [ + "DAC2aAidType206" + ] + } + ], + "status": "definite", + "spec": { + "spec_id": "spec_473682ae7e62be173cac86a13815f0fa", + "definition": { + "schema_version": 1, + "spec_id": "spec_473682ae7e62be173cac86a13815f0fa", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal_family_f096b1ba", + "label": "gross disbursements (official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "DAC2aAidType206", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "dacTypeOfFinance" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "1960", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 65, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 65 + }, + { + "label": "variables", + "count": 1 + } + ] + }, + "headline": { + "year": 2024, + "year_named": false, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + }, + "recent_years": [ + { + "year": 2024, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2023, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + }, + { + "year": 2022, + "observations": 1, + "series": 1, + "role_counts": { + "financingProvider": 1, + "financingRecipient": 1 + } + } + ] + }, + "download": { + "rows": 65, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 1960, + "end_year": 2024 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "DAC2aAidType218", + "label": "ODA loans and other long-term capital" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 2, + "served_rows": 61, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType201", + "label": "ODA grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 1, + "served_rows": 65, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType207", + "label": "free-standing technical co-operation" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 59, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType213", + "label": "developmental food aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 44, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType216", + "label": "humanitarian aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 29, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross disbursements to Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "1960 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2a", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "DAC2aAidType206", + "label": "official development assistance" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "capability_version": "cap_347a470e04c97eec" + }, + "confidence": "high", + "available_at_place": true, + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_433a5ca3b9aa482f8f332201570ef664", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": { + "destination": [ + "country/KEN" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 65, + "served_rows_exact": true + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 1997, + "end_year": 2021 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2002, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2014, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 1996, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 1985, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 1992, + "end_year": 2019 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 1973, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 1994, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2003, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2000, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 1986, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 1987, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 1995, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2001, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 1989, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 1987, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 1961, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 1998, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 1985, + "end_year": 1990 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2013, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 1997, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2010, + "end_year": 2020 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2000, + "end_year": 2023 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2011, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2010 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2010 + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 1990, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2006, + "end_year": 2016 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 1991, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 1960, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 1992, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2014, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 1980, + "end_year": 2024 + }, + "constant_years": { + "start_year": 1960, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": { + "destination": "KES", + "origin": "EUR" + } + } + } + } + } + ], + "rendered_sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 1960 to 2025. Current US dollars · OECD DAC1. You asked for Kenya. The data holds no values for it. Germany's gross disbursements to Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a. Assumed: official development assistance.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Germany and Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "1960 to 2025", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "You asked for Kenya. The data holds no values for it.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Germany", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "country/DEU" + ], + "states": [ + "origin:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], + "states": [ + "where:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "1960 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "OECD DAC2a", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "Assumed: ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "official development assistance", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 1 + } + ], + "status": "definite" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "mixed", + "sentence": "Answered 1 of 2 parts. GNI has 2 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 1960 to 2025 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 1990 to 2025. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself. Germany's gross disbursements to Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a. You asked for aid flows. This shows gross disbursements, the closest measure the data holds. You named Germany without a direction. Only the data with Germany as the provider holds values, so this reads it as the provider. Assumed: official development assistance.", + "complete": false, + "specs": [ + "spec_473682ae7e62be173cac86a13815f0fa" + ], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 2 + } + ] + } + }, + { + "answer": { + "kind": "resolution", + "status": "definite", + "sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 1960 to 2025. Current US dollars · OECD DAC1. You asked for Kenya. The data holds no values for it. Germany's gross disbursements to Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a. Assumed: official development assistance.", + "complete": true, + "specs": [ + "spec_f0d0bb4841c0e55d6d4a353e45dcd52c", + "spec_473682ae7e62be173cac86a13815f0fa" + ], + "gaps": [] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-candidate-label.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-candidate-label.json new file mode 100644 index 0000000..a1c904f --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-candidate-label.json @@ -0,0 +1,2402 @@ +{ + "format_version": 1, + "name": "choose-refused-shared-candidate-label", + "description": "A label two candidates share matches several, so choosing by it raises InvalidRequestError with no request.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-candidates-choose-fetch", + "edit": "Candidate 1 takes candidate 0's sentence plan, and the choice names their shared label." + }, + "call": [ + { + "op": "search", + "question": "GNI of Germany from 2015 to 2022" + }, + { + "op": "choose", + "option": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022." + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "GNI of Germany from 2015 to 2022" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "d107dd88e50147378d54464bcdaf9695" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "GNI of Germany from 2015 to 2022", + "normalized_query": "GNI of Germany from 2015 to 2022", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "d107dd88e50147378d54464bcdaf9695", + "warnings": [], + "timing_ms": { + "total": 4075, + "by_step": { + "coverage": 0, + "extract": 1004 + } + }, + "llm_usage": { + "input_tokens": 7300, + "output_tokens": 300, + "cached_tokens": 861 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GNI", + "warnings": [], + "timing_ms": { + "total": 2799, + "by_step": { + "recall": 381, + "shape_arcs": 2, + "shape_probe_coverage": 1, + "shape_probe": 203, + "shape_groups": 18, + "shape_labels": 5, + "shape_admission": 0, + "shape": 1186, + "bind": 829, + "materialise": 217, + "answer": 186 + } + }, + "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "sentence_plan": [ + { + "kind": "text", + "text": "3 readings.", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "primary income", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross of fixed capital consumption", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "OECD DAC1", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity per capita", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "GNI", + "entities": [ + { + "text": "Germany" + } + ], + "time_text": "2015 to 2022", + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "candidates", + "candidates": { + "ordering": "intent_rank", + "max_candidates": 6, + "specs": [ + { + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "definition": { + "schema_version": 1, + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicunit_primaryincome_measuredvalue_nominal", + "label": "Gross national income", + "population_type": { + "ref": "EconomicUnit", + "label": "economic unit" + }, + "measured_property": { + "ref": "primaryIncome", + "label": "primary income" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "distinguishes": true + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + }, + { + "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "definition": { + "schema_version": 1, + "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "PurchasingPowerParity" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossNationalIncome" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity", + "label": "Gross National Income Based on Purchasing Power Parity", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "PurchasingPowerParity", + "label": "PurchasingPowerParity" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "833b9da89613fa6c1775652daac2388f38204c6c9f9929ca113deed9a0d08369", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ], + "upstream": { + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + } + } + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "fallback", + "ref": "InternationalDollar", + "label": "InternationalDollar" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "InternationalDollar", + "label": "InternationalDollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross national income based on purchasing power parity in international dollars, 2015 to 2022. World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "distinguishes": true + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + }, + { + "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", + "definition": { + "schema_version": 1, + "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "PurchasingPowerParity", + "measurement_denominator": { + "unresolved": true + } + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossNationalIncome" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity_per_unresolved", + "label": "Gross National Income Based on Purchasing Power Parity Per Capita", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "PurchasingPowerParity", + "label": "PurchasingPowerParity" + }, + "measurement_denominator": { + "ref": "PerCapita", + "label": "PerCapita" + }, + "measurement_denominator_unresolved": true, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "7b2d5b0fc09cfc0215c8d7c6c21a5195fa21e79f2a148a6bca9ce6c3af8bbb9f", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ], + "upstream": { + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + } + } + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "fallback", + "ref": "InternationalDollar", + "label": "InternationalDollar" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "InternationalDollar", + "label": "InternationalDollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross national income based on purchasing power parity per capita in international dollars, 2015 to 2022. World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross national income based on purchasing power parity per capita", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "in international dollars", + "axis": "unit", + "segment": "heading", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "truncated": false + }, + "reading_assumptions": { + "spec_c0f61f3ca3558aac184973441a67601e": [], + "spec_403a96317ee8b97f1d8569c71015e5ce": [], + "spec_d94656e5d53b7b6c6b0c683145a1cd98": [] + } + } + ], + "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "sentence_plan": [ + { + "kind": "text", + "text": "3 readings.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "primary income", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross of fixed capital consumption", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "OECD DAC1", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity per capita", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "candidates" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "candidates", + "sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 3 + } + ] + } + }, + { + "error": { + "class": "InvalidRequestError", + "code": "choice_invalid", + "trace_id": null + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-candidate-label.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-candidate-label.json new file mode 100644 index 0000000..42705ac --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-candidate-label.json @@ -0,0 +1,2393 @@ +{ + "format_version": 1, + "name": "choose-refused-unknown-candidate-label", + "description": "Choosing a candidate by a label no candidate has raises InvalidRequestError with no request.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-candidates-choose-fetch", + "edit": "A choice of \"Germany's net lending\" follows the search." + }, + "call": [ + { + "op": "search", + "question": "GNI of Germany from 2015 to 2022" + }, + { + "op": "choose", + "option": "Germany's net lending" + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "raw_text", + "query": "GNI of Germany from 2015 to 2022" + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "d107dd88e50147378d54464bcdaf9695" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "raw_text", + "raw_query": "GNI of Germany from 2015 to 2022", + "normalized_query": "GNI of Germany from 2015 to 2022", + "extract_skipped": false + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "d107dd88e50147378d54464bcdaf9695", + "warnings": [], + "timing_ms": { + "total": 4075, + "by_step": { + "coverage": 0, + "extract": 1004 + } + }, + "llm_usage": { + "input_tokens": 7300, + "output_tokens": 300, + "cached_tokens": 861 + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "GNI", + "warnings": [], + "timing_ms": { + "total": 2799, + "by_step": { + "recall": 381, + "shape_arcs": 2, + "shape_probe_coverage": 1, + "shape_probe": 203, + "shape_groups": 18, + "shape_labels": 5, + "shape_admission": 0, + "shape": 1186, + "bind": 829, + "materialise": 217, + "answer": 186 + } + }, + "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "sentence_plan": [ + { + "kind": "text", + "text": "3 readings.", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "primary income", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross of fixed capital consumption", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "OECD DAC1", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity per capita", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "restatement": { + "variable_text": "GNI", + "entities": [ + { + "text": "Germany" + } + ], + "time_text": "2015 to 2022", + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [], + "assumptions": [], + "status": "candidates", + "candidates": { + "ordering": "intent_rank", + "max_candidates": 6, + "specs": [ + { + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "definition": { + "schema_version": 1, + "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicUnit", + "measured_property": "primaryIncome", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicunit_primaryincome_measuredvalue_nominal", + "label": "Gross national income", + "population_type": { + "ref": "EconomicUnit", + "label": "economic unit" + }, + "measured_property": { + "ref": "primaryIncome", + "label": "primary income" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "primary income", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "distinguishes": true + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross of fixed capital consumption", + "axis": "how", + "segment": "heading", + "property_dcid": "fixedCapitalConsumptionBasis", + "binding_ref": "how:fixedCapitalConsumptionBasis", + "entity_refs": [], + "states": [ + "how:fixedCapitalConsumptionBasis" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC1", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC1", + "label": "OECD DAC1", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC1" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + }, + { + "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "definition": { + "schema_version": 1, + "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "PurchasingPowerParity" + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossNationalIncome" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity", + "label": "Gross National Income Based on Purchasing Power Parity", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "PurchasingPowerParity", + "label": "PurchasingPowerParity" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "833b9da89613fa6c1775652daac2388f38204c6c9f9929ca113deed9a0d08369", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ], + "upstream": { + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + } + } + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "fallback", + "ref": "InternationalDollar", + "label": "InternationalDollar" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "InternationalDollar", + "label": "InternationalDollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross national income based on purchasing power parity in international dollars, 2015 to 2022. World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross national income based on purchasing power parity", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "in international dollars", + "axis": "unit", + "segment": "heading", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + }, + { + "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", + "definition": { + "schema_version": 1, + "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "PurchasingPowerParity", + "measurement_denominator": { + "unresolved": true + } + }, + "slots": [ + { + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossNationalIncome" + } + } + ], + "entities": { + "observationAbout": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2015, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity_per_unresolved", + "label": "Gross National Income Based on Purchasing Power Parity Per Capita", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "PurchasingPowerParity", + "label": "PurchasingPowerParity" + }, + "measurement_denominator": { + "ref": "PerCapita", + "label": "PerCapita" + }, + "measurement_denominator_unresolved": true, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "7b2d5b0fc09cfc0215c8d7c6c21a5195fa21e79f2a148a6bca9ce6c3af8bbb9f", + "refine_supported": true, + "data_commons": [ + { + "id": "base", + "label": "Data Commons by Google" + } + ], + "upstream": { + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + } + } + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/DEU", + "label": "Germany" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2015, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2015", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2015, + "end_year": 2022 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2015, + "end_year": 2022 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "fallback", + "ref": "InternationalDollar", + "label": "InternationalDollar" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "InternationalDollar", + "label": "InternationalDollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross national income based on purchasing power parity per capita in international dollars, 2015 to 2022. World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Germany", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "gross national income based on purchasing power parity per capita", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "in international dollars", + "axis": "unit", + "segment": "heading", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2015 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossNationalIncome", + "label": "GrossNationalIncome" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/DEU", + "label": "Germany" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2015, + "end_year": 2022 + }, + "capability_version": "cap_347a470e04c97eec", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826" + ] + } + }, + "confidence": "high", + "basis": "nominated", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "truncated": false + }, + "reading_assumptions": { + "spec_c0f61f3ca3558aac184973441a67601e": [], + "spec_403a96317ee8b97f1d8569c71015e5ce": [], + "spec_d94656e5d53b7b6c6b0c683145a1cd98": [] + } + } + ], + "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "sentence_plan": [ + { + "kind": "text", + "text": "3 readings.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "primary income", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross of fixed capital consumption", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "OECD DAC1", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Current US dollars", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Germany", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "gross national income based on purchasing power parity per capita", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "in international dollars", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2015 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "candidates" + } + } + } + ], + "expect": [ + { + "answer": { + "kind": "resolution", + "status": "candidates", + "sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "complete": false, + "specs": [], + "gaps": [ + { + "part": 0, + "kind": "choice", + "options": 3 + } + ] + } + }, + { + "error": { + "class": "InvalidRequestError", + "code": "choice_invalid", + "trace_id": null + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-other-spec.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-other-spec.json new file mode 100644 index 0000000..8f94217 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-other-spec.json @@ -0,0 +1,910 @@ +{ + "format_version": 1, + "name": "fetch-ref-expired-rebuild-other-spec", + "description": "A rebuild of a ref's spec must answer the ref's spec_id as well as its content_version: a manifest of another spec_id raises ContractError contract_violation, as a snapshot of another spec_id does, and the client downloads nothing.", + "origin": { + "kind": "synthetic", + "derived_from": "answer-definite-fetch", + "edit": "As fetch-ref-expired-rebuild-same-version, with the rebuild's manifest naming spec_22222222222222222222222222222222." + }, + "call": [ + { + "op": "fetch", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [ + "basic health care ODA disbursements" + ], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + }, + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "artifact": { + "digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "rendering": { + "format": "parquet", + "bundle": false + } + } + } + ] + } + } + ], + "exchanges": [ + { + "request": { + "method": "GET", + "path": "/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756" + }, + "response": { + "status": 410, + "headers": { + "content-type": "application/problem+json" + }, + "json": { + "type": "/codes/artifact_expired", + "title": "Gone", + "status": 410, + "detail": "Every listable artifact of this version aged out of the working tier unpinned.", + "code": "artifact_expired", + "trace_id": "00000000000000000000000000000000", + "capability_version": "synthetic", + "retryable": false + } + } + }, + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "definition": { + "schema_version": 1, + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "all" + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "90ec74fce6534d0d8e4142b0e1355782" + }, + "json": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_22222222222222222222222222222222", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } + } + }, + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "prepared_at": "2026-10-21T13:05:05Z", + "coverage": { + "rows": 30, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 27 + } + ], + "window": { + "kind": "all", + "start_year": 1995, + "end_year": 2024, + "origin": "default" + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "applied_window": { + "kind": "all", + "start_year": 1995, + "end_year": 2024, + "origin": "default" + }, + "graph_revision": null, + "code_index_stamp": { + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-20T19:50:14Z", + "graph_endpoint": "graph_release" + }, + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 6 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 7 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 1 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 15 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "family_member_count": 21, + "facets": [ + { + "axis": "provenance", + "ref": "provenance/OECDCreditorReportingSystem", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + }, + { + "axis": "unit", + "ref": "CurrencyUSD", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "default_policy_version": "1", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868" + } + ], + "normalisations": [], + "frame_grammar_version": "1.1.0", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_88fecfec3c5b89d1", + "served_from": "materialise", + "confirmed_at": "2026-10-21T13:05:06.336796+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9785, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:06.298931+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + }, + { + "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", + "rendering": { + "statistics": "series" + }, + "bytes": 5981, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:06.298931+00:00", + "tier": "working", + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" + } + ], + "series_count": 5, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 5 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 27 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "stat_var", + "columns": "time_period", + "state": "available", + "width": 28, + "cells": 140 + }, + { + "index": "time_period", + "columns": "stat_var", + "state": "available", + "width": 6, + "cells": 162 + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T13:05:06.298810Z" + } + } + } + } + ], + "expect": [ + { + "error": { + "class": "ContractError", + "code": "contract_violation", + "trace_id": "90ec74fce6534d0d8e4142b0e1355782" + } + } + ] +} diff --git a/tools/README.md b/tools/README.md index 2d0404f..6fe2b93 100644 --- a/tools/README.md +++ b/tools/README.md @@ -38,13 +38,13 @@ uv run tools/validate_provenance_docs_vectors.py uv run tools/validate_descriptions_vectors.py ``` -`validate_client_contract.py` validates the client contract under `python/client-contract/src/dfo_client_contract/` against its schemas, then checks what they cannot express: every `strict-fields.json` pointer resolves in `served/openapi.json` and stays required and non-nullable, or keeps its enum values; `actions.json` holds one row, in code order, for each active refusal code in `registries/codes.json` that reaches a problem document or a no_data reason, with a gap kind exactly for the no_data reasons; `client-codes.json` lists each code a client raises itself once, in code order, none of them a code in `actions.json` or the registry, each with a class a scenario names and a retryable flag; `proxy-codes.json` and `warning-codes.json` list their codes once, in code order, apart from every other table, and the warning codes are those the client rules issue; `served/openapi.json` holds the Search, Datasets, Graph and Presentation surfaces and nothing outside them but the platform's `/codes` route; each recorded scenario's requests match a served route and its JSON bodies validate against that route's schemas, where a required member stays required when it admits null; every problem document in a scenario, synthetic ones and failed operations' errors included, carries an active code registered at its status, and every website proxy body a code `proxy-codes.json` lists at its status; each recorded scenario names `served/SOURCE.json`'s commit; each scenario's `expect` equals the outcomes its steps reach over its exchanges, with refusals' error classes and gap kinds from `actions.json`, each error the client raises itself carrying its code and class from `client-codes.json`, a repeated refused request counted a retry only where the retry rules allow one, a record that stops retrying while a retry remains refused, and the waits before retries and the warnings response headers issue derived; each POST carries its body, each build posts the body its spec, narrowing and layout give, each Search request posts the whole body its steps derive, each poll names the operation the client holds, and each signed download is the URL its redirect names; every absolute URL a record holds is a signed URL on the storage host with the redacted query, or a `location` under the base URL; and each `DatasetRef` example gets the verdict it states. It does not import `dfo_client_contract`, whose `tests/test_rules.py` replays the rule vectors. Also a PEP 723 script: +`validate_client_contract.py` validates the client contract under `python/client-contract/src/dfo_client_contract/` against its schemas, then checks what they cannot express: every `strict-fields.json` pointer resolves in `served/openapi.json` and stays required and non-nullable, or keeps its enum values; `actions.json` holds one row, in code order, for each active refusal code in `registries/codes.json` that reaches a problem document or a no_data reason, with a gap kind exactly for the no_data reasons; `client-codes.json` lists each code a client raises itself once, in code order, none of them a code in `actions.json` or the registry, each with a class a scenario names and a retryable flag; `proxy-codes.json` and `warning-codes.json` list their codes once, in code order, apart from every other table, and the warning codes are those the client rules issue; `served/openapi.json` holds the Search, Datasets, Graph and Presentation surfaces and nothing outside them but the platform's `/codes` route; each recorded scenario's requests match a served route and its JSON bodies validate against that route's schemas, where a required member stays required when it admits null; every problem document in a scenario, synthetic ones and failed operations' errors included, carries an active code registered at its status, and every website proxy body a code `proxy-codes.json` lists at its status; each recorded scenario names `served/SOURCE.json`'s commit; each scenario's `expect` equals the outcomes its steps reach over its exchanges, with refusals' error classes and gap kinds from `actions.json`, each error the client raises itself carrying its code and class from `client-codes.json`, a repeated refused request counted a retry only where the retry rules allow one, a record that stops retrying while a retry remains refused, and the waits before retries and the warnings response headers issue derived; each POST carries its body, each build posts the body its spec, narrowing and layout give, each Search request posts the whole body its steps derive, each poll names the operation the client holds, and each signed download is the URL its redirect names; each body file a record names is a bare file name in `scenarios/` and no symlink; every absolute URL a record holds is a signed URL on the storage host with the redacted query, or a `location` under the base URL; and each `DatasetRef` example gets the verdict it states. It does not import `dfo_client_contract`, whose `tests/test_rules.py` replays the rule vectors. Also a PEP 723 script: ```bash uv run tools/validate_client_contract.py ``` -`capture_client_contract.py` refreshes the client contract from dfo-apis. `openapi --dfo-apis PATH` builds the composed app in that checkout's environment, in process, and writes `served/openapi.json` and `served/SOURCE.json`, refusing a checkout with uncommitted changes or untracked files and an environment out of step with its `uv.lock`; `record` runs the contract's scenarios against a base URL, dev by default, writes the records with every absolute URL's query redacted and a local app's signed URLs written as storage URLs, refusing a record that still names any other host, derives the synthetic ones and validates the result, and `record --offline` derives the outcomes again from the records with no request. A recorded scenario holds only exchanges the server made. `record` refuses a recorded scenario that a canned exchange answered, and a synthetic derivation makes no request. Nothing in a record marks an exchange as canned, so `validate_client_contract.py` cannot check this rule and the capture enforces it. It imports its outcome rules from `validate_client_contract.py`. `python/client-contract/README.md` has the recipe. A PEP 723 script whose tests run without network or pyarrow: +`capture_client_contract.py` refreshes the client contract from dfo-apis. `openapi --dfo-apis PATH` builds the composed app in that checkout's environment, in process, and writes `served/openapi.json` and `served/SOURCE.json`, refusing a checkout with uncommitted changes or untracked files and an environment out of step with its `uv.lock`; `record` runs the contract's scenarios against a base URL, dev by default, writes the records with every absolute URL's query redacted and a local app's signed URLs written as storage URLs, refusing a record that still names any other host, derives the synthetic ones and validates the result, and `record --offline` derives the outcomes again from the records with no request. A recorded scenario holds only exchanges the server made. `record` refuses a recorded scenario that a canned exchange answered, and a synthetic derivation makes no request. Nothing in a record marks an exchange as canned, so `validate_client_contract.py` cannot check this rule and the capture enforces it. It reads and writes a binary body only through a bare file name beside its record, and refuses a name that is absolute or leaves that directory, or a symlink, before it reads or writes anything. It imports its outcome rules from `validate_client_contract.py`. `python/client-contract/README.md` has the recipe. A PEP 723 script whose tests run without network or pyarrow: ```bash uv run tools/capture_client_contract.py record diff --git a/tools/capture_client_contract.py b/tools/capture_client_contract.py index ae74779..a9b77d1 100644 --- a/tools/capture_client_contract.py +++ b/tools/capture_client_contract.py @@ -94,7 +94,9 @@ answer_members, answer_outcome, artifact_route, + body_path, build_body, + candidate_label, choice_for, choice_input, data_warning, @@ -1076,6 +1078,8 @@ def _stored(self, member: dict[str, Any]) -> Member: refusal = refusal if refusal is not None else error newest = self._newest(spec_id) else: + if manifest["definition"]["spec_id"] != spec_id: + raise ClientError("contract_violation") if manifest["content_version"] == version: return self._member(member["parts"], held, manifest, rendering, False) newest = manifest["content_version"] @@ -2007,6 +2011,8 @@ def _build_index(parent: dict[str, Any]) -> int: ) # The content version a rebuild answers when the data moved on. NEWER_VERSION = "cv_" + "1" * 32 +# The spec_id a ref's rebuild answers in `fetch-ref-expired-rebuild-other-spec`. +REBUILT_SPEC_ID = "spec_" + "2" * 32 def _retry_after_504( @@ -2230,6 +2236,22 @@ def _expired_newer(parent: dict[str, Any], ctx: Context) -> Derived: ) +def _expired_other_spec(parent: dict[str, Any], ctx: Context) -> Derived: + """As `_expired_rebuilt`, with the rebuild's manifest naming + REBUILT_SPEC_ID, which raises before any download.""" + ref = _answer_ref(parent) + build = copy.deepcopy(parent["exchanges"][_build_index(parent)]) + build["response"]["json"]["definition"]["spec_id"] = REBUILT_SPEC_ID + session = ctx.session("synthetic", canned=[_snapshot_expired(ref), build]) + session.fetch_ref(ref) + require(not session.recorder.canned, "the lookup makes every exchange") + require( + _raises(session.expect[-1], "contract_violation", ctx), + "the rebuild of another spec_id raises ContractError", + ) + return Derived(session.call, session.recorder.exchanges, session.expect) + + # The digest a ref names for a file the lookup never reaches. UNREACHED_DIGEST = "sha256:" + "0" * 64 @@ -3120,6 +3142,81 @@ def _labels_shared(body: Any, ctx: Context) -> Any: return body +def _first_candidate_label(body: Any) -> str: + """The label of the first candidate of the answer's first part, which no + other candidate of that part shares.""" + specs = body["parts"][0]["candidates"]["specs"] + labels = [candidate_label(spec) for spec in specs] + require( + labels[0] is not None and labels.count(labels[0]) == 1, + "the first candidate's label is its own", + ) + assert labels[0] is not None + return labels[0] + + +def _candidate_by_label(parent: dict[str, Any], ctx: Context) -> Derived: + """The parent's search and its choice of candidate 0, named by its label, + which posts what the index posts and reaches the same answer.""" + search, choose = parent["call"][:2] + require(choose.get("option") == 0, "the parent chooses candidate 0") + label = _first_candidate_label(parent["exchanges"][0]["response"]["json"]) + session = ctx.session("synthetic", canned=copy.deepcopy(parent["exchanges"][:2])) + answer = session.search(search["question"]) + session.choose(answer, label, part=choose.get("part")) + require(not session.recorder.canned, "the choice makes the parent's request") + require( + session.expect == parent["expect"][:2], + "the label reaches the answer the index reaches", + ) + return Derived(session.call, session.recorder.exchanges, session.expect) + + +def _candidate_label_shared(parent: dict[str, Any], ctx: Context) -> Derived: + """The second candidate takes the first one's sentence plan, so both have + the first one's label, and the choice names that label.""" + + def edit(body: Any, ctx: Context) -> Any: + body = copy.deepcopy(body) + first, second = body["parts"][0]["candidates"]["specs"][:2] + plan = first["resolved"]["sentence_plan"] + second["resolved"]["sentence_plan"] = copy.deepcopy(plan) + return body + + label = _first_candidate_label(parent["exchanges"][0]["response"]["json"]) + return _choice_refused(label, edit=edit)(parent, ctx) + + +def _malformed_echo_items(body: Any, ctx: Context) -> Any: + """The definite part's operations hold 42 before GROWTH and its + assumptions end with a string, and the chosen candidate's + reading_assumptions end with 7.""" + body = copy.deepcopy(body) + candidates, definite = body["parts"] + spec_id = candidates["candidates"]["specs"][0]["spec_id"] + candidates["reading_assumptions"][spec_id].append(7) + definite["operations"] = [42, dict(GROWTH)] + definite["assumptions"].append("assumed") + return body + + +def _echo_drops_malformed(parent: dict[str, Any], ctx: Context) -> Derived: + """The parent's choice over `_malformed_echo_items`' answer, which posts + only the object items of each list it echoes.""" + derived = _choice_posted(_malformed_echo_items)(parent, ctx) + body = parent["exchanges"][0]["response"]["json"] + candidates, definite = body["parts"] + spec_id = candidates["candidates"]["specs"][0]["spec_id"] + chosen, beside = derived.exchanges[1]["request"]["json"]["input"]["entries"] + require( + chosen["assumptions"] == candidates["reading_assumptions"][spec_id] + and beside["operations"] == [GROWTH] + and beside["assumptions"] == definite["assumptions"], + "the echo drops each item that is not an object", + ) + return derived + + def _two_part_query(body: Any, ctx: Context) -> Any: """The first option's data_query holds its one part twice.""" body = copy.deepcopy(body) @@ -3378,6 +3475,16 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: "the rebuilt version as the newest, and downloads nothing.", _expired_newer, ), + Synthetic( + "fetch-ref-expired-rebuild-other-spec", + "answer-definite-fetch", + f"As fetch-ref-expired-rebuild-same-version, with the rebuild's manifest naming {REBUILT_SPEC_ID}.", + "A rebuild of a ref's spec must answer the ref's spec_id as well as its " + "content_version: a manifest of another spec_id raises ContractError " + "contract_violation, as a snapshot of another spec_id does, and the client " + "downloads nothing.", + _expired_other_spec, + ), Synthetic( "fetch-ref-expired-not-reproducible", "fetch-ref-newest-version", @@ -3738,6 +3845,16 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: "and its operations when it has any.", _choice_posted(_separate_with_operation), ), + Synthetic( + "choose-echo-drops-malformed-items", + "choose-candidate-echoes-assumptions", + "The definite part's operations hold 42 before an operation and its assumptions " + "end with a string, and the chosen candidate's reading_assumptions end with 7.", + "An item that is not an object reads as absent, so each echoed operations and " + "assumptions list posts only its object items: the definite part's one operation " + "and its own assumptions, and the chosen candidate's empty list.", + _echo_drops_malformed, + ), Synthetic( "choose-posts-unsupported-placeholder", "choose-option-beside-definite", @@ -3935,6 +4052,31 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: "request.", _choice_refused("Congo [Nowhere]"), ), + Synthetic( + "choose-candidate-by-label", + "answer-candidates-choose-fetch", + "The choice names candidate 0 by its label, and the fetch goes.", + "A candidate is chosen by its label, the heading of its sentence plan, as by its " + "index: the choice posts the same identity entry and reaches the same answer.", + _candidate_by_label, + ), + Synthetic( + "choose-refused-unknown-candidate-label", + "answer-candidates-choose-fetch", + 'A choice of "Germany\'s net lending" follows the search.', + "Choosing a candidate by a label no candidate has raises InvalidRequestError " + "with no request.", + _choice_refused("Germany's net lending"), + ), + Synthetic( + "choose-refused-shared-candidate-label", + "answer-candidates-choose-fetch", + "Candidate 1 takes candidate 0's sentence plan, and the choice names their shared " + "label.", + "A label two candidates share matches several, so choosing by it raises " + "InvalidRequestError with no request.", + _candidate_label_shared, + ), Synthetic( "choose-refused-answered-part", "answer-mixed-fetch-raises", @@ -3988,16 +4130,21 @@ def write_record( ) -> None: """Writes `record` and its bodies, removing the body files of its own an earlier record of the same name named. A parent's body file it names - stays.""" + stays. Every body file it removes or writes is checked by `body_path` + before any is touched, so a bad name or a symlink changes nothing.""" path = directory / f"{record['name']}.json" + stale = [] if path.exists(): old = json.loads(path.read_text(encoding="utf-8")) for exchange in old["exchanges"]: body_file = exchange["response"].get("body_file") if body_file and owns_body_file(record["name"], body_file): - (directory / body_file).unlink(missing_ok=True) - for body_file, data in bodies.items(): - (directory / body_file).write_bytes(data) + stale.append(body_path(directory, body_file)) + written = {body_path(directory, name): data for name, data in bodies.items()} + for body in stale: + body.unlink(missing_ok=True) + for body, data in written.items(): + body.write_bytes(data) _write_json(path, record) @@ -4114,7 +4261,7 @@ def __call__( if "json" in response: data = json.dumps(response["json"]).encode() elif "body_file" in response: - data = (self.body_dir / response["body_file"]).read_bytes() + data = body_path(self.body_dir, response["body_file"]).read_bytes() else: data = b"" return Response(response["status"], dict(response.get("headers", {})), data) @@ -4176,6 +4323,12 @@ def rederive_recorded(name: str, ctx: Context, directory: Path) -> None: if not path.exists(): raise SystemExit(f"{name}: no record to derive from; record it live") record = json.loads(path.read_text(encoding="utf-8")) + for exchange in record["exchanges"]: + if "body_file" in exchange["response"]: + try: + body_path(directory, exchange["response"]["body_file"]) + except ValueError as exc: + raise SystemExit(f"{name}: {exc}") from exc served = Served(record, directory) session = Session( Recorder(name, served.base_url, served), diff --git a/tools/tests/test_capture_client_contract.py b/tools/tests/test_capture_client_contract.py index 51e78e0..5e56bde 100644 --- a/tools/tests/test_capture_client_contract.py +++ b/tools/tests/test_capture_client_contract.py @@ -260,6 +260,54 @@ def test_an_offline_rederivation_rewrites_only_the_expect(tmp_path: Path) -> Non assert fresh == (SCENARIOS / f"{name}.json").read_text(encoding="utf-8") +@pytest.mark.parametrize("named", ["symlink", "parent", "absolute"]) +def test_an_offline_rederivation_refuses_a_body_file_outside_its_directory( + tmp_path: Path, named: str +) -> None: + """A body file that is a symlink, or a name that leaves the scenarios + directory, is refused before its bytes are read into a record.""" + name = "answer-definite-fetch" + scenarios, outside = tmp_path / "scenarios", tmp_path / "outside.parquet" + scenarios.mkdir() + for path in SCENARIOS.glob(f"{name}.*"): + (scenarios / path.name).write_bytes(path.read_bytes()) + body = scenarios / f"{name}.parquet" + body.rename(outside) + body_file = { + "symlink": body.name, + "parent": f"../{outside.name}", + "absolute": str(outside), + }[named] + if named == "symlink": + body.symlink_to(outside) + record = scenarios / f"{name}.json" + stale = json.loads(record.read_text(encoding="utf-8")) + for exchange in stale["exchanges"]: + if "body_file" in exchange["response"]: + exchange["response"]["body_file"] = body_file + record.write_text(json.dumps(stale), encoding="utf-8") + ctx = capture.Context( + capture.DEV_BASE_URL, capture._offline, ACTIONS, CLIENT_CODES, read_shape=_shape + ) + with pytest.raises(SystemExit, match="body file"): + capture.rederive_recorded(name, ctx, scenarios) + assert json.loads(record.read_text(encoding="utf-8")) == stale + assert body.is_symlink() == (named == "symlink") + + +def test_a_writer_refuses_a_symlinked_body_file(tmp_path: Path) -> None: + outside = tmp_path / "outside.parquet" + outside.write_bytes(b"outside") + scenarios = tmp_path / "scenarios" + scenarios.mkdir() + (scenarios / "s.parquet").symlink_to(outside) + record = {"name": "s", "exchanges": [{"response": {"body_file": "s.parquet"}}]} + with pytest.raises(ValueError, match="symlink"): + capture.write_record(scenarios, record, {"s.parquet": b"new"}) + assert outside.read_bytes() == b"outside" + assert sorted(p.name for p in scenarios.iterdir()) == ["s.parquet"] + + def test_a_recorder_refuses_a_request_that_is_not_the_next_canned_one() -> None: def transport(method: str, url: str, **kwargs: Any) -> Any: raise AssertionError(f"{method} {url} reached the network") diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index a5e468b..8613647 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -1870,6 +1870,19 @@ def test_a_missing_body_file_is_reported(package_dir: Path) -> None: assert validator.main() == 1 +def test_a_symlinked_body_file_is_reported(package_dir: Path, tmp_path: Path) -> None: + body = package_dir / "scenarios" / "fetch-spec-known-sentence.parquet" + outside = tmp_path / "outside.parquet" + body.rename(outside) + body.symlink_to(outside) + problems = validator.validate() + assert any( + "'fetch-spec-known-sentence.parquet'" in p and "is a symlink" in p + for p in problems + ), problems + assert validator.main() == 1 + + def test_an_orphan_body_file_is_reported(package_dir: Path) -> None: (package_dir / "scenarios" / "stray.parquet").write_bytes(b"") problems = validator.validate() diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index 20206b1..7cabc3b 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -1159,9 +1159,10 @@ def choice_for( With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. A part is named by its index, its variable text, or a word that one gap's options mention, and must be a gap. A - candidates part's options are its candidates, chosen by index. Any other - gap's are its no_data options, chosen by index or label, a label scoped to - the options that mention the word the part was named by.""" + candidates part's options are its candidates, chosen by index or by + `candidate_label`. Any other gap's are its no_data options, chosen by + index or label, a label scoped to the options that mention the word the + part was named by. A label must match exactly one option.""" gaps = answer_gaps(answer, kinds) gap_parts = {gap["part"] for gap in gaps} mention = None @@ -1194,11 +1195,13 @@ def choice_for( chosen = answer.parts[index] if chosen.get("status") == "candidates": specs = chosen["candidates"]["specs"] - if not isinstance(option, int): - raise _UnfitError("candidates are chosen by index") - if not 0 <= option < len(specs): + if isinstance(option, int): + picked = [specs[option]] if 0 <= option < len(specs) else [] + else: + picked = [spec for spec in specs if candidate_label(spec) == option] + if len(picked) != 1: raise _refuse() - return Choice(index, candidate=specs[option]) + return Choice(index, candidate=picked[0]) options = _options(answer, index) if isinstance(option, int): found = [options[option]] if 0 <= option < len(options) else [] @@ -1214,6 +1217,20 @@ def choice_for( return Choice(index, option=found[0]) +def candidate_label(spec: Mapping[str, Any]) -> str | None: + """A candidate's label: the `text` of its spec's `resolved.sentence_plan` + tokens in the `heading` segment, a token whose `segment` is not a string + counted in it, joined and stripped of surrounding white space; else its + `resolved.rendered_sentence`; else None.""" + resolved = read_object(spec, "resolved") + heading = "".join( + read_string(token, "text") or "" + for token in read_objects(resolved, "sentence_plan") + if read_string(token, "segment") in (None, "heading") + ).strip() + return heading or read_string(resolved, "rendered_sentence") or None + + def _options(answer: Answer, index: int) -> list[dict[str, Any]]: """A part's no_data options, as `read_objects` reads them.""" return read_objects(read_object(answer.parts[index], "no_data"), "options") @@ -1300,12 +1317,16 @@ def _option_part(option: Mapping[str, Any]) -> Any: def reading_echo(part: Mapping[str, Any], spec: Mapping[str, Any]) -> Any: """The assumptions a resubmitted reading of `part` echoes: a definite part's `assumptions`, or a candidates part's `reading_assumptions` under - the reading's spec_id. None, when the part carries no such member, posts - no `assumptions`, and Search reads the reading as a fresh request does. - `[]` states none.""" + the reading's spec_id, each item that is not an object read as absent. + None, when the part carries no such list, posts no `assumptions`, and + Search reads the reading as a fresh request does. `[]` states none.""" if part.get("status") == "candidates": - return read_list(read_object(part, "reading_assumptions"), spec["spec_id"]) - return read_list(part, "assumptions") + holder, name = read_object(part, "reading_assumptions"), spec["spec_id"] + else: + holder, name = part, "assumptions" + if read_list(holder, name) is None: + return None + return read_objects(holder, name) def _restated_entry(part: dict[str, Any]) -> dict[str, Any]: @@ -1342,14 +1363,15 @@ def _identity(spec: dict[str, Any], assumptions: Any = None) -> dict[str, Any]: def _echo(part: dict[str, Any], **members: Any) -> dict[str, Any]: """An entry with the members every entry but a parsed one echoes from its - part: variable_text, separate when true, and operations when any.""" + part: variable_text, separate when true, and operations when it has any + that are objects, an item of another type reading as absent.""" variable_text = read_string(part, "variable_text") if not variable_text: raise _refuse() entry: dict[str, Any] = {**members, "variable_text": variable_text} if part.get("separate") is True: entry["separate"] = True - if operations := read_list(part, "operations"): + if operations := read_objects(part, "operations"): entry["operations"] = operations return entry @@ -2125,7 +2147,7 @@ def strict(self, schema: Any, body: Any) -> None: def body(self, response: dict[str, Any]) -> bytes: if "body_file" in response: - path = self.body_dir / response["body_file"] + path = body_path(self.body_dir, response["body_file"]) if not path.is_file(): raise _UnfitError(f"body file {response['body_file']!r} is missing") return path.read_bytes() @@ -2310,7 +2332,9 @@ def stored_version(self, member: dict[str, Any]) -> dict[str, Any]: """One version a ref names, through the lookup order: the snapshot route and the files route at the stored digest, then the file selector, then a build that must answer the same version. A snapshot - refusal other than artifact_expired ends the lookup. Otherwise a + or build that answers another spec_id raises ContractError, as a + snapshot of another version does. A snapshot refusal other than + artifact_expired ends the lookup. Otherwise a lookup that finds no file raises VersionUnavailableError with the first refusal's code, or version_unavailable, and the newest version, either the one the build answered or the versions route's first.""" @@ -2346,6 +2370,8 @@ def stored_version(self, member: dict[str, Any]) -> dict[str, Any]: refusal = refusal if refusal is not None else error newest = self.newest(spec_id) else: + if manifest["definition"]["spec_id"] != spec_id: + raise ClientError("contract_violation") if manifest["content_version"] == version: held = {**spec, "sentence": member["sentence"]} return self.member(member["parts"], held, manifest, rendering, False) @@ -2640,6 +2666,30 @@ def moved(value: Any) -> Any: ] +# A body file's name as `scenario.schema.json`'s `body_file` pattern states +# it: a bare file name, so it is never absolute and never leaves its directory. +BODY_FILE_NAME = re.compile(r"[a-z0-9]+(-[a-z0-9]+)*\.[a-z0-9]+") + + +def body_path(directory: Path, body_file: str) -> Path: + """The path of the body file `body_file` beside the records in + `directory`, checked before anything reads or writes it. + + Raises: + ValueError: `body_file` is not a bare file name, so it could be + absolute or resolve outside `directory`, or it names a symlink, + which would read or write the file it points to. + """ + if BODY_FILE_NAME.fullmatch(body_file) is None: + raise ValueError( + f"body file {body_file!r} is not a bare file name in {directory}" + ) + path = directory / body_file + if path.is_symlink(): + raise ValueError(f"body file {body_file!r} in {directory} is a symlink") + return path + + def owns_body_file(name: str, body_file: str) -> bool: """Whether `body_file` is one the scenario `name` writes: `.`, or `-.` for its n-th body.""" @@ -2712,7 +2762,12 @@ def _check_body_files( f"scenarios/{file_name}: exchange {index}: body file {body_file!r} is " "neither the scenario's own nor one its parent names" ) - if not (directory / body_file).is_file(): + try: + path = body_path(directory, body_file) + except ValueError as exc: + problems.append(f"scenarios/{file_name}: exchange {index}: {exc}") + continue + if not path.is_file(): problems.append( f"scenarios/{file_name}: exchange {index}: body file " f"{body_file!r} is missing" From 091bebe377c8cfe891fa3202b6f9940de4ae007e Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Fri, 23 Oct 2026 09:21:49 +0200 Subject: [PATCH 29/39] fix(contract): describe choose-candidate-by-label without a fetch --- .../scenarios/choose-candidate-by-label.json | 2 +- tools/capture_client_contract.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-by-label.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-by-label.json index 8e3295c..8cab458 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-by-label.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-by-label.json @@ -5,7 +5,7 @@ "origin": { "kind": "synthetic", "derived_from": "answer-candidates-choose-fetch", - "edit": "The choice names candidate 0 by its label, and the fetch goes." + "edit": "The choice names candidate 0 by its label." }, "call": [ { diff --git a/tools/capture_client_contract.py b/tools/capture_client_contract.py index a9b77d1..49785e7 100644 --- a/tools/capture_client_contract.py +++ b/tools/capture_client_contract.py @@ -4055,7 +4055,7 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: Synthetic( "choose-candidate-by-label", "answer-candidates-choose-fetch", - "The choice names candidate 0 by its label, and the fetch goes.", + "The choice names candidate 0 by its label.", "A candidate is chosen by its label, the heading of its sentence plan, as by its " "index: the choice posts the same identity entry and reaches the same answer.", _candidate_by_label, From 2f51e0410b24b459b0927b9e81d65cf7265ed447 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Fri, 23 Oct 2026 10:06:07 +0200 Subject: [PATCH 30/39] fix(contract): echo only the assumptions and operations a client reads An `assumptions` or `reading_assumptions` item now reads only when its `kind`, `binding_ref` and `text` are strings, and an `operations` item only when its `verb` and `phrase` are strings, matching the served `Assumption` and `Operation` schemas. A read item holds its schema's members alone, with wrong-typed optional members absent. The resubmit echo posts exactly the items read, built from the members read, so a client never posts back an item or member the server's schema refuses. `choose-echo-drops-malformed-items` pins a wrong-typed required member, wrong-typed optional members, a filtered `refs` list, an unknown member and an assumptions list that posts `[]`. --- python/client-contract/README.md | 6 +- .../choose-echo-drops-malformed-items.json | 50 ++++++++- tools/capture_client_contract.py | 83 ++++++++++++--- tools/tests/test_validate_client_contract.py | 100 ++++++++++++++++++ tools/validate_client_contract.py | 75 +++++++++++-- 5 files changed, 282 insertions(+), 32 deletions(-) diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 2cf9c20..ac29d54 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -73,7 +73,7 @@ uv run ty check src/dfo_client_contract ## Strict fields -`strict-fields.json` lists the members a client cannot act without. Each pointer names one property of one component schema, `/components/schemas//properties/`. A `required` entry stays in its schema's `required` list and admits no null, so a client raises `ContractError` when one is missing or null. Every entry is a member some client rule acts on, and a client checks a body only along them: from the body's root it goes down through strict members alone, so a member no client reads goes unchecked, however deep. A `Spec` where no rule reads it, in `resolved.equivalent_readings`, `no_data.flagged_match` or `no_data.alternate_match`, may lack `resolved` or its definition's `identity` and raises nothing, which `answer-nested-specs-unchecked` pins at all three. A strict member that holds a JSON type its schema does not admit raises `ContractError` `contract_violation` at its pointer, as a missing one does, which `answer-candidate-specs-not-a-list` pins with `candidates.specs` as an object. Each item of a strict list, `parts`, `candidates.specs` or `artifacts`, must be an object, and an item of another type raises `contract_violation` at its index pointer, such as `/parts/0/candidates/specs/0`. A member a client reads that no strict pointer names, and that holds a JSON type other than the list, object or string its rule reads, reads as absent, and so does every member of a holder that is not an object; an item of another type in such a list reads as absent too. So `no_data.options` as an object or null offers no option, `mentions` as a string mentions nothing, and a `diagnostics` that is not an object holds no `timed_out` and no warnings. `answer-operations-not-a-list` pins a definite part's `operations` as an object. An `enums` entry keeps every listed value, the values a client branches on: the answer kinds, the part statuses and the operation statuses. A client still accepts a value no entry lists. +`strict-fields.json` lists the members a client cannot act without. Each pointer names one property of one component schema, `/components/schemas//properties/`. A `required` entry stays in its schema's `required` list and admits no null, so a client raises `ContractError` when one is missing or null. Every entry is a member some client rule acts on, and a client checks a body only along them: from the body's root it goes down through strict members alone, so a member no client reads goes unchecked, however deep. A `Spec` where no rule reads it, in `resolved.equivalent_readings`, `no_data.flagged_match` or `no_data.alternate_match`, may lack `resolved` or its definition's `identity` and raises nothing, which `answer-nested-specs-unchecked` pins at all three. A strict member that holds a JSON type its schema does not admit raises `ContractError` `contract_violation` at its pointer, as a missing one does, which `answer-candidate-specs-not-a-list` pins with `candidates.specs` as an object. Each item of a strict list, `parts`, `candidates.specs` or `artifacts`, must be an object, and an item of another type raises `contract_violation` at its index pointer, such as `/parts/0/candidates/specs/0`. A member a client reads that no strict pointer names, and that holds a JSON type other than the list, object or string its rule reads, reads as absent, and so does every member of a holder that is not an object; an item of another type in such a list reads as absent too. So `no_data.options` as an object or null offers no option, `mentions` as a string mentions nothing, and a `diagnostics` that is not an object holds no `timed_out` and no warnings. `answer-operations-not-a-list` pins a definite part's `operations` as an object. An item of an `assumptions` or `reading_assumptions` list reads only when it is an object whose `kind`, `binding_ref` and `text` are strings, and an item of an `operations` list only when it is an object whose `verb` and `phrase` are strings; any other item reads as absent. A read item holds its schema's members alone: an assumption's `refs` as its string items when it is a list, and an operation's `over` when it is a string or null and its `target_year` when it is an integer other than a boolean, or null. An optional member of another type reads as absent, and a client reads no member the schema does not name. An `enums` entry keeps every listed value, the values a client branches on: the answer kinds, the part statuses and the operation statuses. A client still accepts a value no entry lists. The answer's `kind` and each part's `status` are the discriminators of their unions in the served document. A search response with no `kind` raises `ContractError`, as a part with no `status` does, although the served document gives `kind` a default and leaves it out of `required`. A part `status` a client does not know raises nothing and makes the part an `unknown` gap. An answer `kind` a client does not know raises `ContractError`, because the client cannot read the answer. A Search response body that is not an object, a `resolution` answer whose `parts` is empty, at pointer `/parts`, since the served schema gives it at least one item, a part whose `status` is not a string, at pointer `/parts//status`, and a definite or candidate spec whose `definition.spec_id` differs from its `spec_id` raise `ContractError` `contract_violation`, in a Search response as in a ref; `search-body-not-an-object`, `answer-empty-parts`, `answer-part-status-not-a-string` and `answer-definition-spec-id-mismatch` pin the four. @@ -163,8 +163,8 @@ The records also fix these client rules: - A choice names its part by index, by variable text, or by a word that one gap's options mention, and its option, a candidate among them, by index or label. A candidate's label is the `text` of its spec's `resolved.sentence_plan` tokens in the `heading` segment, a token whose `segment` is not a string counted in it, joined and stripped of surrounding white space, or else its `resolved.rendered_sentence`. A candidate with neither a heading nor a sentence has a null label; no scenario pins it. A no_data option's label is matched among the options that mention the word the part was named by. With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. - A choice raises `InvalidRequestError` `choice_invalid` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is out of range or matches no label or several. It raises the same when an entry it would post cannot be built: a part with no `variable_text`, or a part of a status the client does not know that has no `restatement`. A chosen option whose `data_query` holds other than one part raises `ContractError`, and so does a chosen option with no `data_query`, in a one-part answer as in a several-part one, before any request. `choose-refused-shared-label`, `choose-refused-unknown-candidate-label`, `choose-refused-shared-candidate-label`, `choose-refused-part-without-variable-text`, `choose-refused-unknown-status`, `choose-option-two-part-query` and `choose-option-without-data-query` pin these, and `choose-candidate-by-label` pins a candidate chosen by its label. - Every pick of a candidate asks Search for the picked answer, and no client builds it locally. In a one-part answer the pick posts `dataset_resubmit`, without `raw_query`, with one identity entry: the candidate's identity and `entity_groups`, and the part's `variable_text`, `separate` and `operations` as below. The picked answer, its sentence with any "Assumed: …" clause, and its assumptions are Search's response. A choice of a no_data option in a one-part answer posts the option's `data_query` as the input. -- In a several-part answer a choice posts `dataset_resubmit`, without `raw_query`, with one entry per part in part order. The chosen candidate posts an identity entry with its identity and `entity_groups`, and the chosen option its `data_query`'s one part as a parsed entry. A definite part posts an identity entry with its spec's identity and `entity_groups`. A candidates part left alone posts a `candidates` entry: its candidate set in the server's order, each with its identity and `entity_groups`, and its `ordering` and `truncated` echoed. The server cannot recompute that order, because it rests on the first answer's bind election and availability reads, and a parsed entry would cost an LLM bind. Any other part posts its `restatement` as a parsed entry, or a placeholder entry with its no_data `reason` or unsupported `code` when it has none. Every entry but a parsed one carries the part's `variable_text`, `separate` when true and `operations` when the part has any that are objects, posting those alone. `entity_groups` is left out when the spec has none. `choose-echoes-separate-and-operations` pins the echo on a definite part's entry, and `choose-posts-unsupported-placeholder` an unsupported part's placeholder. -- Each identity a choice posts echoes its reading's assumptions as `assumptions`: the chosen candidate's entry carries its part's `reading_assumptions` under the candidate's `spec_id`, a definite part's entry carries the part's `assumptions`, and each candidate of a `candidates` entry carries its own `reading_assumptions` entry. Search then states the echoed items that still hold, so the picked answer states what that reading assumed. `[]` states none. An identity with no `assumptions` reads as a fresh request, so a client that holds no list for a reading, from a part that carries no `assumptions` or `reading_assumptions`, posts none. The identity entry that asks for a built sentence posts no `assumptions`, since it reads only the spec's own `rendered_sentence`. An echoed `operations` or `assumptions` list posts its object items alone: by the absent-value rule under Strict fields an item of another type reads as absent, so the echo drops it, and an `assumptions` list with no object item posts `[]`. `choose-echo-drops-malformed-items` pins both lists. +- In a several-part answer a choice posts `dataset_resubmit`, without `raw_query`, with one entry per part in part order. The chosen candidate posts an identity entry with its identity and `entity_groups`, and the chosen option its `data_query`'s one part as a parsed entry. A definite part posts an identity entry with its spec's identity and `entity_groups`. A candidates part left alone posts a `candidates` entry: its candidate set in the server's order, each with its identity and `entity_groups`, and its `ordering` and `truncated` echoed. The server cannot recompute that order, because it rests on the first answer's bind election and availability reads, and a parsed entry would cost an LLM bind. Any other part posts its `restatement` as a parsed entry, or a placeholder entry with its no_data `reason` or unsupported `code` when it has none. Every entry but a parsed one carries the part's `variable_text`, `separate` when true and `operations` when any of the part's operations reads. `entity_groups` is left out when the spec has none. `choose-echoes-separate-and-operations` pins the echo on a definite part's entry, and `choose-posts-unsupported-placeholder` an unsupported part's placeholder. +- Each identity a choice posts echoes its reading's assumptions as `assumptions`: the chosen candidate's entry carries its part's `reading_assumptions` under the candidate's `spec_id`, a definite part's entry carries the part's `assumptions`, and each candidate of a `candidates` entry carries its own `reading_assumptions` entry. Search then states the echoed items that still hold, so the picked answer states what that reading assumed. `[]` states none. An identity with no `assumptions` reads as a fresh request, so a client that holds no list for a reading, from a part that carries no `assumptions` or `reading_assumptions`, posts none. The identity entry that asks for a built sentence posts no `assumptions`, since it reads only the spec's own `rendered_sentence`. An echoed `operations` or `assumptions` list posts exactly the items a client reads under Strict fields, in order, each built from the members it read: an optional member that read as absent is left out, and a `refs` list posts its string items. An `assumptions` list with no item read posts `[]`, and an `operations` list with none is left out. `choose-echo-drops-malformed-items` pins both lists. - A strict fetch raises the manifest's first warning above `info` severity as a `DataWarning` with that warning's code, before the sentence lookup and the download. - An identity resubmit whose answer is not one definite part of the built `spec_id`, with a sentence, raises `ContractError`. - The `frame` layout posts `{"format": "parquet", "bundle": false, "layout": "frame"}` as the build's `options` and downloads the artifact whose rendering's `layout` is `frame`; the `long` layout posts `{"format": "parquet", "bundle": false}` and downloads the bare Parquet artifact with any other layout. A fetch of an answer with several members in the `frame` layout raises `InvalidRequestError` before any build. diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-echo-drops-malformed-items.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-echo-drops-malformed-items.json index 0579b1e..84cfded 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-echo-drops-malformed-items.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-echo-drops-malformed-items.json @@ -1,11 +1,11 @@ { "format_version": 1, "name": "choose-echo-drops-malformed-items", - "description": "An item that is not an object reads as absent, so each echoed operations and assumptions list posts only its object items: the definite part's one operation and its own assumptions, and the chosen candidate's empty list.", + "description": "An item that is not an object, or whose required members are not strings, reads as absent, and an item reads as its schema's members of the types they admit, so each echoed operations and assumptions list posts its read forms: rank without over or target_year and the growth operation, the definite part's own assumption and the grants assumption with its string ref alone, and the chosen candidate's empty list, as none of its items reads.", "origin": { "kind": "synthetic", "derived_from": "choose-candidate-echoes-assumptions", - "edit": "The definite part's operations hold 42 before an operation and its assumptions end with a string, and the chosen candidate's reading_assumptions end with 7." + "edit": "The definite part's operations hold 42, an operation whose verb is a number and one whose over and target_year are not read, its assumptions gain a string, an assumption whose text is null and one with a number among its refs and an unknown member, and the chosen candidate's reading_assumptions hold 7 and an assumption whose text is null." }, "call": [ { @@ -1411,7 +1411,12 @@ }, "reading_assumptions": { "spec_f0d0bb4841c0e55d6d4a353e45dcd52c": [ - 7 + 7, + { + "kind": "place_scope", + "binding_ref": "where:", + "text": null + } ], "spec_c024875e07eee23ed7cb8d18b4436df1": [] } @@ -1463,6 +1468,16 @@ }, "operations": [ 42, + { + "verb": 7, + "phrase": "top 5 donors" + }, + { + "verb": "rank", + "phrase": "top 5 donors", + "over": 3, + "target_year": true + }, { "verb": "growth", "phrase": "growth of GDP", @@ -1492,7 +1507,22 @@ "DAC2aAidType206" ] }, - "assumed" + "assumed", + { + "kind": "place_scope", + "binding_ref": "where:", + "text": null + }, + { + "kind": "declared_default", + "binding_ref": "how:dacTypeOfFinance", + "text": "grants", + "refs": [ + "DACTypeOfFinance110", + 110 + ], + "note": "unread" + } ], "status": "definite", "spec": { @@ -5051,10 +5081,22 @@ "refs": [ "DAC2aAidType206" ] + }, + { + "kind": "declared_default", + "binding_ref": "how:dacTypeOfFinance", + "text": "grants", + "refs": [ + "DACTypeOfFinance110" + ] } ], "variable_text": "aid flows", "operations": [ + { + "verb": "rank", + "phrase": "top 5 donors" + }, { "verb": "growth", "phrase": "growth of GDP", diff --git a/tools/capture_client_contract.py b/tools/capture_client_contract.py index 49785e7..8cc0714 100644 --- a/tools/capture_client_contract.py +++ b/tools/capture_client_contract.py @@ -3187,32 +3187,77 @@ def edit(body: Any, ctx: Context) -> Any: return _choice_refused(label, edit=edit)(parent, ctx) +# The malformed items `_malformed_echo_items` adds. A required member of +# another type leaves an item unread; an optional member of another type, and a +# member the schema does not name, read as absent. +_OPERATION_BAD_VERB = {"verb": 7, "phrase": "top 5 donors"} +_OPERATION_BAD_OVER = { + "verb": "rank", + "phrase": "top 5 donors", + "over": 3, + "target_year": True, +} +_ASSUMPTION_BAD_TEXT = { + "kind": "place_scope", + "binding_ref": "where:", + "text": None, +} +_ASSUMPTION_BAD_REFS = { + "kind": "declared_default", + "binding_ref": "how:dacTypeOfFinance", + "text": "grants", + "refs": ["DACTypeOfFinance110", 110], + "note": "unread", +} +_ASSUMPTION_REFS_READ = { + "kind": "declared_default", + "binding_ref": "how:dacTypeOfFinance", + "text": "grants", + "refs": ["DACTypeOfFinance110"], +} + + def _malformed_echo_items(body: Any, ctx: Context) -> Any: - """The definite part's operations hold 42 before GROWTH and its - assumptions end with a string, and the chosen candidate's - reading_assumptions end with 7.""" + """The definite part's operations hold 42, an operation whose verb is a + number and one whose over and target_year are not read before GROWTH, its + assumptions end with a string, one whose text is null and one with a + number among its refs and an unknown member, and the chosen candidate's + reading_assumptions, empty in the parent, hold 7 and an assumption whose + text is null, so none of them reads.""" body = copy.deepcopy(body) candidates, definite = body["parts"] spec_id = candidates["candidates"]["specs"][0]["spec_id"] - candidates["reading_assumptions"][spec_id].append(7) - definite["operations"] = [42, dict(GROWTH)] - definite["assumptions"].append("assumed") + unread = [7, copy.deepcopy(_ASSUMPTION_BAD_TEXT)] + candidates["reading_assumptions"][spec_id] += unread + definite["operations"] = [ + 42, + dict(_OPERATION_BAD_VERB), + dict(_OPERATION_BAD_OVER), + dict(GROWTH), + ] + definite["assumptions"] += [ + "assumed", + copy.deepcopy(_ASSUMPTION_BAD_TEXT), + copy.deepcopy(_ASSUMPTION_BAD_REFS), + ] return body def _echo_drops_malformed(parent: dict[str, Any], ctx: Context) -> Derived: """The parent's choice over `_malformed_echo_items`' answer, which posts - only the object items of each list it echoes.""" + each echoed list's items in their read forms and leaves out the items + that do not read.""" derived = _choice_posted(_malformed_echo_items)(parent, ctx) body = parent["exchanges"][0]["response"]["json"] candidates, definite = body["parts"] spec_id = candidates["candidates"]["specs"][0]["spec_id"] chosen, beside = derived.exchanges[1]["request"]["json"]["input"]["entries"] require( - chosen["assumptions"] == candidates["reading_assumptions"][spec_id] - and beside["operations"] == [GROWTH] - and beside["assumptions"] == definite["assumptions"], - "the echo drops each item that is not an object", + candidates["reading_assumptions"][spec_id] == [] + and chosen["assumptions"] == [] + and beside["operations"] == [{"verb": "rank", "phrase": "top 5 donors"}, GROWTH] + and beside["assumptions"] == [*definite["assumptions"], _ASSUMPTION_REFS_READ], + "the echo posts each list's read forms", ) return derived @@ -3848,11 +3893,17 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: Synthetic( "choose-echo-drops-malformed-items", "choose-candidate-echoes-assumptions", - "The definite part's operations hold 42 before an operation and its assumptions " - "end with a string, and the chosen candidate's reading_assumptions end with 7.", - "An item that is not an object reads as absent, so each echoed operations and " - "assumptions list posts only its object items: the definite part's one operation " - "and its own assumptions, and the chosen candidate's empty list.", + "The definite part's operations hold 42, an operation whose verb is a number " + "and one whose over and target_year are not read, its assumptions gain a " + "string, an assumption whose text is null and one with a number among its refs " + "and an unknown member, and the chosen candidate's reading_assumptions hold 7 " + "and an assumption whose text is null.", + "An item that is not an object, or whose required members are not strings, " + "reads as absent, and an item reads as its schema's members of the types they " + "admit, so each echoed operations and assumptions list posts its read forms: " + "rank without over or target_year and the growth operation, the definite part's " + "own assumption and the grants assumption with its string ref alone, and the " + "chosen candidate's empty list, as none of its items reads.", _echo_drops_malformed, ), Synthetic( diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index 8613647..ff616a5 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -370,6 +370,7 @@ def change(doc: Any) -> None: _ECHOES_SEPARATE = "scenarios/choose-echoes-separate-and-operations.json" _PLACEHOLDER = "scenarios/choose-posts-unsupported-placeholder.json" _CODELESS = "scenarios/search-refused-without-code.json" +_ECHO_DROPS = "scenarios/choose-echo-drops-malformed-items.json" def _first_part(change: Callable[[Any], None]) -> Callable[[Any], None]: @@ -1446,6 +1447,26 @@ def change(doc: Any) -> None: _first_entry(lambda entry: entry.pop("operations")), "where the rules post", ), + ( + _ECHO_DROPS, + _posted(1, lambda entry: entry["operations"][0].update(over=3)), + "where the rules post", + ), + ( + _ECHO_DROPS, + _posted(1, lambda entry: entry["assumptions"][1].update(note="unread")), + "where the rules post", + ), + ( + _ECHO_DROPS, + _posted(1, lambda entry: entry["assumptions"][1]["refs"].append(110)), + "where the rules post", + ), + ( + _ECHO_DROPS, + _posted(0, lambda entry: entry["assumptions"].append(7)), + "where the rules post", + ), ( _PLACEHOLDER, _first_entry(lambda entry: entry.update(code="scope_unsupported")), @@ -1744,6 +1765,10 @@ def change(doc: Any) -> None: "separate-not-echoed", "separate-false-echoed", "operations-not-echoed", + "unread-operation-member-echoed", + "unknown-assumption-member-echoed", + "unread-ref-echoed", + "unread-assumption-echoed", "placeholder-of-another-code", "unknown-status-refusal-on-a-postable-part", "variable-text-refusal-on-a-named-part", @@ -1889,6 +1914,81 @@ def test_an_orphan_body_file_is_reported(package_dir: Path) -> None: assert any("no scenario names this body file" in p for p in problems), problems +_ASSUMED = {"kind": "place_scope", "binding_ref": "where:", "text": "every place"} + + +@pytest.mark.parametrize( + ("item", "read"), + [ + (_ASSUMED, _ASSUMED), + ({**_ASSUMED, "refs": ["a", 1, None, "b"]}, {**_ASSUMED, "refs": ["a", "b"]}), + ({**_ASSUMED, "refs": "a"}, _ASSUMED), + ({**_ASSUMED, "refs": None}, _ASSUMED), + ({**_ASSUMED, "note": "x"}, _ASSUMED), + ({**_ASSUMED, "text": None}, None), + ({"kind": "place_scope", "text": "every place"}, None), + ("assumed", None), + ], + ids=[ + "whole", + "refs-string-items", + "refs-not-a-list", + "refs-null", + "unknown-member", + "text-null", + "binding-ref-missing", + "not-an-object", + ], +) +def test_an_assumption_reads_as_its_schema_members(item: Any, read: Any) -> None: + assert validator.read_assumption(item) == read + + +_RANK = {"verb": "rank", "phrase": "top 5 donors"} + + +@pytest.mark.parametrize( + ("item", "read"), + [ + ( + {**_RANK, "over": "place", "target_year": 2020}, + {**_RANK, "over": "place", "target_year": 2020}, + ), + ( + {**_RANK, "over": None, "target_year": None}, + {**_RANK, "over": None, "target_year": None}, + ), + ({**_RANK, "over": 3, "target_year": True}, _RANK), + ({**_RANK, "target_year": 2020.0}, _RANK), + ({**_RANK, "note": "x"}, _RANK), + ({"verb": 7, "phrase": "top 5 donors"}, None), + ({"verb": "rank"}, None), + (42, None), + ], + ids=[ + "whole", + "optional-null", + "optional-of-another-type", + "target-year-a-float", + "unknown-member", + "verb-a-number", + "phrase-missing", + "not-an-object", + ], +) +def test_an_operation_reads_as_its_schema_members(item: Any, read: Any) -> None: + assert validator.read_operation(item) == read + + +def test_an_assumptions_list_with_no_item_read_echoes_empty() -> None: + """A list none of whose items reads still states that the reading assumed + nothing, where a part with no list posts no assumptions.""" + spec = {"spec_id": "spec_a"} + part = {"status": "definite", "assumptions": [7, {**_ASSUMED, "kind": 1}]} + assert validator.reading_echo(part, spec) == [] + assert validator.reading_echo({"status": "definite"}, spec) is None + + def test_a_required_member_that_admits_null_stays_required() -> None: """A recorded body must carry a required member, null or not.""" served = validator.PACKAGE_DIR / "served" / "openapi.json" diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index 7cabc3b..7e41784 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -93,7 +93,7 @@ import json import re import sys -from collections.abc import Iterator, Mapping, Sequence +from collections.abc import Callable, Iterator, Mapping, Sequence from dataclasses import dataclass, field, replace from functools import partial from pathlib import Path @@ -1080,6 +1080,62 @@ def read_string(holder: Any, name: str) -> str | None: return value if isinstance(value, str) else None +# An `assumptions`, `reading_assumptions` or `operations` item reads only when +# it is an object whose required members are strings, and reads as the schema's +# members alone: an optional member of another type, and an unknown member, +# read as absent. A client posts these read forms back, in order. +ASSUMPTION_REQUIRED = ("kind", "binding_ref", "text") +OPERATION_REQUIRED = ("verb", "phrase") + + +def _required_strings(item: Any, names: tuple[str, ...]) -> dict[str, Any] | None: + """`item`'s members `names` when it is an object holding each as a string, + else None.""" + if not isinstance(item, dict) or not all( + isinstance(item.get(name), str) for name in names + ): + return None + return {name: item[name] for name in names} + + +def read_assumption(item: Any) -> dict[str, Any] | None: + """An `Assumption` as a client reads it: kind, binding_ref and text, and + refs as its string items when it is a list. None when the item does not + read.""" + read = _required_strings(item, ASSUMPTION_REQUIRED) + if read is not None and (refs := read_list(item, "refs")) is not None: + read["refs"] = [ref for ref in refs if isinstance(ref, str)] + return read + + +def read_operation(item: Any) -> dict[str, Any] | None: + """An `Operation` as a client reads it: verb and phrase, over when it is a + string or null, and target_year when it is an integer or null. None when + the item does not read.""" + read = _required_strings(item, OPERATION_REQUIRED) + if read is None: + return None + over = item.get("over") + if "over" in item and (over is None or isinstance(over, str)): + read["over"] = over + year = item.get("target_year") + if "target_year" in item and ( + year is None or (isinstance(year, int) and not isinstance(year, bool)) + ): + read["target_year"] = year + return read + + +def read_items( + holder: Any, name: str, read: Callable[[Any], dict[str, Any] | None] +) -> list[dict[str, Any]]: + """The items of `holder`'s list member `name` that `read` reads, in + order, each in its read form.""" + return [ + item for item in map(read, read_list(holder, name) or []) if item is not None + ] + + # The answer kinds a client reads. Any other kind raises ContractError. ANSWER_KINDS = ("resolution", "catalogue", "declined") RESOLUTION = "resolution" @@ -1317,7 +1373,8 @@ def _option_part(option: Mapping[str, Any]) -> Any: def reading_echo(part: Mapping[str, Any], spec: Mapping[str, Any]) -> Any: """The assumptions a resubmitted reading of `part` echoes: a definite part's `assumptions`, or a candidates part's `reading_assumptions` under - the reading's spec_id, each item that is not an object read as absent. + the reading's spec_id, each in its read form and an item that does not + read left out. None, when the part carries no such list, posts no `assumptions`, and Search reads the reading as a fresh request does. `[]` states none.""" if part.get("status") == "candidates": @@ -1326,7 +1383,7 @@ def reading_echo(part: Mapping[str, Any], spec: Mapping[str, Any]) -> Any: holder, name = part, "assumptions" if read_list(holder, name) is None: return None - return read_objects(holder, name) + return read_items(holder, name, read_assumption) def _restated_entry(part: dict[str, Any]) -> dict[str, Any]: @@ -1363,15 +1420,15 @@ def _identity(spec: dict[str, Any], assumptions: Any = None) -> dict[str, Any]: def _echo(part: dict[str, Any], **members: Any) -> dict[str, Any]: """An entry with the members every entry but a parsed one echoes from its - part: variable_text, separate when true, and operations when it has any - that are objects, an item of another type reading as absent.""" + part: variable_text, separate when true, and operations when any item + reads, in its read form.""" variable_text = read_string(part, "variable_text") if not variable_text: raise _refuse() entry: dict[str, Any] = {**members, "variable_text": variable_text} if part.get("separate") is True: entry["separate"] = True - if operations := read_objects(part, "operations"): + if operations := read_items(part, "operations", read_operation): entry["operations"] = operations return entry @@ -1393,9 +1450,9 @@ def notices(holder: Any) -> None: for part in answer.parts: if part.get("status") != "definite": continue - for operation in read_objects(part, "operations"): - if verb := read_string(operation, "verb"): - phrase = json.dumps(operation.get("phrase")) + for operation in read_items(part, "operations", read_operation): + if verb := operation["verb"]: + phrase = json.dumps(operation["phrase"]) hints.setdefault(f"Not done: {verb} ({phrase})", verb) for departure in read_objects(part, "departures"): if text := read_string(departure, "text"): From 452469997fd2a5bbd593b2c2c454613dd9f9054b Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Fri, 23 Oct 2026 10:22:56 +0200 Subject: [PATCH 31/39] fix(contract): read a whole-valued target_year as an integer JSON Schema's `integer` admits `2020.0`, and a JavaScript client cannot tell it from `2020` after parsing, so an operation's `target_year` now reads when it is a number with no fractional part other than a boolean, as that integer. `2020.0` reads and echoes as `2020`; `2020.5` reads as absent. --- python/client-contract/README.md | 2 +- tools/tests/test_validate_client_contract.py | 9 ++++++--- tools/validate_client_contract.py | 13 ++++++++----- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/python/client-contract/README.md b/python/client-contract/README.md index ac29d54..909097f 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -73,7 +73,7 @@ uv run ty check src/dfo_client_contract ## Strict fields -`strict-fields.json` lists the members a client cannot act without. Each pointer names one property of one component schema, `/components/schemas//properties/`. A `required` entry stays in its schema's `required` list and admits no null, so a client raises `ContractError` when one is missing or null. Every entry is a member some client rule acts on, and a client checks a body only along them: from the body's root it goes down through strict members alone, so a member no client reads goes unchecked, however deep. A `Spec` where no rule reads it, in `resolved.equivalent_readings`, `no_data.flagged_match` or `no_data.alternate_match`, may lack `resolved` or its definition's `identity` and raises nothing, which `answer-nested-specs-unchecked` pins at all three. A strict member that holds a JSON type its schema does not admit raises `ContractError` `contract_violation` at its pointer, as a missing one does, which `answer-candidate-specs-not-a-list` pins with `candidates.specs` as an object. Each item of a strict list, `parts`, `candidates.specs` or `artifacts`, must be an object, and an item of another type raises `contract_violation` at its index pointer, such as `/parts/0/candidates/specs/0`. A member a client reads that no strict pointer names, and that holds a JSON type other than the list, object or string its rule reads, reads as absent, and so does every member of a holder that is not an object; an item of another type in such a list reads as absent too. So `no_data.options` as an object or null offers no option, `mentions` as a string mentions nothing, and a `diagnostics` that is not an object holds no `timed_out` and no warnings. `answer-operations-not-a-list` pins a definite part's `operations` as an object. An item of an `assumptions` or `reading_assumptions` list reads only when it is an object whose `kind`, `binding_ref` and `text` are strings, and an item of an `operations` list only when it is an object whose `verb` and `phrase` are strings; any other item reads as absent. A read item holds its schema's members alone: an assumption's `refs` as its string items when it is a list, and an operation's `over` when it is a string or null and its `target_year` when it is an integer other than a boolean, or null. An optional member of another type reads as absent, and a client reads no member the schema does not name. An `enums` entry keeps every listed value, the values a client branches on: the answer kinds, the part statuses and the operation statuses. A client still accepts a value no entry lists. +`strict-fields.json` lists the members a client cannot act without. Each pointer names one property of one component schema, `/components/schemas//properties/`. A `required` entry stays in its schema's `required` list and admits no null, so a client raises `ContractError` when one is missing or null. Every entry is a member some client rule acts on, and a client checks a body only along them: from the body's root it goes down through strict members alone, so a member no client reads goes unchecked, however deep. A `Spec` where no rule reads it, in `resolved.equivalent_readings`, `no_data.flagged_match` or `no_data.alternate_match`, may lack `resolved` or its definition's `identity` and raises nothing, which `answer-nested-specs-unchecked` pins at all three. A strict member that holds a JSON type its schema does not admit raises `ContractError` `contract_violation` at its pointer, as a missing one does, which `answer-candidate-specs-not-a-list` pins with `candidates.specs` as an object. Each item of a strict list, `parts`, `candidates.specs` or `artifacts`, must be an object, and an item of another type raises `contract_violation` at its index pointer, such as `/parts/0/candidates/specs/0`. A member a client reads that no strict pointer names, and that holds a JSON type other than the list, object or string its rule reads, reads as absent, and so does every member of a holder that is not an object; an item of another type in such a list reads as absent too. So `no_data.options` as an object or null offers no option, `mentions` as a string mentions nothing, and a `diagnostics` that is not an object holds no `timed_out` and no warnings. `answer-operations-not-a-list` pins a definite part's `operations` as an object. An item of an `assumptions` or `reading_assumptions` list reads only when it is an object whose `kind`, `binding_ref` and `text` are strings, and an item of an `operations` list only when it is an object whose `verb` and `phrase` are strings; any other item reads as absent. A read item holds its schema's members alone: an assumption's `refs` as its string items when it is a list, and an operation's `over` when it is a string or null and its `target_year` when it is null or a number other than a boolean with no fractional part, read as that integer, so `2020.0` reads and echoes as `2020` and `2020.5` reads as absent. An optional member of another type reads as absent, and a client reads no member the schema does not name. An `enums` entry keeps every listed value, the values a client branches on: the answer kinds, the part statuses and the operation statuses. A client still accepts a value no entry lists. The answer's `kind` and each part's `status` are the discriminators of their unions in the served document. A search response with no `kind` raises `ContractError`, as a part with no `status` does, although the served document gives `kind` a default and leaves it out of `required`. A part `status` a client does not know raises nothing and makes the part an `unknown` gap. An answer `kind` a client does not know raises `ContractError`, because the client cannot read the answer. A Search response body that is not an object, a `resolution` answer whose `parts` is empty, at pointer `/parts`, since the served schema gives it at least one item, a part whose `status` is not a string, at pointer `/parts//status`, and a definite or candidate spec whose `definition.spec_id` differs from its `spec_id` raise `ContractError` `contract_violation`, in a Search response as in a ref; `search-body-not-an-object`, `answer-empty-parts`, `answer-part-status-not-a-string` and `answer-definition-spec-id-mismatch` pin the four. diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index ff616a5..f886cdf 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -1959,7 +1959,8 @@ def test_an_assumption_reads_as_its_schema_members(item: Any, read: Any) -> None {**_RANK, "over": None, "target_year": None}, ), ({**_RANK, "over": 3, "target_year": True}, _RANK), - ({**_RANK, "target_year": 2020.0}, _RANK), + ({**_RANK, "target_year": 2020.0}, {**_RANK, "target_year": 2020}), + ({**_RANK, "target_year": 2020.5}, _RANK), ({**_RANK, "note": "x"}, _RANK), ({"verb": 7, "phrase": "top 5 donors"}, None), ({"verb": "rank"}, None), @@ -1969,7 +1970,8 @@ def test_an_assumption_reads_as_its_schema_members(item: Any, read: Any) -> None "whole", "optional-null", "optional-of-another-type", - "target-year-a-float", + "target-year-a-whole-float", + "target-year-fractional", "unknown-member", "verb-a-number", "phrase-missing", @@ -1977,7 +1979,8 @@ def test_an_assumption_reads_as_its_schema_members(item: Any, read: Any) -> None ], ) def test_an_operation_reads_as_its_schema_members(item: Any, read: Any) -> None: - assert validator.read_operation(item) == read + # JSON text tells 2020 from 2020.0, which compare equal in Python. + assert json.dumps(validator.read_operation(item)) == json.dumps(read) def test_an_assumptions_list_with_no_item_read_echoes_empty() -> None: diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index 7e41784..9a4adf3 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -1110,8 +1110,9 @@ def read_assumption(item: Any) -> dict[str, Any] | None: def read_operation(item: Any) -> dict[str, Any] | None: """An `Operation` as a client reads it: verb and phrase, over when it is a - string or null, and target_year when it is an integer or null. None when - the item does not read.""" + string or null, and target_year when it is null or a number other than a + boolean with no fractional part, read as that integer, so 2020.0 reads as + 2020. None when the item does not read.""" read = _required_strings(item, OPERATION_REQUIRED) if read is None: return None @@ -1119,10 +1120,12 @@ def read_operation(item: Any) -> dict[str, Any] | None: if "over" in item and (over is None or isinstance(over, str)): read["over"] = over year = item.get("target_year") - if "target_year" in item and ( - year is None or (isinstance(year, int) and not isinstance(year, bool)) + if year is None and "target_year" in item: + read["target_year"] = None + elif (isinstance(year, int) and not isinstance(year, bool)) or ( + isinstance(year, float) and year.is_integer() ): - read["target_year"] = year + read["target_year"] = int(year) return read From f479c214cc1d5106bc14fff5130526c152b054ca Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Fri, 23 Oct 2026 11:50:32 +0200 Subject: [PATCH 32/39] fix(contract): check a ref's schema_version where it is written A manifest definition's `schema_version` is now a strict required member, so a client refuses a manifest without one (pinned by `fetch-spec-manifest-without-schema-version`) and never writes a ref it would then reject. The ref format takes any integer version and leaves it to the server, and its definition admits no member CanonicalDefinition does not (`ref-definition-extra-member-rejected`). The README states that the echo's item rule checks JSON types alone and the server still checks its value constraints, that an operation that does not read gives no "Not done" hint, and that a boolean option is neither an index nor a label. The oracle quotes hint phrases keeping non-ASCII characters, as both clients do, and refuses a boolean option. The capture and the validator share one `stored_version` decision for ref recovery. `BODY_FILE_NAME` is compiled from the scenario schema, and a refused body file is checked once, on read, with a message naming it. --- python/client-contract/CHANGELOG.md | 4 +- python/client-contract/README.md | 12 +- .../dataset-ref.schema.json | 5 +- .../ref-definition-extra-member-rejected.json | 98 ++ ...-spec-manifest-without-schema-version.json | 866 ++++++++++++++++++ .../dfo_client_contract/strict-fields.json | 3 + tools/capture_client_contract.py | 129 +-- tools/tests/test_capture_client_contract.py | 5 +- tools/tests/test_validate_client_contract.py | 87 +- tools/validate_client_contract.py | 143 ++- 10 files changed, 1230 insertions(+), 122 deletions(-) create mode 100644 python/client-contract/src/dfo_client_contract/refs/ref-definition-extra-member-rejected.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-schema-version.json diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index 561952b..741bade 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -8,10 +8,10 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be - Package scaffolding (uv, ruff, ty, pytest). - `served/openapi.json`, the composed dfo-apis app's OpenAPI document, and `served/SOURCE.json`, naming dfo-apis commit `635943e03a297f686ca5af32f6d027181d1971d4`. -- `strict-fields.json` and its schema: 28 members that stay required and non-nullable, each one a client reads, and the answer kinds, part statuses and operation statuses the clients branch on. +- `strict-fields.json` and its schema: 29 members that stay required and non-nullable, each one a client reads, and the answer kinds, part statuses and operation statuses the clients branch on. - `actions.json` and its schema: the caller's next step for each of the 101 active refusal codes on `problem_details` or `no_data_reason`, with the gap kind of each no_data reason. - The status fallback for a refusal whose code has no row: 400 and 422 to `InvalidRequestError`, 401 to `AuthenticationError`, 403 to `PermissionDeniedError`, 404 and 410 to `NotFoundError`, 408 to `DfoTimeoutError`, 429 to `RateLimitError`, and any other 4xx or 5xx to `InvalidRequestError` or `ServerError`. -- `scenario.schema.json`, the scenario record, and 117 scenarios: 31 recorded against the composed dfo-apis app at `635943e03`, and 86 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 2,105,201 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, a part without variable_text, an unknown status without a restatement, a shared label, a one-part option whose data_query holds two parts, the separate and operations echo, an unsupported part's placeholder, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a cut-off build retried after its Retry-After, a build refused 504 then 503 and one refused 503 then 504, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, a signed URL refused on both rounds, a relative files-route Location, an artifact url on a foreign origin, on the storage host and absolute on the API's origin, a manifest definition without identity, a Search spec without identity or resolved, nested specs no rule reads, an empty parts list, a Search body that is not an object, a codeless 503 problem document that is not retryable, a 401, an identity resubmit answering another spec, a part whose status is not a string, a Search spec whose definition names another spec_id, a Search response with no JSON body, an option with no data_query, empty entities and facets, a Sunset header issued once, `x-dfo-warning` messages and a Deprecation and Sunset pair, an unreadable versions page, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, 503 polls retried within the budget an answered poll restores, a 404 poll that raises, a failed operation posted again, a failed operation with no error, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route. +- `scenario.schema.json`, the scenario record, and 118 scenarios: 31 recorded against the composed dfo-apis app at `635943e03`, and 87 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 2,105,201 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, a part without variable_text, an unknown status without a restatement, a shared label, a one-part option whose data_query holds two parts, the separate and operations echo, an unsupported part's placeholder, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a cut-off build retried after its Retry-After, a build refused 504 then 503 and one refused 503 then 504, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, a signed URL refused on both rounds, a relative files-route Location, an artifact url on a foreign origin, on the storage host and absolute on the API's origin, a manifest definition without identity or schema_version, a Search spec without identity or resolved, nested specs no rule reads, an empty parts list, a Search body that is not an object, a codeless 503 problem document that is not retryable, a 401, an identity resubmit answering another spec, a part whose status is not a string, a Search spec whose definition names another spec_id, a Search response with no JSON body, an option with no data_query, empty entities and facets, a Sunset header issued once, `x-dfo-warning` messages and a Deprecation and Sunset pair, an unreadable versions page, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, 503 polls retried within the budget an answered poll restores, a 404 poll that raises, a failed operation posted again, a failed operation with no error, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route. - `client-codes.json` and its schema: the 17 codes a client sets on the errors it raises itself, each with its error class, retryable flag and condition, disjoint from `actions.json` and `registries/codes.json`, and the `client_codes()` and `client_codes_schema()` accessors. Every scenario error the client raises itself carries its code, and `refusal_without_code` names a refusal whose body carries no code. - `proxy-codes.json` and its schema, the website proxy's `rate_limited` and `transient_unavailable` codes with their statuses, and `warning-codes.json` and its schema, the 5 codes a client sets on the warnings it issues itself, with the `proxy_codes()` and `warning_codes()` accessors. - Error outcomes give the error's `trace_id`, the body's, else the `x-dfo-trace-id` header's, else null. Scenario outcomes give `retry_waits`, the waits before each retry, and `warnings`, the warning codes a step's responses issued. Scenario steps take no `timeout`. diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 909097f..2b29aa5 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -77,7 +77,7 @@ uv run ty check src/dfo_client_contract The answer's `kind` and each part's `status` are the discriminators of their unions in the served document. A search response with no `kind` raises `ContractError`, as a part with no `status` does, although the served document gives `kind` a default and leaves it out of `required`. A part `status` a client does not know raises nothing and makes the part an `unknown` gap. An answer `kind` a client does not know raises `ContractError`, because the client cannot read the answer. A Search response body that is not an object, a `resolution` answer whose `parts` is empty, at pointer `/parts`, since the served schema gives it at least one item, a part whose `status` is not a string, at pointer `/parts//status`, and a definite or candidate spec whose `definition.spec_id` differs from its `spec_id` raise `ContractError` `contract_violation`, in a Search response as in a ref; `search-body-not-an-object`, `answer-empty-parts`, `answer-part-status-not-a-string` and `answer-definition-spec-id-mismatch` pin the four. -The required members are each part's `status` and its payload (`spec`, `candidates`, `no_data`, `unsupported`), `Resolution.parts`, `CandidateSet.specs`, `NoData.reason`, `Unsupported.code`, `Spec.spec_id`, `definition` and `resolved`, `SpecDefinition.spec_id` and `identity`, the manifest's `definition`, `definition.spec_id` and `definition.identity`, `content_version` and `artifacts`, each artifact's `artifact_digest`, `rendering` and `url`, and the operation resource's `operation`, `operation_id` and `status`. The operation's `poll` is nullable in the served document, so a client builds the poll path from `operation_id`. A client posts a spec's `identity` back to Search and reads its `resolved.entity_groups`, so a Search spec without `resolved`, or a definition, a Search spec's or a manifest's, without `identity` raises `ContractError` `contract_violation`; `answer-spec-without-resolved`, `answer-spec-without-identity` and `fetch-spec-manifest-without-identity` pin them. +The required members are each part's `status` and its payload (`spec`, `candidates`, `no_data`, `unsupported`), `Resolution.parts`, `CandidateSet.specs`, `NoData.reason`, `Unsupported.code`, `Spec.spec_id`, `definition` and `resolved`, `SpecDefinition.spec_id` and `identity`, the manifest's `definition`, `definition.schema_version`, `definition.spec_id` and `definition.identity`, `content_version` and `artifacts`, each artifact's `artifact_digest`, `rendering` and `url`, and the operation resource's `operation`, `operation_id` and `status`. The operation's `poll` is nullable in the served document, so a client builds the poll path from `operation_id`. A client posts a spec's `identity` back to Search and reads its `resolved.entity_groups`, so a Search spec without `resolved`, or a definition, a Search spec's or a manifest's, without `identity` raises `ContractError` `contract_violation`; `answer-spec-without-resolved`, `answer-spec-without-identity` and `fetch-spec-manifest-without-identity` pin them. A ref holds a manifest's definition as it is, and the ref format requires its `schema_version`, so a manifest definition without `schema_version` raises `ContractError` `contract_violation` too, which `fetch-spec-manifest-without-schema-version` pins. ## Actions @@ -160,11 +160,11 @@ The records also fix these client rules: - A fetch of a spec posts its narrowing as the build's `input.scope`, and posts no `scope` when it narrows nothing. A mint takes a layout and no narrowing, so it posts no `scope`. `window` posts `{"kind": "range", "start_year", "end_year"}` for a pair of years, or `{"kind": "all"}` or `{"kind": "latest"}`, and `facets` posts each axis as `{"ref": ...}`, and `facets: {}` names no axis and posts no `facets`. The server's `scope.entities` replaces the spec's whole entity binding, so `entities` posts a whole map: the roles the spec's `definition.identity.entities` binds, with each role the caller names replaced by its refs and each role the caller binds to null dropped. Naming `origin` alone on a spec bound to `origin` and `destination` keeps `destination`. A fetch that names no role, `entities: {}` included, posts no `entities`, so a fetch whose narrowing is all empty posts no `scope`; `fetch-spec-empty-narrowing` pins it. - A built `spec_id` that differs from the posted one, or a spec with no sentence, takes its sentence from Search: the client posts the built definition's `identity` as one `dataset_resubmit` identity entry, with the member's first part as `variable_text`, or `"dataset"` when no answer part names it, and checks the answer's `spec_id` equals the built one. The entry's `entity_groups` holds the spec's `resolved.entity_groups` for each role the built identity binds to the same entities as the spec's definition, so a window or facets narrowing keeps every group and a role the narrowing rebound or dropped loses its group. The entry leaves `entity_groups` out when it keeps no group, as for a resumed operation, whose spec the client does not hold. The server reads a role posted without its group as its members, so a narrowed spec of flows to the least developed countries would read "44 recipients" in place of "the 44 Least Developed Countries". - A dataset of several members puts the `part` column first, then each member's columns in member order, each column once. A column that members hold in different types widens as pyarrow's permissive promotion widens it, and a pair that cannot widen raises `ContractError` `contract_violation`. A member file that already holds a `part` column raises `contract_violation` when members stack. Rows and columns are not derived, so no scenario pins these. The `part` value on a member's rows is the member's `parts` joined by `"; "`, so a member that answers two folded parts reads `"health ODA disbursements; education ODA disbursements"`, or the member's sentence when `parts` is empty. A definite part whose `variable_text` is absent or empty adds nothing to its member's `parts`, which `answer-folded-parts-unnamed` pins. -- A choice names its part by index, by variable text, or by a word that one gap's options mention, and its option, a candidate among them, by index or label. A candidate's label is the `text` of its spec's `resolved.sentence_plan` tokens in the `heading` segment, a token whose `segment` is not a string counted in it, joined and stripped of surrounding white space, or else its `resolved.rendered_sentence`. A candidate with neither a heading nor a sentence has a null label; no scenario pins it. A no_data option's label is matched among the options that mention the word the part was named by. With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. -- A choice raises `InvalidRequestError` `choice_invalid` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is out of range or matches no label or several. It raises the same when an entry it would post cannot be built: a part with no `variable_text`, or a part of a status the client does not know that has no `restatement`. A chosen option whose `data_query` holds other than one part raises `ContractError`, and so does a chosen option with no `data_query`, in a one-part answer as in a several-part one, before any request. `choose-refused-shared-label`, `choose-refused-unknown-candidate-label`, `choose-refused-shared-candidate-label`, `choose-refused-part-without-variable-text`, `choose-refused-unknown-status`, `choose-option-two-part-query` and `choose-option-without-data-query` pin these, and `choose-candidate-by-label` pins a candidate chosen by its label. +- A choice names its part by index, by variable text, or by a word that one gap's options mention, and its option, a candidate among them, by index or label. A boolean option is neither an index nor a label. A candidate's label is the `text` of its spec's `resolved.sentence_plan` tokens in the `heading` segment, a token whose `segment` is not a string counted in it, joined and stripped of surrounding white space, or else its `resolved.rendered_sentence`. A candidate with neither a heading nor a sentence has a null label; no scenario pins it, and the validator's tests do. A no_data option's label is matched among the options that mention the word the part was named by. With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. +- A choice raises `InvalidRequestError` `choice_invalid` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is a boolean, is out of range or matches no label or several. No scenario can hold a boolean option, and the validator's tests pin it. It raises the same when an entry it would post cannot be built: a part with no `variable_text`, or a part of a status the client does not know that has no `restatement`. A chosen option whose `data_query` holds other than one part raises `ContractError`, and so does a chosen option with no `data_query`, in a one-part answer as in a several-part one, before any request. `choose-refused-shared-label`, `choose-refused-unknown-candidate-label`, `choose-refused-shared-candidate-label`, `choose-refused-part-without-variable-text`, `choose-refused-unknown-status`, `choose-option-two-part-query` and `choose-option-without-data-query` pin these, and `choose-candidate-by-label` pins a candidate chosen by its label. - Every pick of a candidate asks Search for the picked answer, and no client builds it locally. In a one-part answer the pick posts `dataset_resubmit`, without `raw_query`, with one identity entry: the candidate's identity and `entity_groups`, and the part's `variable_text`, `separate` and `operations` as below. The picked answer, its sentence with any "Assumed: …" clause, and its assumptions are Search's response. A choice of a no_data option in a one-part answer posts the option's `data_query` as the input. - In a several-part answer a choice posts `dataset_resubmit`, without `raw_query`, with one entry per part in part order. The chosen candidate posts an identity entry with its identity and `entity_groups`, and the chosen option its `data_query`'s one part as a parsed entry. A definite part posts an identity entry with its spec's identity and `entity_groups`. A candidates part left alone posts a `candidates` entry: its candidate set in the server's order, each with its identity and `entity_groups`, and its `ordering` and `truncated` echoed. The server cannot recompute that order, because it rests on the first answer's bind election and availability reads, and a parsed entry would cost an LLM bind. Any other part posts its `restatement` as a parsed entry, or a placeholder entry with its no_data `reason` or unsupported `code` when it has none. Every entry but a parsed one carries the part's `variable_text`, `separate` when true and `operations` when any of the part's operations reads. `entity_groups` is left out when the spec has none. `choose-echoes-separate-and-operations` pins the echo on a definite part's entry, and `choose-posts-unsupported-placeholder` an unsupported part's placeholder. -- Each identity a choice posts echoes its reading's assumptions as `assumptions`: the chosen candidate's entry carries its part's `reading_assumptions` under the candidate's `spec_id`, a definite part's entry carries the part's `assumptions`, and each candidate of a `candidates` entry carries its own `reading_assumptions` entry. Search then states the echoed items that still hold, so the picked answer states what that reading assumed. `[]` states none. An identity with no `assumptions` reads as a fresh request, so a client that holds no list for a reading, from a part that carries no `assumptions` or `reading_assumptions`, posts none. The identity entry that asks for a built sentence posts no `assumptions`, since it reads only the spec's own `rendered_sentence`. An echoed `operations` or `assumptions` list posts exactly the items a client reads under Strict fields, in order, each built from the members it read: an optional member that read as absent is left out, and a `refs` list posts its string items. An `assumptions` list with no item read posts `[]`, and an `operations` list with none is left out. `choose-echo-drops-malformed-items` pins both lists. +- Each identity a choice posts echoes its reading's assumptions as `assumptions`: the chosen candidate's entry carries its part's `reading_assumptions` under the candidate's `spec_id`, a definite part's entry carries the part's `assumptions`, and each candidate of a `candidates` entry carries its own `reading_assumptions` entry. Search then states the echoed items that still hold, so the picked answer states what that reading assumed. `[]` states none. An identity with no `assumptions` reads as a fresh request, so a client that holds no list for a reading, from a part that carries no `assumptions` or `reading_assumptions`, posts none. The identity entry that asks for a built sentence posts no `assumptions`, since it reads only the spec's own `rendered_sentence`. An echoed `operations` or `assumptions` list posts exactly the items a client reads under Strict fields, in order, each built from the members it read: an optional member that read as absent is left out, and a `refs` list posts its string items. An `assumptions` list with no item read posts `[]`, and an `operations` list with none is left out. The item rule checks JSON types alone, so the echo posts what a client read, and the server still checks it against its own value constraints: the `verb` enum, the lengths of `phrase` and `text`, and at most one item in `refs`. `choose-echo-drops-malformed-items` pins both lists. - A strict fetch raises the manifest's first warning above `info` severity as a `DataWarning` with that warning's code, before the sentence lookup and the download. - An identity resubmit whose answer is not one definite part of the built `spec_id`, with a sentence, raises `ContractError`. - The `frame` layout posts `{"format": "parquet", "bundle": false, "layout": "frame"}` as the build's `options` and downloads the artifact whose rendering's `layout` is `frame`; the `long` layout posts `{"format": "parquet", "bundle": false}` and downloads the bare Parquet artifact with any other layout. A fetch of an answer with several members in the `frame` layout raises `InvalidRequestError` before any build. @@ -174,7 +174,7 @@ The records also fix these client rules: - The redirect rules above hold where a client reads the files route's response itself: the Python client, and the TypeScript client in Node. A browser page or worker cannot, because a `fetch` with `redirect: "manual"` answers an opaque redirect with no status and no `location`. There the TypeScript client asks the files route again with `redirect: "follow"`, sending the API key alone, which the browser drops on the way to another origin, and the followed request is the round's one fetch. The response must end on the API's origin or `https://storage.googleapis.com`, and any other host raises `ContractError` `contract_violation` after the fetch. So in a browser a files route answering 301, 303, 307 or 308 is followed as a 302 is. The refusal rules, the retry rules, the rounds and the digest check hold in every runtime. The scenario format names no runtime, so the scenarios fix the Python and Node behaviour, and the TypeScript client's own tests check the browser's. - A declined or catalogue answer is not complete, and fetching it raises `DeclinedError`. - Fetching an answer with a gap raises `IncompleteAnswerError` before any request, unless the fetch is partial and some part has a reading. -- A fetch of an answer issues one `SearchWarning` when a definite part has an operation Search did not run, a departure, or a warning at severity `warn` or `degraded` with a `message`, or the answer's `diagnostics.warnings` holds such a warning. An `info` warning, and a warning with no `message`, issue nothing. Each way is one line a client shows: `Not done: ()` coded by the verb, the departure's `text` coded by its code, or `Note: ` coded by the warning's code, in part order with the diagnostics warnings last, and ways that show the same line count once, under the first one's code. A strict fetch raises the `SearchWarning` before any build, with the code of its one line, or a null code when there are several lines. A strict fetch raises it before the `frame` layout's several-member check. +- A fetch of an answer issues one `SearchWarning` when a definite part has an operation Search did not run, a departure, or a warning at severity `warn` or `degraded` with a `message`, or the answer's `diagnostics.warnings` holds such a warning. An `info` warning, a warning with no `message`, and an operation that does not read under Strict fields issue nothing. Each way is one line a client shows: `Not done: ()` coded by the verb, the phrase quoted as a JSON string that keeps non-ASCII characters as they are, the departure's `text` coded by its code, or `Note: ` coded by the warning's code, in part order with the diagnostics warnings last, and ways that show the same line count once, under the first one's code. A strict fetch raises the `SearchWarning` before any build, with the code of its one line, or a null code when there are several lines. A strict fetch raises it before the `frame` layout's several-member check. - A ref's version is found in this order: the snapshot route and the files route at the stored digest; the file selector, `GET /datasets/{id}/{content_version}/file` with the ref's rendering as the query; and a build of the ref's spec in the ref's rendering, which must answer the ref's `spec_id` and the same `content_version`. Both recovery steps keep the ref's identity, so a recovered member carries the ref's `spec_id` and `content_version`: a snapshot manifest whose `definition.spec_id` or `content_version` is not the ref's, or a rebuild manifest whose `definition.spec_id` is not the ref's, raises `ContractError` `contract_violation` before any download, which `fetch-ref-expired-rebuild-other-spec` pins for the rebuild. A snapshot refusal other than `artifact_expired` ends the lookup, so `snapshot_not_found` raises `NotFoundError` with no further request. A files route or selector refusal of `artifact_expired`, `artifact_not_found` or `not_found` takes the next step, and a selector file of another digest is not the stored file. A snapshot manifest whose artifacts list no artifact of the ref member's digest sends the client to the selector in the ref member's own rendering, and a file that hashes to that digest gives the dataset, which `fetch-ref-artifact-unlisted` pins. A rebuild that answers another version, or that raises `InvalidRequestError`, `NotFoundError` or `VersionUnavailableError`, ends in `VersionUnavailableError` with the first refusal's code, or `version_unavailable` when nothing refused. Its `newest_version` is the version the rebuild answered, or else the newest stored version, which `GET /datasets/{id}/versions?limit=1` lists alone, as a `newest_version` step finds it, since the route lists versions newest first and needs no key; or null when that route lists none or refuses with `NotFoundError`. Any other refusal of the versions route raises, and a page whose `versions` is not a list of versions each with a `content_version` raises `ContractError` `contract_violation`, which `newest-version-unreadable-page` pins. - A build answers 200 with the manifest, or 202 with an operation the client polls at `/datasets/operations/{operation_id}`, the id of the operation it holds. A mint's build answers 202. A record whose mint answers 200 fits no mint step. Before each poll it waits the `Retry-After` of the refusal that answered the last poll, whatever its status, as every retry of a refused request waits; else the last operation resource's `retry_after_ms`, else the `Retry-After` of the last answered poll, the response that carried that resource, else a backoff of 1, 2, 4 and then 8 seconds that advances one step each time it is used, a poll after a refusal included. - A retryable 429 poll spends no retry, and a 429 whose body says it is not retryable raises at once, as a refusal's `retryable` outranks its status, which `fetch-spec-poll-rate-limited-not-retryable` pins. Any other retryable refused poll spends one of the two retries, which a poll that answers restores, and a refusal that is not retryable raises. `fetch-spec-poll-refused` pins two 503s polled again after an answered poll, `fetch-spec-poll-refused-backoff` a 503 with no `Retry-After` among polls no response paces, after which the backoff advances, `fetch-spec-poll-refused-retry-after` a 503 whose `Retry-After` paces the next poll, and `fetch-spec-poll-not-found` a 404 that raises at once. A poll that answers a failed operation whose error is retryable posts the same build once more and polls the operation it starts; a second failure, an error that is not retryable, and a resumed operation, whose build request the client does not hold, raise the operation's error. A refused poll whose code is `operation_failed` is a failed operation with that error. A failed operation whose resource carries no `error` raises `ServerError` with `operation_failed`, retryable by status 500 as a refusal without a document is, which `operation-failed-without-error` pins. A 202 or resumed operation that already reads `failed` raises its error before any poll. @@ -211,7 +211,7 @@ A record's `origin.base_url` is the base URL the run was given, a local app's in ## DatasetRef -`dataset-ref.schema.json` is the frozen format a client writes for `data.ref` and reads back in any language: `format_version: 1` and one or more `members`, each `{parts, sentence, spec: {spec_id, definition}, content_version, artifact: {digest, rendering}}`. `parts` holds the variable text of each answer part the member answers, in query order, and is empty for a spec fetched outside an answer. `definition` is the server's definition unmodified, so it holds the `schema_version`, `spec_id` and `identity` the served `CanonicalDefinition` requires, and a rebuild posts it as it is. `rendering` is the selector a client matches an artifact on, `{format, bundle}` with `layout: "frame"` for the frame layout, never the server's rendering object. Beyond the schema, each member's `definition.spec_id` equals its `spec.spec_id`, and members hold distinct `spec_id`s. `ref-bare-definition-rejected`, `ref-definition-without-identity-rejected` and `ref-definition-without-schema-version-rejected` pin the definition's required members. `refs/` holds accepted examples and rejected ones, each `{format_version, name, description, ref}` with `expect: "accept"` or `error`, `{by: "schema"}` or `{by: "rule", reason}`, the reason `definition_spec_id_mismatch` or `repeated_spec_id`. +`dataset-ref.schema.json` is the frozen format a client writes for `data.ref` and reads back in any language: `format_version: 1` and one or more `members`, each `{parts, sentence, spec: {spec_id, definition}, content_version, artifact: {digest, rendering}}`. `parts` holds the variable text of each answer part the member answers, in query order, and is empty for a spec fetched outside an answer. `definition` is the server's definition unmodified, so it holds the `schema_version`, `spec_id` and `identity` the served `CanonicalDefinition` requires and no other member, and a rebuild posts it as it is. The format takes any integer `schema_version` and leaves the version to the server, which checks it when a rebuild posts the definition. `rendering` is the selector a client matches an artifact on, `{format, bundle}` with `layout: "frame"` for the frame layout, never the server's rendering object. Beyond the schema, each member's `definition.spec_id` equals its `spec.spec_id`, and members hold distinct `spec_id`s. `ref-bare-definition-rejected`, `ref-definition-without-identity-rejected` and `ref-definition-without-schema-version-rejected` pin the definition's required members, and `ref-definition-extra-member-rejected` a member it does not admit. `refs/` holds accepted examples and rejected ones, each `{format_version, name, description, ref}` with `expect: "accept"` or `error`, `{by: "schema"}` or `{by: "rule", reason}`, the reason `definition_spec_id_mismatch` or `repeated_spec_id`. ## Rules diff --git a/python/client-contract/src/dfo_client_contract/dataset-ref.schema.json b/python/client-contract/src/dfo_client_contract/dataset-ref.schema.json index 382e739..88cbedf 100644 --- a/python/client-contract/src/dfo_client_contract/dataset-ref.schema.json +++ b/python/client-contract/src/dfo_client_contract/dataset-ref.schema.json @@ -58,8 +58,9 @@ "$ref": "#/$defs/spec_id" }, "definition": { - "description": "The server's definition for spec_id, unmodified. It holds the members the served CanonicalDefinition requires, so a rebuild can post it as it is.", + "description": "The server's definition for spec_id, unmodified. It holds the members the served CanonicalDefinition admits, each it requires and no other, so a rebuild can post it as it is.", "type": "object", + "additionalProperties": false, "required": [ "schema_version", "spec_id", @@ -67,7 +68,7 @@ ], "properties": { "schema_version": { - "const": 1 + "type": "integer" }, "spec_id": { "$ref": "#/$defs/spec_id" diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-definition-extra-member-rejected.json b/python/client-contract/src/dfo_client_contract/refs/ref-definition-extra-member-rejected.json new file mode 100644 index 0000000..0a71366 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/refs/ref-definition-extra-member-rejected.json @@ -0,0 +1,98 @@ +{ + "format_version": 1, + "name": "ref-definition-extra-member-rejected", + "description": "A member's definition holds only the members the served CanonicalDefinition admits.", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "artifact": { + "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "format": "parquet", + "bundle": false + } + } + } + ] + }, + "error": { + "by": "schema" + } +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-schema-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-schema-version.json new file mode 100644 index 0000000..daeb3ba --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-schema-version.json @@ -0,0 +1,866 @@ +{ + "format_version": 1, + "name": "fetch-spec-manifest-without-schema-version", + "description": "A manifest whose definition has no schema_version, a strict member, raises ContractError contract_violation on the build response, before any download, so a ref never holds a definition without one.", + "origin": { + "kind": "synthetic", + "derived_from": "fetch-spec-known-sentence", + "edit": "The build's manifest definition loses schema_version, and the exchanges after it go." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS)." + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" + }, + "json": { + "schema_version": 1, + "definition": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "state": "unbound" + }, + "property": "crsCooperationModality" + }, + { + "binding": { + "ref": "CRSPurposeCode12220", + "state": "value" + }, + "property": "crsPurpose" + }, + { + "binding": { + "state": "unbound" + }, + "property": "crsTypeOfFinance" + }, + { + "binding": { + "ref": "CRSTypeOfFlow10", + "state": "value" + }, + "property": "crsTypeOfFlow" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "prepared_at": "2026-10-21T13:05:35Z", + "coverage": { + "rows": 4, + "dimensions": [ + { + "label": "financingProvider", + "count": 1, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 1, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 4 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + } + }, + "citation": { + "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=crs&pg=0&snb=30&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_CRS%40DF_CRS&df[ag]=OECD.DCD.FSD&df[vs]=1.6&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1973-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Exclude donor core contributions to multilaterals", + "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets." + }, + { + "transformation": "Select dimensions", + "description": "Every figure is reported against the year, the provider and the recipient, and four dimensions from the CRS: type of flow, co-operation modality, type of finance and purpose code. The CRS describes each activity in far more detail than this, including project titles, descriptions, channels and policy markers, none of which is carried through." + }, + { + "transformation": "Aggregate totals", + "description": "Activities sharing the same year, provider, recipient and dimensions are summed. Commitments, disbursements, net disbursements and grant equivalents are each aggregated as separate measures. Every figure is reported in US dollars at current prices." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2023, + "start_year": 2020 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDCreditorReportingSystem", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 4 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB031_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB032_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB033_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB04_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityE02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityG01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance210_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance421_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance510_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + }, + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance520_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 0 + } + ], + "family_member_count": 21, + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "head", + "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + }, + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityB03_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityC01_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityD02_CRSPurposeCode12220_Nominal, dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSPurposeCode12220_Nominal, which hold none at the observation period the other members serve in the requested years." + } + ], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 9541, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:35.038218+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + }, + { + "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", + "rendering": { + "statistics": "series" + }, + "bytes": 5741, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T13:05:35.038218+00:00", + "tier": "working", + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" + } + ], + "series_count": 1, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 1 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 4 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [], + "pivots": [], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T13:05:35.038284Z" + } + } + } + } + ], + "expect": [ + { + "error": { + "class": "ContractError", + "code": "contract_violation", + "trace_id": "72492035a830492dba11a29fa89ded8c" + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/strict-fields.json b/python/client-contract/src/dfo_client_contract/strict-fields.json index ff799a3..ac5d929 100644 --- a/python/client-contract/src/dfo_client_contract/strict-fields.json +++ b/python/client-contract/src/dfo_client_contract/strict-fields.json @@ -61,6 +61,9 @@ { "pointer": "/components/schemas/Manifest/properties/artifacts" }, + { + "pointer": "/components/schemas/DefinitionModel/properties/schema_version" + }, { "pointer": "/components/schemas/DefinitionModel/properties/spec_id" }, diff --git a/tools/capture_client_contract.py b/tools/capture_client_contract.py index 8cc0714..08310de 100644 --- a/tools/capture_client_contract.py +++ b/tools/capture_client_contract.py @@ -80,7 +80,6 @@ POLL_BACKOFF_CAP, POLL_BACKOFF_FIRST, POLL_PATH, - REBUILD_REFUSED, SIGNED_FETCH_STATUS, STORAGE_ORIGIN, TRACE_HEADER, @@ -125,6 +124,7 @@ selector_path, sentence_entry, shared_cacheable, + stored_version, surface_problems, trace_id, untraced, @@ -1040,54 +1040,43 @@ def _wait( def _stored(self, member: dict[str, Any]) -> Member: """One version a ref names, through the lookup order - `validate_client_contract._Replay.stored_version` states.""" + `validate_client_contract.stored_version` states.""" spec = member["spec"] spec_id, version = spec["spec_id"], member["content_version"] rendering = member["artifact"]["rendering"] held = Spec(spec_id, spec["definition"], member["sentence"]) - refusal: ClientError | None = None - manifest = None - try: - manifest = self._acted(self._api("GET", f"/datasets/{spec_id}/{version}")) - except ClientError as error: - if error.code != FILE_EXPIRED: - raise - refusal = error - if manifest is not None: - built = (manifest["definition"]["spec_id"], manifest["content_version"]) - if built != (spec_id, version): - raise ClientError("contract_violation") + + def stored_file( + manifest: dict[str, Any], + ) -> tuple[Member | None, ClientError | None]: data, refusal = self._stored_file(member, manifest) - if data is not None: - rows, columns = self.read_shape(data) - return Member( - member["parts"], - spec["definition"], - version, - member["sentence"], - member["artifact"]["digest"], - rows, - columns, - dict(rendering), - ) - try: - manifest = self._built(_build_body(held, None, rendering)) - except ClientError as error: - if error.error_class(self.client_codes) not in REBUILD_REFUSED: - raise - refusal = refusal if refusal is not None else error - newest = self._newest(spec_id) - else: - if manifest["definition"]["spec_id"] != spec_id: - raise ClientError("contract_violation") - if manifest["content_version"] == version: - return self._member(member["parts"], held, manifest, rendering, False) - newest = manifest["content_version"] - raise ClientError( - refusal.code if refusal is not None else "version_unavailable", - error=VERSION_UNAVAILABLE, - newest_version=newest, - trace_id=refusal.trace_id if refusal is not None else None, + if data is None: + return None, refusal + rows, columns = self.read_shape(data) + stored = Member( + member["parts"], + spec["definition"], + version, + member["sentence"], + member["artifact"]["digest"], + rows, + columns, + dict(rendering), + ) + return stored, None + + return stored_version( + member, + self.client_codes, + snapshot=lambda: self._acted( + self._api("GET", f"/datasets/{spec_id}/{version}") + ), + stored_file=stored_file, + rebuild=lambda: self._built(_build_body(held, None, rendering)), + rebuilt=lambda manifest: self._member( + member["parts"], held, manifest, rendering, False + ), + newest=lambda: self._newest(spec_id), ) def _stored_file( @@ -3307,16 +3296,22 @@ def change(response: dict[str, Any]) -> None: return change -def _manifest_without_identity(parent: dict[str, Any], ctx: Context) -> Derived: - index = _build_index(parent) - exchanges = copy.deepcopy(parent["exchanges"][: index + 1]) - del exchanges[index]["response"]["json"]["definition"]["identity"] - error = ctx.raised("contract_violation", exchanges[index]["response"]) - return Derived( - copy.deepcopy(parent["call"]), - exchanges, - [*copy.deepcopy(parent["expect"][:-1]), error], - ) +def _manifest_without(member: str) -> Callable[[dict[str, Any], Context], Derived]: + """The build's manifest definition loses `member`, a strict one, so the + build raises contract_violation and the exchanges after it go.""" + + def derive(parent: dict[str, Any], ctx: Context) -> Derived: + index = _build_index(parent) + exchanges = copy.deepcopy(parent["exchanges"][: index + 1]) + del exchanges[index]["response"]["json"]["definition"][member] + error = ctx.raised("contract_violation", exchanges[index]["response"]) + return Derived( + copy.deepcopy(parent["call"]), + exchanges, + [*copy.deepcopy(parent["expect"][:-1]), error], + ) + + return derive def _nested_specs_unchecked(parent: dict[str, Any], ctx: Context) -> Derived: @@ -3734,7 +3729,17 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: "The build's manifest definition loses identity, and the exchanges after it go.", "A manifest whose definition has no identity, a strict member, raises ContractError " "contract_violation on the build response, before any download.", - _manifest_without_identity, + _manifest_without("identity"), + ), + Synthetic( + "fetch-spec-manifest-without-schema-version", + "fetch-spec-known-sentence", + "The build's manifest definition loses schema_version, and the exchanges after it " + "go.", + "A manifest whose definition has no schema_version, a strict member, raises " + "ContractError contract_violation on the build response, before any download, so " + "a ref never holds a definition without one.", + _manifest_without("schema_version"), ), Synthetic( "operation-failed-without-error", @@ -4312,7 +4317,13 @@ def __call__( if "json" in response: data = json.dumps(response["json"]).encode() elif "body_file" in response: - data = body_path(self.body_dir, response["body_file"]).read_bytes() + # A refused body file is the record's fault, which recording live + # would not mend, so it ends the run past `drive`'s advice. + try: + path = body_path(self.body_dir, response["body_file"]) + except ValueError as exc: + raise SystemExit(f"{self.name}: {exc}") from exc + data = path.read_bytes() else: data = b"" return Response(response["status"], dict(response.get("headers", {})), data) @@ -4374,12 +4385,6 @@ def rederive_recorded(name: str, ctx: Context, directory: Path) -> None: if not path.exists(): raise SystemExit(f"{name}: no record to derive from; record it live") record = json.loads(path.read_text(encoding="utf-8")) - for exchange in record["exchanges"]: - if "body_file" in exchange["response"]: - try: - body_path(directory, exchange["response"]["body_file"]) - except ValueError as exc: - raise SystemExit(f"{name}: {exc}") from exc served = Served(record, directory) session = Session( Recorder(name, served.base_url, served), diff --git a/tools/tests/test_capture_client_contract.py b/tools/tests/test_capture_client_contract.py index 5e56bde..f51bc5d 100644 --- a/tools/tests/test_capture_client_contract.py +++ b/tools/tests/test_capture_client_contract.py @@ -289,8 +289,11 @@ def test_an_offline_rederivation_refuses_a_body_file_outside_its_directory( ctx = capture.Context( capture.DEV_BASE_URL, capture._offline, ACTIONS, CLIENT_CODES, read_shape=_shape ) - with pytest.raises(SystemExit, match="body file"): + with pytest.raises(SystemExit) as refused: capture.rederive_recorded(name, ctx, scenarios) + message = str(refused.value) + assert f"body file {body_file!r}" in message + assert "record it live" not in message assert json.loads(record.read_text(encoding="utf-8")) == stale assert body.is_symlink() == (named == "symlink") diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index f886cdf..17fbc58 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -1921,7 +1921,7 @@ def test_an_orphan_body_file_is_reported(package_dir: Path) -> None: ("item", "read"), [ (_ASSUMED, _ASSUMED), - ({**_ASSUMED, "refs": ["a", 1, None, "b"]}, {**_ASSUMED, "refs": ["a", "b"]}), + ({**_ASSUMED, "refs": ["a", 1, None]}, {**_ASSUMED, "refs": ["a"]}), ({**_ASSUMED, "refs": "a"}, _ASSUMED), ({**_ASSUMED, "refs": None}, _ASSUMED), ({**_ASSUMED, "note": "x"}, _ASSUMED), @@ -1992,6 +1992,91 @@ def test_an_assumptions_list_with_no_item_read_echoes_empty() -> None: assert validator.reading_echo({"status": "definite"}, spec) is None +def _answer(*parts: dict[str, Any]) -> Any: + return validator.answer_from_body({"kind": "resolution", "parts": list(parts)}) + + +@pytest.mark.parametrize( + ("operations", "hints"), + [ + ([_RANK], {'Not done: rank ("top 5 donors")': "rank"}), + ( + [{**_RANK, "phrase": "aide au Sénégal"}], + {'Not done: rank ("aide au Sénégal")': "rank"}, + ), + ([{**_RANK, "phrase": 5}, "rank"], {}), + ], + ids=["ascii-phrase", "non-ascii-phrase", "operation-not-read"], +) +def test_an_operation_not_done_is_one_hint( + operations: list[Any], hints: dict[str, str] +) -> None: + """The phrase is quoted as JSON with its characters kept, as both clients + quote it, and an operation that does not read gives no hint.""" + spec = {"spec_id": "spec_a", "definition": {"spec_id": "spec_a"}} + answer = _answer({"status": "definite", "spec": spec, "operations": operations}) + assert validator.reading_hints(answer) == hints + + +def _candidate(**resolved: Any) -> dict[str, Any]: + return { + "spec_id": "spec_a", + "definition": {"spec_id": "spec_a"}, + "resolved": resolved, + } + + +@pytest.mark.parametrize( + "part", + [ + {"status": "candidates", "candidates": {"specs": [_candidate()] * 2}}, + { + "status": "no_data", + "no_data": {"reason": "r", "options": [{"label": "a"}, {"label": "b"}]}, + }, + ], + ids=["candidate", "no-data-option"], +) +@pytest.mark.parametrize("option", [True, False]) +def test_a_boolean_option_is_neither_an_index_nor_a_label( + part: dict[str, Any], option: bool +) -> None: + with pytest.raises(validator.ClientError) as raised: + validator.choice_for(_answer(part), {}, 0, option) + assert raised.value.code == "choice_invalid" + + +@pytest.mark.parametrize( + ("resolved", "label"), + [ + ( + { + "sentence_plan": [ + {"segment": "heading", "text": " Aid "}, + {"text": "to Kenya "}, + {"segment": "assumptions", "text": "every donor"}, + ], + "rendered_sentence": "Aid to Kenya, every donor.", + }, + "Aid to Kenya", + ), + ( + { + "sentence_plan": [{"segment": "assumptions", "text": "every donor"}], + "rendered_sentence": "Aid to Kenya, every donor.", + }, + "Aid to Kenya, every donor.", + ), + ({}, None), + ], + ids=["segment-less-token-in-heading", "rendered-sentence-fallback", "neither"], +) +def test_a_candidate_label_is_its_heading_or_its_sentence( + resolved: dict[str, Any], label: str | None +) -> None: + assert validator.candidate_label(_candidate(**resolved)) == label + + def test_a_required_member_that_admits_null_stays_required() -> None: """A recorded body must carry a required member, null or not.""" served = validator.PACKAGE_DIR / "served" / "openapi.json" diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index 9a4adf3..56ab923 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -1221,7 +1221,8 @@ def choice_for( candidates part's options are its candidates, chosen by index or by `candidate_label`. Any other gap's are its no_data options, chosen by index or label, a label scoped to the options that mention the word the - part was named by. A label must match exactly one option.""" + part was named by. A label must match exactly one option, and a boolean + option is neither an index nor a label.""" gaps = answer_gaps(answer, kinds) gap_parts = {gap["part"] for gap in gaps} mention = None @@ -1248,7 +1249,7 @@ def choice_for( if len(named) != 1: raise _refuse() index = named[0] - if index not in gap_parts: + if index not in gap_parts or isinstance(option, bool): raise _refuse() chosen = answer.parts[index] @@ -1455,7 +1456,7 @@ def notices(holder: Any) -> None: continue for operation in read_items(part, "operations", read_operation): if verb := operation["verb"]: - phrase = json.dumps(operation["phrase"]) + phrase = json.dumps(operation["phrase"], ensure_ascii=False) hints.setdefault(f"Not done: {verb} ({phrase})", verb) for departure in read_objects(part, "departures"): if text := read_string(departure, "text"): @@ -1792,6 +1793,68 @@ def newest_listed(body: Any) -> str | None: return versions[0]["content_version"] if versions else None +def stored_version[T]( + member: Mapping[str, Any], + client_codes: Mapping[str, Any], + *, + snapshot: Callable[[], Any], + stored_file: Callable[[Any], tuple[T | None, ClientError | None]], + rebuild: Callable[[], Any], + rebuilt: Callable[[Any], T], + newest: Callable[[], str | None], +) -> T: + """One version a ref names, through the lookup order: the snapshot + route and the files route at the stored digest, then the file + selector, then a build that must answer the same version. A snapshot + or build that answers another spec_id raises ContractError, as a + snapshot of another version does. A snapshot refusal other than + artifact_expired ends the lookup. Otherwise a lookup that finds no file + raises VersionUnavailableError with the first refusal's code, or + version_unavailable, and the newest version, either the one the build + answered or the versions route's first. + + The callers make the requests: `snapshot` asks the snapshot route, + `stored_file` gives what the files route or the selector served for a + snapshot manifest, or None and the refusal it met, `rebuild` builds the + member's spec, `rebuilt` gives what a build of the stored version + serves, and `newest` asks the versions route.""" + spec_id, version = member["spec"]["spec_id"], member["content_version"] + refusal: ClientError | None = None + manifest = None + try: + manifest = snapshot() + except ClientError as error: + if error.code != FILE_EXPIRED: + raise + refusal = error + if manifest is not None: + built = (manifest["definition"]["spec_id"], manifest["content_version"]) + if built != (spec_id, version): + raise ClientError("contract_violation") + found, refusal = stored_file(manifest) + if found is not None: + return found + try: + manifest = rebuild() + except ClientError as error: + if error.error_class(client_codes) not in REBUILD_REFUSED: + raise + refusal = refusal if refusal is not None else error + newest_version = newest() + else: + if manifest["definition"]["spec_id"] != spec_id: + raise ClientError("contract_violation") + if manifest["content_version"] == version: + return rebuilt(manifest) + newest_version = manifest["content_version"] + raise ClientError( + refusal.code if refusal is not None else "version_unavailable", + error=VERSION_UNAVAILABLE, + newest_version=newest_version, + trace_id=refusal.trace_id if refusal is not None else None, + ) + + def build_body( spec: Mapping[str, Any], scope: Mapping[str, Any] | None, @@ -2389,15 +2452,8 @@ def sentence( # -- stored versions -- def stored_version(self, member: dict[str, Any]) -> dict[str, Any]: - """One version a ref names, through the lookup order: the snapshot - route and the files route at the stored digest, then the file - selector, then a build that must answer the same version. A snapshot - or build that answers another spec_id raises ContractError, as a - snapshot of another version does. A snapshot refusal other than - artifact_expired ends the lookup. Otherwise a - lookup that finds no file raises VersionUnavailableError with the - first refusal's code, or version_unavailable, and the newest version, - either the one the build answered or the versions route's first.""" + """One version a ref names, through the lookup order + `stored_version` states.""" spec = member["spec"] spec_id, version = spec["spec_id"], member["content_version"] rendering = member["artifact"]["rendering"] @@ -2407,40 +2463,27 @@ def stored_version(self, member: dict[str, Any]) -> dict[str, Any]: "content_version": version, "sentence": member["sentence"], } - refusal: ClientError | None = None - try: - manifest = self.acted_on(self.call("GET", f"/datasets/{spec_id}/{version}")) - except ClientError as error: - if error.code != FILE_EXPIRED: - raise - refusal, manifest = error, None - if manifest is not None: - built = (manifest["definition"]["spec_id"], manifest["content_version"]) - if built != (spec_id, version): - raise ClientError("contract_violation") - found, refusal = self.stored_file(member, manifest) - if found: - return stored - try: - manifest = self.build(spec, rendering) - except ClientError as error: - if error.error_class(self.client_codes) not in REBUILD_REFUSED: - raise - refusal = refusal if refusal is not None else error - newest = self.newest(spec_id) - else: - if manifest["definition"]["spec_id"] != spec_id: - raise ClientError("contract_violation") - if manifest["content_version"] == version: - held = {**spec, "sentence": member["sentence"]} - return self.member(member["parts"], held, manifest, rendering, False) - newest = manifest["content_version"] - raise ClientError( - refusal.code if refusal is not None else "version_unavailable", - error=VERSION_UNAVAILABLE, - newest_version=newest, - trace_id=refusal.trace_id if refusal is not None else None, + def stored_file( + manifest: dict[str, Any], + ) -> tuple[dict[str, Any] | None, ClientError | None]: + served, refusal = self.stored_file(member, manifest) + return (stored if served else None), refusal + + def rebuilt(manifest: dict[str, Any]) -> dict[str, Any]: + held = {**spec, "sentence": member["sentence"]} + return self.member(member["parts"], held, manifest, rendering, False) + + return stored_version( + member, + self.client_codes, + snapshot=lambda: self.acted_on( + self.call("GET", f"/datasets/{spec_id}/{version}") + ), + stored_file=stored_file, + rebuild=lambda: self.build(spec, rendering), + rebuilt=rebuilt, + newest=lambda: self.newest(spec_id), ) def stored_file( @@ -2726,9 +2769,13 @@ def moved(value: Any) -> Any: ] -# A body file's name as `scenario.schema.json`'s `body_file` pattern states -# it: a bare file name, so it is never absolute and never leaves its directory. -BODY_FILE_NAME = re.compile(r"[a-z0-9]+(-[a-z0-9]+)*\.[a-z0-9]+") +# A body file's name, `scenario.schema.json`'s `body_file` pattern: a bare +# file name, so it is never absolute and never leaves its directory. +BODY_FILE_NAME = re.compile( + _load(PACKAGE_DIR / "scenario.schema.json")["$defs"]["response"]["properties"][ + "body_file" + ]["pattern"] +) def body_path(directory: Path, body_file: str) -> Path: From 7ab92c3aa13d03c4b7cfd551ce94f4f95a03edba Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Fri, 23 Oct 2026 12:03:05 +0200 Subject: [PATCH 33/39] fix(contract): read a whole-valued number as an integer and refuse a boolean part An integer is a JSON number with no fractional part that is not a boolean, as JSON Schema reads it, since a JavaScript client cannot tell `1.0` from `1`. Strict integer members, a manifest definition's `schema_version` among them, and a ref's `definition.schema_version` admit `1.0` and refuse `1.5` and `true`. A choice that names its part by a boolean raises `choice_invalid`, as a boolean option does. --- python/client-contract/README.md | 6 +-- tools/tests/test_validate_client_contract.py | 56 ++++++++++++++++++-- tools/validate_client_contract.py | 14 +++-- 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 2b29aa5..ca57143 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -73,7 +73,7 @@ uv run ty check src/dfo_client_contract ## Strict fields -`strict-fields.json` lists the members a client cannot act without. Each pointer names one property of one component schema, `/components/schemas//properties/`. A `required` entry stays in its schema's `required` list and admits no null, so a client raises `ContractError` when one is missing or null. Every entry is a member some client rule acts on, and a client checks a body only along them: from the body's root it goes down through strict members alone, so a member no client reads goes unchecked, however deep. A `Spec` where no rule reads it, in `resolved.equivalent_readings`, `no_data.flagged_match` or `no_data.alternate_match`, may lack `resolved` or its definition's `identity` and raises nothing, which `answer-nested-specs-unchecked` pins at all three. A strict member that holds a JSON type its schema does not admit raises `ContractError` `contract_violation` at its pointer, as a missing one does, which `answer-candidate-specs-not-a-list` pins with `candidates.specs` as an object. Each item of a strict list, `parts`, `candidates.specs` or `artifacts`, must be an object, and an item of another type raises `contract_violation` at its index pointer, such as `/parts/0/candidates/specs/0`. A member a client reads that no strict pointer names, and that holds a JSON type other than the list, object or string its rule reads, reads as absent, and so does every member of a holder that is not an object; an item of another type in such a list reads as absent too. So `no_data.options` as an object or null offers no option, `mentions` as a string mentions nothing, and a `diagnostics` that is not an object holds no `timed_out` and no warnings. `answer-operations-not-a-list` pins a definite part's `operations` as an object. An item of an `assumptions` or `reading_assumptions` list reads only when it is an object whose `kind`, `binding_ref` and `text` are strings, and an item of an `operations` list only when it is an object whose `verb` and `phrase` are strings; any other item reads as absent. A read item holds its schema's members alone: an assumption's `refs` as its string items when it is a list, and an operation's `over` when it is a string or null and its `target_year` when it is null or a number other than a boolean with no fractional part, read as that integer, so `2020.0` reads and echoes as `2020` and `2020.5` reads as absent. An optional member of another type reads as absent, and a client reads no member the schema does not name. An `enums` entry keeps every listed value, the values a client branches on: the answer kinds, the part statuses and the operation statuses. A client still accepts a value no entry lists. +`strict-fields.json` lists the members a client cannot act without. Each pointer names one property of one component schema, `/components/schemas//properties/`. A `required` entry stays in its schema's `required` list and admits no null, so a client raises `ContractError` when one is missing or null. Every entry is a member some client rule acts on, and a client checks a body only along them: from the body's root it goes down through strict members alone, so a member no client reads goes unchecked, however deep. A `Spec` where no rule reads it, in `resolved.equivalent_readings`, `no_data.flagged_match` or `no_data.alternate_match`, may lack `resolved` or its definition's `identity` and raises nothing, which `answer-nested-specs-unchecked` pins at all three. A strict member that holds a JSON type its schema does not admit raises `ContractError` `contract_violation` at its pointer, as a missing one does, which `answer-candidate-specs-not-a-list` pins with `candidates.specs` as an object. An integer is a JSON number with no fractional part that is not a boolean, as JSON Schema's `integer` reads it, since a JavaScript client cannot tell `1.0` from `1`: a strict member such as a manifest definition's `schema_version`, and a ref's `definition.schema_version`, admit `1.0` and refuse `1.5` and `true`. Each item of a strict list, `parts`, `candidates.specs` or `artifacts`, must be an object, and an item of another type raises `contract_violation` at its index pointer, such as `/parts/0/candidates/specs/0`. A member a client reads that no strict pointer names, and that holds a JSON type other than the list, object or string its rule reads, reads as absent, and so does every member of a holder that is not an object; an item of another type in such a list reads as absent too. So `no_data.options` as an object or null offers no option, `mentions` as a string mentions nothing, and a `diagnostics` that is not an object holds no `timed_out` and no warnings. `answer-operations-not-a-list` pins a definite part's `operations` as an object. An item of an `assumptions` or `reading_assumptions` list reads only when it is an object whose `kind`, `binding_ref` and `text` are strings, and an item of an `operations` list only when it is an object whose `verb` and `phrase` are strings; any other item reads as absent. A read item holds its schema's members alone: an assumption's `refs` as its string items when it is a list, and an operation's `over` when it is a string or null and its `target_year` when it is null or a number other than a boolean with no fractional part, read as that integer, so `2020.0` reads and echoes as `2020` and `2020.5` reads as absent. An optional member of another type reads as absent, and a client reads no member the schema does not name. An `enums` entry keeps every listed value, the values a client branches on: the answer kinds, the part statuses and the operation statuses. A client still accepts a value no entry lists. The answer's `kind` and each part's `status` are the discriminators of their unions in the served document. A search response with no `kind` raises `ContractError`, as a part with no `status` does, although the served document gives `kind` a default and leaves it out of `required`. A part `status` a client does not know raises nothing and makes the part an `unknown` gap. An answer `kind` a client does not know raises `ContractError`, because the client cannot read the answer. A Search response body that is not an object, a `resolution` answer whose `parts` is empty, at pointer `/parts`, since the served schema gives it at least one item, a part whose `status` is not a string, at pointer `/parts//status`, and a definite or candidate spec whose `definition.spec_id` differs from its `spec_id` raise `ContractError` `contract_violation`, in a Search response as in a ref; `search-body-not-an-object`, `answer-empty-parts`, `answer-part-status-not-a-string` and `answer-definition-spec-id-mismatch` pin the four. @@ -160,8 +160,8 @@ The records also fix these client rules: - A fetch of a spec posts its narrowing as the build's `input.scope`, and posts no `scope` when it narrows nothing. A mint takes a layout and no narrowing, so it posts no `scope`. `window` posts `{"kind": "range", "start_year", "end_year"}` for a pair of years, or `{"kind": "all"}` or `{"kind": "latest"}`, and `facets` posts each axis as `{"ref": ...}`, and `facets: {}` names no axis and posts no `facets`. The server's `scope.entities` replaces the spec's whole entity binding, so `entities` posts a whole map: the roles the spec's `definition.identity.entities` binds, with each role the caller names replaced by its refs and each role the caller binds to null dropped. Naming `origin` alone on a spec bound to `origin` and `destination` keeps `destination`. A fetch that names no role, `entities: {}` included, posts no `entities`, so a fetch whose narrowing is all empty posts no `scope`; `fetch-spec-empty-narrowing` pins it. - A built `spec_id` that differs from the posted one, or a spec with no sentence, takes its sentence from Search: the client posts the built definition's `identity` as one `dataset_resubmit` identity entry, with the member's first part as `variable_text`, or `"dataset"` when no answer part names it, and checks the answer's `spec_id` equals the built one. The entry's `entity_groups` holds the spec's `resolved.entity_groups` for each role the built identity binds to the same entities as the spec's definition, so a window or facets narrowing keeps every group and a role the narrowing rebound or dropped loses its group. The entry leaves `entity_groups` out when it keeps no group, as for a resumed operation, whose spec the client does not hold. The server reads a role posted without its group as its members, so a narrowed spec of flows to the least developed countries would read "44 recipients" in place of "the 44 Least Developed Countries". - A dataset of several members puts the `part` column first, then each member's columns in member order, each column once. A column that members hold in different types widens as pyarrow's permissive promotion widens it, and a pair that cannot widen raises `ContractError` `contract_violation`. A member file that already holds a `part` column raises `contract_violation` when members stack. Rows and columns are not derived, so no scenario pins these. The `part` value on a member's rows is the member's `parts` joined by `"; "`, so a member that answers two folded parts reads `"health ODA disbursements; education ODA disbursements"`, or the member's sentence when `parts` is empty. A definite part whose `variable_text` is absent or empty adds nothing to its member's `parts`, which `answer-folded-parts-unnamed` pins. -- A choice names its part by index, by variable text, or by a word that one gap's options mention, and its option, a candidate among them, by index or label. A boolean option is neither an index nor a label. A candidate's label is the `text` of its spec's `resolved.sentence_plan` tokens in the `heading` segment, a token whose `segment` is not a string counted in it, joined and stripped of surrounding white space, or else its `resolved.rendered_sentence`. A candidate with neither a heading nor a sentence has a null label; no scenario pins it, and the validator's tests do. A no_data option's label is matched among the options that mention the word the part was named by. With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. -- A choice raises `InvalidRequestError` `choice_invalid` and makes no request when no gap, or more than one, awaits it, when the named part is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is a boolean, is out of range or matches no label or several. No scenario can hold a boolean option, and the validator's tests pin it. It raises the same when an entry it would post cannot be built: a part with no `variable_text`, or a part of a status the client does not know that has no `restatement`. A chosen option whose `data_query` holds other than one part raises `ContractError`, and so does a chosen option with no `data_query`, in a one-part answer as in a several-part one, before any request. `choose-refused-shared-label`, `choose-refused-unknown-candidate-label`, `choose-refused-shared-candidate-label`, `choose-refused-part-without-variable-text`, `choose-refused-unknown-status`, `choose-option-two-part-query` and `choose-option-without-data-query` pin these, and `choose-candidate-by-label` pins a candidate chosen by its label. +- A choice names its part by index, by variable text, or by a word that one gap's options mention, and its option, a candidate among them, by index or label. A boolean part or option is neither an index nor a label. A candidate's label is the `text` of its spec's `resolved.sentence_plan` tokens in the `heading` segment, a token whose `segment` is not a string counted in it, joined and stripped of surrounding white space, or else its `resolved.rendered_sentence`. A candidate with neither a heading nor a sentence has a null label; no scenario pins it, and the validator's tests do. A no_data option's label is matched among the options that mention the word the part was named by. With no part named, exactly one gap must await a choice: a `choice` gap, or any gap with options. +- A choice raises `InvalidRequestError` `choice_invalid` and makes no request when no gap, or more than one, awaits it, when the part is named by a boolean, is unknown, names more than one part or already has a reading, when the gap offers no options, or when the option is a boolean, is out of range or matches no label or several. No scenario can hold a boolean part or option, and the validator's tests pin both. It raises the same when an entry it would post cannot be built: a part with no `variable_text`, or a part of a status the client does not know that has no `restatement`. A chosen option whose `data_query` holds other than one part raises `ContractError`, and so does a chosen option with no `data_query`, in a one-part answer as in a several-part one, before any request. `choose-refused-shared-label`, `choose-refused-unknown-candidate-label`, `choose-refused-shared-candidate-label`, `choose-refused-part-without-variable-text`, `choose-refused-unknown-status`, `choose-option-two-part-query` and `choose-option-without-data-query` pin these, and `choose-candidate-by-label` pins a candidate chosen by its label. - Every pick of a candidate asks Search for the picked answer, and no client builds it locally. In a one-part answer the pick posts `dataset_resubmit`, without `raw_query`, with one identity entry: the candidate's identity and `entity_groups`, and the part's `variable_text`, `separate` and `operations` as below. The picked answer, its sentence with any "Assumed: …" clause, and its assumptions are Search's response. A choice of a no_data option in a one-part answer posts the option's `data_query` as the input. - In a several-part answer a choice posts `dataset_resubmit`, without `raw_query`, with one entry per part in part order. The chosen candidate posts an identity entry with its identity and `entity_groups`, and the chosen option its `data_query`'s one part as a parsed entry. A definite part posts an identity entry with its spec's identity and `entity_groups`. A candidates part left alone posts a `candidates` entry: its candidate set in the server's order, each with its identity and `entity_groups`, and its `ordering` and `truncated` echoed. The server cannot recompute that order, because it rests on the first answer's bind election and availability reads, and a parsed entry would cost an LLM bind. Any other part posts its `restatement` as a parsed entry, or a placeholder entry with its no_data `reason` or unsupported `code` when it has none. Every entry but a parsed one carries the part's `variable_text`, `separate` when true and `operations` when any of the part's operations reads. `entity_groups` is left out when the spec has none. `choose-echoes-separate-and-operations` pins the echo on a definite part's entry, and `choose-posts-unsupported-placeholder` an unsupported part's placeholder. - Each identity a choice posts echoes its reading's assumptions as `assumptions`: the chosen candidate's entry carries its part's `reading_assumptions` under the candidate's `spec_id`, a definite part's entry carries the part's `assumptions`, and each candidate of a `candidates` entry carries its own `reading_assumptions` entry. Search then states the echoed items that still hold, so the picked answer states what that reading assumed. `[]` states none. An identity with no `assumptions` reads as a fresh request, so a client that holds no list for a reading, from a part that carries no `assumptions` or `reading_assumptions`, posts none. The identity entry that asks for a built sentence posts no `assumptions`, since it reads only the spec's own `rendered_sentence`. An echoed `operations` or `assumptions` list posts exactly the items a client reads under Strict fields, in order, each built from the members it read: an optional member that read as absent is left out, and a `refs` list posts its string items. An `assumptions` list with no item read posts `[]`, and an `operations` list with none is left out. The item rule checks JSON types alone, so the echo posts what a client read, and the server still checks it against its own value constraints: the `verb` enum, the lengths of `phrase` and `text`, and at most one item in `refs`. `choose-echo-drops-malformed-items` pins both lists. diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index 17fbc58..c824b32 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -2037,15 +2037,63 @@ def _candidate(**resolved: Any) -> dict[str, Any]: ], ids=["candidate", "no-data-option"], ) -@pytest.mark.parametrize("option", [True, False]) -def test_a_boolean_option_is_neither_an_index_nor_a_label( - part: dict[str, Any], option: bool +@pytest.mark.parametrize( + ("key", "option"), + [(0, True), (0, False), (True, 0), (False, 0)], + ids=["option-true", "option-false", "part-true", "part-false"], +) +def test_a_boolean_part_or_option_is_neither_an_index_nor_a_label( + part: dict[str, Any], key: int | bool, option: int | bool ) -> None: + """Each boolean would name a gap or option as 0 or 1 if read as an index.""" with pytest.raises(validator.ClientError) as raised: - validator.choice_for(_answer(part), {}, 0, option) + validator.choice_for(_answer(part, part), {}, key, option) assert raised.value.code == "choice_invalid" +@pytest.mark.parametrize( + ("value", "kind"), + [(1, "integer"), (1.0, "integer"), (1.5, "number"), (True, "boolean")], + ids=["integer", "whole-float", "fractional", "boolean"], +) +def test_a_number_with_no_fractional_part_is_an_integer(value: Any, kind: str) -> None: + assert validator.json_type(value) == kind + + +@pytest.mark.parametrize( + ("schema_version", "gaps"), + [ + (1, []), + (1.0, []), + (1.5, ["/definition/schema_version"]), + (True, ["/definition/schema_version"]), + ], + ids=["integer", "whole-float", "fractional", "boolean"], +) +def test_a_manifest_schema_version_is_an_integer( + schema_version: Any, gaps: list[str] +) -> None: + """The oracle's strict check and the ref schema agree on what an integer + `schema_version` is.""" + package = validator.PACKAGE_DIR + openapi = json.loads((package / "served" / "openapi.json").read_text("utf-8")) + strict = json.loads((package / "strict-fields.json").read_text("utf-8")) + record = json.loads((package / _FETCH).read_text("utf-8")) + manifest = copy.deepcopy(record["exchanges"][0]["response"]["json"]) + manifest["definition"]["schema_version"] = schema_version + members = validator._strict_members(strict) + schema = {"$ref": "#/components/schemas/Manifest"} + assert validator.strict_gaps(openapi, members, schema, manifest) == gaps + + ref = json.loads((package / "refs" / "ref-one-member.json").read_text("utf-8")) + ref["ref"]["members"][0]["spec"]["definition"]["schema_version"] = schema_version + ref_schema = json.loads((package / "dataset-ref.schema.json").read_text("utf-8")) + accepted = validator.jsonschema.Draft202012Validator(ref_schema).is_valid( + ref["ref"] + ) + assert accepted == (not gaps) + + @pytest.mark.parametrize( ("resolved", "label"), [ diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index 56ab923..64a2174 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -1221,8 +1221,10 @@ def choice_for( candidates part's options are its candidates, chosen by index or by `candidate_label`. Any other gap's are its no_data options, chosen by index or label, a label scoped to the options that mention the word the - part was named by. A label must match exactly one option, and a boolean - option is neither an index nor a label.""" + part was named by. A label must match exactly one option. A boolean part + or option is neither an index nor a label.""" + if isinstance(part, bool) or isinstance(option, bool): + raise _refuse() gaps = answer_gaps(answer, kinds) gap_parts = {gap["part"] for gap in gaps} mention = None @@ -1249,7 +1251,7 @@ def choice_for( if len(named) != 1: raise _refuse() index = named[0] - if index not in gap_parts or isinstance(option, bool): + if index not in gap_parts: raise _refuse() chosen = answer.parts[index] @@ -1597,10 +1599,12 @@ def _strict_members(strict: dict[str, Any]) -> dict[str, list[str]]: def json_type(value: Any) -> str: - """The JSON type of a parsed value, an integer's as `integer`.""" + """The JSON type of a parsed value, a number with no fractional part as + `integer`, as JSON Schema reads it, so `1.0` is an integer, as it is to a + client whose JSON parser keeps no separate integer type.""" if isinstance(value, bool): return "boolean" - if isinstance(value, int): + if isinstance(value, int) or (isinstance(value, float) and value.is_integer()): return "integer" for kind, name in ((dict, "object"), (list, "array"), (str, "string")): if isinstance(value, kind): From 4ef22b70d0f11af87ed9a78afda841ab66f6230c Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Fri, 23 Oct 2026 20:57:00 +0200 Subject: [PATCH 34/39] feat(client-contract): read the newest plain build and record against dfo-apis 035d29cd0 (#15) * feat(client-contract): read the newest plain build and record against dfo-apis c7543c9d6 "Newest version" is the first listed version with no base_content_version, read across every versions page (`validate_client_contract.newest_plain`), so a derived groupby rendering listed first is skipped. The served document and all 31 recorded scenarios are captured at dfo-apis c7543c9d6, whose versions page carries `enrichment_stamp`, and the 87 synthetic scenarios are derived again. Twelve scenario questions are reworded where Search now answers the old wording with another shape: the candidates questions read mortality in Kenya, the async build reads ODA disbursements by sector, and the place question names a year. * fix(client-contract): record at dfo-apis 035d29cd0 within a size budget and check refs against their scenarios The async build questions read one variable over donor and recipient groups, so the finished operation's manifest lists one variable and the scenarios hold 13,080,568 bytes, under the 16,000,000-byte budget the validator and the record run now enforce (`validate_client_contract.SCENARIOS_BUDGET`). A ref whose record holds members names the scenario that serves them, and the validator checks each member's spec, content version, sentence and digest against it (`_served_by`). `newest_plain` reads the whole versions page before it takes a plain version. The validator tests hard-link their package copy. --- python/client-contract/CHANGELOG.md | 6 +- python/client-contract/README.md | 6 +- .../refs/ref-answer-member.json | 3 +- .../refs/ref-bare-definition-rejected.json | 3 +- .../ref-definition-extra-member-rejected.json | 3 +- ...-definition-spec-id-mismatch-rejected.json | 3 +- ...-definition-without-identity-rejected.json | 3 +- ...ition-without-schema-version-rejected.json | 3 +- .../refs/ref-frame-layout.json | 15 +- .../refs/ref-one-member.json | 3 +- .../refs/ref-repeated-spec-id-rejected.json | 5 +- .../refs/ref-server-rendering-rejected.json | 5 +- .../rules/cache-layout.json | 4 +- .../dfo_client_contract/scenario.schema.json | 2 +- .../answer-candidate-specs-not-a-list.json | 2449 +- .../answer-candidates-choose-fetch.json | 3241 ++- .../answer-candidates-choose-fetch.parquet | Bin 4800 -> 5000 bytes .../scenarios/answer-catalogue.json | 24 +- .../scenarios/answer-declined.json | 26 +- .../scenarios/answer-definite-fetch.json | 535 +- .../scenarios/answer-definite-fetch.parquet | Bin 9785 -> 9842 bytes .../answer-definition-spec-id-mismatch.json | 337 +- .../scenarios/answer-empty-parts.json | 27 +- .../answer-folded-parts-unnamed.json | 1280 +- .../scenarios/answer-mixed-fetch-partial.json | 248 +- .../answer-mixed-fetch-partial.parquet | Bin 6025 -> 6095 bytes .../scenarios/answer-mixed-fetch-raises.json | 78 +- .../answer-nested-specs-unchecked.json | 1335 +- .../answer-operations-not-a-list.json | 529 +- .../answer-part-status-not-a-string.json | 72 +- .../answer-several-readings-folded.json | 1296 +- .../answer-several-readings-folded.parquet | Bin 16150 -> 16208 bytes .../answer-spec-without-identity.json | 337 +- .../answer-spec-without-resolved.json | 55 +- .../scenarios/answer-timed-out.json | 68 +- .../scenarios/answer-unknown-enum-value.json | 34 +- .../scenarios/answer-unknown-kind.json | 36 +- .../scenarios/answer-unknown-part-status.json | 72 +- .../scenarios/answer-unsupported-part.json | 72 +- .../choose-candidate-assumed-reading.json | 2847 +- .../scenarios/choose-candidate-by-label.json | 2849 +- .../choose-candidate-echoes-assumptions.json | 5199 ++-- .../choose-candidate-two-parts-2.parquet | Bin 10503 -> 10233 bytes .../scenarios/choose-candidate-two-parts.json | 23874 ++++++++-------- .../choose-candidate-two-parts.parquet | Bin 9453 -> 9259 bytes .../choose-echo-drops-malformed-items.json | 5193 ++-- ...choose-echoes-separate-and-operations.json | 10451 +++---- .../choose-option-beside-definite.json | 10459 +++---- .../choose-option-two-part-query.json | 36 +- .../choose-option-without-data-query.json | 34 +- .../scenarios/choose-part-by-mention.json | 1332 +- .../scenarios/choose-place-one-part.json | 1329 +- .../scenarios/choose-place-two-parts.json | 92 +- .../choose-posts-unsupported-placeholder.json | 8153 +++--- .../choose-refused-answered-part.json | 70 +- ...hoose-refused-mention-names-two-parts.json | 25 +- .../scenarios/choose-refused-no-choice.json | 335 +- .../scenarios/choose-refused-no-options.json | 32 +- .../choose-refused-option-out-of-range.json | 2451 +- ...se-refused-part-without-variable-text.json | 2609 +- ...choose-refused-shared-candidate-label.json | 2375 +- .../choose-refused-shared-label.json | 31 +- .../scenarios/choose-refused-two-choices.json | 25 +- ...hoose-refused-unknown-candidate-label.json | 2451 +- .../choose-refused-unknown-label.json | 34 +- .../choose-refused-unknown-part.json | 70 +- .../choose-refused-unknown-status.json | 2599 +- .../fetch-frame-several-readings.json | 1119 +- .../scenarios/fetch-null-member.json | 529 +- .../fetch-partial-nothing-answered.json | 36 +- .../fetch-ref-artifact-unlisted.json | 224 +- .../fetch-ref-expired-file-selector.json | 229 +- .../fetch-ref-expired-newer-version.json | 180 +- .../fetch-ref-expired-not-reproducible.json | 36 +- .../fetch-ref-expired-rebuild-other-spec.json | 182 +- ...etch-ref-expired-rebuild-same-version.json | 198 +- .../scenarios/fetch-ref-newest-version.json | 42 +- .../fetch-ref-signed-url-refused-twice.json | 229 +- .../fetch-ref-signed-url-refused.json | 238 +- .../scenarios/fetch-ref-unknown-version.json | 18 +- .../scenarios/fetch-ref.json | 235 +- .../scenarios/fetch-ref.parquet | Bin 9785 -> 9842 bytes .../scenarios/fetch-renamed-strict-field.json | 513 +- .../scenarios/fetch-retry-after-504.json | 529 +- .../scenarios/fetch-spec-503-then-504.json | 101 +- .../scenarios/fetch-spec-504-retry-after.json | 101 +- .../scenarios/fetch-spec-async-build.json | 1224 +- .../scenarios/fetch-spec-digest-mismatch.json | 109 +- .../scenarios/fetch-spec-empty-narrowing.json | 101 +- .../scenarios/fetch-spec-entity-dropped.json | 243 +- .../fetch-spec-entity-dropped.parquet | Bin 13341 -> 13398 bytes .../scenarios/fetch-spec-entity-rebound.json | 255 +- .../fetch-spec-entity-rebound.parquet | Bin 9059 -> 9116 bytes .../fetch-spec-files-route-no-content.json | 91 +- .../fetch-spec-files-route-serves-file.json | 95 +- ...h-spec-files-route-temporary-redirect.json | 93 +- .../fetch-spec-foreign-artifact-url.json | 87 +- .../scenarios/fetch-spec-frame-layout.json | 129 +- .../scenarios/fetch-spec-group-narrowed.json | 373 +- .../fetch-spec-group-narrowed.parquet | Bin 8716 -> 8777 bytes .../fetch-spec-group-origin-rebound.json | 369 +- .../fetch-spec-group-origin-rebound.parquet | Bin 21027 -> 21088 bytes .../scenarios/fetch-spec-known-sentence.json | 107 +- .../fetch-spec-known-sentence.parquet | Bin 9541 -> 9599 bytes .../fetch-spec-manifest-without-identity.json | 87 +- ...-spec-manifest-without-schema-version.json | 87 +- .../scenarios/fetch-spec-narrowed.json | 259 +- .../scenarios/fetch-spec-narrowed.parquet | Bin 9541 -> 9599 bytes ...tch-spec-operation-failed-resubmitted.json | 1424 +- .../scenarios/fetch-spec-poll-not-found.json | 392 +- ...-spec-poll-rate-limited-not-retryable.json | 392 +- .../fetch-spec-poll-rate-limited.json | 1226 +- .../fetch-spec-poll-refused-backoff.json | 1190 +- .../fetch-spec-poll-refused-retry-after.json | 1226 +- .../scenarios/fetch-spec-poll-refused.json | 1230 +- .../fetch-spec-relative-location.json | 97 +- .../scenarios/fetch-spec-request-invalid.json | 14 +- .../fetch-spec-resubmit-other-spec.json | 239 +- .../fetch-spec-same-origin-artifact-url.json | 103 +- .../fetch-spec-signed-fetch-partial.json | 113 +- .../fetch-spec-storage-artifact-url.json | 87 +- .../scenarios/fetch-spec-strict-warning.json | 83 +- .../scenarios/fetch-strict-info-notice.json | 529 +- .../scenarios/mint-async-build.json | 1232 +- .../scenarios/mint-async-build.parquet | Bin 913395 -> 473679 bytes .../newest-version-unreadable-page.json | 36 +- .../operation-failed-without-error.json | 30 +- .../scenarios/operation-resume.json | 7409 +++-- .../scenarios/operation-resume.parquet | Bin 1031059 -> 489647 bytes .../resubmit-candidates-sibling.json | 5301 ++-- ...ubmit-placeholder-without-restatement.json | 3220 ++- .../scenarios/search-body-not-an-object.json | 36 +- .../scenarios/search-no-json-body.json | 4 +- .../scenarios/search-place-ambiguous.json | 40 +- .../scenarios/search-proxy-rate-limited.json | 36 +- .../scenarios/search-proxy-unavailable.json | 8 +- .../search-refused-without-code.json | 4 +- .../scenarios/search-retry-after-503.json | 36 +- .../scenarios/search-server-warning.json | 102 +- .../scenarios/search-sunset-warning.json | 68 +- .../search-two-parts-place-ambiguous.json | 31 +- .../scenarios/search-unauthorized.json | 4 +- .../scenarios/search-warning-top5.json | 251 +- .../scenarios/search-warning-top5.parquet | Bin 10828 -> 10927 bytes .../dfo_client_contract/served/SOURCE.json | 2 +- .../dfo_client_contract/served/openapi.json | 119 +- tools/capture_client_contract.py | 82 +- tools/tests/test_validate_client_contract.py | 133 +- tools/validate_client_contract.py | 148 +- 149 files changed, 69749 insertions(+), 62546 deletions(-) diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index 741bade..52d87a2 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -7,17 +7,17 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be ### Added - Package scaffolding (uv, ruff, ty, pytest). -- `served/openapi.json`, the composed dfo-apis app's OpenAPI document, and `served/SOURCE.json`, naming dfo-apis commit `635943e03a297f686ca5af32f6d027181d1971d4`. +- `served/openapi.json`, the composed dfo-apis app's OpenAPI document, and `served/SOURCE.json`, naming dfo-apis commit `035d29cd05fb31d7cb47cfb33197d4002f773df6`. - `strict-fields.json` and its schema: 29 members that stay required and non-nullable, each one a client reads, and the answer kinds, part statuses and operation statuses the clients branch on. - `actions.json` and its schema: the caller's next step for each of the 101 active refusal codes on `problem_details` or `no_data_reason`, with the gap kind of each no_data reason. - The status fallback for a refusal whose code has no row: 400 and 422 to `InvalidRequestError`, 401 to `AuthenticationError`, 403 to `PermissionDeniedError`, 404 and 410 to `NotFoundError`, 408 to `DfoTimeoutError`, 429 to `RateLimitError`, and any other 4xx or 5xx to `InvalidRequestError` or `ServerError`. -- `scenario.schema.json`, the scenario record, and 118 scenarios: 31 recorded against the composed dfo-apis app at `635943e03`, and 87 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 2,105,201 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, a part without variable_text, an unknown status without a restatement, a shared label, a one-part option whose data_query holds two parts, the separate and operations echo, an unsupported part's placeholder, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a cut-off build retried after its Retry-After, a build refused 504 then 503 and one refused 503 then 504, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, a signed URL refused on both rounds, a relative files-route Location, an artifact url on a foreign origin, on the storage host and absolute on the API's origin, a manifest definition without identity or schema_version, a Search spec without identity or resolved, nested specs no rule reads, an empty parts list, a Search body that is not an object, a codeless 503 problem document that is not retryable, a 401, an identity resubmit answering another spec, a part whose status is not a string, a Search spec whose definition names another spec_id, a Search response with no JSON body, an option with no data_query, empty entities and facets, a Sunset header issued once, `x-dfo-warning` messages and a Deprecation and Sunset pair, an unreadable versions page, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, 503 polls retried within the budget an answered poll restores, a 404 poll that raises, a failed operation posted again, a failed operation with no error, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route. +- `scenario.schema.json`, the scenario record, and 118 scenarios: 31 recorded against the deployed dfo-apis dev app at `035d29cd0`, and 87 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 1,124,502 bytes and records and bodies together 13,080,568 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, a part without variable_text, an unknown status without a restatement, a shared label, a one-part option whose data_query holds two parts, the separate and operations echo, an unsupported part's placeholder, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a cut-off build retried after its Retry-After, a build refused 504 then 503 and one refused 503 then 504, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, a signed URL refused on both rounds, a relative files-route Location, an artifact url on a foreign origin, on the storage host and absolute on the API's origin, a manifest definition without identity or schema_version, a Search spec without identity or resolved, nested specs no rule reads, an empty parts list, a Search body that is not an object, a codeless 503 problem document that is not retryable, a 401, an identity resubmit answering another spec, a part whose status is not a string, a Search spec whose definition names another spec_id, a Search response with no JSON body, an option with no data_query, empty entities and facets, a Sunset header issued once, `x-dfo-warning` messages and a Deprecation and Sunset pair, an unreadable versions page, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, 503 polls retried within the budget an answered poll restores, a 404 poll that raises, a failed operation posted again, a failed operation with no error, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route: the first version it lists with no `base_content_version`, the newest plain build, so a derived version listed before it is skipped. - `client-codes.json` and its schema: the 17 codes a client sets on the errors it raises itself, each with its error class, retryable flag and condition, disjoint from `actions.json` and `registries/codes.json`, and the `client_codes()` and `client_codes_schema()` accessors. Every scenario error the client raises itself carries its code, and `refusal_without_code` names a refusal whose body carries no code. - `proxy-codes.json` and its schema, the website proxy's `rate_limited` and `transient_unavailable` codes with their statuses, and `warning-codes.json` and its schema, the 5 codes a client sets on the warnings it issues itself, with the `proxy_codes()` and `warning_codes()` accessors. - Error outcomes give the error's `trace_id`, the body's, else the `x-dfo-trace-id` header's, else null. Scenario outcomes give `retry_waits`, the waits before each retry, and `warnings`, the warning codes a step's responses issued. Scenario steps take no `timeout`. - `dataset-ref.schema.json`, the frozen `DatasetRef` format, with accepted and rejected examples. - `tools/capture_client_contract.py`, which captures `served/openapi.json` from a dfo-apis checkout in process and records the scenarios against a base URL, dev by default, or with `record --offline` derives their outcomes again from the records with no request. A local app's signed URLs are written as the storage URLs a deployment signs. -- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, checks `client-codes.json` against them and against the reasons the key-lookup rule raises, and checks each scenario's `expect` against the outcomes its exchanges, `actions.json` and `client-codes.json` give, each Search request against the input its steps derive, a sentence lookup's `entity_groups` included, each build's `input.scope` against the narrowing its step names over the spec's bound roles, each build's options against its layout, each Search request's whole body, each download against its artifact's digest, each recorded scenario's commit against `served/SOURCE.json`, each proxy refusal's code against `proxy-codes.json`, and each absolute URL against the storage host. A record that ends a run of retries while a retry remains does not fit. The outcomes include each long build's operation id, poll waits and resubmissions, and a `VersionUnavailableError`'s newest version. +- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, checks `client-codes.json` against them and against the reasons the key-lookup rule raises, and checks each scenario's `expect` against the outcomes its exchanges, `actions.json` and `client-codes.json` give, each Search request against the input its steps derive, a sentence lookup's `entity_groups` included, each build's `input.scope` against the narrowing its step names over the spec's bound roles, each build's options against its layout, each Search request's whole body, each download against its artifact's digest, each recorded scenario's commit against `served/SOURCE.json`, each proxy refusal's code against `proxy-codes.json`, and each absolute URL against the storage host, each ref example's members against the dataset members and downloaded files of the scenario it names, and the scenarios directory against a 16,000,000-byte budget for records and bodies together. A record that ends a run of retries while a retry remains does not fit. The outcomes include each long build's operation id, poll waits and resubmissions, and a `VersionUnavailableError`'s newest version. - The client rules and their vectors: the credentials path and file format, the key lookup order, with an empty `api_key` refused as `key_empty` and an empty profile key as `profile_without_key`, the key format check, and the cache directory and layout. [unreleased]: https://github.com/DevelopmentFinanceObservatory/spec-kit/commits/main/python diff --git a/python/client-contract/README.md b/python/client-contract/README.md index ca57143..711d150 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -175,7 +175,7 @@ The records also fix these client rules: - A declined or catalogue answer is not complete, and fetching it raises `DeclinedError`. - Fetching an answer with a gap raises `IncompleteAnswerError` before any request, unless the fetch is partial and some part has a reading. - A fetch of an answer issues one `SearchWarning` when a definite part has an operation Search did not run, a departure, or a warning at severity `warn` or `degraded` with a `message`, or the answer's `diagnostics.warnings` holds such a warning. An `info` warning, a warning with no `message`, and an operation that does not read under Strict fields issue nothing. Each way is one line a client shows: `Not done: ()` coded by the verb, the phrase quoted as a JSON string that keeps non-ASCII characters as they are, the departure's `text` coded by its code, or `Note: ` coded by the warning's code, in part order with the diagnostics warnings last, and ways that show the same line count once, under the first one's code. A strict fetch raises the `SearchWarning` before any build, with the code of its one line, or a null code when there are several lines. A strict fetch raises it before the `frame` layout's several-member check. -- A ref's version is found in this order: the snapshot route and the files route at the stored digest; the file selector, `GET /datasets/{id}/{content_version}/file` with the ref's rendering as the query; and a build of the ref's spec in the ref's rendering, which must answer the ref's `spec_id` and the same `content_version`. Both recovery steps keep the ref's identity, so a recovered member carries the ref's `spec_id` and `content_version`: a snapshot manifest whose `definition.spec_id` or `content_version` is not the ref's, or a rebuild manifest whose `definition.spec_id` is not the ref's, raises `ContractError` `contract_violation` before any download, which `fetch-ref-expired-rebuild-other-spec` pins for the rebuild. A snapshot refusal other than `artifact_expired` ends the lookup, so `snapshot_not_found` raises `NotFoundError` with no further request. A files route or selector refusal of `artifact_expired`, `artifact_not_found` or `not_found` takes the next step, and a selector file of another digest is not the stored file. A snapshot manifest whose artifacts list no artifact of the ref member's digest sends the client to the selector in the ref member's own rendering, and a file that hashes to that digest gives the dataset, which `fetch-ref-artifact-unlisted` pins. A rebuild that answers another version, or that raises `InvalidRequestError`, `NotFoundError` or `VersionUnavailableError`, ends in `VersionUnavailableError` with the first refusal's code, or `version_unavailable` when nothing refused. Its `newest_version` is the version the rebuild answered, or else the newest stored version, which `GET /datasets/{id}/versions?limit=1` lists alone, as a `newest_version` step finds it, since the route lists versions newest first and needs no key; or null when that route lists none or refuses with `NotFoundError`. Any other refusal of the versions route raises, and a page whose `versions` is not a list of versions each with a `content_version` raises `ContractError` `contract_violation`, which `newest-version-unreadable-page` pins. +- A ref's version is found in this order: the snapshot route and the files route at the stored digest; the file selector, `GET /datasets/{id}/{content_version}/file` with the ref's rendering as the query; and a build of the ref's spec in the ref's rendering, which must answer the ref's `spec_id` and the same `content_version`. Both recovery steps keep the ref's identity, so a recovered member carries the ref's `spec_id` and `content_version`: a snapshot manifest whose `definition.spec_id` or `content_version` is not the ref's, or a rebuild manifest whose `definition.spec_id` is not the ref's, raises `ContractError` `contract_violation` before any download, which `fetch-ref-expired-rebuild-other-spec` pins for the rebuild. A snapshot refusal other than `artifact_expired` ends the lookup, so `snapshot_not_found` raises `NotFoundError` with no further request. A files route or selector refusal of `artifact_expired`, `artifact_not_found` or `not_found` takes the next step, and a selector file of another digest is not the stored file. A snapshot manifest whose artifacts list no artifact of the ref member's digest sends the client to the selector in the ref member's own rendering, and a file that hashes to that digest gives the dataset, which `fetch-ref-artifact-unlisted` pins. A rebuild that answers another version, or that raises `InvalidRequestError`, `NotFoundError` or `VersionUnavailableError`, ends in `VersionUnavailableError` with the first refusal's code, or `version_unavailable` when nothing refused. Its `newest_version` is the version the rebuild answered, or else the newest stored version, as a `newest_version` step finds it: the first version `GET /datasets/{id}/versions?limit=100` lists with a null `base_content_version`, the newest plain build, read page by page through `&cursor=` with each page's `next_cursor` until one is listed. The route lists versions newest first and needs no key. A version with a `base_content_version` is derived from a plain build, a groupby collapse or a party-totals cut, and is skipped, which `fetch-ref-newest-version` pins. The newest version is null when the list ends without a plain version or the route refuses with `NotFoundError`. Any other refusal of the versions route raises, and a page whose `versions` is not a list of versions each with a `content_version` and a `base_content_version` that is a string or null, or whose `next_cursor` is neither a string nor null, raises `ContractError` `contract_violation`, which `newest-version-unreadable-page` pins. - A build answers 200 with the manifest, or 202 with an operation the client polls at `/datasets/operations/{operation_id}`, the id of the operation it holds. A mint's build answers 202. A record whose mint answers 200 fits no mint step. Before each poll it waits the `Retry-After` of the refusal that answered the last poll, whatever its status, as every retry of a refused request waits; else the last operation resource's `retry_after_ms`, else the `Retry-After` of the last answered poll, the response that carried that resource, else a backoff of 1, 2, 4 and then 8 seconds that advances one step each time it is used, a poll after a refusal included. - A retryable 429 poll spends no retry, and a 429 whose body says it is not retryable raises at once, as a refusal's `retryable` outranks its status, which `fetch-spec-poll-rate-limited-not-retryable` pins. Any other retryable refused poll spends one of the two retries, which a poll that answers restores, and a refusal that is not retryable raises. `fetch-spec-poll-refused` pins two 503s polled again after an answered poll, `fetch-spec-poll-refused-backoff` a 503 with no `Retry-After` among polls no response paces, after which the backoff advances, `fetch-spec-poll-refused-retry-after` a 503 whose `Retry-After` paces the next poll, and `fetch-spec-poll-not-found` a 404 that raises at once. A poll that answers a failed operation whose error is retryable posts the same build once more and polls the operation it starts; a second failure, an error that is not retryable, and a resumed operation, whose build request the client does not hold, raise the operation's error. A refused poll whose code is `operation_failed` is a failed operation with that error. A failed operation whose resource carries no `error` raises `ServerError` with `operation_failed`, retryable by status 500 as a refusal without a document is, which `operation-failed-without-error` pins. A 202 or resumed operation that already reads `failed` raises its error before any poll. - Any other refusal is retried when it is retryable: as a problem document's `retryable` says, or the website proxy's `retry` of `retry_after_delay`, else when its status is 408, 429, 500, 502, 503 or 504. A client makes two retries by default, and the scenarios assume that default. A build's POST shares those two retries with every other refusal of it, and once a 504 cuts the build off the client posts it once more only, whatever that post answers: a build refused 504 then 503 raises the 503, a build refused 503 then 504 is posted once more after the 504, and a second 504 raises. `fetch-spec-504-then-503`, `fetch-spec-503-then-504` and `fetch-spec-504-twice` pin the three. A refusal that is not retryable, or one past the retries, raises its error. @@ -207,11 +207,11 @@ Each record names the commit in the responses' `x-dfo-commit` header, and the ru uv run tools/capture_client_contract.py record --base-url http://127.0.0.1:8083/api ``` -A record's `origin.base_url` is the base URL the run was given, a local app's included. A local app's signed URL, which its launcher serves at `/__e2e__/blob/{bucket}/{object}` on the API's origin, is written as `https://storage.googleapis.com/{bucket}/{object}` with its query redacted, as a deployment signs it, because a production download is cross-origin and the client sends no key there; the run, like the validator, refuses a record holding any absolute URL other than such a storage URL, or a `location` under the base URL, so a local app's host under another name or port is refused too. A server answers a version it has built inline, so `mint-async-build` and `operation-resume` each need a spec just above the 100,000-row sync budget that the server has not built: the DAC2a recipient flows from 2018 to 2024 for the mint, and from 2017 to 2024 for the resumed operation. A local recording therefore starts on a fresh datasets database with `DATASETS_SYNC_BUDGET_ROWS=100000`. `--scenarios-dir` writes records outside the package, unvalidated. +A record's `origin.base_url` is the base URL the run was given, a local app's included. A local app's signed URL, which its launcher serves at `/__e2e__/blob/{bucket}/{object}` on the API's origin, is written as `https://storage.googleapis.com/{bucket}/{object}` with its query redacted, as a deployment signs it, because a production download is cross-origin and the client sends no key there; the run, like the validator, refuses a record holding any absolute URL other than such a storage URL, or a `location` under the base URL, so a local app's host under another name or port is refused too. A server answers a version it has built inline, so `mint-async-build` and `operation-resume` each need a spec just above the 100,000-row sync budget that the server has not built: ODA disbursements from the 32 DAC countries to the 133 G77 countries from 1963 to 2024 for the mint, and from the 38 OECD countries to the G77 countries from 1966 to 2024 for the resumed operation, each one variable over some 3,700 donor and recipient pairs, so the done manifest stays small. A local recording therefore starts on a fresh datasets database with `DATASETS_SYNC_BUDGET_ROWS=100000`. `--scenarios-dir` writes records outside the package, unvalidated. ## DatasetRef -`dataset-ref.schema.json` is the frozen format a client writes for `data.ref` and reads back in any language: `format_version: 1` and one or more `members`, each `{parts, sentence, spec: {spec_id, definition}, content_version, artifact: {digest, rendering}}`. `parts` holds the variable text of each answer part the member answers, in query order, and is empty for a spec fetched outside an answer. `definition` is the server's definition unmodified, so it holds the `schema_version`, `spec_id` and `identity` the served `CanonicalDefinition` requires and no other member, and a rebuild posts it as it is. The format takes any integer `schema_version` and leaves the version to the server, which checks it when a rebuild posts the definition. `rendering` is the selector a client matches an artifact on, `{format, bundle}` with `layout: "frame"` for the frame layout, never the server's rendering object. Beyond the schema, each member's `definition.spec_id` equals its `spec.spec_id`, and members hold distinct `spec_id`s. `ref-bare-definition-rejected`, `ref-definition-without-identity-rejected` and `ref-definition-without-schema-version-rejected` pin the definition's required members, and `ref-definition-extra-member-rejected` a member it does not admit. `refs/` holds accepted examples and rejected ones, each `{format_version, name, description, ref}` with `expect: "accept"` or `error`, `{by: "schema"}` or `{by: "rule", reason}`, the reason `definition_spec_id_mismatch` or `repeated_spec_id`. +`dataset-ref.schema.json` is the frozen format a client writes for `data.ref` and reads back in any language: `format_version: 1` and one or more `members`, each `{parts, sentence, spec: {spec_id, definition}, content_version, artifact: {digest, rendering}}`. `parts` holds the variable text of each answer part the member answers, in query order, and is empty for a spec fetched outside an answer. `definition` is the server's definition unmodified, so it holds the `schema_version`, `spec_id` and `identity` the served `CanonicalDefinition` requires and no other member, and a rebuild posts it as it is. The format takes any integer `schema_version` and leaves the version to the server, which checks it when a rebuild posts the definition. `rendering` is the selector a client matches an artifact on, `{format, bundle}` with `layout: "frame"` for the frame layout, never the server's rendering object. Beyond the schema, each member's `definition.spec_id` equals its `spec.spec_id`, and members hold distinct `spec_id`s. `ref-bare-definition-rejected`, `ref-definition-without-identity-rejected` and `ref-definition-without-schema-version-rejected` pin the definition's required members, and `ref-definition-extra-member-rejected` a member it does not admit. `refs/` holds accepted examples and rejected ones, each `{format_version, name, description, scenario, ref}` with `expect: "accept"` or `error`, `{by: "schema"}` or `{by: "rule", reason}`, the reason `definition_spec_id_mismatch` or `repeated_spec_id`. `scenario` names the recorded scenario that serves the ref's members, and is left out of a ref with no members. Each member's `spec_id`, `content_version` and `sentence` are those of a dataset member of that scenario, and its artifact digest is the digest of a file the scenario downloads, so a re-recording that changes a member also fails the refs that still name the old one. ## Rules diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-answer-member.json b/python/client-contract/src/dfo_client_contract/refs/ref-answer-member.json index 7ca8187..50815d9 100644 --- a/python/client-contract/src/dfo_client_contract/refs/ref-answer-member.json +++ b/python/client-contract/src/dfo_client_contract/refs/ref-answer-member.json @@ -2,6 +2,7 @@ "format_version": 1, "name": "ref-answer-member", "description": "A member built from an answer names the part it answers.", + "scenario": "fetch-spec-known-sentence", "ref": { "format_version": 1, "members": [ @@ -84,7 +85,7 @@ }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", "artifact": { - "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "format": "parquet", "bundle": false diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-bare-definition-rejected.json b/python/client-contract/src/dfo_client_contract/refs/ref-bare-definition-rejected.json index 232a9f8..1cdc751 100644 --- a/python/client-contract/src/dfo_client_contract/refs/ref-bare-definition-rejected.json +++ b/python/client-contract/src/dfo_client_contract/refs/ref-bare-definition-rejected.json @@ -2,6 +2,7 @@ "format_version": 1, "name": "ref-bare-definition-rejected", "description": "A member's definition is the server's whole definition, with its schema_version and identity beside its spec_id.", + "scenario": "fetch-spec-known-sentence", "ref": { "format_version": 1, "members": [ @@ -16,7 +17,7 @@ }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", "artifact": { - "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "format": "parquet", "bundle": false diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-definition-extra-member-rejected.json b/python/client-contract/src/dfo_client_contract/refs/ref-definition-extra-member-rejected.json index 0a71366..2ef647e 100644 --- a/python/client-contract/src/dfo_client_contract/refs/ref-definition-extra-member-rejected.json +++ b/python/client-contract/src/dfo_client_contract/refs/ref-definition-extra-member-rejected.json @@ -2,6 +2,7 @@ "format_version": 1, "name": "ref-definition-extra-member-rejected", "description": "A member's definition holds only the members the served CanonicalDefinition admits.", + "scenario": "fetch-spec-known-sentence", "ref": { "format_version": 1, "members": [ @@ -83,7 +84,7 @@ }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", "artifact": { - "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "format": "parquet", "bundle": false diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-definition-spec-id-mismatch-rejected.json b/python/client-contract/src/dfo_client_contract/refs/ref-definition-spec-id-mismatch-rejected.json index efe42b8..ef3d06c 100644 --- a/python/client-contract/src/dfo_client_contract/refs/ref-definition-spec-id-mismatch-rejected.json +++ b/python/client-contract/src/dfo_client_contract/refs/ref-definition-spec-id-mismatch-rejected.json @@ -2,6 +2,7 @@ "format_version": 1, "name": "ref-definition-spec-id-mismatch-rejected", "description": "A member's definition is the definition for its own spec_id.", + "scenario": "fetch-spec-known-sentence", "ref": { "format_version": 1, "members": [ @@ -80,7 +81,7 @@ }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", "artifact": { - "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "format": "parquet", "bundle": false diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-definition-without-identity-rejected.json b/python/client-contract/src/dfo_client_contract/refs/ref-definition-without-identity-rejected.json index b2b93fd..65ad764 100644 --- a/python/client-contract/src/dfo_client_contract/refs/ref-definition-without-identity-rejected.json +++ b/python/client-contract/src/dfo_client_contract/refs/ref-definition-without-identity-rejected.json @@ -2,6 +2,7 @@ "format_version": 1, "name": "ref-definition-without-identity-rejected", "description": "A member's definition holds its identity.", + "scenario": "fetch-spec-known-sentence", "ref": { "format_version": 1, "members": [ @@ -17,7 +18,7 @@ }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", "artifact": { - "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "format": "parquet", "bundle": false diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-definition-without-schema-version-rejected.json b/python/client-contract/src/dfo_client_contract/refs/ref-definition-without-schema-version-rejected.json index 9cc8ed9..9628b91 100644 --- a/python/client-contract/src/dfo_client_contract/refs/ref-definition-without-schema-version-rejected.json +++ b/python/client-contract/src/dfo_client_contract/refs/ref-definition-without-schema-version-rejected.json @@ -2,6 +2,7 @@ "format_version": 1, "name": "ref-definition-without-schema-version-rejected", "description": "A member's definition holds its schema_version.", + "scenario": "fetch-spec-known-sentence", "ref": { "format_version": 1, "members": [ @@ -81,7 +82,7 @@ }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", "artifact": { - "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "format": "parquet", "bundle": false diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-frame-layout.json b/python/client-contract/src/dfo_client_contract/refs/ref-frame-layout.json index eb52150..a8495b7 100644 --- a/python/client-contract/src/dfo_client_contract/refs/ref-frame-layout.json +++ b/python/client-contract/src/dfo_client_contract/refs/ref-frame-layout.json @@ -2,17 +2,18 @@ "format_version": 1, "name": "ref-frame-layout", "description": "A member fetched with layout frame names the frame layout in its rendering.", + "scenario": "fetch-spec-frame-layout", "ref": { "format_version": 1, "members": [ { "parts": [], - "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS).", + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 1995 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", "spec": { - "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", "definition": { "schema_version": 1, - "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", "identity": { "identity_version": "spec1", "shape": { @@ -73,16 +74,14 @@ ] }, "requested_window": { - "kind": "range", - "start_year": 2020, - "end_year": 2023 + "kind": "all" } } } }, - "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", "artifact": { - "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "digest": "sha256:f4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104", "rendering": { "format": "parquet", "bundle": false, diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-one-member.json b/python/client-contract/src/dfo_client_contract/refs/ref-one-member.json index 544cd44..50e1dd6 100644 --- a/python/client-contract/src/dfo_client_contract/refs/ref-one-member.json +++ b/python/client-contract/src/dfo_client_contract/refs/ref-one-member.json @@ -2,6 +2,7 @@ "format_version": 1, "name": "ref-one-member", "description": "A ref to one bare long Parquet version, the member of fetch-spec-known-sentence.", + "scenario": "fetch-spec-known-sentence", "ref": { "format_version": 1, "members": [ @@ -82,7 +83,7 @@ }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", "artifact": { - "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "format": "parquet", "bundle": false diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-repeated-spec-id-rejected.json b/python/client-contract/src/dfo_client_contract/refs/ref-repeated-spec-id-rejected.json index 7c4df56..830c942 100644 --- a/python/client-contract/src/dfo_client_contract/refs/ref-repeated-spec-id-rejected.json +++ b/python/client-contract/src/dfo_client_contract/refs/ref-repeated-spec-id-rejected.json @@ -2,6 +2,7 @@ "format_version": 1, "name": "ref-repeated-spec-id-rejected", "description": "Each member holds a distinct spec_id.", + "scenario": "fetch-spec-known-sentence", "ref": { "format_version": 1, "members": [ @@ -82,7 +83,7 @@ }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", "artifact": { - "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "format": "parquet", "bundle": false @@ -168,7 +169,7 @@ }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", "artifact": { - "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "format": "parquet", "bundle": false diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-server-rendering-rejected.json b/python/client-contract/src/dfo_client_contract/refs/ref-server-rendering-rejected.json index 5ba2ee1..1d4560e 100644 --- a/python/client-contract/src/dfo_client_contract/refs/ref-server-rendering-rejected.json +++ b/python/client-contract/src/dfo_client_contract/refs/ref-server-rendering-rejected.json @@ -2,6 +2,7 @@ "format_version": 1, "name": "ref-server-rendering-rejected", "description": "The server's rendering object, with its integer layout, is not the selector a ref stores.", + "scenario": "fetch-spec-known-sentence", "ref": { "format_version": 1, "members": [ @@ -82,11 +83,11 @@ }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", "artifact": { - "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 } } } diff --git a/python/client-contract/src/dfo_client_contract/rules/cache-layout.json b/python/client-contract/src/dfo_client_contract/rules/cache-layout.json index 9a63b8a..d60f92b 100644 --- a/python/client-contract/src/dfo_client_contract/rules/cache-layout.json +++ b/python/client-contract/src/dfo_client_contract/rules/cache-layout.json @@ -5,8 +5,8 @@ { "name": "file-by-digest", "entry": "file", - "digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", - "path": "files/sha256/e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", + "path": "files/sha256/c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170" }, { "name": "manifest-long-parquet", diff --git a/python/client-contract/src/dfo_client_contract/scenario.schema.json b/python/client-contract/src/dfo_client_contract/scenario.schema.json index d1c6481..f0d9256 100644 --- a/python/client-contract/src/dfo_client_contract/scenario.schema.json +++ b/python/client-contract/src/dfo_client_contract/scenario.schema.json @@ -373,7 +373,7 @@ } }, "newest_version_step": { - "description": "The newest stored version of a spec, the one the versions route lists first.", + "description": "The newest stored version of a spec, the first the versions route lists with no base_content_version.", "type": "object", "additionalProperties": false, "required": [ diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-candidate-specs-not-a-list.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidate-specs-not-a-list.json index c8d1bb2..1fe86c2 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-candidate-specs-not-a-list.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidate-specs-not-a-list.json @@ -10,7 +10,7 @@ "call": [ { "op": "search", - "question": "GNI of Germany from 2015 to 2022" + "question": "mortality in Kenya from 2013 to 2022" } ], "exchanges": [ @@ -22,7 +22,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "GNI of Germany from 2015 to 2022" + "query": "mortality in Kenya from 2013 to 2022" } } }, @@ -30,60 +30,72 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "d107dd88e50147378d54464bcdaf9695" + "x-dfo-trace-id": "2fefffc9aac84b4fae2eb1888a1d3b74" }, "json": { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "GNI of Germany from 2015 to 2022", - "normalized_query": "GNI of Germany from 2015 to 2022", + "raw_query": "mortality in Kenya from 2013 to 2022", + "normalized_query": "mortality in Kenya from 2013 to 2022", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d107dd88e50147378d54464bcdaf9695", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "2fefffc9aac84b4fae2eb1888a1d3b74", "warnings": [], "timing_ms": { - "total": 4075, + "total": 2300, "by_step": { "coverage": 0, - "extract": 1004 + "extract": 1022, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 7300, - "output_tokens": 300, - "cached_tokens": 861 + "input_tokens": 2237, + "output_tokens": 143, + "cached_tokens": 842, + "jev_input_tokens": 13358, + "jev_output_tokens": 2855 }, "timed_out": false }, "kind": "resolution", "parts": [ { - "variable_text": "GNI", + "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 2799, + "total": 1274, "by_step": { - "recall": 381, - "shape_arcs": 2, - "shape_probe_coverage": 1, - "shape_probe": 203, - "shape_groups": 18, - "shape_labels": 5, - "shape_admission": 0, - "shape": 1186, - "bind": 829, - "materialise": 217, - "answer": 186 + "recall": 0, + "phase_resolve_places": 0, + "phase_check_entities": 0, + "shape_arcs": 4, + "shape_probe": 112, + "shape_groups": 5, + "shape_labels": 1, + "shape_admission": 1, + "phase_derive_shapes": 0, + "shape": 237, + "phase_prune_and_rank": 0, + "bind": 214, + "phase_bind": 3, + "phase_settle": 7, + "phase_place_bindings": 27, + "phase_facet_requests": 0, + "materialise": 124, + "phase_materialise": 1, + "answer": 25, + "phase_outcome": 636 } }, - "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", "sentence_plan": [ { "kind": "text", - "text": "3 readings.", + "text": "2 readings.", "segment": "heading", "entity_refs": [], "states": [] @@ -97,7 +109,7 @@ }, { "kind": "text", - "text": "Germany", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [] @@ -118,112 +130,7 @@ }, { "kind": "text", - "text": "primary income", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " for ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "gross of fixed capital consumption", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "OECD DAC1", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "2015 to 2022", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "Current US dollars", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "Germany", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "gross national income based on purchasing power parity", + "text": "deaths rate", "segment": "heading", "entity_refs": [], "states": [] @@ -237,7 +144,7 @@ }, { "kind": "text", - "text": "in international dollars", + "text": "per capita", "segment": "heading", "entity_refs": [], "states": [] @@ -272,7 +179,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2022", "segment": "byline", "entity_refs": [], "states": [] @@ -293,7 +200,7 @@ }, { "kind": "text", - "text": "Germany", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [] @@ -314,21 +221,7 @@ }, { "kind": "text", - "text": "gross national income based on purchasing power parity per capita", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "in international dollars", + "text": "number of deaths", "segment": "heading", "entity_refs": [], "states": [] @@ -349,7 +242,7 @@ }, { "kind": "text", - "text": "World Development Indicators", + "text": "Kenya Census", "segment": "byline", "entity_refs": [], "states": [] @@ -363,7 +256,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2018 to 2022", "segment": "byline", "entity_refs": [], "states": [] @@ -377,13 +270,13 @@ } ], "restatement": { - "variable_text": "GNI", + "variable_text": "mortality", "entities": [ { - "text": "Germany" + "text": "Kenya" } ], - "time_text": "2015 to 2022", + "time_text": "2013 to 2022", "sources": [], "operations": [] }, @@ -396,69 +289,70 @@ "max_candidates": 6, "specs": { "0": { - "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "definition": { "schema_version": 1, - "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU" + "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicunit_primaryincome_measuredvalue_nominal", - "label": "Gross national income", + "shape_id": "mortalityevent_count_measuredvalue_per_count_person", + "label": "Deaths Rate", "population_type": { - "ref": "EconomicUnit", - "label": "economic unit" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "primaryIncome", - "label": "primary income" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "Nominal", - "label": "Nominal" + "measurement_denominator": { + "ref": "Count_Person", + "label": "Total population" }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, { "axis": "where", @@ -473,13 +367,13 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", - "refine_supported": true, + "member_count": 133, + "member_digest": "c090b56d31a596a8be16dafb518382db666c6b100a80534c3cb81dbfe3111c5d", + "refine_supported": false, "data_commons": [ { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" } ] }, @@ -488,20 +382,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - }, - "value_kind": "enum_value" - } + "kind": "unbound" }, "summable": false }, @@ -514,8 +401,8 @@ "kind": "value", "value": { "ref": { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" }, "value_kind": "entity" } @@ -532,7 +419,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } @@ -550,21 +437,23 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 2, "member_count_exact": false, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2013", "end": "2022" } }, "entities": [ { - "ref": "country/DEU", - "label": "Germany", + "ref": "country/KEN", + "label": "Kenya", "entity_type": "Country", "role": "observationAbout" } @@ -572,7 +461,7 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 8, + "observation_count": 10, "evidence": "facet_metadata", "dimensions": [ { @@ -581,7 +470,7 @@ }, { "label": "observations", - "count": 8 + "count": 10 }, { "label": "variables", @@ -589,43 +478,46 @@ } ], "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, "download": { - "rows": 8, + "rows": 10, "rows_exact": true, "series": 1, "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, "licence": { - "label": "OECD Terms and Conditions" + "label": "Creative Commons Attribution License" } }, "facets": { "provenance": { "basis": "fallback", - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1", - "account": "provider" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "measurementMethod": { + "basis": "fallback", + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" }, "unit": { "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" + "ref": "Per1000Persons", + "label": "Per 1000 people" } }, "slot_options": [ @@ -633,17 +525,17 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" + "ref": "ICD10/X60-X84", + "label": "X60-X84 (Intentional self-harm)" }, "value_kind": "enum_value" } @@ -661,8 +553,17 @@ { "value": { "ref": { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1" + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + }, + { + "value": { + "ref": { + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, "value_kind": "source" } @@ -671,28 +572,54 @@ "truncated": false, "source": "observed" }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "ref": { + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, { "axis": "unit", "options": [ { "value": { "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" + "ref": "Per1000Persons", + "label": "Per 1000 people" }, "value_kind": "enum_value" } + }, + { + "value": { + "value_kind": "enum_value" + } } ], "truncated": false, "source": "observed" } ], - "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "rendered_sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators.", "sentence_plan": [ { "kind": "slot", - "text": "Germany", + "text": "Kenya", "axis": "where", "segment": "heading", "binding_ref": "where:", @@ -717,7 +644,7 @@ }, { "kind": "slot", - "text": "primary income", + "text": "deaths rate", "axis": "what", "segment": "heading", "entity_refs": [], @@ -726,23 +653,28 @@ }, { "kind": "text", - "text": " for ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "gross of fixed capital consumption", + "text": "per capita", + "axis": "unit", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", "axis": "how", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ], - "distinguishes": true + "states": [] }, { "kind": "text", @@ -753,14 +685,15 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", "entity_refs": [], "states": [ "when:" - ] + ], + "distinguishes": true }, { "kind": "text", @@ -778,26 +711,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -817,23 +731,23 @@ "trace": { "resolved_entities": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "resolved_sources": [ { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" } ], "slot_filters": [ @@ -841,18 +755,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -863,8 +772,8 @@ "binding_kind": "value", "refs": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "provenance": "binder" @@ -890,38 +799,13 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] + "removed_stat_vars": [] } }, "confidence": "high", @@ -931,122 +815,294 @@ } }, "1": { - "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "spec_id": "spec_7923e67e0706d6d9738c78cb374ee8fb", "definition": { "schema_version": 1, - "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "spec_id": "spec_7923e67e0706d6d9738c78cb374ee8fb", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicActivity", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "PurchasingPowerParity" + "population_type": "MortalityEvent", + "measured_property": "count", + "stat_type": "measuredValue" }, "slots": [ { - "property": "activitySource", + "property": "age", + "binding": { + "state": "unbound" + } + }, + { + "property": "ageGroupClassification", + "binding": { + "state": "unbound" + } + }, + { + "property": "causeOfDeath", + "binding": { + "state": "unbound" + } + }, + { + "property": "ethnicity", + "binding": { + "state": "unbound" + } + }, + { + "property": "gender", + "binding": { + "state": "unbound" + } + }, + { + "property": "incidentType", + "binding": { + "state": "unbound" + } + }, + { + "property": "race", + "binding": { + "state": "unbound" + } + }, + { + "property": "residentStatus", "binding": { - "state": "value", - "ref": "GrossNationalIncome" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU" + "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity", - "label": "Gross National Income Based on Purchasing Power Parity", + "shape_id": "mortalityevent_count_measuredvalue", + "label": "Number of Deaths", "population_type": { - "ref": "EconomicActivity", - "label": "EconomicActivity" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "amount", - "label": "amount" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "PurchasingPowerParity", - "label": "PurchasingPowerParity" - }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, { - "axis": "where", - "label": "place" + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" }, { - "axis": "when", - "label": "time window" + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" }, { - "axis": "source", - "label": "data source" - } + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } ], - "member_count": 1, - "member_digest": "833b9da89613fa6c1775652daac2388f38204c6c9f9929ca113deed9a0d08369", + "member_count": 2978, "refine_supported": true, "data_commons": [ { "id": "base", "label": "Data Commons by Google" } - ], - "upstream": { - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" - } - } + ] }, "slots": [ { "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - }, - "value_kind": "enum_value" - } + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + "binding": { + "kind": "unbound" }, "summable": false }, @@ -1059,8 +1115,8 @@ "kind": "value", "value": { "ref": { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" }, "value_kind": "entity" } @@ -1077,7 +1133,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 } } @@ -1095,21 +1151,30 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath", + "gender", + "age", + "race", + "incidentType", + "ethnicity", + "residentStatus", + "ageGroupClassification" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 37, "member_count_exact": false, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2018", "end": "2022" } }, "entities": [ { - "ref": "country/DEU", - "label": "Germany", + "ref": "country/KEN", + "label": "Kenya", "entity_type": "Country", "role": "observationAbout" } @@ -1117,7 +1182,7 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 8, + "observation_count": 5, "evidence": "facet_metadata", "dimensions": [ { @@ -1126,7 +1191,7 @@ }, { "label": "observations", - "count": 8 + "count": 5 }, { "label": "variables", @@ -1134,16 +1199,16 @@ } ], "window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 } }, "download": { - "rows": 8, + "rows": 5, "rows_exact": true, "series": 1, "window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 }, "licence": { @@ -1153,22 +1218,17 @@ "facets": { "provenance": { "basis": "fallback", - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census", "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "ref": "dc/s/OpenDataForAfrica", + "label": "Open Data for Africa" }, "data_commons": { "id": "base", "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" - }, - "unit": { - "basis": "fallback", - "ref": "InternationalDollar", - "label": "InternationalDollar" + "documentation": "/api/graph/documentation/dc/base/Kenya_Census" } }, "slot_options": [ @@ -1176,559 +1236,713 @@ "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + "ref": "ICD10/A00-B99", + "label": "A00-B99 (Certain infectious and parasitic diseases)" }, "value_kind": "enum_value" } - } - ], - "truncated": true, - "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ - { - "axis": "provenance", - "options": [ + }, { "value": { "ref": { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators" + "ref": "ICD10/D50-D89", + "label": "D50-D89 (Diseases of the blood and blood-forming organs and certain disorders involving the immune mechanism)" }, - "value_kind": "source" + "value_kind": "enum_value" } - } - ], - "truncated": false, - "source": "observed" - }, - { - "axis": "unit", - "options": [ + }, { "value": { "ref": { - "ref": "InternationalDollar", - "label": "InternationalDollar" + "ref": "ICD10/I00-I99", + "label": "I00-I99 (Diseases of the circulatory system)" }, "value_kind": "enum_value" } - } - ], - "truncated": false, - "source": "observed" - } - ], - "rendered_sentence": "Germany's gross national income based on purchasing power parity in international dollars, 2015 to 2022. World Development Indicators.", - "sentence_plan": [ - { - "kind": "slot", - "text": "Germany", - "axis": "where", - "segment": "heading", - "binding_ref": "where:", - "entity_refs": [], - "states": [ - "where:" - ] - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "gross national income based on purchasing power parity", - "axis": "what", - "segment": "heading", - "entity_refs": [], - "states": [ - "how:activitySource" - ], - "distinguishes": true - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "in international dollars", - "axis": "unit", - "segment": "heading", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:" - ] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "activitySource", - "binding_ref": "how:activitySource", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": ", ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "2015 to 2022", - "axis": "when", - "segment": "heading", - "binding_ref": "when:", - "entity_refs": [], - "states": [ - "when:" - ] - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] + }, + { + "value": { + "ref": { + "ref": "ICD10/K00-K92", + "label": "K00-K92 (Diseases of the digestive system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/N00-N98", + "label": "N00-N98 (Diseases of the genitourinary system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/M00-M99", + "label": "M00-M99 (Diseases of the musculoskeletal system and connective tissue)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/G00-G98", + "label": "G00-G98 (Diseases of the nervous system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/J00-J98", + "label": "J00-J98 (Diseases of the respiratory system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/L00-L98", + "label": "L00-L98 (Diseases of the skin and subcutaneous tissue)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/E00-E88", + "label": "E00-E88 (Endocrine, nutritional and metabolic diseases)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/F01-F99", + "label": "F01-F99 (Mental and behavioural disorders)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/O00-O99", + "label": "O00-O99 (Pregnancy, childbirth and the puerperium)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/U00-U99", + "label": "U00-U99 (Codes for special purposes)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Diabetes", + "label": "Diabetes" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Suicide", + "label": "Suicide" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/V01-Y89", + "label": "V01-Y89 (External causes of morbidity and mortality)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/C00-D48", + "label": "C00-D48 (Neoplasms)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/P00-P96", + "label": "P00-P96 (Certain conditions originating in the perinatal period)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/Q00-Q99", + "label": "Q00-Q99 (Congenital malformations, deformations and chromosomal abnormalities)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CerebrovascularDiseases", + "label": "CerebrovascularDiseases" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CongenitalAnomalies", + "label": "CongenitalAnomalies" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CongenitalHeartAnomalies", + "label": "CongenitalHeartAnomalies" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "GenitourinaryDiseases", + "label": "GenitourinaryDiseases" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "HypertensiveHeartDisease", + "label": "HypertensiveHeartDisease" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MalignantNeoplasms", + "label": "MalignantNeoplasms" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Neoplasms", + "label": "Neoplasms" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PerinatalInfection", + "label": "Perinatal Infection" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Pneumonia", + "label": "Pneumonia" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SGP_OtherDiseasesAndCauses", + "label": "SGP_OtherDiseasesAndCauses" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TransportAccidents", + "label": "TransportAccidents" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Tuberculosis", + "label": "Tuberculosis" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, { - "kind": "slot", - "text": "World Development Indicators", - "axis": "source", - "segment": "byline", - "entity_refs": [], - "states": [ - "source:" + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Female", + "label": "Female" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Male", + "label": "Male" + }, + "value_kind": "enum_value" + } + } ], - "distinguishes": true + "truncated": true, + "source": "observed" }, { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [] - } - ], - "trace": { - "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" - } - ], - "resolved_sources": [ - { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Years0To1", + "label": "Years 0 To 1" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Day0To27", + "label": "Day 0 To 27" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years10To14", + "label": "Years 10 To 14" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years15To19", + "label": "Years 15 To 19" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years15To24", + "label": "Years 15 To 24" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years1To4", + "label": "Years 1 To 4" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years20To24", + "label": "Years 20 To 24" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years25To29", + "label": "Years 25 To 29" + }, + "value_kind": "enum_value" + } }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" + { + "value": { + "ref": { + "ref": "Years25To34", + "label": "Years 25 To 34" + }, + "value_kind": "enum_value" + } }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" - } - ], - "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "activitySource", - "label": "activitySource" - }, - "label": "activity source" + { + "value": { + "ref": { + "ref": "Years30To34", + "label": "Years 30 To 34" + }, + "value_kind": "enum_value" + } }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + { + "value": { + "ref": { + "ref": "Years35To39", + "label": "Years 35 To 39" + }, + "value_kind": "enum_value" } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "where", - "label": "place" }, - "binding_kind": "value", - "refs": [ - { - "ref": "country/DEU", - "label": "Germany" + { + "value": { + "ref": { + "ref": "Years35To44", + "label": "Years 35 To 44" + }, + "value_kind": "enum_value" } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "when", - "label": "time window" }, - "binding_kind": "value", - "refs": [], - "provenance": "binder" - }, - { - "key": { - "axis": "source", - "label": "data source" + { + "value": { + "ref": { + "ref": "Years40To44", + "label": "Years 40 To 44" + }, + "value_kind": "enum_value" + } }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - } - ], - "query_qualifiers": [], - "requested_window": { - "start_year": 2015, - "end_year": 2022 - }, - "capability_version": "cap_347a470e04c97eec", - "default_reading": { - "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] - } - }, - "confidence": "high", - "basis": "nominated", - "available_at_place": true, - "measure_label_axes": [], - "measure_axis_values": [] - } - }, - "2": { - "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", - "definition": { - "schema_version": 1, - "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "EconomicActivity", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "PurchasingPowerParity", - "measurement_denominator": { - "unresolved": true - } - }, - "slots": [ - { - "property": "activitySource", - "binding": { - "state": "value", - "ref": "GrossNationalIncome" - } - } - ], - "entities": { - "observationAbout": [ - "country/DEU" - ] - }, - "requested_window": { - "kind": "range", - "start_year": 2015, - "end_year": 2022 - } - } - }, - "resolved": { - "shape": { - "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity_per_unresolved", - "label": "Gross National Income Based on Purchasing Power Parity Per Capita", - "population_type": { - "ref": "EconomicActivity", - "label": "EconomicActivity" - }, - "measured_property": { - "ref": "amount", - "label": "amount" - }, - "stat_type": { - "ref": "measuredValue", - "label": "measuredValue" - }, - "measurement_qualifier": { - "ref": "PurchasingPowerParity", - "label": "PurchasingPowerParity" - }, - "measurement_denominator": { - "ref": "PerCapita", - "label": "PerCapita" - }, - "measurement_denominator_unresolved": true, - "slot_keys": [ - { - "axis": "how", - "property": { - "ref": "activitySource", - "label": "activitySource" + { + "value": { + "ref": { + "ref": "Years45To49", + "label": "Years 45 To 49" + }, + "value_kind": "enum_value" + } }, - "label": "activity source" - }, - { - "axis": "where", - "label": "place" - }, - { - "axis": "when", - "label": "time window" - }, - { - "axis": "source", - "label": "data source" - } - ], - "member_count": 1, - "member_digest": "7b2d5b0fc09cfc0215c8d7c6c21a5195fa21e79f2a148a6bca9ce6c3af8bbb9f", - "refine_supported": true, - "data_commons": [ - { - "id": "base", - "label": "Data Commons by Google" - } - ], - "upstream": { - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" - } - } - }, - "slots": [ + { + "value": { + "ref": { + "ref": "Years45To54", + "label": "Years 45 To 54" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years50To54", + "label": "Years 50 To 54" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years55To59", + "label": "Years 55 To 59" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years55To64", + "label": "Years 55 To 64" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years5To9", + "label": "Years 5 To 9" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years60To64", + "label": "Years 60 To 64" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years65To69", + "label": "Years 65 To 69" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years65To74", + "label": "Years 65 To 74" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years70To74", + "label": "Years 70 To 74" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years75To79", + "label": "Years 75 To 79" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years75To84", + "label": "Years 75 To 84" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years80To84", + "label": "Years 80 To 84" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "USC_AgeNotStated", + "label": "USC_AgeNotStated" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years0To4", + "label": "Years 0 To 4" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, { "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "race", + "label": "race" }, - "label": "activity source" + "label": "race" }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - }, - "value_kind": "enum_value" + "options": [ + { + "value": { + "ref": { + "ref": "CDC_AmericanIndianAndAlaskaNativeAlone", + "label": "American Indian and Alaska native alone" + }, + "value_kind": "enum_value" + } } - }, - "summable": false + ], + "truncated": true, + "source": "observed" }, { "key": { - "axis": "where", - "label": "place" + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" + "options": [ + { + "value": { + "ref": { + "ref": "COVID_19", + "label": "COVID-19" + }, + "value_kind": "enum_value" + } } - }, - "summable": false + ], + "truncated": true, + "source": "observed" }, { "key": { - "axis": "when", - "label": "time window" + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" }, - "binding": { - "kind": "value", - "value": { - "value_kind": "time_window", - "time_window": { - "start_year": 2015, - "end_year": 2022 + "options": [ + { + "value": { + "ref": { + "ref": "Chinese", + "label": "Chinese" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Indian", + "label": "Indian" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Malay", + "label": "Malay" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SGP_OtherEthnicity", + "label": "SGP_OtherEthnicity" + }, + "value_kind": "enum_value" } } - }, - "summable": false - }, - { - "key": { - "axis": "source", - "label": "data source" - }, - "binding": { - "kind": "unbound" - }, - "summable": false - } - ], - "inapplicable_slots": [], - "unresolved_slots": [], - "stat_vars": { - "member_count": 1, - "member_count_exact": false, - "served_count": 1, - "data_date_range": { - "start": "2015", - "end": "2022" - } - }, - "entities": [ - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - } - ], - "coverage": { - "kind": "exact", - "has_data": true, - "observation_count": 8, - "evidence": "facet_metadata", - "dimensions": [ - { - "label": "sources", - "count": 1 - }, - { - "label": "observations", - "count": 8 - }, - { - "label": "variables", - "count": 1 - } - ], - "window": { - "start_year": 2015, - "end_year": 2022 - } - }, - "download": { - "rows": 8, - "rows_exact": true, - "series": 1, - "window": { - "start_year": 2015, - "end_year": 2022 - }, - "licence": { - "label": "Creative Commons Attribution License" - } - }, - "facets": { - "provenance": { - "basis": "fallback", - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" - }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + ], + "truncated": true, + "source": "observed" }, - "unit": { - "basis": "fallback", - "ref": "InternationalDollar", - "label": "InternationalDollar" - } - }, - "slot_options": [ { "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "residentStatus", + "label": "residentStatus" }, - "label": "activity source" + "label": "resident status" }, "options": [ { "value": { "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + "ref": "Citizen", + "label": "Citizen" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Resident", + "label": "Resident" }, "value_kind": "enum_value" } @@ -1736,36 +1950,52 @@ ], "truncated": true, "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ + }, { - "axis": "provenance", + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, "options": [ { "value": { "ref": { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators" + "ref": "Infant", + "label": "Infant" }, - "value_kind": "source" + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Newborn", + "label": "Newborn" + }, + "value_kind": "enum_value" } } ], - "truncated": false, + "truncated": true, "source": "observed" - }, + } + ], + "entity_options": [], + "facet_options": [ { - "axis": "unit", + "axis": "provenance", "options": [ { "value": { "ref": { - "ref": "InternationalDollar", - "label": "InternationalDollar" + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, - "value_kind": "enum_value" + "value_kind": "source" } } ], @@ -1773,69 +2003,119 @@ "source": "observed" } ], - "rendered_sentence": "Germany's gross national income based on purchasing power parity per capita in international dollars, 2015 to 2022. World Development Indicators.", + "rendered_sentence": "Kenya's number of deaths, 2018 to 2022. Kenya Census.", "sentence_plan": [ { "kind": "slot", - "text": "Germany", - "axis": "where", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "number of deaths", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "distinguishes": true + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "age", + "binding_ref": "how:age", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", "segment": "heading", - "binding_ref": "where:", + "property_dcid": "ageGroupClassification", + "binding_ref": "how:ageGroupClassification", "entity_refs": [], - "states": [ - "where:" - ] + "states": [] }, { - "kind": "text", - "text": "'s", + "kind": "slot", + "text": "", + "axis": "how", "segment": "heading", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", "entity_refs": [], "states": [] }, { - "kind": "text", - "text": " ", + "kind": "slot", + "text": "", + "axis": "how", "segment": "heading", + "property_dcid": "ethnicity", + "binding_ref": "how:ethnicity", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "gross national income based on purchasing power parity per capita", - "axis": "what", + "text": "", + "axis": "how", "segment": "heading", + "property_dcid": "gender", + "binding_ref": "how:gender", "entity_refs": [], - "states": [ - "how:activitySource" - ], - "distinguishes": true + "states": [] }, { - "kind": "text", - "text": " ", + "kind": "slot", + "text": "", + "axis": "how", "segment": "heading", + "property_dcid": "incidentType", + "binding_ref": "how:incidentType", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "in international dollars", - "axis": "unit", + "text": "", + "axis": "how", "segment": "heading", - "binding_ref": "unit:", + "property_dcid": "race", + "binding_ref": "how:race", "entity_refs": [], - "states": [ - "unit:" - ] + "states": [] }, { "kind": "slot", "text": "", "axis": "how", "segment": "heading", - "property_dcid": "activitySource", - "binding_ref": "how:activitySource", + "property_dcid": "residentStatus", + "binding_ref": "how:residentStatus", "entity_refs": [], "states": [] }, @@ -1848,14 +2128,15 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2018 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", "entity_refs": [], "states": [ "when:" - ] + ], + "distinguishes": true }, { "kind": "text", @@ -1873,7 +2154,7 @@ }, { "kind": "slot", - "text": "World Development Indicators", + "text": "Kenya Census", "axis": "source", "segment": "byline", "entity_refs": [], @@ -1893,23 +2174,23 @@ "trace": { "resolved_entities": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "resolved_sources": [ { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census", "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "ref": "dc/s/OpenDataForAfrica", + "label": "Open Data for Africa" }, "data_commons": { "id": "base", "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + "documentation": "/api/graph/documentation/dc/base/Kenya_Census" } ], "slot_filters": [ @@ -1917,18 +2198,104 @@ "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - } - ], + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -1939,8 +2306,8 @@ "binding_kind": "value", "refs": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "provenance": "binder" @@ -1966,42 +2333,17 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] + "removed_stat_vars": [] } }, - "confidence": "high", - "basis": "nominated", + "confidence": "low", + "basis": "structural", "available_at_place": true, "measure_label_axes": [], "measure_axis_values": [] @@ -2011,142 +2353,21 @@ "truncated": false }, "reading_assumptions": { - "spec_c0f61f3ca3558aac184973441a67601e": [], - "spec_403a96317ee8b97f1d8569c71015e5ce": [], - "spec_d94656e5d53b7b6c6b0c683145a1cd98": [] + "spec_10bf62f9687154286b463d206f03a086": [], + "spec_7923e67e0706d6d9738c78cb374ee8fb": [] } } ], - "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", "sentence_plan": [ { "kind": "text", - "text": "3 readings.", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "Germany", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "primary income", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " for ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "gross of fixed capital consumption", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": ".", + "text": "2 readings.", "segment": "heading", "entity_refs": [], "states": [], "part_index": 0 }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "OECD DAC1", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "2015 to 2022", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "Current US dollars", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, { "kind": "text", "text": " ", @@ -2157,7 +2378,7 @@ }, { "kind": "text", - "text": "Germany", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [], @@ -2181,7 +2402,7 @@ }, { "kind": "text", - "text": "gross national income based on purchasing power parity", + "text": "deaths rate", "segment": "heading", "entity_refs": [], "states": [], @@ -2197,7 +2418,7 @@ }, { "kind": "text", - "text": "in international dollars", + "text": "per capita", "segment": "heading", "entity_refs": [], "states": [], @@ -2237,7 +2458,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2022", "segment": "byline", "entity_refs": [], "states": [], @@ -2261,7 +2482,7 @@ }, { "kind": "text", - "text": "Germany", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [], @@ -2285,23 +2506,7 @@ }, { "kind": "text", - "text": "gross national income based on purchasing power parity per capita", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "in international dollars", + "text": "number of deaths", "segment": "heading", "entity_refs": [], "states": [], @@ -2325,7 +2530,7 @@ }, { "kind": "text", - "text": "World Development Indicators", + "text": "Kenya Census", "segment": "byline", "entity_refs": [], "states": [], @@ -2341,7 +2546,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2018 to 2022", "segment": "byline", "entity_refs": [], "states": [], @@ -2366,7 +2571,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "d107dd88e50147378d54464bcdaf9695" + "trace_id": "2fefffc9aac84b4fae2eb1888a1d3b74" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json index 433d123..023638d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json @@ -1,17 +1,17 @@ { "format_version": 1, "name": "answer-candidates-choose-fetch", - "description": "A question with three readings answers one candidates part, a choice gap with three options. Choosing option 0 posts that candidate's identity to Search as the one dataset_resubmit identity entry, echoing the part's reading_assumptions under its spec_id as assumptions. Search answers that reading definite with its own sentence, and fetching the answer builds that candidate's spec.", + "description": "A question with two readings answers one candidates part, a choice gap with two options. Choosing option 0 posts that candidate's identity to Search as the one dataset_resubmit identity entry, echoing the part's reading_assumptions under its spec_id as assumptions. Search answers that reading definite with its own sentence, and fetching the answer builds that candidate's spec.", "origin": { "kind": "recorded", - "base_url": "http://127.0.0.1:19493/api", - "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T13:05:06Z" + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "recorded_at": "2026-10-23T18:36:53Z" }, "call": [ { "op": "search", - "question": "GNI of Germany from 2015 to 2022" + "question": "mortality in Kenya from 2013 to 2022" }, { "op": "choose", @@ -30,7 +30,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "GNI of Germany from 2015 to 2022" + "query": "mortality in Kenya from 2013 to 2022" } } }, @@ -38,60 +38,72 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "d107dd88e50147378d54464bcdaf9695" + "x-dfo-trace-id": "2fefffc9aac84b4fae2eb1888a1d3b74" }, "json": { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "GNI of Germany from 2015 to 2022", - "normalized_query": "GNI of Germany from 2015 to 2022", + "raw_query": "mortality in Kenya from 2013 to 2022", + "normalized_query": "mortality in Kenya from 2013 to 2022", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d107dd88e50147378d54464bcdaf9695", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "2fefffc9aac84b4fae2eb1888a1d3b74", "warnings": [], "timing_ms": { - "total": 4075, + "total": 2300, "by_step": { "coverage": 0, - "extract": 1004 + "extract": 1022, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 7300, - "output_tokens": 300, - "cached_tokens": 861 + "input_tokens": 2237, + "output_tokens": 143, + "cached_tokens": 842, + "jev_input_tokens": 13358, + "jev_output_tokens": 2855 }, "timed_out": false }, "kind": "resolution", "parts": [ { - "variable_text": "GNI", + "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 2799, + "total": 1274, "by_step": { - "recall": 381, - "shape_arcs": 2, - "shape_probe_coverage": 1, - "shape_probe": 203, - "shape_groups": 18, - "shape_labels": 5, - "shape_admission": 0, - "shape": 1186, - "bind": 829, - "materialise": 217, - "answer": 186 + "recall": 0, + "phase_resolve_places": 0, + "phase_check_entities": 0, + "shape_arcs": 4, + "shape_probe": 112, + "shape_groups": 5, + "shape_labels": 1, + "shape_admission": 1, + "phase_derive_shapes": 0, + "shape": 237, + "phase_prune_and_rank": 0, + "bind": 214, + "phase_bind": 3, + "phase_settle": 7, + "phase_place_bindings": 27, + "phase_facet_requests": 0, + "materialise": 124, + "phase_materialise": 1, + "answer": 25, + "phase_outcome": 636 } }, - "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", "sentence_plan": [ { "kind": "text", - "text": "3 readings.", + "text": "2 readings.", "segment": "heading", "entity_refs": [], "states": [] @@ -105,7 +117,7 @@ }, { "kind": "text", - "text": "Germany", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [] @@ -126,112 +138,7 @@ }, { "kind": "text", - "text": "primary income", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " for ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "gross of fixed capital consumption", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "OECD DAC1", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "2015 to 2022", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "Current US dollars", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "Germany", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "gross national income based on purchasing power parity", + "text": "deaths rate", "segment": "heading", "entity_refs": [], "states": [] @@ -245,7 +152,7 @@ }, { "kind": "text", - "text": "in international dollars", + "text": "per capita", "segment": "heading", "entity_refs": [], "states": [] @@ -280,7 +187,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2022", "segment": "byline", "entity_refs": [], "states": [] @@ -301,7 +208,7 @@ }, { "kind": "text", - "text": "Germany", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [] @@ -322,21 +229,7 @@ }, { "kind": "text", - "text": "gross national income based on purchasing power parity per capita", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "in international dollars", + "text": "number of deaths", "segment": "heading", "entity_refs": [], "states": [] @@ -357,7 +250,7 @@ }, { "kind": "text", - "text": "World Development Indicators", + "text": "Kenya Census", "segment": "byline", "entity_refs": [], "states": [] @@ -371,7 +264,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2018 to 2022", "segment": "byline", "entity_refs": [], "states": [] @@ -385,13 +278,13 @@ } ], "restatement": { - "variable_text": "GNI", + "variable_text": "mortality", "entities": [ { - "text": "Germany" + "text": "Kenya" } ], - "time_text": "2015 to 2022", + "time_text": "2013 to 2022", "sources": [], "operations": [] }, @@ -404,69 +297,70 @@ "max_candidates": 6, "specs": [ { - "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "definition": { "schema_version": 1, - "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU" + "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicunit_primaryincome_measuredvalue_nominal", - "label": "Gross national income", + "shape_id": "mortalityevent_count_measuredvalue_per_count_person", + "label": "Deaths Rate", "population_type": { - "ref": "EconomicUnit", - "label": "economic unit" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "primaryIncome", - "label": "primary income" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "Nominal", - "label": "Nominal" + "measurement_denominator": { + "ref": "Count_Person", + "label": "Total population" }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, { "axis": "where", @@ -481,13 +375,13 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", - "refine_supported": true, + "member_count": 133, + "member_digest": "c090b56d31a596a8be16dafb518382db666c6b100a80534c3cb81dbfe3111c5d", + "refine_supported": false, "data_commons": [ { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" } ] }, @@ -496,20 +390,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - }, - "value_kind": "enum_value" - } + "kind": "unbound" }, "summable": false }, @@ -522,8 +409,8 @@ "kind": "value", "value": { "ref": { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" }, "value_kind": "entity" } @@ -540,7 +427,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } @@ -558,21 +445,23 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 2, "member_count_exact": false, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2013", "end": "2022" } }, "entities": [ { - "ref": "country/DEU", - "label": "Germany", + "ref": "country/KEN", + "label": "Kenya", "entity_type": "Country", "role": "observationAbout" } @@ -580,7 +469,7 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 8, + "observation_count": 10, "evidence": "facet_metadata", "dimensions": [ { @@ -589,7 +478,7 @@ }, { "label": "observations", - "count": 8 + "count": 10 }, { "label": "variables", @@ -597,43 +486,46 @@ } ], "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, "download": { - "rows": 8, + "rows": 10, "rows_exact": true, "series": 1, "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, "licence": { - "label": "OECD Terms and Conditions" + "label": "Creative Commons Attribution License" } }, "facets": { "provenance": { "basis": "fallback", - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1", - "account": "provider" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "measurementMethod": { + "basis": "fallback", + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" }, "unit": { "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" + "ref": "Per1000Persons", + "label": "Per 1000 people" } }, "slot_options": [ @@ -641,17 +533,17 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" + "ref": "ICD10/X60-X84", + "label": "X60-X84 (Intentional self-harm)" }, "value_kind": "enum_value" } @@ -669,8 +561,17 @@ { "value": { "ref": { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1" + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + }, + { + "value": { + "ref": { + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, "value_kind": "source" } @@ -679,28 +580,54 @@ "truncated": false, "source": "observed" }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "ref": { + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, { "axis": "unit", "options": [ { "value": { "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" + "ref": "Per1000Persons", + "label": "Per 1000 people" }, "value_kind": "enum_value" } + }, + { + "value": { + "value_kind": "enum_value" + } } ], "truncated": false, "source": "observed" } ], - "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "rendered_sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators.", "sentence_plan": [ { "kind": "slot", - "text": "Germany", + "text": "Kenya", "axis": "where", "segment": "heading", "binding_ref": "where:", @@ -725,7 +652,7 @@ }, { "kind": "slot", - "text": "primary income", + "text": "deaths rate", "axis": "what", "segment": "heading", "entity_refs": [], @@ -734,23 +661,28 @@ }, { "kind": "text", - "text": " for ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "gross of fixed capital consumption", + "text": "per capita", + "axis": "unit", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", "axis": "how", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ], - "distinguishes": true + "states": [] }, { "kind": "text", @@ -761,14 +693,15 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", "entity_refs": [], "states": [ "when:" - ] + ], + "distinguishes": true }, { "kind": "text", @@ -786,26 +719,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -825,23 +739,23 @@ "trace": { "resolved_entities": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "resolved_sources": [ { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" } ], "slot_filters": [ @@ -849,18 +763,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -871,8 +780,8 @@ "binding_kind": "value", "refs": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "provenance": "binder" @@ -898,38 +807,13 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] + "removed_stat_vars": [] } }, "confidence": "high", @@ -939,122 +823,294 @@ } }, { - "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "spec_id": "spec_7923e67e0706d6d9738c78cb374ee8fb", "definition": { "schema_version": 1, - "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "spec_id": "spec_7923e67e0706d6d9738c78cb374ee8fb", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicActivity", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "PurchasingPowerParity" + "population_type": "MortalityEvent", + "measured_property": "count", + "stat_type": "measuredValue" }, "slots": [ { - "property": "activitySource", + "property": "age", + "binding": { + "state": "unbound" + } + }, + { + "property": "ageGroupClassification", + "binding": { + "state": "unbound" + } + }, + { + "property": "causeOfDeath", + "binding": { + "state": "unbound" + } + }, + { + "property": "ethnicity", + "binding": { + "state": "unbound" + } + }, + { + "property": "gender", + "binding": { + "state": "unbound" + } + }, + { + "property": "incidentType", + "binding": { + "state": "unbound" + } + }, + { + "property": "race", + "binding": { + "state": "unbound" + } + }, + { + "property": "residentStatus", "binding": { - "state": "value", - "ref": "GrossNationalIncome" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU" + "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity", - "label": "Gross National Income Based on Purchasing Power Parity", + "shape_id": "mortalityevent_count_measuredvalue", + "label": "Number of Deaths", "population_type": { - "ref": "EconomicActivity", - "label": "EconomicActivity" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "amount", - "label": "amount" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "PurchasingPowerParity", - "label": "PurchasingPowerParity" - }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, { - "axis": "where", - "label": "place" + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" }, { - "axis": "when", - "label": "time window" + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" }, { - "axis": "source", - "label": "data source" - } + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } ], - "member_count": 1, - "member_digest": "833b9da89613fa6c1775652daac2388f38204c6c9f9929ca113deed9a0d08369", + "member_count": 2978, "refine_supported": true, "data_commons": [ { "id": "base", "label": "Data Commons by Google" } - ], - "upstream": { - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" - } - } + ] }, "slots": [ { "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - }, - "value_kind": "enum_value" - } + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + "binding": { + "kind": "unbound" }, "summable": false }, @@ -1067,8 +1123,8 @@ "kind": "value", "value": { "ref": { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" }, "value_kind": "entity" } @@ -1085,7 +1141,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 } } @@ -1103,21 +1159,30 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath", + "gender", + "age", + "race", + "incidentType", + "ethnicity", + "residentStatus", + "ageGroupClassification" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 37, "member_count_exact": false, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2018", "end": "2022" } }, "entities": [ { - "ref": "country/DEU", - "label": "Germany", + "ref": "country/KEN", + "label": "Kenya", "entity_type": "Country", "role": "observationAbout" } @@ -1125,7 +1190,7 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 8, + "observation_count": 5, "evidence": "facet_metadata", "dimensions": [ { @@ -1134,7 +1199,7 @@ }, { "label": "observations", - "count": 8 + "count": 5 }, { "label": "variables", @@ -1142,16 +1207,16 @@ } ], "window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 } }, "download": { - "rows": 8, + "rows": 5, "rows_exact": true, "series": 1, "window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 }, "licence": { @@ -1161,22 +1226,17 @@ "facets": { "provenance": { "basis": "fallback", - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census", "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "ref": "dc/s/OpenDataForAfrica", + "label": "Open Data for Africa" }, "data_commons": { "id": "base", "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" - }, - "unit": { - "basis": "fallback", - "ref": "InternationalDollar", - "label": "InternationalDollar" + "documentation": "/api/graph/documentation/dc/base/Kenya_Census" } }, "slot_options": [ @@ -1184,559 +1244,713 @@ "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + "ref": "ICD10/A00-B99", + "label": "A00-B99 (Certain infectious and parasitic diseases)" }, "value_kind": "enum_value" } - } - ], - "truncated": true, - "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ - { - "axis": "provenance", - "options": [ + }, { "value": { "ref": { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators" + "ref": "ICD10/D50-D89", + "label": "D50-D89 (Diseases of the blood and blood-forming organs and certain disorders involving the immune mechanism)" }, - "value_kind": "source" + "value_kind": "enum_value" } - } - ], - "truncated": false, - "source": "observed" - }, - { - "axis": "unit", - "options": [ + }, { "value": { "ref": { - "ref": "InternationalDollar", - "label": "InternationalDollar" + "ref": "ICD10/I00-I99", + "label": "I00-I99 (Diseases of the circulatory system)" }, "value_kind": "enum_value" } - } - ], - "truncated": false, - "source": "observed" - } - ], - "rendered_sentence": "Germany's gross national income based on purchasing power parity in international dollars, 2015 to 2022. World Development Indicators.", - "sentence_plan": [ - { - "kind": "slot", - "text": "Germany", - "axis": "where", - "segment": "heading", - "binding_ref": "where:", - "entity_refs": [], - "states": [ - "where:" - ] - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "gross national income based on purchasing power parity", - "axis": "what", - "segment": "heading", - "entity_refs": [], - "states": [ - "how:activitySource" - ], - "distinguishes": true - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "in international dollars", - "axis": "unit", - "segment": "heading", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:" - ] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "activitySource", - "binding_ref": "how:activitySource", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": ", ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "2015 to 2022", - "axis": "when", - "segment": "heading", - "binding_ref": "when:", - "entity_refs": [], - "states": [ - "when:" - ] - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] + }, + { + "value": { + "ref": { + "ref": "ICD10/K00-K92", + "label": "K00-K92 (Diseases of the digestive system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/N00-N98", + "label": "N00-N98 (Diseases of the genitourinary system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/M00-M99", + "label": "M00-M99 (Diseases of the musculoskeletal system and connective tissue)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/G00-G98", + "label": "G00-G98 (Diseases of the nervous system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/J00-J98", + "label": "J00-J98 (Diseases of the respiratory system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/L00-L98", + "label": "L00-L98 (Diseases of the skin and subcutaneous tissue)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/E00-E88", + "label": "E00-E88 (Endocrine, nutritional and metabolic diseases)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/F01-F99", + "label": "F01-F99 (Mental and behavioural disorders)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/O00-O99", + "label": "O00-O99 (Pregnancy, childbirth and the puerperium)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/U00-U99", + "label": "U00-U99 (Codes for special purposes)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Diabetes", + "label": "Diabetes" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Suicide", + "label": "Suicide" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/V01-Y89", + "label": "V01-Y89 (External causes of morbidity and mortality)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/C00-D48", + "label": "C00-D48 (Neoplasms)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/P00-P96", + "label": "P00-P96 (Certain conditions originating in the perinatal period)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/Q00-Q99", + "label": "Q00-Q99 (Congenital malformations, deformations and chromosomal abnormalities)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CerebrovascularDiseases", + "label": "CerebrovascularDiseases" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CongenitalAnomalies", + "label": "CongenitalAnomalies" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CongenitalHeartAnomalies", + "label": "CongenitalHeartAnomalies" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "GenitourinaryDiseases", + "label": "GenitourinaryDiseases" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "HypertensiveHeartDisease", + "label": "HypertensiveHeartDisease" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MalignantNeoplasms", + "label": "MalignantNeoplasms" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Neoplasms", + "label": "Neoplasms" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PerinatalInfection", + "label": "Perinatal Infection" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Pneumonia", + "label": "Pneumonia" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SGP_OtherDiseasesAndCauses", + "label": "SGP_OtherDiseasesAndCauses" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TransportAccidents", + "label": "TransportAccidents" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Tuberculosis", + "label": "Tuberculosis" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, { - "kind": "slot", - "text": "World Development Indicators", - "axis": "source", - "segment": "byline", - "entity_refs": [], - "states": [ - "source:" + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Female", + "label": "Female" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Male", + "label": "Male" + }, + "value_kind": "enum_value" + } + } ], - "distinguishes": true + "truncated": true, + "source": "observed" }, { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [] - } - ], - "trace": { - "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" - } - ], - "resolved_sources": [ - { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Years0To1", + "label": "Years 0 To 1" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Day0To27", + "label": "Day 0 To 27" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years10To14", + "label": "Years 10 To 14" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years15To19", + "label": "Years 15 To 19" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years15To24", + "label": "Years 15 To 24" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years1To4", + "label": "Years 1 To 4" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years20To24", + "label": "Years 20 To 24" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years25To29", + "label": "Years 25 To 29" + }, + "value_kind": "enum_value" + } }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" + { + "value": { + "ref": { + "ref": "Years25To34", + "label": "Years 25 To 34" + }, + "value_kind": "enum_value" + } }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" - } - ], - "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "activitySource", - "label": "activitySource" - }, - "label": "activity source" + { + "value": { + "ref": { + "ref": "Years30To34", + "label": "Years 30 To 34" + }, + "value_kind": "enum_value" + } }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + { + "value": { + "ref": { + "ref": "Years35To39", + "label": "Years 35 To 39" + }, + "value_kind": "enum_value" } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "where", - "label": "place" }, - "binding_kind": "value", - "refs": [ - { - "ref": "country/DEU", - "label": "Germany" + { + "value": { + "ref": { + "ref": "Years35To44", + "label": "Years 35 To 44" + }, + "value_kind": "enum_value" } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "when", - "label": "time window" }, - "binding_kind": "value", - "refs": [], - "provenance": "binder" - }, - { - "key": { - "axis": "source", - "label": "data source" + { + "value": { + "ref": { + "ref": "Years40To44", + "label": "Years 40 To 44" + }, + "value_kind": "enum_value" + } }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - } - ], - "query_qualifiers": [], - "requested_window": { - "start_year": 2015, - "end_year": 2022 - }, - "capability_version": "cap_347a470e04c97eec", - "default_reading": { - "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] - } - }, - "confidence": "high", - "basis": "nominated", - "available_at_place": true, - "measure_label_axes": [], - "measure_axis_values": [] - } - }, - { - "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", - "definition": { - "schema_version": 1, - "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "EconomicActivity", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "PurchasingPowerParity", - "measurement_denominator": { - "unresolved": true - } - }, - "slots": [ - { - "property": "activitySource", - "binding": { - "state": "value", - "ref": "GrossNationalIncome" - } - } - ], - "entities": { - "observationAbout": [ - "country/DEU" - ] - }, - "requested_window": { - "kind": "range", - "start_year": 2015, - "end_year": 2022 - } - } - }, - "resolved": { - "shape": { - "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity_per_unresolved", - "label": "Gross National Income Based on Purchasing Power Parity Per Capita", - "population_type": { - "ref": "EconomicActivity", - "label": "EconomicActivity" - }, - "measured_property": { - "ref": "amount", - "label": "amount" - }, - "stat_type": { - "ref": "measuredValue", - "label": "measuredValue" - }, - "measurement_qualifier": { - "ref": "PurchasingPowerParity", - "label": "PurchasingPowerParity" - }, - "measurement_denominator": { - "ref": "PerCapita", - "label": "PerCapita" - }, - "measurement_denominator_unresolved": true, - "slot_keys": [ - { - "axis": "how", - "property": { - "ref": "activitySource", - "label": "activitySource" + { + "value": { + "ref": { + "ref": "Years45To49", + "label": "Years 45 To 49" + }, + "value_kind": "enum_value" + } }, - "label": "activity source" - }, - { - "axis": "where", - "label": "place" - }, - { - "axis": "when", - "label": "time window" - }, - { - "axis": "source", - "label": "data source" - } - ], - "member_count": 1, - "member_digest": "7b2d5b0fc09cfc0215c8d7c6c21a5195fa21e79f2a148a6bca9ce6c3af8bbb9f", - "refine_supported": true, - "data_commons": [ - { - "id": "base", - "label": "Data Commons by Google" - } - ], - "upstream": { - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" - } - } - }, - "slots": [ + { + "value": { + "ref": { + "ref": "Years45To54", + "label": "Years 45 To 54" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years50To54", + "label": "Years 50 To 54" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years55To59", + "label": "Years 55 To 59" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years55To64", + "label": "Years 55 To 64" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years5To9", + "label": "Years 5 To 9" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years60To64", + "label": "Years 60 To 64" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years65To69", + "label": "Years 65 To 69" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years65To74", + "label": "Years 65 To 74" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years70To74", + "label": "Years 70 To 74" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years75To79", + "label": "Years 75 To 79" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years75To84", + "label": "Years 75 To 84" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years80To84", + "label": "Years 80 To 84" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "USC_AgeNotStated", + "label": "USC_AgeNotStated" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years0To4", + "label": "Years 0 To 4" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, { "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "race", + "label": "race" }, - "label": "activity source" + "label": "race" }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - }, - "value_kind": "enum_value" + "options": [ + { + "value": { + "ref": { + "ref": "CDC_AmericanIndianAndAlaskaNativeAlone", + "label": "American Indian and Alaska native alone" + }, + "value_kind": "enum_value" + } } - }, - "summable": false + ], + "truncated": true, + "source": "observed" }, { "key": { - "axis": "where", - "label": "place" + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" + "options": [ + { + "value": { + "ref": { + "ref": "COVID_19", + "label": "COVID-19" + }, + "value_kind": "enum_value" + } } - }, - "summable": false + ], + "truncated": true, + "source": "observed" }, { "key": { - "axis": "when", - "label": "time window" + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" }, - "binding": { - "kind": "value", - "value": { - "value_kind": "time_window", - "time_window": { - "start_year": 2015, - "end_year": 2022 + "options": [ + { + "value": { + "ref": { + "ref": "Chinese", + "label": "Chinese" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Indian", + "label": "Indian" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Malay", + "label": "Malay" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SGP_OtherEthnicity", + "label": "SGP_OtherEthnicity" + }, + "value_kind": "enum_value" } } - }, - "summable": false - }, - { - "key": { - "axis": "source", - "label": "data source" - }, - "binding": { - "kind": "unbound" - }, - "summable": false - } - ], - "inapplicable_slots": [], - "unresolved_slots": [], - "stat_vars": { - "member_count": 1, - "member_count_exact": false, - "served_count": 1, - "data_date_range": { - "start": "2015", - "end": "2022" - } - }, - "entities": [ - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - } - ], - "coverage": { - "kind": "exact", - "has_data": true, - "observation_count": 8, - "evidence": "facet_metadata", - "dimensions": [ - { - "label": "sources", - "count": 1 - }, - { - "label": "observations", - "count": 8 - }, - { - "label": "variables", - "count": 1 - } - ], - "window": { - "start_year": 2015, - "end_year": 2022 - } - }, - "download": { - "rows": 8, - "rows_exact": true, - "series": 1, - "window": { - "start_year": 2015, - "end_year": 2022 - }, - "licence": { - "label": "Creative Commons Attribution License" - } - }, - "facets": { - "provenance": { - "basis": "fallback", - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" - }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + ], + "truncated": true, + "source": "observed" }, - "unit": { - "basis": "fallback", - "ref": "InternationalDollar", - "label": "InternationalDollar" - } - }, - "slot_options": [ { "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "residentStatus", + "label": "residentStatus" }, - "label": "activity source" + "label": "resident status" }, "options": [ { "value": { "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + "ref": "Citizen", + "label": "Citizen" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Resident", + "label": "Resident" }, "value_kind": "enum_value" } @@ -1744,36 +1958,52 @@ ], "truncated": true, "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ + }, { - "axis": "provenance", + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, "options": [ { "value": { "ref": { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators" + "ref": "Infant", + "label": "Infant" }, - "value_kind": "source" + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Newborn", + "label": "Newborn" + }, + "value_kind": "enum_value" } } ], - "truncated": false, + "truncated": true, "source": "observed" - }, + } + ], + "entity_options": [], + "facet_options": [ { - "axis": "unit", + "axis": "provenance", "options": [ { "value": { "ref": { - "ref": "InternationalDollar", - "label": "InternationalDollar" + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, - "value_kind": "enum_value" + "value_kind": "source" } } ], @@ -1781,11 +2011,11 @@ "source": "observed" } ], - "rendered_sentence": "Germany's gross national income based on purchasing power parity per capita in international dollars, 2015 to 2022. World Development Indicators.", + "rendered_sentence": "Kenya's number of deaths, 2018 to 2022. Kenya Census.", "sentence_plan": [ { "kind": "slot", - "text": "Germany", + "text": "Kenya", "axis": "where", "segment": "heading", "binding_ref": "where:", @@ -1795,55 +2025,105 @@ ] }, { - "kind": "text", - "text": "'s", + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "number of deaths", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "distinguishes": true + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "age", + "binding_ref": "how:age", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "ageGroupClassification", + "binding_ref": "how:ageGroupClassification", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", "segment": "heading", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", "entity_refs": [], "states": [] }, { - "kind": "text", - "text": " ", + "kind": "slot", + "text": "", + "axis": "how", "segment": "heading", + "property_dcid": "ethnicity", + "binding_ref": "how:ethnicity", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "gross national income based on purchasing power parity per capita", - "axis": "what", + "text": "", + "axis": "how", "segment": "heading", + "property_dcid": "gender", + "binding_ref": "how:gender", "entity_refs": [], - "states": [ - "how:activitySource" - ], - "distinguishes": true + "states": [] }, { - "kind": "text", - "text": " ", + "kind": "slot", + "text": "", + "axis": "how", "segment": "heading", + "property_dcid": "incidentType", + "binding_ref": "how:incidentType", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "in international dollars", - "axis": "unit", + "text": "", + "axis": "how", "segment": "heading", - "binding_ref": "unit:", + "property_dcid": "race", + "binding_ref": "how:race", "entity_refs": [], - "states": [ - "unit:" - ] + "states": [] }, { "kind": "slot", "text": "", "axis": "how", "segment": "heading", - "property_dcid": "activitySource", - "binding_ref": "how:activitySource", + "property_dcid": "residentStatus", + "binding_ref": "how:residentStatus", "entity_refs": [], "states": [] }, @@ -1856,14 +2136,15 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2018 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", "entity_refs": [], "states": [ "when:" - ] + ], + "distinguishes": true }, { "kind": "text", @@ -1881,7 +2162,7 @@ }, { "kind": "slot", - "text": "World Development Indicators", + "text": "Kenya Census", "axis": "source", "segment": "byline", "entity_refs": [], @@ -1901,23 +2182,23 @@ "trace": { "resolved_entities": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "resolved_sources": [ { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census", "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "ref": "dc/s/OpenDataForAfrica", + "label": "Open Data for Africa" }, "data_commons": { "id": "base", "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + "documentation": "/api/graph/documentation/dc/base/Kenya_Census" } ], "slot_filters": [ @@ -1925,232 +2206,172 @@ "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { "key": { - "axis": "where", - "label": "place" + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" }, - "binding_kind": "value", - "refs": [ - { - "ref": "country/DEU", - "label": "Germany" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { "key": { - "axis": "when", - "label": "time window" + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" }, - "binding_kind": "value", + "binding_kind": "unbound", "refs": [], "provenance": "binder" }, { "key": { - "axis": "source", - "label": "data source" + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" }, "binding_kind": "unbound", "refs": [], "provenance": "binder" - } - ], - "query_qualifiers": [], - "requested_window": { - "start_year": 2015, - "end_year": 2022 - }, - "capability_version": "cap_347a470e04c97eec", - "default_reading": { - "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] - } - }, - "confidence": "high", - "basis": "nominated", - "available_at_place": true, - "measure_label_axes": [], - "measure_axis_values": [] - } - } - ], - "truncated": false - }, - "reading_assumptions": { - "spec_c0f61f3ca3558aac184973441a67601e": [], - "spec_403a96317ee8b97f1d8569c71015e5ce": [], - "spec_d94656e5d53b7b6c6b0c683145a1cd98": [] - } - } - ], - "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", - "sentence_plan": [ - { - "kind": "text", - "text": "3 readings.", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "Germany", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "primary income", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " for ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "gross of fixed capital consumption", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "OECD DAC1", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "2015 to 2022", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "Current US dollars", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "country/KEN", + "label": "Kenya" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2013, + "end_year": 2022 + }, + "capability_version": "cap_94e25737d859392c", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "low", + "basis": "structural", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "truncated": false + }, + "reading_assumptions": { + "spec_10bf62f9687154286b463d206f03a086": [], + "spec_7923e67e0706d6d9738c78cb374ee8fb": [] + } + } + ], + "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", + "sentence_plan": [ { "kind": "text", - "text": ".", - "segment": "byline", + "text": "2 readings.", + "segment": "heading", "entity_refs": [], "states": [], "part_index": 0 @@ -2165,7 +2386,7 @@ }, { "kind": "text", - "text": "Germany", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [], @@ -2189,7 +2410,7 @@ }, { "kind": "text", - "text": "gross national income based on purchasing power parity", + "text": "deaths rate", "segment": "heading", "entity_refs": [], "states": [], @@ -2205,7 +2426,7 @@ }, { "kind": "text", - "text": "in international dollars", + "text": "per capita", "segment": "heading", "entity_refs": [], "states": [], @@ -2245,7 +2466,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2022", "segment": "byline", "entity_refs": [], "states": [], @@ -2269,7 +2490,7 @@ }, { "kind": "text", - "text": "Germany", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [], @@ -2293,23 +2514,7 @@ }, { "kind": "text", - "text": "gross national income based on purchasing power parity per capita", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "in international dollars", + "text": "number of deaths", "segment": "heading", "entity_refs": [], "states": [], @@ -2333,7 +2538,7 @@ }, { "kind": "text", - "text": "World Development Indicators", + "text": "Kenya Census", "segment": "byline", "entity_refs": [], "states": [], @@ -2349,7 +2554,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2018 to 2022", "segment": "byline", "entity_refs": [], "states": [], @@ -2383,33 +2588,34 @@ "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU" + "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, "assumptions": [], - "variable_text": "GNI" + "variable_text": "mortality" } ] } @@ -2419,7 +2625,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4386e87708a64f078f39a795faeb0100" + "x-dfo-trace-id": "8122d1bf0e034c8b833ac2f202e2a9c0" }, "json": { "schema_version": 1, @@ -2428,11 +2634,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "4386e87708a64f078f39a795faeb0100", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "8122d1bf0e034c8b833ac2f202e2a9c0", "warnings": [], "timing_ms": { - "total": 9, + "total": 637, "by_step": { "coverage": 0 } @@ -2442,20 +2648,20 @@ "kind": "resolution", "parts": [ { - "variable_text": "GNI", + "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 8, + "total": 590, "by_step": { "validate": 0, - "walk": 5, + "walk": 215, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 0, + "shape": 257, "bind": 0, - "where_places": 1, - "materialise": 0, + "where_places": 0, + "materialise": 116, "answer": 1, "options": 1 } @@ -2465,69 +2671,70 @@ "assumptions": [], "status": "definite", "spec": { - "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "definition": { "schema_version": 1, - "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU" + "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicunit_primaryincome_measuredvalue_nominal", - "label": "Gross national income", + "shape_id": "mortalityevent_count_measuredvalue_per_count_person", + "label": "Deaths Rate", "population_type": { - "ref": "EconomicUnit", - "label": "economic unit" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "primaryIncome", - "label": "primary income" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "Nominal", - "label": "Nominal" + "measurement_denominator": { + "ref": "Count_Person", + "label": "Total population" }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, { "axis": "where", @@ -2542,13 +2749,13 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", - "refine_supported": true, + "member_count": 133, + "member_digest": "c090b56d31a596a8be16dafb518382db666c6b100a80534c3cb81dbfe3111c5d", + "refine_supported": false, "data_commons": [ { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" } ] }, @@ -2557,20 +2764,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - }, - "value_kind": "enum_value" - } + "kind": "unbound" }, "summable": false }, @@ -2583,8 +2783,8 @@ "kind": "value", "value": { "ref": { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" }, "value_kind": "entity" } @@ -2601,7 +2801,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } @@ -2619,21 +2819,23 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 2, "member_count_exact": true, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2013", "end": "2022" } }, "entities": [ { - "ref": "country/DEU", - "label": "Germany", + "ref": "country/KEN", + "label": "Kenya", "entity_type": "Country", "role": "observationAbout" } @@ -2641,7 +2843,7 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 8, + "observation_count": 10, "evidence": "facet_metadata", "dimensions": [ { @@ -2650,7 +2852,7 @@ }, { "label": "observations", - "count": 8 + "count": 10 }, { "label": "variables", @@ -2658,43 +2860,46 @@ } ], "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, "download": { - "rows": 8, + "rows": 10, "rows_exact": true, "series": 1, "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, "licence": { - "label": "OECD Terms and Conditions" + "label": "Creative Commons Attribution License" } }, "facets": { "provenance": { "basis": "fallback", - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1", - "account": "provider" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "measurementMethod": { + "basis": "fallback", + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" }, "unit": { "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" + "ref": "Per1000Persons", + "label": "Per 1000 people" } }, "slot_options": [ @@ -2702,17 +2907,17 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" + "ref": "ICD10/X60-X84", + "label": "X60-X84 (Intentional self-harm)" }, "value_kind": "enum_value" } @@ -2730,8 +2935,17 @@ { "value": { "ref": { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1" + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + }, + { + "value": { + "ref": { + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, "value_kind": "source" } @@ -2740,28 +2954,54 @@ "truncated": false, "source": "observed" }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "ref": { + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, { "axis": "unit", "options": [ { "value": { "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" + "ref": "Per1000Persons", + "label": "Per 1000 people" }, "value_kind": "enum_value" } + }, + { + "value": { + "value_kind": "enum_value" + } } ], "truncated": false, "source": "observed" } ], - "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "rendered_sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators.", "sentence_plan": [ { "kind": "slot", - "text": "Germany", + "text": "Kenya", "axis": "where", "segment": "heading", "binding_ref": "where:", @@ -2786,7 +3026,7 @@ }, { "kind": "slot", - "text": "primary income", + "text": "deaths rate", "axis": "what", "segment": "heading", "entity_refs": [], @@ -2794,22 +3034,28 @@ }, { "kind": "text", - "text": " for ", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "per capita", + "axis": "unit", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "gross of fixed capital consumption", + "text": "", "axis": "how", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ] + "states": [] }, { "kind": "text", @@ -2820,7 +3066,7 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -2845,26 +3091,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -2883,23 +3110,23 @@ "trace": { "resolved_entities": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "resolved_sources": [ { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" } ], "slot_filters": [ @@ -2907,18 +3134,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -2929,8 +3151,8 @@ "binding_kind": "value", "refs": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "provenance": "binder" @@ -2956,25 +3178,60 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec" + "capability_version": "cap_94e25737d859392c" }, "confidence": "high", "available_at_place": true, "measure_label_axes": [], "measure_axis_values": [], - "related_measures": [] + "related_group": { + "ref": "dc/g/MortalityEvent", + "label": "Mortality Event" + }, + "related_measures": [ + { + "stat_var": { + "ref": "Count_Death", + "label": "Number of Deaths" + }, + "definition": { + "schema_version": 1, + "spec_id": "spec_31961a9c9519bb4db004fa793f0457e5", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "MortalityEvent", + "measured_property": "count", + "stat_type": "measuredValue" + }, + "slots": [], + "entities": { + "observationAbout": [ + "country/KEN" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2013, + "end_year": 2022 + } + } + } + } + ] } } } ], - "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "rendered_sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators.", "sentence_plan": [ { "kind": "slot", - "text": "Germany", + "text": "Kenya", "axis": "where", "segment": "heading", "binding_ref": "where:", @@ -3002,7 +3259,7 @@ }, { "kind": "slot", - "text": "primary income", + "text": "deaths rate", "axis": "what", "segment": "heading", "entity_refs": [], @@ -3011,7 +3268,16 @@ }, { "kind": "text", - "text": " for ", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "per capita", + "axis": "unit", "segment": "heading", "entity_refs": [], "states": [], @@ -3019,15 +3285,13 @@ }, { "kind": "slot", - "text": "gross of fixed capital consumption", + "text": "", "axis": "how", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ], + "states": [], "part_index": 0 }, { @@ -3039,7 +3303,7 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -3064,26 +3328,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -3111,36 +3356,37 @@ "schema_version": 1, "input": { "kind": "spec_id", - "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "definition": { "schema_version": 1, - "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU" + "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } @@ -3156,47 +3402,48 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "1b25ce6b48064cf199e5d3f405c4275a" + "x-dfo-trace-id": "5e77a52f3b71403a8932a67a979c4608" }, "json": { "schema_version": 1, "definition": { "schema_version": 1, - "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "identity": { "shape": { "kind": "statvar_schema", "stat_type": "measuredValue", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", - "measurement_qualifier": "Nominal" + "population_type": "MortalityEvent", + "measured_property": "count", + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { "binding": { - "ref": "GrossOfFixedCapitalConsumption", - "state": "value" + "state": "unbound" }, - "property": "fixedCapitalConsumptionBasis" + "property": "causeOfDeath" } ], "entities": { "observationAbout": [ - "country/DEU" + "country/KEN" ] }, "identity_version": "spec1", "requested_window": { "kind": "range", "end_year": 2022, - "start_year": 2015 + "start_year": 2013 } } }, - "content_version": "cv_3cae36487750f272df16f77858171e89", - "prepared_at": "2026-10-21T13:05:11Z", + "content_version": "cv_9834a942532e03aac3aa48f2cf731a4c", + "prepared_at": "2026-10-23T17:33:59Z", "coverage": { - "rows": 8, + "rows": 10, "dimensions": [ { "label": "observationAbout", @@ -3204,150 +3451,166 @@ }, { "label": "years", - "count": 8 + "count": 10 } ], "window": { "kind": "range", - "start_year": 2015, + "origin": "query", "end_year": 2022, - "origin": "query" + "start_year": 2013 } }, "citation": { - "text": "OECD DAC1 (2026), via the Development Finance Observatory", + "text": "World Development Indicators (2026), via the Development Finance Observatory", "sources": [ { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", - "license": "OECD Terms and Conditions", - "license_type": "OECDTermsAndConditions", - "license_url": "https://www.oecd.org/en/about/terms-conditions.html", - "url": "https://data-explorer.oecd.org/vis?fs[0]=Topic,0%7CDevelopment%23DEV%23&fs[1]=Topic,1%7CDevelopment%23DEV%23%7COfficial%20Development%20Assistance%20%28ODA%29%23DEV_ODA%23&pg=0&fc=Topic&snb=23&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_DAC1%40DF_DAC1&df[ag]=OECD.DCD.FSD&df[vs]=1.7&dq=._Z.....&pd=,&to[TIME_PERIOD]=false&isAvailabilityDisabled=false&page=0", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "license": "Creative Commons Attribution License", + "license_type": "CreativeCommonsAttributionLicense", + "license_url": "https://datacatalog.worldbank.org/search/dataset/0037712", + "url": "https://datatopics.worldbank.org/world-development-indicators/", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, "documentation": { - "publisher": "Organisation for Economic Co-operation and Development (OECD)", - "description": "DAC1 is the OECD Development Assistance Committee's table of total flows by provider. It reports each donor's ODA, other official flows, export credits and private flows by aid type, with no recipient or sector breakdown. It is the official source for headline ODA, the bilateral and multilateral split, in-donor costs such as refugees in donor countries, and the ODA/GNI ratio.", - "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC1/Table1_Data.zip", - "attribution": "OECD (2026), OECD DAC1, OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC1/Table1_Data.zip (accessed on 2026-10-12)", - "update_cadence": "Quarterly", - "last_update": "2026-10-12", - "years_covered": "1960-2025", - "granularity": "Annual, by provider and recipient", - "currencies": [ - "USD" - ], - "transformation_log": [ - { - "transformation": "Download the source data", - "description": "The OECD publishes DAC1 in April, June, September and December. The complete table is downloaded from the OECD each time it is republished, and replaces the previous copy, so the data reflects the OECD's latest release." - }, - { - "transformation": "Standardise providers", - "description": "Provider codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets. The totals DAC1 reports for groups of providers, such as all DAC countries, the G7 and the EU members of the DAC, are kept as providers of their own." - }, - { - "transformation": "Select figures", - "description": "Only figures in current US dollars are included, not constant US dollars or providers' own currencies. Amounts received are left out, though net disbursements, which subtract them, are kept. Where DAC1 reports a grant equivalent under two types of aid, the fuller of the two is used, and total flows as a share of GNI in grant equivalents are left out, since they repeat ODA as a share of GNI." - }, - { - "transformation": "Convert to whole units", - "description": "DAC1 reports amounts, GNI and population in millions, which are converted to whole units." - }, - { - "transformation": "Select dimensions", - "description": "Every figure is reported against the year and the provider. Flows are broken down by type of aid as DAC1 reports it, and by gross or net disbursements, commitments or grant equivalents, split into grants and non-grants where DAC1 splits them. Shares record that they are a share of the provider's GNI. GNI and population are reported about the provider." - } - ], - "version_history": [ - { - "date": "2026-10-14", - "title": "First release", - "changes": [ - { - "kind": "added", - "note": "Total flows by provider and aid type, including ODA, other official flows and private flows, and ODA as a share of GNI." - } - ] - } - ] + "publisher": "World Bank", + "description": "The primary World Bank collection of development indicators encompassing global economic and social data.", + "source_data_url": "http://api.worldbank.org/v2/en/country/AFG?downloadformat=csv", + "update_cadence": "Monthly", + "last_update": "2026-10-13", + "currencies": [], + "transformation_log": [], + "version_history": [] } } ] }, "trace": { - "applied_window": { - "kind": "range", - "start_year": 2015, - "end_year": 2022, - "origin": "query" - }, - "graph_revision": null, - "code_index_stamp": { - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", - "exported_at": "2026-10-20T19:50:14Z", - "graph_endpoint": "graph_release" - }, - "origin_catalogue_build_id": "20261021T070020Z-7262111e", - "source_revisions": [ - { - "source": "provenance/OECDDAC1", - "revision": "2026-10-12" - } - ], - "resolved_stat_vars": [ - { - "ref": "dcid:PrimaryIncome_EconomicUnit_GrossOfFixedCapitalConsumption_Nominal", - "roles": [ - "observationAbout" - ], - "observation_count": 8 - } - ], - "family_member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", - "family_member_count": 1, "facets": [ { + "ref": "dc/base/WorldDevelopmentIndicators", "axis": "provenance", - "ref": "provenance/OECDDAC1", "basis": "deployment_fallback", "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "8223167158242641624" + "selection_reason": "most_observations_over_disagreement", + "dispatch_facet_id": "14219717798868772133", + "default_policy_version": "1" }, { + "ref": "WorldBankWeightedAverage", "axis": "measurementMethod", - "ref": null, "basis": "deployment_fallback", "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "absent_on_selected_facet", - "dispatch_facet_id": "8223167158242641624" + "selection_reason": "most_observations_over_disagreement", + "dispatch_facet_id": "14219717798868772133", + "default_policy_version": "1" }, { + "ref": "Per1000Persons", "axis": "unit", - "ref": "CurrencyUSD", "basis": "deployment_fallback", "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "8223167158242641624" + "selection_reason": "most_observations_over_disagreement", + "dispatch_facet_id": "14219717798868772133", + "default_policy_version": "1" + } + ], + "choices": [ + { + "axis": "provenance", + "candidates": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "years": 10, + "places": 1, + "observations": 65 + }, + { + "ref": "dc/base/Kenya_Census", + "years": 1, + "places": 1, + "observations": 1 + } + ] + }, + { + "axis": "measurementMethod", + "candidates": [ + { + "ref": "WorldBankWeightedAverage", + "years": 10, + "places": 1, + "observations": 65 + }, + { + "ref": null, + "years": 1, + "places": 1, + "observations": 1 + } + ] + }, + { + "axis": "unit", + "candidates": [ + { + "ref": "Per1000Persons", + "years": 10, + "places": 1, + "observations": 65 + }, + { + "ref": null, + "years": 1, + "places": 1, + "observations": 1 + } + ] } ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2022, + "start_year": 2013 + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00260-6xk", "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-23T13:00:17Z", + "content_hash": "29eb81d7b6c88641b1d4e8eb5e850ca36de66b99d6e9e09680aac020507a6392", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "dc/base/WorldDevelopmentIndicators", + "revision": "2026-10-13" + } + ], + "capability_version": "dset_cc753cefa9199881", + "materialiser_build": "c7543c9d64fb0dbeea028b04da6c59c997e50fbc", + "resolved_stat_vars": [ + { + "ref": "dcid:Count_Death_AsAFractionOfCount_Person", + "roles": [ + "observationAbout" + ], + "observation_count": 10 + } + ], + "family_member_count": 133, + "family_member_digest": "c090b56d31a596a8be16dafb518382db666c6b100a80534c3cb81dbfe3111c5d", "frame_grammar_version": "1.1.0", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "capability_version": "dset_88fecfec3c5b89d1", - "served_from": "materialise", - "confirmed_at": "2026-10-21T13:05:11.583868+00:00" + "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", + "served_from": "head", + "confirmed_at": "2026-10-23T18:36:57.109042+00:00" }, "warnings": [], "diagnostics": [ @@ -3359,33 +3622,33 @@ ], "artifacts": [ { - "artifact_digest": "sha256:9086e741fcbfa1fe56a9d8af57c54ae3784744b50a03086d9e715623d9c71766", + "artifact_digest": "sha256:38f1b5db24567c68f9791ac00bce803082c607f23c78688edf2d95e0778a070a", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 4800, + "bytes": 5000, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:11.551892+00:00", + "created_at": "2026-10-23T17:34:00.253714+00:00", "tier": "working", - "url": "/api/datasets/spec_c0f61f3ca3558aac184973441a67601e/cv_3cae36487750f272df16f77858171e89/files/sha256:9086e741fcbfa1fe56a9d8af57c54ae3784744b50a03086d9e715623d9c71766" + "url": "/api/datasets/spec_10bf62f9687154286b463d206f03a086/cv_9834a942532e03aac3aa48f2cf731a4c/files/sha256:38f1b5db24567c68f9791ac00bce803082c607f23c78688edf2d95e0778a070a" }, { - "artifact_digest": "sha256:d822d05c709d2d1ca448023a433f936b28403893dede278e2b2696eca3587d1c", + "artifact_digest": "sha256:4ebc83c47bfdfbbe2341270bfed75fc264b6a9eb099f3b481e6cac553ce27baf", "rendering": { "statistics": "series" }, - "bytes": 5294, + "bytes": 5485, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:11.551892+00:00", + "created_at": "2026-10-23T17:34:00.253714+00:00", "tier": "working", - "url": "/api/datasets/spec_c0f61f3ca3558aac184973441a67601e/cv_3cae36487750f272df16f77858171e89/files/sha256:d822d05c709d2d1ca448023a433f936b28403893dede278e2b2696eca3587d1c" + "url": "/api/datasets/spec_10bf62f9687154286b463d206f03a086/cv_9834a942532e03aac3aa48f2cf731a4c/files/sha256:4ebc83c47bfdfbbe2341270bfed75fc264b6a9eb099f3b481e6cac553ce27baf" } ], "series_count": 1, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -3403,7 +3666,7 @@ "name": "time_period", "kind": "grain", "droppable": false, - "distinct": 8 + "distinct": 10 }, { "name": "value", @@ -3524,10 +3787,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:11.551738Z" + "held_until": "2026-11-22T17:34:00.253769Z" } } } @@ -3535,26 +3798,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_c0f61f3ca3558aac184973441a67601e/cv_3cae36487750f272df16f77858171e89/files/sha256:9086e741fcbfa1fe56a9d8af57c54ae3784744b50a03086d9e715623d9c71766" + "origin_path": "/api/datasets/spec_10bf62f9687154286b463d206f03a086/cv_9834a942532e03aac3aa48f2cf731a4c/files/sha256:38f1b5db24567c68f9791ac00bce803082c607f23c78688edf2d95e0778a070a" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A9086e741fcbfa1fe56a9d8af57c54ae3784744b50a03086d9e715623d9c71766?X-Goog-Signature=redacted", - "x-dfo-trace-id": "0abf22ccda6d4496896abfc9dbacd47b" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A38f1b5db24567c68f9791ac00bce803082c607f23c78688edf2d95e0778a070a?X-Goog-Signature=redacted", + "x-dfo-trace-id": "4893fb552b5f47aa836ba70d4d4512b9" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3A9086e741fcbfa1fe56a9d8af57c54ae3784744b50a03086d9e715623d9c71766?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A38f1b5db24567c68f9791ac00bce803082c607f23c78688edf2d95e0778a070a?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "90ff16f5dd7746d3842158d1e5ae0635" + "content-type": "application/vnd.apache.parquet" }, "body_file": "answer-candidates-choose-fetch.parquet" } @@ -3565,14 +3828,14 @@ "answer": { "kind": "resolution", "status": "candidates", - "sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", "complete": false, "specs": [], "gaps": [ { "part": 0, "kind": "choice", - "options": 3 + "options": 2 } ] } @@ -3581,17 +3844,17 @@ "answer": { "kind": "resolution", "status": "definite", - "sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators.", "complete": true, "specs": [ - "spec_c0f61f3ca3558aac184973441a67601e" + "spec_10bf62f9687154286b463d206f03a086" ], "gaps": [] } }, { "dataset": { - "rows": 8, + "rows": 10, "columns": [ "stat_var", "stat_var_label", @@ -3613,11 +3876,11 @@ "members": [ { "parts": [ - "GNI" + "mortality" ], - "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", - "content_version": "cv_3cae36487750f272df16f77858171e89", - "sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1." + "spec_id": "spec_10bf62f9687154286b463d206f03a086", + "content_version": "cv_9834a942532e03aac3aa48f2cf731a4c", + "sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators." } ], "missing": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.parquet b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.parquet index 4b92f5b78256ab7d29cbbf74f285b2642a8b15e2..39ea8a31a365aa95ad7f20244925b92dae96c732 100644 GIT binary patch literal 5000 zcmcIoU2NM_6t+#8r9W%atu_t|5KY4>D_hcbg%(Ya>$Pd=+OCbZriqY>V|z)~{NXqW zt&sQ;0*MC@Frht6h{rtuLVyqt2oMiwPdxB|gfw8lKs>2UvE10p54; z2QA)x;AYy^Eq2=)E~dd>7VFMX2e3Y= z7uOXRqaCzEY}{N7z0UI4Iq*EjZPEAj9;Sn3zS-+zzJ>EDoZrFuJ)A$ld2O%n_>X%4 z433{R?*JL%4{gUz^jSS3TBC=+47x}u8UOJ{EIb|lk<+ycpbjAcPUqPzQp_mJzW#17 z`oy^p%~vi2qc48?=itLH2BWWtp5@**gV6)wuMc^j3Px8Z-n(4;Xs>wa$nDWe_N8AR z|M<>M-{6CxXb(5^obXjJ>ZD55KtuFdMv$sgx-->7{Gb(weUrUFA2ND45{WbtyW$d% z-ewK4rR@?Ti9c*%?4RjtV1y7PRMt!7yjzy`0f=2iY!$e`Fg!O0d@&K=%J=g7wxfFQ z00{SpG*&c3|DWKdu(hLUlcwz!k7xMPotBOc&o zi@}|b9k3XLkV44f5Zal<0ZPJMU2NCsLS>F$w5Uku4+0fU4X2fg9;O(RdQH!l$_2e> zK2+3ls$!N5x0E}0<5A)+bX@pF`ALgk=<(o|t8BzVZJ7ldzH-+W+x9xy1g`tX7|~l% zvwA_{?_l_zyExHTF%@&QrWkiIb4ZX1doAH=UP~FRJTy^zO2eQ}tDd zf39MecVb4YuItTn>@Vm_rE2Jy9rL=GEot^Kw>o;AB)ZB*siqf|qN>}6`nSbRV}yY~ zFmSz3VuE~6V2ttl1KZB$IblHfnG=5Fq-R*k_y1P-z&%hyV1vS4%n!HY!ewv38;}^> z#O(B1(twhDixu8yrT1@<{^pRSy~4Madne8n))mK*Q#PbuJknbpiexMJt<`_mNIN7b z#e1F=US_3Nz0$P~#A|&qaAIgplksfE)Slqf?iEhB#7WopNPl^QH&y)|hXV-D3qmn>+F+0_ zE|8`bV&8JMtUT?PuHBTC?G0+n#udNxk^g3xIJYxu>pCku!%4sOOBedle>;}>wl4rq zZ(O~_HF`Vknv}{5obW0q{kvbfxF4ystMoT|4R8{==y4@v+oCCl4>;iyPI^s{-rpo#%v$uyRG|_gj%y+roasvhU>b_O^F~s{vs^@(Iu0#sq?5 z4~fT5CGKy$5{OTBhVdBAOcFwt;Kbu3A$1~WNQ{sSIgz0YxT1bS$*z>(Bs8fS{5o0zYU&3);uvft*A|xq^?2c%f9}GvTx0Ff?R2 zPK9fD#etg#<*Uxj*0jQMHJKPYms*~vBonjwG*yu2aeQuZG#svjVCf9ipP_y9kv`G+ z&B*KN(NsQNh*gs#XMq2?iEwx*(t=;Y0XF;Fr;G80)JnXR9*Lh# zPsehpM4eO+e`o{jp^v6wFne$X#ix(hBr-nAW-1Ze&{lwdV!5hK4d=D#Y%PWTr%vPe zOt{wM4;8y?d}gtoEW|dz4`X0!9otij_l3iejiDxd86ARwunu&+TvrQu^kFW!vQSp* zWE}By9N*4=XkvO{SSBBt7wTcnBS0?NxV0X3@PDKfQC%6RMeVpb12oO z^CtMHo?4kLr$?4>J;1uifcF~ffsTX}0yArtz0Le>&7TBnrAKBrz}84|B@Xt+Cxqee`Zf3l_k6&u}wa7=C=Gfg;vzj zcoy)1&+JwXlX)CJzC>g?-)UUMxM5)OZ3Sg>ebG&Uu3uE3`vt70g$T^=Ecl-0B(863 zC?kf-it%VwH;<_0@)5-_O7#$Y&Q{=SBQ$dCXyj-FUZLSTW%obkpC0(v0se#g5Ah6u A!~g&Q literal 4800 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

(EL2txqt~;oCmK#a zi+iqItmF+^;goPuBW!8V?I!eIleM3D`QJ?+wHUO!S~zI;u|G7U-Dc1q5g~9a*08Nd z_u=hhq2M$1|EsXqg5GF(j)DPF1{ZtjMYPoln}&DTJpp}v6!gLk_Ld1fGQu5Ujs4Jq z?wP^KdtkjoV&Al(eJgy?vB@6T(G@$KG0w9)BKqC|*NoN1Z5P^eDthpjPJ};oolr8J zVILkx2X6SpRN%imfp%ZA8o_IBhm+j95ek+zXm0O-Z_EOF@g%y@4G+vE z_BKZEW0_d+fFT~#JLw9^o z)lb4{o5XGpppW{&+>(U5HoJR2B%DGz;imv&vKn6?$z(kJ%1Um&u$VRe){4~y7JJw> z91A4~NsdI^##=jR0J84)Jm-K&f^3#W~0irv@<|r1GvXmyvx6Vbc}lqhSi;7~FIPISJ2V zOn`Iu@v;I3R)Dz2c~Zx;uNipP9p*<$w6U%-#T}YFXgX~de4+VVCF#%fu2yFj>7B{& zl9KM1Y1eh?CMFb+j47KklgDdBIY*``C$cuxyRbIxjV{o$o=s1#X{ZJ(|eRbvSP-#Qv2bI+-zgcPnfMYjO;q==+&!^%cfQ?){M@Eo_A>Qk9$PhoPf zmQDN1Y9Lag#I6ar+3DEoY_pt=uICpQ%F~(X?951{IGwJOvQj^=f#GMnT_e#l<_k(k zF;y`^=<^t+O%Reh6s6DOiR|O)jH*iiOo!$Za(29DDwCYeFGkL*VLH91se}v-F-DR8 hH_K~<)$Uxi+MTV{mg?eqp$2;Nn(o&QhLK6q`#0cMhK2wD diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json index 010956c..f76ba2b 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json @@ -30,7 +30,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "d09ca5f0ae574410bf93b5d905ea8009" + "x-dfo-trace-id": "8ff5daac36fe403ab946f5b02785cb0d" }, "json": { "schema_version": 1, @@ -41,47 +41,58 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d09ca5f0ae574410bf93b5d905ea8009", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "8ff5daac36fe403ab946f5b02785cb0d", "warnings": [], "timing_ms": { - "total": 5038, + "total": 4716, "by_step": { "coverage": 0, - "extract": 1141 + "extract": 1242, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 6116, - "output_tokens": 408, - "cached_tokens": 0 + "input_tokens": 6216, + "output_tokens": 423, + "cached_tokens": 841 }, "timed_out": false }, "kind": "resolution", "parts": [ { - "variable_text": "basic health care ODA disbursements", + "variable_text": "ODA disbursements for basic health care", "warnings": [], "timing_ms": { - "total": 3758, + "total": 3468, "by_step": { - "recall": 694, + "recall": 547, + "phase_resolve_places": 0, + "phase_check_entities": 0, "shape_arcs": 1, "shape_probe_coverage": 6, - "shape_probe": 489, - "shape_groups": 16, - "shape_labels": 0, - "shape_admission": 1, - "shape": 1365, - "bind": 1248, - "materialise": 11, - "answer": 423, - "options": 17 + "shape_probe": 136, + "shape_groups": 43, + "shape_labels": 1, + "shape_admission": 0, + "phase_derive_shapes": 0, + "shape": 1190, + "phase_prune_and_rank": 0, + "bind": 1278, + "phase_bind": 149, + "phase_settle": 50, + "phase_place_bindings": 19, + "phase_facet_requests": 0, + "materialise": 30, + "phase_materialise": 0, + "answer": 110, + "options": 38, + "phase_outcome": 57 } }, "restatement": { - "variable_text": "basic health care ODA disbursements", + "variable_text": "ODA disbursements for basic health care", "entities": [ { "text": "Germany", @@ -190,6 +201,14 @@ }, "measurement_denominator_unresolved": false, "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, { "axis": "how", "property": { @@ -230,14 +249,6 @@ }, "label": "netting basis" }, - { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, { "axis": "where", "label": "place" @@ -262,6 +273,20 @@ ] }, "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, { "key": { "axis": "how", @@ -360,20 +385,6 @@ }, "summable": false }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding": { - "kind": "unbound" - }, - "summable": true - }, { "key": { "axis": "where", @@ -510,7 +521,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "facets": { "provenance": { "basis": "fallback", @@ -535,102 +546,6 @@ } }, "slot_options": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsPurpose", - "label": "CRS purpose" - }, - "label": "sector" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSPurposeCode122", - "label": "basic health" - }, - "value_kind": "enum_value" - }, - "relation": "parent", - "parent": "CRSPurposeCode120", - "member_count": 4, - "served_rows": 88, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFinance", - "label": "CRS type of finance" - }, - "label": "instrument" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance100", - "label": "grant" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 30, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance110", - "label": "standard grant" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSTypeOfFinance100", - "member_count": 12672, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFlow", - "label": "CRS type of flow" - }, - "label": "flow" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 14098, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, { "key": { "axis": "how", @@ -739,6 +654,102 @@ ], "truncated": false, "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 88, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 30, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" } ], "entity_options": [], @@ -1006,6 +1017,19 @@ } ], "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "how", @@ -1091,19 +1115,6 @@ ], "provenance": "measure_elected" }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "where", @@ -1139,31 +1150,31 @@ ], "query_qualifiers": [ { - "text": "basic health care", + "text": "ODA", "named": [ { - "ref": "CRSPurposeCode12220", - "label": "basic health care" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" } ], - "slot": "crsPurpose", + "slot": "crsTypeOfFlow", "disposition": "bound", "selected": [] }, { - "text": "ODA", + "text": "basic health care", "named": [ { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode12220", + "label": "basic health care" } ], - "slot": "crsTypeOfFlow", + "slot": "crsPurpose", "disposition": "bound", "selected": [] } ], - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3680,7 +3691,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "d09ca5f0ae574410bf93b5d905ea8009" + "trace_id": "8ff5daac36fe403ab946f5b02785cb0d" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json index c9d2c46..781f7ea 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json @@ -10,7 +10,7 @@ "call": [ { "op": "search", - "question": "ODA disbursements from Germany to Congo" + "question": "ODA disbursements from Germany to Congo in 2018" } ], "exchanges": [ @@ -22,7 +22,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, @@ -30,31 +30,32 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d" + "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f" }, "json": { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "ODA disbursements from Germany to Congo", - "normalized_query": "ODA disbursements from Germany to Congo", + "raw_query": "ODA disbursements from Germany to Congo in 2018", + "normalized_query": "ODA disbursements from Germany to Congo in 2018", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "95b872cf11e44fffb92260b2bb583f0d", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "a321fb82bfba461b9dc922634789650f", "warnings": [], "timing_ms": { - "total": 1697, + "total": 1126, "by_step": { "coverage": 0, - "extract": 982 + "extract": 1119, + "cache_lookup": 1 } }, "llm_usage": { - "input_tokens": 2249, - "output_tokens": 154, - "cached_tokens": 859 + "input_tokens": 2233, + "output_tokens": 193, + "cached_tokens": 841 }, "timed_out": false }, @@ -99,7 +100,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "95b872cf11e44fffb92260b2bb583f0d" + "trace_id": "a321fb82bfba461b9dc922634789650f" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-folded-parts-unnamed.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-folded-parts-unnamed.json index 6432111..deece61 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-folded-parts-unnamed.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-folded-parts-unnamed.json @@ -33,7 +33,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "3ceef86d0eac49fa96380d3340878cf1" + "x-dfo-trace-id": "6d68317966c44c48a0701ff661a5e655" }, "json": { "schema_version": 1, @@ -44,20 +44,23 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "3ceef86d0eac49fa96380d3340878cf1", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "6d68317966c44c48a0701ff661a5e655", "warnings": [], "timing_ms": { - "total": 5613, + "total": 4868, "by_step": { "coverage": 0, - "extract": 1020 + "extract": 1143, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 15731, - "output_tokens": 1021, - "cached_tokens": 861 + "input_tokens": 2237, + "output_tokens": 215, + "cached_tokens": 842, + "jev_input_tokens": 25205, + "jev_output_tokens": 5698 }, "timed_out": false }, @@ -66,24 +69,34 @@ { "warnings": [], "timing_ms": { - "total": 3674, + "total": 3437, "by_step": { - "recall": 773, - "shape_arcs": 0, - "shape_probe_coverage": 11, - "shape_probe": 224, - "shape_groups": 26, - "shape_labels": 8, - "shape_admission": 0, - "shape": 1251, - "bind": 1411, - "materialise": 115, - "answer": 15, - "options": 109 + "recall": 538, + "phase_resolve_places": 0, + "phase_check_entities": 0, + "shape_arcs": 85, + "shape_probe_coverage": 3, + "shape_probe": 426, + "shape_groups": 43, + "shape_labels": 9, + "shape_admission": 1, + "phase_derive_shapes": 0, + "shape": 1403, + "phase_prune_and_rank": 0, + "bind": 228, + "phase_bind": 458, + "phase_settle": 103, + "phase_place_bindings": 23, + "phase_facet_requests": 0, + "materialise": 385, + "phase_materialise": 1, + "answer": 18, + "options": 174, + "phase_outcome": 106 } }, "restatement": { - "variable_text": "ODA disbursements for health", + "variable_text": "health ODA disbursements", "entities": [ { "text": "Germany", @@ -195,14 +208,6 @@ }, "measurement_denominator_unresolved": false, "slot_keys": [ - { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, { "axis": "how", "property": { @@ -243,6 +248,14 @@ }, "label": "netting basis" }, + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, { "axis": "where", "label": "place" @@ -267,20 +280,6 @@ ] }, "slots": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding": { - "kind": "unbound" - }, - "summable": true - }, { "key": { "axis": "how", @@ -480,6 +479,20 @@ }, "summable": false }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, { "key": { "axis": "where", @@ -587,170 +600,6 @@ } }, "slot_options": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSCooperationModalityB", - "label": "core contribution and pooled programme and fund" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 104, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityB03", - "label": "contribution to specific-purpose programme and fund managed by an international organisation" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityB", - "member_count": 1606, - "served_rows": 21, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityB01", - "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityB", - "member_count": 1331, - "served_rows": 83, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityC", - "label": "project-type intervention (group)" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 136, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityC01", - "label": "project-type intervention" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityC", - "member_count": 7005, - "served_rows": 136, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityD", - "label": "expert and other technical assistance" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 111, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityD02", - "label": "other technical assistance" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityD", - "member_count": 1600, - "served_rows": 84, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityD01", - "label": "donor country personnel" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityD", - "member_count": 976, - "served_rows": 27, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityE", - "label": "scholarship and student cost in donor country" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 38, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityE01", - "label": "scholarship and training in donor country" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityE", - "member_count": 819, - "served_rows": 19, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSCooperationModalityE02", - "label": "imputed student cost" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSCooperationModalityE", - "member_count": 315, - "served_rows": 19, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, { "key": { "axis": "how", @@ -970,44 +819,208 @@ ], "truncated": false, "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ + }, { - "axis": "provenance", + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, "options": [ { "value": { "ref": { - "ref": "provenance/OECDCreditorReportingSystem", - "label": "OECD Creditor Reporting System (CRS)" + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" }, - "value_kind": "source" - } - } - ], - "truncated": false, - "source": "observed" - }, - { - "axis": "unit", - "options": [ + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 104, + "served_rows_exact": true + }, { "value": { "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" }, "value_kind": "enum_value" - } - } - ], - "truncated": false, - "source": "observed" - } - ], - "rendered_sentence": "Germany's gross ODA disbursements to Kenya for education and health, 1997 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1606, + "served_rows": 21, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 83, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 136, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 136, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 111, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 1600, + "served_rows": 84, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 976, + "served_rows": 27, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE", + "label": "scholarship and student cost in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 38, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 819, + "served_rows": 19, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 315, + "served_rows": 19, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDCreditorReportingSystem", + "label": "OECD Creditor Reporting System (CRS)" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Germany's gross ODA disbursements to Kenya for education and health, 1997 to 2024. Current US dollars · OECD Creditor Reporting System (CRS).", "sentence_plan": [ { "kind": "slot", @@ -1236,19 +1249,6 @@ } ], "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "how", @@ -1338,6 +1338,19 @@ ], "provenance": "measure_elected" }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "where", @@ -1373,26 +1386,26 @@ ], "query_qualifiers": [ { - "text": "ODA", + "text": "health", "named": [ { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode120", + "label": "health" } ], - "slot": "crsTypeOfFlow", + "slot": "crsPurpose", "disposition": "bound", "selected": [] }, { - "text": "health", + "text": "ODA", "named": [ { - "ref": "CRSPurposeCode120", - "label": "health" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" } ], - "slot": "crsPurpose", + "slot": "crsTypeOfFlow", "disposition": "bound", "selected": [] }, @@ -1409,7 +1422,7 @@ "selected": [] } ], - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3733,28 +3746,38 @@ { "code": "binding_folded", "severity": "info", - "message": "'ODA disbursements for education' resolved to the same shape as an earlier part; folded into that part's spec." + "message": "'education ODA disbursements' resolved to the same shape as an earlier part; folded into that part's spec." } ], "timing_ms": { - "total": 3542, + "total": 3091, "by_step": { - "recall": 791, - "shape_arcs": 0, + "recall": 450, + "phase_resolve_places": 0, + "phase_check_entities": 0, + "shape_arcs": 93, "shape_probe_coverage": 2, - "shape_probe": 240, - "shape_groups": 39, - "shape_labels": 5, + "shape_probe": 98, + "shape_groups": 44, + "shape_labels": 9, "shape_admission": 1, - "shape": 1008, - "bind": 1505, - "materialise": 146, - "answer": 13, - "options": 79 + "phase_derive_shapes": 0, + "shape": 374, + "phase_prune_and_rank": 0, + "bind": 223, + "phase_bind": 160, + "phase_settle": 51, + "phase_place_bindings": 27, + "phase_facet_requests": 0, + "materialise": 1197, + "phase_materialise": 0, + "answer": 20, + "options": 455, + "phase_outcome": 134 } }, "restatement": { - "variable_text": "ODA disbursements for education", + "variable_text": "education ODA disbursements", "entities": [ { "text": "Germany", @@ -3866,14 +3889,6 @@ }, "measurement_denominator_unresolved": false, "slot_keys": [ - { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, { "axis": "how", "property": { @@ -3914,6 +3929,14 @@ }, "label": "netting basis" }, + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, { "axis": "where", "label": "place" @@ -3938,20 +3961,6 @@ ] }, "slots": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding": { - "kind": "unbound" - }, - "summable": true - }, { "key": { "axis": "how", @@ -4151,6 +4160,20 @@ }, "summable": false }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, { "key": { "axis": "where", @@ -4262,160 +4285,189 @@ "key": { "axis": "how", "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" + "ref": "crsPurpose", + "label": "CRS purpose" }, - "label": "modality" + "label": "sector" }, "options": [ { "value": { "ref": { - "ref": "CRSCooperationModalityB", - "label": "core contribution and pooled programme and fund" + "ref": "CRSPurposeCode121", + "label": "general health" }, "value_kind": "enum_value" }, - "relation": "root", - "member_count": 0, - "served_rows": 104, + "relation": "child", + "parent": "CRSPurposeCode120", + "member_count": 6, + "served_rows": 82, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityB03", - "label": "contribution to specific-purpose programme and fund managed by an international organisation" + "ref": "CRSPurposeCode122", + "label": "basic health" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSCooperationModalityB", - "member_count": 1606, - "served_rows": 21, + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 108, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityB01", - "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" + "ref": "CRSPurposeCode123", + "label": "noncommunicable disease" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSCooperationModalityB", - "member_count": 1331, - "served_rows": 83, + "parent": "CRSPurposeCode120", + "member_count": 3, + "served_rows": 4, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityC", - "label": "project-type intervention (group)" + "ref": "CRSPurposeCode100", + "label": "social infrastructure and services" }, "value_kind": "enum_value" }, - "relation": "root", - "member_count": 0, - "served_rows": 136, + "relation": "parent", + "member_count": 13, + "served_rows": 1214, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityC01", - "label": "project-type intervention" + "ref": "CRSPurposeCode111", + "label": "unspecified-level education" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSCooperationModalityC", - "member_count": 7005, - "served_rows": 136, + "parent": "CRSPurposeCode110", + "member_count": 6, + "served_rows": 78, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityD", - "label": "expert and other technical assistance" + "ref": "CRSPurposeCode112", + "label": "basic education" }, "value_kind": "enum_value" }, - "relation": "root", - "member_count": 0, - "served_rows": 111, + "relation": "child", + "parent": "CRSPurposeCode110", + "member_count": 6, + "served_rows": 77, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityD02", - "label": "other technical assistance" + "ref": "CRSPurposeCode113", + "label": "upper secondary education" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSCooperationModalityD", - "member_count": 1600, - "served_rows": 84, + "parent": "CRSPurposeCode110", + "member_count": 5, + "served_rows": 69, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityD01", - "label": "donor country personnel" + "ref": "CRSPurposeCode114", + "label": "post-secondary education" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSCooperationModalityD", - "member_count": 976, - "served_rows": 27, + "parent": "CRSPurposeCode110", + "member_count": 4, + "served_rows": 94, "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" }, + "label": "instrument" + }, + "options": [ { "value": { "ref": { - "ref": "CRSCooperationModalityE", - "label": "scholarship and student cost in donor country" + "ref": "CRSTypeOfFinance100", + "label": "grant" }, "value_kind": "enum_value" }, "relation": "root", "member_count": 0, - "served_rows": 38, + "served_rows": 501, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityE01", - "label": "scholarship and training in donor country" + "ref": "CRSTypeOfFinance110", + "label": "standard grant" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSCooperationModalityE", - "member_count": 819, - "served_rows": 19, + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 501, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSCooperationModalityE02", - "label": "imputed student cost" + "ref": "CRSTypeOfFinance420", + "label": "debt instrument" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 11, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance421", + "label": "standard loan" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSCooperationModalityE", - "member_count": 315, - "served_rows": 19, + "parent": "CRSTypeOfFinance420", + "member_count": 4620, + "served_rows": 11, "served_rows_exact": true } ], @@ -4426,216 +4478,187 @@ "key": { "axis": "how", "property": { - "ref": "crsPurpose", - "label": "CRS purpose" + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" }, - "label": "sector" + "label": "flow" }, "options": [ { "value": { "ref": { - "ref": "CRSPurposeCode121", - "label": "general health" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" }, "value_kind": "enum_value" }, - "relation": "child", - "parent": "CRSPurposeCode120", - "member_count": 6, - "served_rows": 82, + "relation": "root", + "member_count": 14098, + "served_rows": 512, "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" }, + "label": "modality" + }, + "options": [ { "value": { "ref": { - "ref": "CRSPurposeCode122", - "label": "basic health" + "ref": "CRSCooperationModalityB", + "label": "core contribution and pooled programme and fund" }, "value_kind": "enum_value" }, - "relation": "child", - "parent": "CRSPurposeCode120", - "member_count": 4, - "served_rows": 108, + "relation": "root", + "member_count": 0, + "served_rows": 104, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode123", - "label": "noncommunicable disease" + "ref": "CRSCooperationModalityB03", + "label": "contribution to specific-purpose programme and fund managed by an international organisation" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSPurposeCode120", - "member_count": 3, - "served_rows": 4, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSPurposeCode100", - "label": "social infrastructure and services" - }, - "value_kind": "enum_value" - }, - "relation": "parent", - "member_count": 13, - "served_rows": 1214, + "parent": "CRSCooperationModalityB", + "member_count": 1606, + "served_rows": 21, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode111", - "label": "unspecified-level education" + "ref": "CRSCooperationModalityB01", + "label": "core support to non-governmental organisations, other private bodies, public-private partnerships, and research institutes" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSPurposeCode110", - "member_count": 6, - "served_rows": 78, + "parent": "CRSCooperationModalityB", + "member_count": 1331, + "served_rows": 83, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode112", - "label": "basic education" + "ref": "CRSCooperationModalityC", + "label": "project-type intervention (group)" }, "value_kind": "enum_value" }, - "relation": "child", - "parent": "CRSPurposeCode110", - "member_count": 6, - "served_rows": 77, + "relation": "root", + "member_count": 0, + "served_rows": 136, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode113", - "label": "upper secondary education" + "ref": "CRSCooperationModalityC01", + "label": "project-type intervention" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSPurposeCode110", - "member_count": 5, - "served_rows": 69, + "parent": "CRSCooperationModalityC", + "member_count": 7005, + "served_rows": 136, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSPurposeCode114", - "label": "post-secondary education" + "ref": "CRSCooperationModalityD", + "label": "expert and other technical assistance" }, "value_kind": "enum_value" }, - "relation": "child", - "parent": "CRSPurposeCode110", - "member_count": 4, - "served_rows": 94, + "relation": "root", + "member_count": 0, + "served_rows": 111, "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFinance", - "label": "CRS type of finance" }, - "label": "instrument" - }, - "options": [ { "value": { "ref": { - "ref": "CRSTypeOfFinance100", - "label": "grant" + "ref": "CRSCooperationModalityD02", + "label": "other technical assistance" }, "value_kind": "enum_value" }, - "relation": "root", - "member_count": 0, - "served_rows": 501, + "relation": "child", + "parent": "CRSCooperationModalityD", + "member_count": 1600, + "served_rows": 84, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSTypeOfFinance110", - "label": "standard grant" + "ref": "CRSCooperationModalityD01", + "label": "donor country personnel" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSTypeOfFinance100", - "member_count": 12672, - "served_rows": 501, + "parent": "CRSCooperationModalityD", + "member_count": 976, + "served_rows": 27, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSTypeOfFinance420", - "label": "debt instrument" + "ref": "CRSCooperationModalityE", + "label": "scholarship and student cost in donor country" }, "value_kind": "enum_value" }, "relation": "root", "member_count": 0, - "served_rows": 11, + "served_rows": 38, "served_rows_exact": true }, { "value": { "ref": { - "ref": "CRSTypeOfFinance421", - "label": "standard loan" + "ref": "CRSCooperationModalityE01", + "label": "scholarship and training in donor country" }, "value_kind": "enum_value" }, "relation": "child", - "parent": "CRSTypeOfFinance420", - "member_count": 4620, - "served_rows": 11, + "parent": "CRSCooperationModalityE", + "member_count": 819, + "served_rows": 19, "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFlow", - "label": "CRS type of flow" }, - "label": "flow" - }, - "options": [ { "value": { "ref": { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSCooperationModalityE02", + "label": "imputed student cost" }, "value_kind": "enum_value" }, - "relation": "root", - "member_count": 14098, - "served_rows": 512, + "relation": "child", + "parent": "CRSCooperationModalityE", + "member_count": 315, + "served_rows": 19, "served_rows_exact": true } ], @@ -4907,19 +4930,6 @@ } ], "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "how", @@ -5009,6 +5019,19 @@ ], "provenance": "measure_elected" }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "where", @@ -5044,26 +5067,26 @@ ], "query_qualifiers": [ { - "text": "ODA", + "text": "health", "named": [ { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode120", + "label": "health" } ], - "slot": "crsTypeOfFlow", + "slot": "crsPurpose", "disposition": "bound", "selected": [] }, { - "text": "health", + "text": "ODA", "named": [ { - "ref": "CRSPurposeCode120", - "label": "health" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" } ], - "slot": "crsPurpose", + "slot": "crsTypeOfFlow", "disposition": "bound", "selected": [] }, @@ -5080,7 +5103,7 @@ "selected": [] } ], - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -7413,20 +7436,30 @@ } ], "timing_ms": { - "total": 3536, + "total": 707, "by_step": { - "recall": 778, - "shape_arcs": 2, - "shape_probe_coverage": 2, - "shape_probe": 277, - "shape_groups": 24, - "shape_labels": 5, + "recall": 3, + "phase_resolve_places": 0, + "phase_check_entities": 0, + "shape_arcs": 3, + "shape_probe_coverage": 6, + "shape_probe": 146, + "shape_groups": 48, + "shape_labels": 9, "shape_admission": 1, - "shape": 973, - "bind": 1109, - "materialise": 1, - "answer": 210, - "options": 465 + "phase_derive_shapes": 0, + "shape": 316, + "phase_prune_and_rank": 0, + "bind": 143, + "phase_bind": 4, + "phase_settle": 16, + "phase_place_bindings": 7, + "phase_facet_requests": 0, + "materialise": 98, + "phase_materialise": 1, + "answer": 6, + "options": 108, + "phase_outcome": 5 } }, "restatement": { @@ -8849,7 +8882,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -9382,7 +9415,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -9963,7 +9996,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "ee49afa94b0440c9b557ce3413d538a5" + "x-dfo-trace-id": "a13e0dc54c8e45028d75f8588accdaff" }, "json": { "schema_version": 1, @@ -10038,7 +10071,7 @@ } }, "content_version": "cv_d6ce435ea267b46680c94eae9423d420", - "prepared_at": "2026-10-21T13:05:29Z", + "prepared_at": "2026-10-20T15:55:47Z", "coverage": { "rows": 512, "dimensions": [ @@ -10067,9 +10100,9 @@ ], "window": { "kind": "all", - "start_year": 1997, + "origin": "default", "end_year": 2024, - "origin": "default" + "start_year": 1997 } }, "citation": { @@ -10155,25 +10188,47 @@ ] }, "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], "applied_window": { "kind": "all", - "start_year": 1997, + "origin": "default", "end_year": 2024, - "origin": "default" + "start_year": 1997 }, - "graph_revision": null, + "graph_revision": "dfo-dev-dc-datacommons-service-00259-rpx", + "normalisations": [], "code_index_stamp": { + "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", - "exported_at": "2026-10-20T19:50:14Z", "graph_endpoint": "graph_release" }, - "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", "revision": "2026-10-15" } ], + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA01_CRSPurposeCode11330_Nominal", @@ -14536,34 +14591,12 @@ "observation_count": 0 } ], - "family_member_digest": "0c7508fd1997d6cdc896f2eab0f092a4915cfca9e2400eb9577bb22b527fe882", "family_member_count": 545, - "facets": [ - { - "axis": "provenance", - "ref": "provenance/OECDCreditorReportingSystem", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868" - }, - { - "axis": "unit", - "ref": "CurrencyUSD", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868" - } - ], - "normalisations": [], + "family_member_digest": "0c7508fd1997d6cdc896f2eab0f092a4915cfca9e2400eb9577bb22b527fe882", "frame_grammar_version": "1.1.0", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "capability_version": "dset_88fecfec3c5b89d1", - "served_from": "materialise", - "confirmed_at": "2026-10-21T13:05:29.417660+00:00" + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "served_from": "head", + "confirmed_at": "2026-10-23T18:37:07.941117+00:00" }, "warnings": [], "diagnostics": [ @@ -14575,17 +14608,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d", + "artifact_digest": "sha256:a189b171faab41729ddc1317add46add9b5eefb5fcac62a98cb735cb5f20f0f8", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 16150, + "bytes": 16208, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:29.374895+00:00", + "created_at": "2026-10-23T16:58:41.714148+00:00", "tier": "working", - "url": "/api/datasets/spec_25f482395c5d012ec278118f38dff29c/cv_d6ce435ea267b46680c94eae9423d420/files/sha256:20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d" + "url": "/api/datasets/spec_25f482395c5d012ec278118f38dff29c/cv_d6ce435ea267b46680c94eae9423d420/files/sha256:a189b171faab41729ddc1317add46add9b5eefb5fcac62a98cb735cb5f20f0f8", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:a5d2d7627c8fe1357519ca0ac021c791182ab08c76f44e8055b4bb50a6059179", @@ -14594,14 +14628,14 @@ }, "bytes": 11612, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:29.374895+00:00", + "created_at": "2026-10-20T15:55:47.734234+00:00", "tier": "working", "url": "/api/datasets/spec_25f482395c5d012ec278118f38dff29c/cv_d6ce435ea267b46680c94eae9423d420/files/sha256:a5d2d7627c8fe1357519ca0ac021c791182ab08c76f44e8055b4bb50a6059179" } ], "series_count": 108, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -14734,6 +14768,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -14793,13 +14851,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [ @@ -14836,10 +14918,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:29.374859Z" + "held_until": "2026-11-19T15:55:47.734809Z" } } } @@ -14847,26 +14929,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_25f482395c5d012ec278118f38dff29c/cv_d6ce435ea267b46680c94eae9423d420/files/sha256:20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d" + "origin_path": "/api/datasets/spec_25f482395c5d012ec278118f38dff29c/cv_d6ce435ea267b46680c94eae9423d420/files/sha256:a189b171faab41729ddc1317add46add9b5eefb5fcac62a98cb735cb5f20f0f8" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d?X-Goog-Signature=redacted", - "x-dfo-trace-id": "cee84dbe25214a0f8ea3f0a28ce10adc" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Aa189b171faab41729ddc1317add46add9b5eefb5fcac62a98cb735cb5f20f0f8?X-Goog-Signature=redacted", + "x-dfo-trace-id": "98ab007ae74543b6ba88210aaea181bb" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3A20de1920cc7d185366a8ef7120e53b8189b34cc22d8a10a414194ecd9cb32d8d?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Aa189b171faab41729ddc1317add46add9b5eefb5fcac62a98cb735cb5f20f0f8?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "c3f031f1d3724d2ea9b19e58197e4f03" + "content-type": "application/vnd.apache.parquet" }, "body_file": "answer-several-readings-folded.parquet" } @@ -14947,7 +15029,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e043b83fa1f8472e814c68afde278ab8" + "x-dfo-trace-id": "0a0ec8988f20490a80444b30363ade09" }, "json": { "schema_version": 1, @@ -15008,7 +15090,7 @@ } }, "content_version": "cv_91f57bfc5bbc5f09983596996238787d", - "prepared_at": "2026-10-21T13:05:30Z", + "prepared_at": "2026-10-20T15:55:49Z", "coverage": { "rows": 132, "dimensions": [ @@ -15023,9 +15105,9 @@ ], "window": { "kind": "all", - "start_year": 1960, + "origin": "default", "end_year": 2025, - "origin": "default" + "start_year": 1960 } }, "citation": { @@ -15060,25 +15142,56 @@ ] }, "trace": { + "facets": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "8535402560764839853", + "default_policy_version": "1" + }, + { + "ref": null, + "axis": "measurementMethod", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "8535402560764839853", + "default_policy_version": "1" + }, + { + "ref": "USDollar", + "axis": "unit", + "basis": "bound", + "default_policy": null, + "selection_reason": null, + "dispatch_facet_id": "8535402560764839853", + "default_policy_version": null + } + ], "applied_window": { "kind": "all", - "start_year": 1960, + "origin": "default", "end_year": 2025, - "origin": "default" + "start_year": 1960 }, - "graph_revision": null, + "graph_revision": "dfo-dev-dc-datacommons-service-00259-rpx", + "normalisations": [], "code_index_stamp": { + "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", - "exported_at": "2026-10-20T19:50:14Z", "graph_endpoint": "graph_release" }, - "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "dc/base/WorldDevelopmentIndicators", "revision": "2026-10-13" } ], + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_EconomicActivity_GrossDomesticProduction_Nominal", @@ -15088,43 +15201,12 @@ "observation_count": 132 } ], - "family_member_digest": "73519eeb75639bdae33042fc844830cd46becc08e4f9122dfcd0886e9875f657", "family_member_count": 65, - "facets": [ - { - "axis": "provenance", - "ref": "dc/base/WorldDevelopmentIndicators", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "8535402560764839853" - }, - { - "axis": "measurementMethod", - "ref": null, - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "absent_on_selected_facet", - "dispatch_facet_id": "8535402560764839853" - }, - { - "axis": "unit", - "ref": "USDollar", - "basis": "bound", - "default_policy": null, - "default_policy_version": null, - "selection_reason": null, - "dispatch_facet_id": "8535402560764839853" - } - ], - "normalisations": [], + "family_member_digest": "73519eeb75639bdae33042fc844830cd46becc08e4f9122dfcd0886e9875f657", "frame_grammar_version": "1.1.0", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "capability_version": "dset_88fecfec3c5b89d1", - "served_from": "materialise", - "confirmed_at": "2026-10-21T13:05:30.811140+00:00" + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "served_from": "head", + "confirmed_at": "2026-10-23T18:37:09.348368+00:00" }, "warnings": [], "diagnostics": [ @@ -15140,11 +15222,11 @@ "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, "bytes": 6545, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:30.778158+00:00", + "created_at": "2026-10-20T15:55:49.978222+00:00", "tier": "working", "url": "/api/datasets/spec_f8dea3052d1ef6ba5667628815d1a663/cv_91f57bfc5bbc5f09983596996238787d/files/sha256:9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839" }, @@ -15155,14 +15237,14 @@ }, "bytes": 5379, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:30.778158+00:00", + "created_at": "2026-10-20T15:55:49.978222+00:00", "tier": "working", "url": "/api/datasets/spec_f8dea3052d1ef6ba5667628815d1a663/cv_91f57bfc5bbc5f09983596996238787d/files/sha256:8eecb62c1741271464d6d66841353d96f7e36aa9c3915f7948ea7c78c7dbc9e7" } ], "series_count": 2, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -15316,10 +15398,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:30.778009Z" + "held_until": "2026-11-19T15:55:49.978519Z" } } } @@ -15332,21 +15414,21 @@ "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839?X-Goog-Signature=redacted", - "x-dfo-trace-id": "8bf21c550f584bcaa21bcb8d69498a7d" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839?X-Goog-Signature=redacted", + "x-dfo-trace-id": "9bd6e2b9ac8b4778b2cd39f9aca71a71" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3A9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "8072bc19c0fc4a5aa825d37c5956317c" + "content-type": "application/vnd.apache.parquet" }, "body_file": "answer-several-readings-folded-2.parquet" } @@ -15374,10 +15456,10 @@ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "crsCooperationModality", "crsCooperationModality_label", "crsPurpose", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json index 4cd0f57..87e46cc 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json @@ -4,9 +4,9 @@ "description": "Fetching the mixed answer with partial=True builds only the answered part and returns a dataset that is not complete, with part 1's not_understood gap in missing.", "origin": { "kind": "recorded", - "base_url": "http://127.0.0.1:19493/api", - "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T13:05:16Z" + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "recorded_at": "2026-10-23T18:37:00Z" }, "call": [ { @@ -35,7 +35,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "8571f47c3ca8460f8e9a594da2fc942b" + "x-dfo-trace-id": "b78bde3ba929452aab7d7cdd34bad909" }, "json": { "schema_version": 1, @@ -46,20 +46,23 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "8571f47c3ca8460f8e9a594da2fc942b", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "b78bde3ba929452aab7d7cdd34bad909", "warnings": [], "timing_ms": { - "total": 3603, + "total": 377, "by_step": { "coverage": 0, - "extract": 839 + "extract": 1, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 5885, - "output_tokens": 606, - "cached_tokens": 2304 + "input_tokens": 0, + "output_tokens": 0, + "cached_tokens": 0, + "jev_input_tokens": 5250, + "jev_output_tokens": 1104 }, "timed_out": false }, @@ -69,20 +72,30 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 2725, + "total": 372, "by_step": { "recall": 1, - "shape_arcs": 1, - "shape_probe_coverage": 12, - "shape_probe": 13, + "phase_resolve_places": 0, + "phase_check_entities": 0, + "shape_arcs": 2, + "shape_probe_coverage": 14, + "shape_probe": 14, "shape_groups": 5, - "shape_labels": 8, + "shape_labels": 10, "shape_admission": 0, - "shape": 788, - "bind": 1929, - "materialise": 4, - "answer": 0, - "options": 3 + "phase_derive_shapes": 0, + "shape": 128, + "phase_prune_and_rank": 0, + "bind": 144, + "phase_bind": 10, + "phase_settle": 12, + "phase_place_bindings": 11, + "phase_facet_requests": 0, + "materialise": 9, + "phase_materialise": 0, + "answer": 1, + "options": 7, + "phase_outcome": 49 } }, "restatement": { @@ -469,7 +482,8 @@ "source_codes": [ { "provenance": "provenance/WorldBankInternationalDebtStatistics", - "code": "DT.TDS.DECT.CD" + "code": "DT.TDS.DECT.CD", + "exact": true } ] }, @@ -548,7 +562,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "facets": { "provenance": { "basis": "fallback", @@ -1266,7 +1280,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3251,15 +3265,19 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 12, + "total": 13, "by_step": { - "recall": 1, + "recall": 0, + "phase_resolve_places": 0, + "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe": 5, - "shape_groups": 0, + "shape_probe": 4, + "shape_groups": 1, "shape_labels": 0, - "shape_admission": 1, - "shape": 11 + "shape_admission": 0, + "phase_derive_shapes": 0, + "shape": 13, + "phase_prune_and_rank": 0 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", @@ -3696,7 +3714,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "afabd49505e34d9d91854d77caca574d" + "x-dfo-trace-id": "a0264860a3af4be098e96eefef69bf74" }, "json": { "schema_version": 1, @@ -3774,7 +3792,7 @@ } }, "content_version": "cv_2c981b422e8f8bdf5dee6067837cff13", - "prepared_at": "2026-10-21T13:05:20Z", + "prepared_at": "2026-10-12T03:03:22Z", "coverage": { "rows": 55, "dimensions": [ @@ -3794,13 +3812,13 @@ ], "window": { "kind": "all", - "start_year": 1970, + "origin": "default", "end_year": 2024, - "origin": "default" + "start_year": 1970 } }, "citation": { - "text": "World Bank International Debt Statistics (IDS) (2026), via the Development Finance Observatory", + "text": "World Bank International Debt Statistics (IDS)", "sources": [ { "ref": "provenance/WorldBankInternationalDebtStatistics", @@ -3823,7 +3841,7 @@ "source_data_url": "https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092201/A_D.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092202/E_K.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092203/L_M.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0093225/N_Q.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092204/R_U.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092205/V_Z.xlsx", "attribution": "International Debt Statistics by the World Bank, https://datacatalog.worldbank.org/search/dataset/0038015/international-debt-statistics, licensed under CC BY 4.0. Modified by The ONE Campaign.", "update_cadence": "Annual", - "last_update": "2026-10-13", + "last_update": "2026-09-29", "years_covered": "1970-2032", "granularity": "Annual, by provider and recipient", "currencies": [ @@ -3857,12 +3875,12 @@ ], "version_history": [ { - "date": "2026-10-14", + "date": "2026-09-29", "title": "First release", "changes": [ { "kind": "added", - "note": "External debt stocks, flows and debt service of low- and middle-income countries by borrower and creditor, with related ratios and gross national income." + "note": "Dataset added to the graph." } ] } @@ -3872,73 +3890,79 @@ ] }, "trace": { - "applied_window": { - "kind": "all", - "start_year": 1970, - "end_year": 2024, - "origin": "default" - }, - "graph_revision": null, - "code_index_stamp": { - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", - "exported_at": "2026-10-20T19:50:14Z", - "graph_endpoint": "graph_release" - }, - "origin_catalogue_build_id": "20261021T070020Z-7262111e", - "source_revisions": [ - { - "source": "provenance/WorldBankInternationalDebtStatistics", - "revision": "2026-10-13" - } - ], - "resolved_stat_vars": [ - { - "ref": "dcid:Amount_FinancialFlow_ServicingPayment_Nominal", - "roles": [ - "financingRecipient" - ], - "observation_count": 55 - } - ], - "family_member_digest": "b66541c53125ee32113e51b4f52a3a428043b5506e15f96277f37b89547fc1c4", - "family_member_count": 65, "facets": [ { - "axis": "provenance", "ref": "provenance/WorldBankInternationalDebtStatistics", + "axis": "provenance", "basis": "deployment_fallback", "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", "selection_reason": "most_observations", - "dispatch_facet_id": "2052749850102211920" + "dispatch_facet_id": "2052749850102211920", + "default_policy_version": "1" }, { - "axis": "measurementMethod", "ref": null, + "axis": "measurementMethod", "basis": "deployment_fallback", "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", "selection_reason": "absent_on_selected_facet", - "dispatch_facet_id": "2052749850102211920" + "dispatch_facet_id": "2052749850102211920", + "default_policy_version": "1" }, { - "axis": "unit", "ref": "CurrencyUSD", + "axis": "unit", "basis": "deployment_fallback", "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", "selection_reason": "most_observations", - "dispatch_facet_id": "2052749850102211920" + "dispatch_facet_id": "2052749850102211920", + "default_policy_version": "1" } ], + "applied_window": { + "kind": "all", + "origin": "default", + "end_year": 2024, + "start_year": 1970 + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-10T10:52:17Z", + "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", + "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" + }, + "source_revisions": [ + { + "source": "provenance/WorldBankInternationalDebtStatistics", + "revision": "2026-09-29" + } + ], + "capability_version": "dset_ac879dbf49857907", + "materialiser_build": "3c49570945bd107f0484c1a16044d714410b1e25", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_ServicingPayment_Nominal", + "roles": [ + "financingRecipient" + ], + "observation_count": 55 + } + ], + "family_member_count": 65, + "family_member_digest": "ef0365e0d7395767fee6210ec02c809839d0e28516031bf225d2cef2acc5e6d5", "frame_grammar_version": "1.1.0", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "capability_version": "dset_88fecfec3c5b89d1", - "served_from": "materialise", - "confirmed_at": "2026-10-21T13:05:20.852361+00:00" + "origin_catalogue_build_id": "20261012T000033Z-84777283", + "served_from": "head", + "confirmed_at": "2026-10-23T18:37:01.252594+00:00" }, - "warnings": [], + "warnings": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], "diagnostics": [ { "code": "processing_level_undeclared", @@ -3948,17 +3972,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:674d9a4ab33eabc631aba510ed88f9d45ddeef43d11d2aee7b267bd1e3546143", + "artifact_digest": "sha256:ab0bfec276a23aaefea6dbc3f1b57854ea520b3a7ae5feeade202f292446ed2c", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 6025, + "bytes": 6095, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:20.814206+00:00", + "created_at": "2026-10-23T16:58:25.889079+00:00", "tier": "working", - "url": "/api/datasets/spec_78d04fefc3b3f1ef71acd622957e4995/cv_2c981b422e8f8bdf5dee6067837cff13/files/sha256:674d9a4ab33eabc631aba510ed88f9d45ddeef43d11d2aee7b267bd1e3546143" + "url": "/api/datasets/spec_78d04fefc3b3f1ef71acd622957e4995/cv_2c981b422e8f8bdf5dee6067837cff13/files/sha256:ab0bfec276a23aaefea6dbc3f1b57854ea520b3a7ae5feeade202f292446ed2c", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:8da8a5b081cc06acba677ac2c668e4bcafb796bf040bede5de00740acda9c9ee", @@ -3967,14 +3992,14 @@ }, "bytes": 5343, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:20.814206+00:00", + "created_at": "2026-10-05T21:15:15.844014+00:00", "tier": "working", "url": "/api/datasets/spec_78d04fefc3b3f1ef71acd622957e4995/cv_2c981b422e8f8bdf5dee6067837cff13/files/sha256:8da8a5b081cc06acba677ac2c668e4bcafb796bf040bede5de00740acda9c9ee" } ], "series_count": 1, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -4100,11 +4125,35 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [], @@ -4126,10 +4175,9 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { - "pinned": false, - "held_until": "2026-11-20T13:05:20.813993Z" + "pinned": true } } } @@ -4137,26 +4185,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_78d04fefc3b3f1ef71acd622957e4995/cv_2c981b422e8f8bdf5dee6067837cff13/files/sha256:674d9a4ab33eabc631aba510ed88f9d45ddeef43d11d2aee7b267bd1e3546143" + "origin_path": "/api/datasets/spec_78d04fefc3b3f1ef71acd622957e4995/cv_2c981b422e8f8bdf5dee6067837cff13/files/sha256:ab0bfec276a23aaefea6dbc3f1b57854ea520b3a7ae5feeade202f292446ed2c" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A674d9a4ab33eabc631aba510ed88f9d45ddeef43d11d2aee7b267bd1e3546143?X-Goog-Signature=redacted", - "x-dfo-trace-id": "f4cc6b35ba294a0380ca97496ec86733" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Aab0bfec276a23aaefea6dbc3f1b57854ea520b3a7ae5feeade202f292446ed2c?X-Goog-Signature=redacted", + "x-dfo-trace-id": "6d3da0693a134de395cfe22836258dd3" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3A674d9a4ab33eabc631aba510ed88f9d45ddeef43d11d2aee7b267bd1e3546143?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Aab0bfec276a23aaefea6dbc3f1b57854ea520b3a7ae5feeade202f292446ed2c?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "7ffed6c80e5f484c9a566956adb5c5c0" + "content-type": "application/vnd.apache.parquet" }, "body_file": "answer-mixed-fetch-partial.parquet" } @@ -4189,7 +4237,7 @@ "stat_var_label", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "time_period", "value", "unit", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.parquet b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.parquet index 58643c6ed01efefb0b10c22a58d64b99994b8b32..794b21a22d79320a92b93e551cfe7c0242af8fdd 100644 GIT binary patch delta 872 zcmbVI-%FEG82&chw<)?`-_EzGGZp2-oONby{sNPCKb(>1ww#+rjIqsa+PCuhRxWNtB+mP=c8wT`L_e<9)vIXOkt zqAY$@i9c1+zD~NW`>!~-WFYFd0^Y3e)?C#~>$Uj2KCSsCO8W-v)TcD}8l*QiyrqxV z>@`Yv8kHURkQeX)Z^e?qjBZ0$^&`9V1(Sx5X0uuPZpR+2?SOj6sGVcdU3_Ldfv1g4 z)$1+N=Yz)$W1Hqfi}a!eH;o?6(>7_N6{#+Zag$%O+aYbY<73mcj=fG%mUQB_#5LG$ zbr23uMu&>YY&xH?y{@53xic6td(Gg2GQc350T?fP0Xze^VfLv4_|ZI~^#^+?byl!P zaPb3lj?y$P2tMuD)F7pfGVTZ?d_ifu@rU5jPAKhx5cXMIS_t-2TB+cY#l;utDy0d0 zVsZ2H4knD?d&^0!7nJrYHjxokKb|L(RcC_~^FlkmA`S87MAW?i-YFJzFr&l;7R?i8 z2vAhOqrmT)QLfqi#g&<;d!Fg!NPc=g5%Vn0M%~WXsY}_J{Pcka0zT&CNK%TsLbK!C zzjOfJh_criWKhOWVq?IUVS=#<=S(a-m&%W>9a{VR%BUY80+0bu2F5`7Re;c8PX8$5 nnJeHGi>0}e3XD2qy|dY*VhX^xKeNNb*kz6Cj_Wxt2;rVze~Sc4 delta 824 zcmZ`$OK1~O6iwPpKGLN5PLtZSwdzw0=EWwdO%cM&w<)CQjIC)367%oSW(+l0(@jA{ zR79i~T(}XT3k4S~1wl6z?4qdP)|GbYTCx#Dd~ZS#g}%j|b3f<2^X`1c_wiOw7ra+n zxJF^6*#e8sX6!&`=d*LGYg^}XS0%Y1mn69+R!UMss>sc}LfE-<%+nn{vYlU&3enXA+^k_prFs3^D&mHjGWQUB=4Bw4I+!G_(G{EC-FHD#&au0d*%LE@eFKn8| zxGg98(Ffm5d9Lk3FI=#zWpxYO?)7M1A4m6KyI0Wc4WLJ$HP3M$+~}1Xu9=gX%|Ub* z^5*mK#e72Zdk`Hc$vF#ecsGpR4lzUURPTe9rNw)@&O8D2(ue*d(} zHQ?+aqL|4}+$b$p>ILV40kbnk;F&dQjS#X*2qq~)(n6GwXdK$sm^uz2TUZyJ@nh_p zg>_p%>%&!yOYp`P()W1&tti^ckMqgXFrUdT>2O3CHrqAXU6 z$%M3!RX8Na^nz>u=_x*_-nt@3wdlr<6r{sbvs3^JEU>|dsPLEzLU(?6G7Oab;$k@w z8l?~WYb4G1;{u5Yg#MN!ogy(dY@qDUv*0V=KTLasOiuf9^J2AJPqbLdmUcJ=jlQhj LWm2hTh5EE z3C8)A7}$D*Y%$pnW1J!Lb7t`)IwbqGXfh))#$QXLaq+hw(M;oen}9zI-rT%7?{m)c zoO7Og*O%@tz4sk|P^;FRQa7j-%?d@6NvTjM3aL~!nT_Y*gz|Bfa_6Sqjo>`5h9{I8 z2B+G+!#tE}q0D5VoS!XLItoSlrsMf+DL$JmAhCjd&e)Zx^ejcG#P06d7VMOtueAs2&66qYmO3k`wD}$FT*3w61u$7NWT_RYOcPi=t`xOR#f(X%S;H zxI_mhUqi5?~dKZzraWKjgs-OH0Pk*W}Q#x3%`dQ989eOyAa$ppT~ z!=Log5}btL9uGH;QyBZ9+GFR5j}9OR@KsNU_YzF!N`d~kZ{Oe)#f@e>2k-V`xO%+l ztaWxKF+EC35}nexD6{DH{s1+CS}`x5^-vCoH!UC2@rWanm=00i#OYWhG?N_2DGU|YVZ+e>(5TJ*KH01!#&FB6hp&6J2jbRTIYvnl>JfH~Vfe$< z2~X2RDH;jp5~P2W;&@TQ;1fFCF*-@09F;j1ZzW-i&BO+ts!%#vkogOQ1PGxsM2UBv x49hrOiS{J~o^>DUlBXj{TR1Zj5UtTO^(&$Oz)q2zCUB*%tSoC43Ws1pQ1iiq=v{u!Id^xWH02U0yh&VAqK zeV_Mz&U+5`&dG}>m+ta#M!AQrq^k83a9P>0Q?}F_z;V6<49ctjlX5+| zO6fu=AFh^X3Yl#6*m~8YJ@NgWo55%{U8oeYrTTjG`X@cZ+nrl+j};50Ove+d(@NDG zqgrIp_gZvStFbGdUl+KkQ?CN6;VEbw(r!O}04>Afp$fZn5Is5o*OdF9uHP$#U)WN` zzxv$lMi;xc?(?moo4u_=A3O(t8Rpq#16t~VrM7eMzM&l)*vPI~(25bJ@T=@MF7&4W zf9y7Z$~eS+HiXuEP;NKMl0L+0_|(|V-Uy%{{cx{c2W=)d`{og}@*>1cRrXO3Ee7HC z-XS>~nT_mE5p*jAFPZb)+G`BDm4KV(9KSNlpx0*^xYpeTaSP$jo@3DRS$Nx0=2qtz zbY%|qSdVhQoM+HS=V8*C;O@^e=zu@8gdRl4%76d1klTZhIC)l{MgxX-AXyu1v4$6x_NVIY!+`_m8Z-_RohQk=A zU`52-h=khUq3C3SAohl~g@O7`q55`1{McTg4&5edF5+T{=1#=j1#%hcSV*J}V!VV4()u{$ZXpG1WB=^?o<+o20_@MT%>g4E)gFdCKCNNSC6v zQFFaAK26U|2Fp^qElgE6sT+w)AUPs!(o8m%Px|`CD977Knx`6Lroa^aHdBd_M#d}F zl8M07xSZ=QO7;Bow2#*d$gv24_k$qnkiIkJlq{-O@&6Q?^`9c=E93 znPze{V9bt))l|Y(lmp&LO4P?OhR^#k+!<)wJ?`@s#u80Zln*=}Phe!0UxQ=$2U3=JETqtRSu+IvC{)2Tg9C1hYgq3)tT hqT`Kh-H@(S45@0h-0YgkR^i^^mz6EGLJ=lW)8Dg5p??4X diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json index a449a5d..9bbb96b 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json @@ -30,7 +30,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "d09ca5f0ae574410bf93b5d905ea8009" + "x-dfo-trace-id": "8ff5daac36fe403ab946f5b02785cb0d" }, "json": { "schema_version": 1, @@ -41,47 +41,58 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d09ca5f0ae574410bf93b5d905ea8009", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "8ff5daac36fe403ab946f5b02785cb0d", "warnings": [], "timing_ms": { - "total": 5038, + "total": 4716, "by_step": { "coverage": 0, - "extract": 1141 + "extract": 1242, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 6116, - "output_tokens": 408, - "cached_tokens": 0 + "input_tokens": 6216, + "output_tokens": 423, + "cached_tokens": 841 }, "timed_out": false }, "kind": "resolution", "parts": [ { - "variable_text": "basic health care ODA disbursements", + "variable_text": "ODA disbursements for basic health care", "warnings": [], "timing_ms": { - "total": 3758, + "total": 3468, "by_step": { - "recall": 694, + "recall": 547, + "phase_resolve_places": 0, + "phase_check_entities": 0, "shape_arcs": 1, "shape_probe_coverage": 6, - "shape_probe": 489, - "shape_groups": 16, - "shape_labels": 0, - "shape_admission": 1, - "shape": 1365, - "bind": 1248, - "materialise": 11, - "answer": 423, - "options": 17 + "shape_probe": 136, + "shape_groups": 43, + "shape_labels": 1, + "shape_admission": 0, + "phase_derive_shapes": 0, + "shape": 1190, + "phase_prune_and_rank": 0, + "bind": 1278, + "phase_bind": 149, + "phase_settle": 50, + "phase_place_bindings": 19, + "phase_facet_requests": 0, + "materialise": 30, + "phase_materialise": 0, + "answer": 110, + "options": 38, + "phase_outcome": 57 } }, "restatement": { - "variable_text": "basic health care ODA disbursements", + "variable_text": "ODA disbursements for basic health care", "entities": [ { "text": "Germany", @@ -127,6 +138,14 @@ }, "measurement_denominator_unresolved": false, "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, { "axis": "how", "property": { @@ -167,14 +186,6 @@ }, "label": "netting basis" }, - { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, { "axis": "where", "label": "place" @@ -199,6 +210,20 @@ ] }, "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, { "key": { "axis": "how", @@ -297,20 +322,6 @@ }, "summable": false }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding": { - "kind": "unbound" - }, - "summable": true - }, { "key": { "axis": "where", @@ -447,7 +458,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "facets": { "provenance": { "basis": "fallback", @@ -472,102 +483,6 @@ } }, "slot_options": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsPurpose", - "label": "CRS purpose" - }, - "label": "sector" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSPurposeCode122", - "label": "basic health" - }, - "value_kind": "enum_value" - }, - "relation": "parent", - "parent": "CRSPurposeCode120", - "member_count": 4, - "served_rows": 88, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFinance", - "label": "CRS type of finance" - }, - "label": "instrument" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance100", - "label": "grant" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 30, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance110", - "label": "standard grant" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSTypeOfFinance100", - "member_count": 12672, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFlow", - "label": "CRS type of flow" - }, - "label": "flow" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 14098, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, { "key": { "axis": "how", @@ -676,6 +591,102 @@ ], "truncated": false, "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 88, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 30, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" } ], "entity_options": [], @@ -943,6 +954,19 @@ } ], "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "how", @@ -1028,19 +1052,6 @@ ], "provenance": "measure_elected" }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "where", @@ -1076,31 +1087,31 @@ ], "query_qualifiers": [ { - "text": "basic health care", + "text": "ODA", "named": [ { - "ref": "CRSPurposeCode12220", - "label": "basic health care" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" } ], - "slot": "crsPurpose", + "slot": "crsTypeOfFlow", "disposition": "bound", "selected": [] }, { - "text": "ODA", + "text": "basic health care", "named": [ { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode12220", + "label": "basic health care" } ], - "slot": "crsTypeOfFlow", + "slot": "crsPurpose", "disposition": "bound", "selected": [] } ], - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3617,7 +3628,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "d09ca5f0ae574410bf93b5d905ea8009" + "trace_id": "8ff5daac36fe403ab946f5b02785cb0d" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json index eb08965..b661d6f 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json @@ -30,7 +30,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "d09ca5f0ae574410bf93b5d905ea8009" + "x-dfo-trace-id": "8ff5daac36fe403ab946f5b02785cb0d" }, "json": { "schema_version": 1, @@ -41,47 +41,58 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d09ca5f0ae574410bf93b5d905ea8009", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "8ff5daac36fe403ab946f5b02785cb0d", "warnings": [], "timing_ms": { - "total": 5038, + "total": 4716, "by_step": { "coverage": 0, - "extract": 1141 + "extract": 1242, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 6116, - "output_tokens": 408, - "cached_tokens": 0 + "input_tokens": 6216, + "output_tokens": 423, + "cached_tokens": 841 }, "timed_out": false }, "kind": "resolution", "parts": [ { - "variable_text": "basic health care ODA disbursements", + "variable_text": "ODA disbursements for basic health care", "warnings": [], "timing_ms": { - "total": 3758, + "total": 3468, "by_step": { - "recall": 694, + "recall": 547, + "phase_resolve_places": 0, + "phase_check_entities": 0, "shape_arcs": 1, "shape_probe_coverage": 6, - "shape_probe": 489, - "shape_groups": 16, - "shape_labels": 0, - "shape_admission": 1, - "shape": 1365, - "bind": 1248, - "materialise": 11, - "answer": 423, - "options": 17 + "shape_probe": 136, + "shape_groups": 43, + "shape_labels": 1, + "shape_admission": 0, + "phase_derive_shapes": 0, + "shape": 1190, + "phase_prune_and_rank": 0, + "bind": 1278, + "phase_bind": 149, + "phase_settle": 50, + "phase_place_bindings": 19, + "phase_facet_requests": 0, + "materialise": 30, + "phase_materialise": 0, + "answer": 110, + "options": 38, + "phase_outcome": 57 } }, "restatement": { - "variable_text": "basic health care ODA disbursements", + "variable_text": "ODA disbursements for basic health care", "entities": [ { "text": "Germany", @@ -397,7 +408,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "d09ca5f0ae574410bf93b5d905ea8009" + "trace_id": "8ff5daac36fe403ab946f5b02785cb0d" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json index 3afa337..f4f913b 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json @@ -44,20 +44,23 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "3b0a506d6d2a43a0becd94837bafffa1", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "4d9323abf43e4fccadfbd64caf2b371c", "warnings": [], "timing_ms": { - "total": 4692, + "total": 1772, "by_step": { "coverage": 0, - "extract": 1001 + "extract": 876, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 5885, - "output_tokens": 606, - "cached_tokens": 860 + "input_tokens": 2232, + "output_tokens": 103, + "cached_tokens": 841, + "jev_input_tokens": 5250, + "jev_output_tokens": 1104 }, "timed_out": true }, @@ -67,20 +70,30 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 3475, + "total": 892, "by_step": { - "recall": 434, + "recall": 414, + "phase_resolve_places": 0, + "phase_check_entities": 0, "shape_arcs": 3, - "shape_probe_coverage": 4, - "shape_probe": 243, - "shape_groups": 3, - "shape_labels": 9, + "shape_probe_coverage": 6, + "shape_probe": 93, + "shape_groups": 5, + "shape_labels": 10, "shape_admission": 0, - "shape": 893, - "bind": 1563, + "phase_derive_shapes": 0, + "shape": 205, + "phase_prune_and_rank": 0, + "bind": 101, + "phase_bind": 10, + "phase_settle": 12, + "phase_place_bindings": 11, + "phase_facet_requests": 0, "materialise": 9, - "answer": 381, - "options": 195 + "phase_materialise": 0, + "answer": 2, + "options": 81, + "phase_outcome": 47 } }, "restatement": { @@ -467,7 +480,8 @@ "source_codes": [ { "provenance": "provenance/WorldBankInternationalDebtStatistics", - "code": "DT.TDS.DECT.CD" + "code": "DT.TDS.DECT.CD", + "exact": true } ] }, @@ -546,7 +560,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "facets": { "provenance": { "basis": "fallback", @@ -1264,7 +1278,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3249,15 +3263,19 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 574, + "total": 466, "by_step": { - "recall": 380, + "recall": 339, + "phase_resolve_places": 1, + "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe": 190, - "shape_groups": 0, + "shape_probe": 122, + "shape_groups": 1, "shape_labels": 0, "shape_admission": 0, - "shape": 194 + "phase_derive_shapes": 0, + "shape": 126, + "phase_prune_and_rank": 0 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json index 5c8c6b2..fca486e 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json @@ -10,7 +10,7 @@ "call": [ { "op": "search", - "question": "ODA disbursements from Germany to Congo" + "question": "ODA disbursements from Germany to Congo in 2018" } ], "exchanges": [ @@ -22,7 +22,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, @@ -30,31 +30,32 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d" + "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f" }, "json": { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "ODA disbursements from Germany to Congo", - "normalized_query": "ODA disbursements from Germany to Congo", + "raw_query": "ODA disbursements from Germany to Congo in 2018", + "normalized_query": "ODA disbursements from Germany to Congo in 2018", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "95b872cf11e44fffb92260b2bb583f0d", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "a321fb82bfba461b9dc922634789650f", "warnings": [], "timing_ms": { - "total": 1697, + "total": 1126, "by_step": { "coverage": 0, - "extract": 982 + "extract": 1119, + "cache_lookup": 1 } }, "llm_usage": { - "input_tokens": 2249, - "output_tokens": 154, - "cached_tokens": 859 + "input_tokens": 2233, + "output_tokens": 193, + "cached_tokens": 841 }, "timed_out": false }, @@ -64,9 +65,11 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 715, + "total": 1, "by_step": { - "recall": 715 + "recall": 1, + "phase_resolve_places": 0, + "phase_check_entities": 0 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -107,6 +110,7 @@ "role_text": "to" } ], + "time_text": "2018", "sources": [], "operations": [] }, @@ -164,6 +168,7 @@ "dcid": "country/COD" } ], + "time_text": "2018", "sources": [], "operations": [] } @@ -192,6 +197,7 @@ "dcid": "country/COG" } ], + "time_text": "2018", "sources": [], "operations": [] } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json index 2c609b2..4a04035 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json @@ -10,7 +10,7 @@ "call": [ { "op": "search", - "question": "ODA disbursements from Germany to Congo" + "question": "ODA disbursements from Germany to Congo in 2018" } ], "exchanges": [ @@ -22,7 +22,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, @@ -30,31 +30,32 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d" + "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f" }, "json": { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "ODA disbursements from Germany to Congo", - "normalized_query": "ODA disbursements from Germany to Congo", + "raw_query": "ODA disbursements from Germany to Congo in 2018", + "normalized_query": "ODA disbursements from Germany to Congo in 2018", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "95b872cf11e44fffb92260b2bb583f0d", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "a321fb82bfba461b9dc922634789650f", "warnings": [], "timing_ms": { - "total": 1697, + "total": 1126, "by_step": { "coverage": 0, - "extract": 982 + "extract": 1119, + "cache_lookup": 1 } }, "llm_usage": { - "input_tokens": 2249, - "output_tokens": 154, - "cached_tokens": 859 + "input_tokens": 2233, + "output_tokens": 193, + "cached_tokens": 841 }, "timed_out": false }, @@ -64,9 +65,11 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 715, + "total": 1, "by_step": { - "recall": 715 + "recall": 1, + "phase_resolve_places": 0, + "phase_check_entities": 0 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -107,6 +110,7 @@ "role_text": "to" } ], + "time_text": "2018", "sources": [], "operations": [] }, @@ -164,6 +168,7 @@ "dcid": "country/COD" } ], + "time_text": "2018", "sources": [], "operations": [] } @@ -192,6 +197,7 @@ "dcid": "country/COG" } ], + "time_text": "2018", "sources": [], "operations": [] } @@ -241,7 +247,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "95b872cf11e44fffb92260b2bb583f0d" + "trace_id": "a321fb82bfba461b9dc922634789650f" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json index c3fac94..d0ba462 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json @@ -33,7 +33,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "3b0a506d6d2a43a0becd94837bafffa1" + "x-dfo-trace-id": "4d9323abf43e4fccadfbd64caf2b371c" }, "json": { "schema_version": 1, @@ -44,20 +44,23 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "3b0a506d6d2a43a0becd94837bafffa1", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "4d9323abf43e4fccadfbd64caf2b371c", "warnings": [], "timing_ms": { - "total": 4692, + "total": 1772, "by_step": { "coverage": 0, - "extract": 1001 + "extract": 876, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 5885, - "output_tokens": 606, - "cached_tokens": 860 + "input_tokens": 2232, + "output_tokens": 103, + "cached_tokens": 841, + "jev_input_tokens": 5250, + "jev_output_tokens": 1104 }, "timed_out": false }, @@ -67,20 +70,30 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 3475, + "total": 892, "by_step": { - "recall": 434, + "recall": 414, + "phase_resolve_places": 0, + "phase_check_entities": 0, "shape_arcs": 3, - "shape_probe_coverage": 4, - "shape_probe": 243, - "shape_groups": 3, - "shape_labels": 9, + "shape_probe_coverage": 6, + "shape_probe": 93, + "shape_groups": 5, + "shape_labels": 10, "shape_admission": 0, - "shape": 893, - "bind": 1563, + "phase_derive_shapes": 0, + "shape": 205, + "phase_prune_and_rank": 0, + "bind": 101, + "phase_bind": 10, + "phase_settle": 12, + "phase_place_bindings": 11, + "phase_facet_requests": 0, "materialise": 9, - "answer": 381, - "options": 195 + "phase_materialise": 0, + "answer": 2, + "options": 81, + "phase_outcome": 47 } }, "restatement": { @@ -467,7 +480,8 @@ "source_codes": [ { "provenance": "provenance/WorldBankInternationalDebtStatistics", - "code": "DT.TDS.DECT.CD" + "code": "DT.TDS.DECT.CD", + "exact": true } ] }, @@ -546,7 +560,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "facets": { "provenance": { "basis": "fallback", @@ -1264,7 +1278,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3249,15 +3263,19 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 574, + "total": 466, "by_step": { - "recall": 380, + "recall": 339, + "phase_resolve_places": 1, + "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe": 190, - "shape_groups": 0, + "shape_probe": 122, + "shape_groups": 1, "shape_labels": 0, "shape_admission": 0, - "shape": 194 + "phase_derive_shapes": 0, + "shape": 126, + "phase_prune_and_rank": 0 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", @@ -3625,7 +3643,7 @@ "error": { "class": "IncompleteAnswerError", "code": "answer_incomplete", - "trace_id": "3b0a506d6d2a43a0becd94837bafffa1" + "trace_id": "4d9323abf43e4fccadfbd64caf2b371c" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json index 8fc9421..ea402dc 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json @@ -33,7 +33,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "3b0a506d6d2a43a0becd94837bafffa1" + "x-dfo-trace-id": "4d9323abf43e4fccadfbd64caf2b371c" }, "json": { "schema_version": 1, @@ -44,20 +44,23 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "3b0a506d6d2a43a0becd94837bafffa1", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "4d9323abf43e4fccadfbd64caf2b371c", "warnings": [], "timing_ms": { - "total": 4692, + "total": 1772, "by_step": { "coverage": 0, - "extract": 1001 + "extract": 876, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 5885, - "output_tokens": 606, - "cached_tokens": 860 + "input_tokens": 2232, + "output_tokens": 103, + "cached_tokens": 841, + "jev_input_tokens": 5250, + "jev_output_tokens": 1104 }, "timed_out": false }, @@ -67,20 +70,30 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 3475, + "total": 892, "by_step": { - "recall": 434, + "recall": 414, + "phase_resolve_places": 0, + "phase_check_entities": 0, "shape_arcs": 3, - "shape_probe_coverage": 4, - "shape_probe": 243, - "shape_groups": 3, - "shape_labels": 9, + "shape_probe_coverage": 6, + "shape_probe": 93, + "shape_groups": 5, + "shape_labels": 10, "shape_admission": 0, - "shape": 893, - "bind": 1563, + "phase_derive_shapes": 0, + "shape": 205, + "phase_prune_and_rank": 0, + "bind": 101, + "phase_bind": 10, + "phase_settle": 12, + "phase_place_bindings": 11, + "phase_facet_requests": 0, "materialise": 9, - "answer": 381, - "options": 195 + "phase_materialise": 0, + "answer": 2, + "options": 81, + "phase_outcome": 47 } }, "restatement": { @@ -467,7 +480,8 @@ "source_codes": [ { "provenance": "provenance/WorldBankInternationalDebtStatistics", - "code": "DT.TDS.DECT.CD" + "code": "DT.TDS.DECT.CD", + "exact": true } ] }, @@ -546,7 +560,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "facets": { "provenance": { "basis": "fallback", @@ -1264,7 +1278,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3249,15 +3263,19 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 574, + "total": 466, "by_step": { - "recall": 380, + "recall": 339, + "phase_resolve_places": 1, + "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe": 190, - "shape_groups": 0, + "shape_probe": 122, + "shape_groups": 1, "shape_labels": 0, "shape_admission": 0, - "shape": 194 + "phase_derive_shapes": 0, + "shape": 126, + "phase_prune_and_rank": 0 } }, "rendered_sentence": "Could not match \"price of tea\" to a supported indicator. Try a different wording or a related indicator.", @@ -3619,7 +3637,7 @@ "error": { "class": "IncompleteAnswerError", "code": "answer_incomplete", - "trace_id": "3b0a506d6d2a43a0becd94837bafffa1" + "trace_id": "4d9323abf43e4fccadfbd64caf2b371c" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-assumed-reading.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-assumed-reading.json index 0a7a407..370fea6 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-assumed-reading.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-assumed-reading.json @@ -10,7 +10,7 @@ "call": [ { "op": "search", - "question": "GNI of Germany from 2015 to 2022" + "question": "mortality in Kenya from 2013 to 2022" }, { "op": "choose", @@ -26,7 +26,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "GNI of Germany from 2015 to 2022" + "query": "mortality in Kenya from 2013 to 2022" } } }, @@ -34,60 +34,72 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "d107dd88e50147378d54464bcdaf9695" + "x-dfo-trace-id": "2fefffc9aac84b4fae2eb1888a1d3b74" }, "json": { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "GNI of Germany from 2015 to 2022", - "normalized_query": "GNI of Germany from 2015 to 2022", + "raw_query": "mortality in Kenya from 2013 to 2022", + "normalized_query": "mortality in Kenya from 2013 to 2022", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d107dd88e50147378d54464bcdaf9695", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "2fefffc9aac84b4fae2eb1888a1d3b74", "warnings": [], "timing_ms": { - "total": 4075, + "total": 2300, "by_step": { "coverage": 0, - "extract": 1004 + "extract": 1022, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 7300, - "output_tokens": 300, - "cached_tokens": 861 + "input_tokens": 2237, + "output_tokens": 143, + "cached_tokens": 842, + "jev_input_tokens": 13358, + "jev_output_tokens": 2855 }, "timed_out": false }, "kind": "resolution", "parts": [ { - "variable_text": "GNI", + "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 2799, + "total": 1274, "by_step": { - "recall": 381, - "shape_arcs": 2, - "shape_probe_coverage": 1, - "shape_probe": 203, - "shape_groups": 18, - "shape_labels": 5, - "shape_admission": 0, - "shape": 1186, - "bind": 829, - "materialise": 217, - "answer": 186 + "recall": 0, + "phase_resolve_places": 0, + "phase_check_entities": 0, + "shape_arcs": 4, + "shape_probe": 112, + "shape_groups": 5, + "shape_labels": 1, + "shape_admission": 1, + "phase_derive_shapes": 0, + "shape": 237, + "phase_prune_and_rank": 0, + "bind": 214, + "phase_bind": 3, + "phase_settle": 7, + "phase_place_bindings": 27, + "phase_facet_requests": 0, + "materialise": 124, + "phase_materialise": 1, + "answer": 25, + "phase_outcome": 636 } }, - "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", "sentence_plan": [ { "kind": "text", - "text": "3 readings.", + "text": "2 readings.", "segment": "heading", "entity_refs": [], "states": [] @@ -101,7 +113,7 @@ }, { "kind": "text", - "text": "Germany", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [] @@ -122,112 +134,7 @@ }, { "kind": "text", - "text": "primary income", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " for ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "gross of fixed capital consumption", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "OECD DAC1", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "2015 to 2022", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "Current US dollars", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "Germany", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "gross national income based on purchasing power parity", + "text": "deaths rate", "segment": "heading", "entity_refs": [], "states": [] @@ -241,7 +148,7 @@ }, { "kind": "text", - "text": "in international dollars", + "text": "per capita", "segment": "heading", "entity_refs": [], "states": [] @@ -276,7 +183,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2022", "segment": "byline", "entity_refs": [], "states": [] @@ -297,7 +204,7 @@ }, { "kind": "text", - "text": "Germany", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [] @@ -318,21 +225,7 @@ }, { "kind": "text", - "text": "gross national income based on purchasing power parity per capita", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "in international dollars", + "text": "number of deaths", "segment": "heading", "entity_refs": [], "states": [] @@ -353,7 +246,7 @@ }, { "kind": "text", - "text": "World Development Indicators", + "text": "Kenya Census", "segment": "byline", "entity_refs": [], "states": [] @@ -367,7 +260,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2018 to 2022", "segment": "byline", "entity_refs": [], "states": [] @@ -381,13 +274,13 @@ } ], "restatement": { - "variable_text": "GNI", + "variable_text": "mortality", "entities": [ { - "text": "Germany" + "text": "Kenya" } ], - "time_text": "2015 to 2022", + "time_text": "2013 to 2022", "sources": [], "operations": [] }, @@ -400,69 +293,70 @@ "max_candidates": 6, "specs": [ { - "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "definition": { "schema_version": 1, - "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU" + "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicunit_primaryincome_measuredvalue_nominal", - "label": "Gross national income", + "shape_id": "mortalityevent_count_measuredvalue_per_count_person", + "label": "Deaths Rate", "population_type": { - "ref": "EconomicUnit", - "label": "economic unit" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "primaryIncome", - "label": "primary income" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "Nominal", - "label": "Nominal" + "measurement_denominator": { + "ref": "Count_Person", + "label": "Total population" }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, { "axis": "where", @@ -477,13 +371,13 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", - "refine_supported": true, + "member_count": 133, + "member_digest": "c090b56d31a596a8be16dafb518382db666c6b100a80534c3cb81dbfe3111c5d", + "refine_supported": false, "data_commons": [ { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" } ] }, @@ -492,20 +386,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - }, - "value_kind": "enum_value" - } + "kind": "unbound" }, "summable": false }, @@ -518,8 +405,8 @@ "kind": "value", "value": { "ref": { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" }, "value_kind": "entity" } @@ -536,7 +423,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } @@ -554,21 +441,23 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 2, "member_count_exact": false, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2013", "end": "2022" } }, "entities": [ { - "ref": "country/DEU", - "label": "Germany", + "ref": "country/KEN", + "label": "Kenya", "entity_type": "Country", "role": "observationAbout" } @@ -576,7 +465,7 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 8, + "observation_count": 10, "evidence": "facet_metadata", "dimensions": [ { @@ -585,7 +474,7 @@ }, { "label": "observations", - "count": 8 + "count": 10 }, { "label": "variables", @@ -593,43 +482,46 @@ } ], "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, "download": { - "rows": 8, + "rows": 10, "rows_exact": true, "series": 1, "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, "licence": { - "label": "OECD Terms and Conditions" + "label": "Creative Commons Attribution License" } }, "facets": { "provenance": { "basis": "fallback", - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1", - "account": "provider" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "measurementMethod": { + "basis": "fallback", + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" }, "unit": { "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" + "ref": "Per1000Persons", + "label": "Per 1000 people" } }, "slot_options": [ @@ -637,17 +529,17 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" + "ref": "ICD10/X60-X84", + "label": "X60-X84 (Intentional self-harm)" }, "value_kind": "enum_value" } @@ -665,8 +557,17 @@ { "value": { "ref": { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1" + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + }, + { + "value": { + "ref": { + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, "value_kind": "source" } @@ -675,28 +576,54 @@ "truncated": false, "source": "observed" }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "ref": { + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, { "axis": "unit", "options": [ { "value": { "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" + "ref": "Per1000Persons", + "label": "Per 1000 people" }, "value_kind": "enum_value" } + }, + { + "value": { + "value_kind": "enum_value" + } } ], "truncated": false, "source": "observed" } ], - "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "rendered_sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators.", "sentence_plan": [ { "kind": "slot", - "text": "Germany", + "text": "Kenya", "axis": "where", "segment": "heading", "binding_ref": "where:", @@ -721,7 +648,7 @@ }, { "kind": "slot", - "text": "primary income", + "text": "deaths rate", "axis": "what", "segment": "heading", "entity_refs": [], @@ -730,23 +657,28 @@ }, { "kind": "text", - "text": " for ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "gross of fixed capital consumption", + "text": "per capita", + "axis": "unit", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", "axis": "how", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ], - "distinguishes": true + "states": [] }, { "kind": "text", @@ -757,14 +689,15 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", "entity_refs": [], "states": [ "when:" - ] + ], + "distinguishes": true }, { "kind": "text", @@ -782,26 +715,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -821,23 +735,23 @@ "trace": { "resolved_entities": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "resolved_sources": [ { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" } ], "slot_filters": [ @@ -845,18 +759,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -867,8 +776,8 @@ "binding_kind": "value", "refs": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "provenance": "binder" @@ -894,38 +803,13 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] + "removed_stat_vars": [] } }, "confidence": "high", @@ -935,122 +819,294 @@ } }, { - "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "spec_id": "spec_7923e67e0706d6d9738c78cb374ee8fb", "definition": { "schema_version": 1, - "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "spec_id": "spec_7923e67e0706d6d9738c78cb374ee8fb", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicActivity", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "PurchasingPowerParity" + "population_type": "MortalityEvent", + "measured_property": "count", + "stat_type": "measuredValue" }, "slots": [ { - "property": "activitySource", + "property": "age", + "binding": { + "state": "unbound" + } + }, + { + "property": "ageGroupClassification", + "binding": { + "state": "unbound" + } + }, + { + "property": "causeOfDeath", + "binding": { + "state": "unbound" + } + }, + { + "property": "ethnicity", + "binding": { + "state": "unbound" + } + }, + { + "property": "gender", + "binding": { + "state": "unbound" + } + }, + { + "property": "incidentType", + "binding": { + "state": "unbound" + } + }, + { + "property": "race", + "binding": { + "state": "unbound" + } + }, + { + "property": "residentStatus", "binding": { - "state": "value", - "ref": "GrossNationalIncome" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU" + "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity", - "label": "Gross National Income Based on Purchasing Power Parity", + "shape_id": "mortalityevent_count_measuredvalue", + "label": "Number of Deaths", "population_type": { - "ref": "EconomicActivity", - "label": "EconomicActivity" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "amount", - "label": "amount" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "PurchasingPowerParity", - "label": "PurchasingPowerParity" - }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, { - "axis": "where", - "label": "place" + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" }, { - "axis": "when", - "label": "time window" + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" }, { - "axis": "source", - "label": "data source" - } + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } ], - "member_count": 1, - "member_digest": "833b9da89613fa6c1775652daac2388f38204c6c9f9929ca113deed9a0d08369", + "member_count": 2978, "refine_supported": true, "data_commons": [ { "id": "base", "label": "Data Commons by Google" } - ], - "upstream": { - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" - } - } + ] }, "slots": [ { "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - }, - "value_kind": "enum_value" - } + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + "binding": { + "kind": "unbound" }, "summable": false }, @@ -1063,8 +1119,8 @@ "kind": "value", "value": { "ref": { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" }, "value_kind": "entity" } @@ -1081,7 +1137,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 } } @@ -1099,21 +1155,30 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath", + "gender", + "age", + "race", + "incidentType", + "ethnicity", + "residentStatus", + "ageGroupClassification" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 37, "member_count_exact": false, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2018", "end": "2022" } }, "entities": [ { - "ref": "country/DEU", - "label": "Germany", + "ref": "country/KEN", + "label": "Kenya", "entity_type": "Country", "role": "observationAbout" } @@ -1121,7 +1186,7 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 8, + "observation_count": 5, "evidence": "facet_metadata", "dimensions": [ { @@ -1130,7 +1195,7 @@ }, { "label": "observations", - "count": 8 + "count": 5 }, { "label": "variables", @@ -1138,16 +1203,16 @@ } ], "window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 } }, "download": { - "rows": 8, + "rows": 5, "rows_exact": true, "series": 1, "window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 }, "licence": { @@ -1157,22 +1222,17 @@ "facets": { "provenance": { "basis": "fallback", - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census", "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "ref": "dc/s/OpenDataForAfrica", + "label": "Open Data for Africa" }, "data_commons": { "id": "base", "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" - }, - "unit": { - "basis": "fallback", - "ref": "InternationalDollar", - "label": "InternationalDollar" + "documentation": "/api/graph/documentation/dc/base/Kenya_Census" } }, "slot_options": [ @@ -1180,559 +1240,681 @@ "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + "ref": "ICD10/A00-B99", + "label": "A00-B99 (Certain infectious and parasitic diseases)" }, "value_kind": "enum_value" } - } - ], - "truncated": true, - "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ - { - "axis": "provenance", - "options": [ + }, { "value": { "ref": { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators" + "ref": "ICD10/D50-D89", + "label": "D50-D89 (Diseases of the blood and blood-forming organs and certain disorders involving the immune mechanism)" }, - "value_kind": "source" + "value_kind": "enum_value" } - } - ], - "truncated": false, - "source": "observed" - }, - { - "axis": "unit", - "options": [ + }, { "value": { "ref": { - "ref": "InternationalDollar", - "label": "InternationalDollar" + "ref": "ICD10/I00-I99", + "label": "I00-I99 (Diseases of the circulatory system)" }, "value_kind": "enum_value" } - } - ], - "truncated": false, - "source": "observed" - } - ], - "rendered_sentence": "Germany's gross national income based on purchasing power parity in international dollars, 2015 to 2022. World Development Indicators.", - "sentence_plan": [ - { - "kind": "slot", - "text": "Germany", - "axis": "where", - "segment": "heading", - "binding_ref": "where:", - "entity_refs": [], - "states": [ - "where:" - ] - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "gross national income based on purchasing power parity", - "axis": "what", - "segment": "heading", - "entity_refs": [], - "states": [ - "how:activitySource" - ], - "distinguishes": true - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "in international dollars", - "axis": "unit", - "segment": "heading", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:" - ] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "activitySource", - "binding_ref": "how:activitySource", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": ", ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "2015 to 2022", - "axis": "when", - "segment": "heading", - "binding_ref": "when:", - "entity_refs": [], - "states": [ - "when:" - ] - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "World Development Indicators", - "axis": "source", - "segment": "byline", - "entity_refs": [], - "states": [ - "source:" - ], - "distinguishes": true - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [] - } - ], - "trace": { - "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" - } - ], - "resolved_sources": [ - { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" + { + "value": { + "ref": { + "ref": "ICD10/K00-K92", + "label": "K00-K92 (Diseases of the digestive system)" + }, + "value_kind": "enum_value" + } }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" - } - ], - "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "activitySource", - "label": "activitySource" - }, - "label": "activity source" + { + "value": { + "ref": { + "ref": "ICD10/N00-N98", + "label": "N00-N98 (Diseases of the genitourinary system)" + }, + "value_kind": "enum_value" + } }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + { + "value": { + "ref": { + "ref": "ICD10/M00-M99", + "label": "M00-M99 (Diseases of the musculoskeletal system and connective tissue)" + }, + "value_kind": "enum_value" } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "where", - "label": "place" }, - "binding_kind": "value", - "refs": [ - { - "ref": "country/DEU", - "label": "Germany" + { + "value": { + "ref": { + "ref": "ICD10/G00-G98", + "label": "G00-G98 (Diseases of the nervous system)" + }, + "value_kind": "enum_value" } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "when", - "label": "time window" }, - "binding_kind": "value", - "refs": [], - "provenance": "binder" - }, - { - "key": { - "axis": "source", - "label": "data source" + { + "value": { + "ref": { + "ref": "ICD10/J00-J98", + "label": "J00-J98 (Diseases of the respiratory system)" + }, + "value_kind": "enum_value" + } }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - } - ], - "query_qualifiers": [], - "requested_window": { - "start_year": 2015, - "end_year": 2022 - }, - "capability_version": "cap_347a470e04c97eec", - "default_reading": { - "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] - } - }, - "confidence": "high", - "basis": "nominated", - "available_at_place": true, - "measure_label_axes": [], - "measure_axis_values": [] - } - }, - { - "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", - "definition": { - "schema_version": 1, - "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "EconomicActivity", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "PurchasingPowerParity", - "measurement_denominator": { - "unresolved": true - } - }, - "slots": [ - { - "property": "activitySource", - "binding": { - "state": "value", - "ref": "GrossNationalIncome" - } - } - ], - "entities": { - "observationAbout": [ - "country/DEU" - ] - }, - "requested_window": { - "kind": "range", - "start_year": 2015, - "end_year": 2022 - } - } - }, - "resolved": { - "shape": { - "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity_per_unresolved", - "label": "Gross National Income Based on Purchasing Power Parity Per Capita", - "population_type": { - "ref": "EconomicActivity", - "label": "EconomicActivity" - }, - "measured_property": { - "ref": "amount", - "label": "amount" - }, - "stat_type": { - "ref": "measuredValue", - "label": "measuredValue" - }, - "measurement_qualifier": { - "ref": "PurchasingPowerParity", - "label": "PurchasingPowerParity" - }, - "measurement_denominator": { - "ref": "PerCapita", - "label": "PerCapita" - }, - "measurement_denominator_unresolved": true, - "slot_keys": [ - { - "axis": "how", - "property": { - "ref": "activitySource", - "label": "activitySource" + { + "value": { + "ref": { + "ref": "ICD10/L00-L98", + "label": "L00-L98 (Diseases of the skin and subcutaneous tissue)" + }, + "value_kind": "enum_value" + } }, - "label": "activity source" - }, - { - "axis": "where", - "label": "place" - }, - { - "axis": "when", - "label": "time window" - }, - { - "axis": "source", - "label": "data source" - } - ], - "member_count": 1, - "member_digest": "7b2d5b0fc09cfc0215c8d7c6c21a5195fa21e79f2a148a6bca9ce6c3af8bbb9f", - "refine_supported": true, - "data_commons": [ - { - "id": "base", - "label": "Data Commons by Google" - } - ], - "upstream": { - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" - } - } - }, - "slots": [ - { - "key": { - "axis": "how", - "property": { - "ref": "activitySource", - "label": "activitySource" + { + "value": { + "ref": { + "ref": "ICD10/E00-E88", + "label": "E00-E88 (Endocrine, nutritional and metabolic diseases)" + }, + "value_kind": "enum_value" + } }, - "label": "activity source" - }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - }, - "value_kind": "enum_value" - } - }, - "summable": false - }, - { - "key": { - "axis": "where", - "label": "place" - }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" - } - }, - "summable": false - }, - { - "key": { - "axis": "when", - "label": "time window" - }, - "binding": { - "kind": "value", - "value": { - "value_kind": "time_window", - "time_window": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "ICD10/F01-F99", + "label": "F01-F99 (Mental and behavioural disorders)" + }, + "value_kind": "enum_value" } - } - }, - "summable": false + }, + { + "value": { + "ref": { + "ref": "ICD10/O00-O99", + "label": "O00-O99 (Pregnancy, childbirth and the puerperium)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/U00-U99", + "label": "U00-U99 (Codes for special purposes)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Diabetes", + "label": "Diabetes" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Suicide", + "label": "Suicide" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/V01-Y89", + "label": "V01-Y89 (External causes of morbidity and mortality)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/C00-D48", + "label": "C00-D48 (Neoplasms)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/P00-P96", + "label": "P00-P96 (Certain conditions originating in the perinatal period)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/Q00-Q99", + "label": "Q00-Q99 (Congenital malformations, deformations and chromosomal abnormalities)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CerebrovascularDiseases", + "label": "CerebrovascularDiseases" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CongenitalAnomalies", + "label": "CongenitalAnomalies" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CongenitalHeartAnomalies", + "label": "CongenitalHeartAnomalies" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "GenitourinaryDiseases", + "label": "GenitourinaryDiseases" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "HypertensiveHeartDisease", + "label": "HypertensiveHeartDisease" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MalignantNeoplasms", + "label": "MalignantNeoplasms" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Neoplasms", + "label": "Neoplasms" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PerinatalInfection", + "label": "Perinatal Infection" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Pneumonia", + "label": "Pneumonia" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SGP_OtherDiseasesAndCauses", + "label": "SGP_OtherDiseasesAndCauses" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TransportAccidents", + "label": "TransportAccidents" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Tuberculosis", + "label": "Tuberculosis" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, { "key": { - "axis": "source", - "label": "data source" - }, - "binding": { - "kind": "unbound" + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" }, - "summable": false - } - ], - "inapplicable_slots": [], - "unresolved_slots": [], - "stat_vars": { - "member_count": 1, - "member_count_exact": false, - "served_count": 1, - "data_date_range": { - "start": "2015", - "end": "2022" - } - }, - "entities": [ + "options": [ + { + "value": { + "ref": { + "ref": "Female", + "label": "Female" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Male", + "label": "Male" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - } - ], - "coverage": { - "kind": "exact", - "has_data": true, - "observation_count": 8, - "evidence": "facet_metadata", - "dimensions": [ - { - "label": "sources", - "count": 1 - }, - { - "label": "observations", - "count": 8 + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" }, - { - "label": "variables", - "count": 1 - } - ], - "window": { - "start_year": 2015, - "end_year": 2022 - } - }, - "download": { - "rows": 8, - "rows_exact": true, - "series": 1, - "window": { - "start_year": 2015, - "end_year": 2022 + "options": [ + { + "value": { + "ref": { + "ref": "Years0To1", + "label": "Years 0 To 1" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Day0To27", + "label": "Day 0 To 27" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years10To14", + "label": "Years 10 To 14" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years15To19", + "label": "Years 15 To 19" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years15To24", + "label": "Years 15 To 24" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years1To4", + "label": "Years 1 To 4" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years20To24", + "label": "Years 20 To 24" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years25To29", + "label": "Years 25 To 29" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years25To34", + "label": "Years 25 To 34" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years30To34", + "label": "Years 30 To 34" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years35To39", + "label": "Years 35 To 39" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years35To44", + "label": "Years 35 To 44" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years40To44", + "label": "Years 40 To 44" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years45To49", + "label": "Years 45 To 49" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years45To54", + "label": "Years 45 To 54" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years50To54", + "label": "Years 50 To 54" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years55To59", + "label": "Years 55 To 59" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years55To64", + "label": "Years 55 To 64" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years5To9", + "label": "Years 5 To 9" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years60To64", + "label": "Years 60 To 64" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years65To69", + "label": "Years 65 To 69" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years65To74", + "label": "Years 65 To 74" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years70To74", + "label": "Years 70 To 74" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years75To79", + "label": "Years 75 To 79" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years75To84", + "label": "Years 75 To 84" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years80To84", + "label": "Years 80 To 84" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "USC_AgeNotStated", + "label": "USC_AgeNotStated" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years0To4", + "label": "Years 0 To 4" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, - "licence": { - "label": "Creative Commons Attribution License" - } - }, - "facets": { - "provenance": { - "basis": "fallback", - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + { + "key": { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" + "options": [ + { + "value": { + "ref": { + "ref": "CDC_AmericanIndianAndAlaskaNativeAlone", + "label": "American Indian and Alaska native alone" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + "options": [ + { + "value": { + "ref": { + "ref": "COVID_19", + "label": "COVID-19" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, - "unit": { - "basis": "fallback", - "ref": "InternationalDollar", - "label": "InternationalDollar" - } - }, - "slot_options": [ { "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "ethnicity", + "label": "ethnicity" }, - "label": "activity source" + "label": "ethnicity" }, "options": [ { "value": { "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + "ref": "Chinese", + "label": "Chinese" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Indian", + "label": "Indian" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Malay", + "label": "Malay" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SGP_OtherEthnicity", + "label": "SGP_OtherEthnicity" }, "value_kind": "enum_value" } @@ -1740,48 +1922,96 @@ ], "truncated": true, "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ + }, { - "axis": "provenance", + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, "options": [ { "value": { "ref": { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators" + "ref": "Citizen", + "label": "Citizen" }, - "value_kind": "source" + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Resident", + "label": "Resident" + }, + "value_kind": "enum_value" } } ], - "truncated": false, + "truncated": true, "source": "observed" }, { - "axis": "unit", + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, "options": [ { "value": { "ref": { - "ref": "InternationalDollar", - "label": "InternationalDollar" + "ref": "Infant", + "label": "Infant" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Newborn", + "label": "Newborn" }, "value_kind": "enum_value" } } ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" + }, + "value_kind": "source" + } + } + ], "truncated": false, "source": "observed" } ], - "rendered_sentence": "Germany's gross national income based on purchasing power parity per capita in international dollars, 2015 to 2022. World Development Indicators.", + "rendered_sentence": "Kenya's number of deaths, 2018 to 2022. Kenya Census.", "sentence_plan": [ { "kind": "slot", - "text": "Germany", + "text": "Kenya", "axis": "where", "segment": "heading", "binding_ref": "where:", @@ -1806,40 +2036,90 @@ }, { "kind": "slot", - "text": "gross national income based on purchasing power parity per capita", + "text": "number of deaths", "axis": "what", "segment": "heading", "entity_refs": [], - "states": [ - "how:activitySource" - ], + "states": [], "distinguishes": true }, { - "kind": "text", - "text": " ", + "kind": "slot", + "text": "", + "axis": "how", "segment": "heading", + "property_dcid": "age", + "binding_ref": "how:age", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "in international dollars", - "axis": "unit", + "text": "", + "axis": "how", "segment": "heading", - "binding_ref": "unit:", + "property_dcid": "ageGroupClassification", + "binding_ref": "how:ageGroupClassification", "entity_refs": [], - "states": [ - "unit:" - ] + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "ethnicity", + "binding_ref": "how:ethnicity", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "gender", + "binding_ref": "how:gender", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "incidentType", + "binding_ref": "how:incidentType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "race", + "binding_ref": "how:race", + "entity_refs": [], + "states": [] }, { "kind": "slot", "text": "", "axis": "how", "segment": "heading", - "property_dcid": "activitySource", - "binding_ref": "how:activitySource", + "property_dcid": "residentStatus", + "binding_ref": "how:residentStatus", "entity_refs": [], "states": [] }, @@ -1852,14 +2132,15 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2018 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", "entity_refs": [], "states": [ "when:" - ] + ], + "distinguishes": true }, { "kind": "text", @@ -1877,7 +2158,7 @@ }, { "kind": "slot", - "text": "World Development Indicators", + "text": "Kenya Census", "axis": "source", "segment": "byline", "entity_refs": [], @@ -1897,23 +2178,23 @@ "trace": { "resolved_entities": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "resolved_sources": [ { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census", "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "ref": "dc/s/OpenDataForAfrica", + "label": "Open Data for Africa" }, "data_commons": { "id": "base", "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + "documentation": "/api/graph/documentation/dc/base/Kenya_Census" } ], "slot_filters": [ @@ -1921,18 +2202,104 @@ "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" + }, + "label": "cause of death" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" }, - "label": "activity source" + "label": "age group classification" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -1943,8 +2310,8 @@ "binding_kind": "value", "refs": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "provenance": "binder" @@ -1970,42 +2337,17 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] + "removed_stat_vars": [] } }, - "confidence": "high", - "basis": "nominated", + "confidence": "low", + "basis": "structural", "available_at_place": true, "measure_label_axes": [], "measure_axis_values": [] @@ -2015,7 +2357,7 @@ "truncated": false }, "reading_assumptions": { - "spec_c0f61f3ca3558aac184973441a67601e": [ + "spec_10bf62f9687154286b463d206f03a086": [ { "kind": "declared_default", "binding_ref": "how:dac2aAidType", @@ -2025,141 +2367,20 @@ ] } ], - "spec_403a96317ee8b97f1d8569c71015e5ce": [], - "spec_d94656e5d53b7b6c6b0c683145a1cd98": [] + "spec_7923e67e0706d6d9738c78cb374ee8fb": [] } } ], - "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", "sentence_plan": [ { "kind": "text", - "text": "3 readings.", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "Germany", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "primary income", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " for ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "gross of fixed capital consumption", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": ".", + "text": "2 readings.", "segment": "heading", "entity_refs": [], "states": [], "part_index": 0 }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "OECD DAC1", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "2015 to 2022", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "Current US dollars", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, { "kind": "text", "text": " ", @@ -2170,7 +2391,7 @@ }, { "kind": "text", - "text": "Germany", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [], @@ -2194,7 +2415,7 @@ }, { "kind": "text", - "text": "gross national income based on purchasing power parity", + "text": "deaths rate", "segment": "heading", "entity_refs": [], "states": [], @@ -2210,7 +2431,7 @@ }, { "kind": "text", - "text": "in international dollars", + "text": "per capita", "segment": "heading", "entity_refs": [], "states": [], @@ -2250,7 +2471,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2022", "segment": "byline", "entity_refs": [], "states": [], @@ -2274,7 +2495,7 @@ }, { "kind": "text", - "text": "Germany", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [], @@ -2298,23 +2519,7 @@ }, { "kind": "text", - "text": "gross national income based on purchasing power parity per capita", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "in international dollars", + "text": "number of deaths", "segment": "heading", "entity_refs": [], "states": [], @@ -2338,7 +2543,7 @@ }, { "kind": "text", - "text": "World Development Indicators", + "text": "Kenya Census", "segment": "byline", "entity_refs": [], "states": [], @@ -2354,7 +2559,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2018 to 2022", "segment": "byline", "entity_refs": [], "states": [], @@ -2388,28 +2593,29 @@ "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU" + "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, @@ -2423,7 +2629,7 @@ ] } ], - "variable_text": "GNI" + "variable_text": "mortality" } ] } @@ -2433,7 +2639,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4386e87708a64f078f39a795faeb0100" + "x-dfo-trace-id": "8122d1bf0e034c8b833ac2f202e2a9c0" }, "json": { "schema_version": 1, @@ -2442,11 +2648,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "4386e87708a64f078f39a795faeb0100", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "8122d1bf0e034c8b833ac2f202e2a9c0", "warnings": [], "timing_ms": { - "total": 9, + "total": 637, "by_step": { "coverage": 0 } @@ -2456,20 +2662,20 @@ "kind": "resolution", "parts": [ { - "variable_text": "GNI", + "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 8, + "total": 590, "by_step": { "validate": 0, - "walk": 5, + "walk": 215, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 0, + "shape": 257, "bind": 0, - "where_places": 1, - "materialise": 0, + "where_places": 0, + "materialise": 116, "answer": 1, "options": 1 } @@ -2488,69 +2694,70 @@ ], "status": "definite", "spec": { - "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "definition": { "schema_version": 1, - "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU" + "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicunit_primaryincome_measuredvalue_nominal", - "label": "Gross national income", + "shape_id": "mortalityevent_count_measuredvalue_per_count_person", + "label": "Deaths Rate", "population_type": { - "ref": "EconomicUnit", - "label": "economic unit" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "primaryIncome", - "label": "primary income" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "Nominal", - "label": "Nominal" + "measurement_denominator": { + "ref": "Count_Person", + "label": "Total population" }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, { "axis": "where", @@ -2565,13 +2772,13 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", - "refine_supported": true, + "member_count": 133, + "member_digest": "c090b56d31a596a8be16dafb518382db666c6b100a80534c3cb81dbfe3111c5d", + "refine_supported": false, "data_commons": [ { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" } ] }, @@ -2580,20 +2787,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - }, - "value_kind": "enum_value" - } + "kind": "unbound" }, "summable": false }, @@ -2606,8 +2806,8 @@ "kind": "value", "value": { "ref": { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" }, "value_kind": "entity" } @@ -2624,7 +2824,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } @@ -2642,21 +2842,23 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 2, "member_count_exact": true, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2013", "end": "2022" } }, "entities": [ { - "ref": "country/DEU", - "label": "Germany", + "ref": "country/KEN", + "label": "Kenya", "entity_type": "Country", "role": "observationAbout" } @@ -2664,7 +2866,7 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 8, + "observation_count": 10, "evidence": "facet_metadata", "dimensions": [ { @@ -2673,7 +2875,7 @@ }, { "label": "observations", - "count": 8 + "count": 10 }, { "label": "variables", @@ -2681,43 +2883,46 @@ } ], "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, "download": { - "rows": 8, + "rows": 10, "rows_exact": true, "series": 1, "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, "licence": { - "label": "OECD Terms and Conditions" + "label": "Creative Commons Attribution License" } }, "facets": { "provenance": { "basis": "fallback", - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1", - "account": "provider" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "measurementMethod": { + "basis": "fallback", + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" }, "unit": { "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" + "ref": "Per1000Persons", + "label": "Per 1000 people" } }, "slot_options": [ @@ -2725,17 +2930,17 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" + "ref": "ICD10/X60-X84", + "label": "X60-X84 (Intentional self-harm)" }, "value_kind": "enum_value" } @@ -2753,8 +2958,17 @@ { "value": { "ref": { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1" + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + }, + { + "value": { + "ref": { + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, "value_kind": "source" } @@ -2763,28 +2977,54 @@ "truncated": false, "source": "observed" }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "ref": { + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, { "axis": "unit", "options": [ { "value": { "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" + "ref": "Per1000Persons", + "label": "Per 1000 people" }, "value_kind": "enum_value" } + }, + { + "value": { + "value_kind": "enum_value" + } } ], "truncated": false, "source": "observed" } ], - "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "rendered_sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators.", "sentence_plan": [ { "kind": "slot", - "text": "Germany", + "text": "Kenya", "axis": "where", "segment": "heading", "binding_ref": "where:", @@ -2809,7 +3049,7 @@ }, { "kind": "slot", - "text": "primary income", + "text": "deaths rate", "axis": "what", "segment": "heading", "entity_refs": [], @@ -2817,22 +3057,28 @@ }, { "kind": "text", - "text": " for ", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "per capita", + "axis": "unit", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "gross of fixed capital consumption", + "text": "", "axis": "how", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ] + "states": [] }, { "kind": "text", @@ -2843,7 +3089,7 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -2868,26 +3114,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -2906,23 +3133,23 @@ "trace": { "resolved_entities": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "resolved_sources": [ { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" } ], "slot_filters": [ @@ -2930,18 +3157,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -2952,8 +3174,8 @@ "binding_kind": "value", "refs": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "provenance": "binder" @@ -2979,25 +3201,60 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec" + "capability_version": "cap_94e25737d859392c" }, "confidence": "high", "available_at_place": true, "measure_label_axes": [], "measure_axis_values": [], - "related_measures": [] + "related_group": { + "ref": "dc/g/MortalityEvent", + "label": "Mortality Event" + }, + "related_measures": [ + { + "stat_var": { + "ref": "Count_Death", + "label": "Number of Deaths" + }, + "definition": { + "schema_version": 1, + "spec_id": "spec_31961a9c9519bb4db004fa793f0457e5", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "MortalityEvent", + "measured_property": "count", + "stat_type": "measuredValue" + }, + "slots": [], + "entities": { + "observationAbout": [ + "country/KEN" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2013, + "end_year": 2022 + } + } + } + } + ] } } } ], - "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1. Assumed: official development assistance.", + "rendered_sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators. Assumed: official development assistance.", "sentence_plan": [ { "kind": "slot", - "text": "Germany", + "text": "Kenya", "axis": "where", "segment": "heading", "binding_ref": "where:", @@ -3025,7 +3282,7 @@ }, { "kind": "slot", - "text": "primary income", + "text": "deaths rate", "axis": "what", "segment": "heading", "entity_refs": [], @@ -3034,7 +3291,16 @@ }, { "kind": "text", - "text": " for ", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "per capita", + "axis": "unit", "segment": "heading", "entity_refs": [], "states": [], @@ -3042,15 +3308,13 @@ }, { "kind": "slot", - "text": "gross of fixed capital consumption", + "text": "", "axis": "how", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ], + "states": [], "part_index": 0 }, { @@ -3062,7 +3326,7 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -3087,26 +3351,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -3164,14 +3409,14 @@ "answer": { "kind": "resolution", "status": "candidates", - "sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", "complete": false, "specs": [], "gaps": [ { "part": 0, "kind": "choice", - "options": 3 + "options": 2 } ] } @@ -3180,10 +3425,10 @@ "answer": { "kind": "resolution", "status": "definite", - "sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1. Assumed: official development assistance.", + "sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators. Assumed: official development assistance.", "complete": true, "specs": [ - "spec_c0f61f3ca3558aac184973441a67601e" + "spec_10bf62f9687154286b463d206f03a086" ], "gaps": [] } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-by-label.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-by-label.json index 8cab458..15fafc5 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-by-label.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-by-label.json @@ -10,11 +10,11 @@ "call": [ { "op": "search", - "question": "GNI of Germany from 2015 to 2022" + "question": "mortality in Kenya from 2013 to 2022" }, { "op": "choose", - "option": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022." + "option": "Kenya's deaths rate per capita, 2013 to 2022." } ], "exchanges": [ @@ -26,7 +26,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "GNI of Germany from 2015 to 2022" + "query": "mortality in Kenya from 2013 to 2022" } } }, @@ -34,60 +34,72 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "d107dd88e50147378d54464bcdaf9695" + "x-dfo-trace-id": "2fefffc9aac84b4fae2eb1888a1d3b74" }, "json": { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "GNI of Germany from 2015 to 2022", - "normalized_query": "GNI of Germany from 2015 to 2022", + "raw_query": "mortality in Kenya from 2013 to 2022", + "normalized_query": "mortality in Kenya from 2013 to 2022", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d107dd88e50147378d54464bcdaf9695", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "2fefffc9aac84b4fae2eb1888a1d3b74", "warnings": [], "timing_ms": { - "total": 4075, + "total": 2300, "by_step": { "coverage": 0, - "extract": 1004 + "extract": 1022, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 7300, - "output_tokens": 300, - "cached_tokens": 861 + "input_tokens": 2237, + "output_tokens": 143, + "cached_tokens": 842, + "jev_input_tokens": 13358, + "jev_output_tokens": 2855 }, "timed_out": false }, "kind": "resolution", "parts": [ { - "variable_text": "GNI", + "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 2799, + "total": 1274, "by_step": { - "recall": 381, - "shape_arcs": 2, - "shape_probe_coverage": 1, - "shape_probe": 203, - "shape_groups": 18, - "shape_labels": 5, - "shape_admission": 0, - "shape": 1186, - "bind": 829, - "materialise": 217, - "answer": 186 + "recall": 0, + "phase_resolve_places": 0, + "phase_check_entities": 0, + "shape_arcs": 4, + "shape_probe": 112, + "shape_groups": 5, + "shape_labels": 1, + "shape_admission": 1, + "phase_derive_shapes": 0, + "shape": 237, + "phase_prune_and_rank": 0, + "bind": 214, + "phase_bind": 3, + "phase_settle": 7, + "phase_place_bindings": 27, + "phase_facet_requests": 0, + "materialise": 124, + "phase_materialise": 1, + "answer": 25, + "phase_outcome": 636 } }, - "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", "sentence_plan": [ { "kind": "text", - "text": "3 readings.", + "text": "2 readings.", "segment": "heading", "entity_refs": [], "states": [] @@ -101,7 +113,7 @@ }, { "kind": "text", - "text": "Germany", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [] @@ -122,112 +134,7 @@ }, { "kind": "text", - "text": "primary income", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " for ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "gross of fixed capital consumption", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "OECD DAC1", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "2015 to 2022", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "Current US dollars", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "Germany", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "gross national income based on purchasing power parity", + "text": "deaths rate", "segment": "heading", "entity_refs": [], "states": [] @@ -241,7 +148,7 @@ }, { "kind": "text", - "text": "in international dollars", + "text": "per capita", "segment": "heading", "entity_refs": [], "states": [] @@ -276,7 +183,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2022", "segment": "byline", "entity_refs": [], "states": [] @@ -297,7 +204,7 @@ }, { "kind": "text", - "text": "Germany", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [] @@ -318,21 +225,7 @@ }, { "kind": "text", - "text": "gross national income based on purchasing power parity per capita", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "in international dollars", + "text": "number of deaths", "segment": "heading", "entity_refs": [], "states": [] @@ -353,7 +246,7 @@ }, { "kind": "text", - "text": "World Development Indicators", + "text": "Kenya Census", "segment": "byline", "entity_refs": [], "states": [] @@ -367,7 +260,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2018 to 2022", "segment": "byline", "entity_refs": [], "states": [] @@ -381,13 +274,13 @@ } ], "restatement": { - "variable_text": "GNI", + "variable_text": "mortality", "entities": [ { - "text": "Germany" + "text": "Kenya" } ], - "time_text": "2015 to 2022", + "time_text": "2013 to 2022", "sources": [], "operations": [] }, @@ -400,69 +293,70 @@ "max_candidates": 6, "specs": [ { - "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "definition": { "schema_version": 1, - "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU" + "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicunit_primaryincome_measuredvalue_nominal", - "label": "Gross national income", + "shape_id": "mortalityevent_count_measuredvalue_per_count_person", + "label": "Deaths Rate", "population_type": { - "ref": "EconomicUnit", - "label": "economic unit" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "primaryIncome", - "label": "primary income" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "Nominal", - "label": "Nominal" + "measurement_denominator": { + "ref": "Count_Person", + "label": "Total population" }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, { "axis": "where", @@ -477,13 +371,13 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", - "refine_supported": true, + "member_count": 133, + "member_digest": "c090b56d31a596a8be16dafb518382db666c6b100a80534c3cb81dbfe3111c5d", + "refine_supported": false, "data_commons": [ { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" } ] }, @@ -492,20 +386,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - }, - "value_kind": "enum_value" - } + "kind": "unbound" }, "summable": false }, @@ -518,8 +405,8 @@ "kind": "value", "value": { "ref": { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" }, "value_kind": "entity" } @@ -536,7 +423,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } @@ -554,21 +441,23 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 2, "member_count_exact": false, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2013", "end": "2022" } }, "entities": [ { - "ref": "country/DEU", - "label": "Germany", + "ref": "country/KEN", + "label": "Kenya", "entity_type": "Country", "role": "observationAbout" } @@ -576,7 +465,7 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 8, + "observation_count": 10, "evidence": "facet_metadata", "dimensions": [ { @@ -585,7 +474,7 @@ }, { "label": "observations", - "count": 8 + "count": 10 }, { "label": "variables", @@ -593,43 +482,46 @@ } ], "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, "download": { - "rows": 8, + "rows": 10, "rows_exact": true, "series": 1, "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, "licence": { - "label": "OECD Terms and Conditions" + "label": "Creative Commons Attribution License" } }, "facets": { "provenance": { "basis": "fallback", - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1", - "account": "provider" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "measurementMethod": { + "basis": "fallback", + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" }, "unit": { "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" + "ref": "Per1000Persons", + "label": "Per 1000 people" } }, "slot_options": [ @@ -637,17 +529,17 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" + "ref": "ICD10/X60-X84", + "label": "X60-X84 (Intentional self-harm)" }, "value_kind": "enum_value" } @@ -665,8 +557,17 @@ { "value": { "ref": { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1" + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + }, + { + "value": { + "ref": { + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, "value_kind": "source" } @@ -675,28 +576,54 @@ "truncated": false, "source": "observed" }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "ref": { + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, { "axis": "unit", "options": [ { "value": { "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" + "ref": "Per1000Persons", + "label": "Per 1000 people" }, "value_kind": "enum_value" } + }, + { + "value": { + "value_kind": "enum_value" + } } ], "truncated": false, "source": "observed" } ], - "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "rendered_sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators.", "sentence_plan": [ { "kind": "slot", - "text": "Germany", + "text": "Kenya", "axis": "where", "segment": "heading", "binding_ref": "where:", @@ -721,7 +648,7 @@ }, { "kind": "slot", - "text": "primary income", + "text": "deaths rate", "axis": "what", "segment": "heading", "entity_refs": [], @@ -730,23 +657,28 @@ }, { "kind": "text", - "text": " for ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "gross of fixed capital consumption", + "text": "per capita", + "axis": "unit", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", "axis": "how", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ], - "distinguishes": true + "states": [] }, { "kind": "text", @@ -757,14 +689,15 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", "entity_refs": [], "states": [ "when:" - ] + ], + "distinguishes": true }, { "kind": "text", @@ -782,26 +715,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -821,23 +735,23 @@ "trace": { "resolved_entities": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "resolved_sources": [ { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" } ], "slot_filters": [ @@ -845,18 +759,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -867,8 +776,8 @@ "binding_kind": "value", "refs": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "provenance": "binder" @@ -894,38 +803,13 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] + "removed_stat_vars": [] } }, "confidence": "high", @@ -935,122 +819,294 @@ } }, { - "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "spec_id": "spec_7923e67e0706d6d9738c78cb374ee8fb", "definition": { "schema_version": 1, - "spec_id": "spec_403a96317ee8b97f1d8569c71015e5ce", + "spec_id": "spec_7923e67e0706d6d9738c78cb374ee8fb", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicActivity", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "PurchasingPowerParity" + "population_type": "MortalityEvent", + "measured_property": "count", + "stat_type": "measuredValue" }, "slots": [ { - "property": "activitySource", + "property": "age", + "binding": { + "state": "unbound" + } + }, + { + "property": "ageGroupClassification", + "binding": { + "state": "unbound" + } + }, + { + "property": "causeOfDeath", + "binding": { + "state": "unbound" + } + }, + { + "property": "ethnicity", + "binding": { + "state": "unbound" + } + }, + { + "property": "gender", + "binding": { + "state": "unbound" + } + }, + { + "property": "incidentType", + "binding": { + "state": "unbound" + } + }, + { + "property": "race", + "binding": { + "state": "unbound" + } + }, + { + "property": "residentStatus", "binding": { - "state": "value", - "ref": "GrossNationalIncome" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU" + "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity", - "label": "Gross National Income Based on Purchasing Power Parity", + "shape_id": "mortalityevent_count_measuredvalue", + "label": "Number of Deaths", "population_type": { - "ref": "EconomicActivity", - "label": "EconomicActivity" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "amount", - "label": "amount" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "PurchasingPowerParity", - "label": "PurchasingPowerParity" - }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, { - "axis": "where", - "label": "place" + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" }, { - "axis": "when", - "label": "time window" + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" }, { - "axis": "source", - "label": "data source" - } + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } ], - "member_count": 1, - "member_digest": "833b9da89613fa6c1775652daac2388f38204c6c9f9929ca113deed9a0d08369", + "member_count": 2978, "refine_supported": true, "data_commons": [ { "id": "base", "label": "Data Commons by Google" } - ], - "upstream": { - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" - } - } + ] }, "slots": [ { "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - }, - "value_kind": "enum_value" - } + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + "binding": { + "kind": "unbound" }, "summable": false }, @@ -1063,8 +1119,8 @@ "kind": "value", "value": { "ref": { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" }, "value_kind": "entity" } @@ -1081,7 +1137,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 } } @@ -1099,21 +1155,30 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath", + "gender", + "age", + "race", + "incidentType", + "ethnicity", + "residentStatus", + "ageGroupClassification" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 37, "member_count_exact": false, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2018", "end": "2022" } }, "entities": [ { - "ref": "country/DEU", - "label": "Germany", + "ref": "country/KEN", + "label": "Kenya", "entity_type": "Country", "role": "observationAbout" } @@ -1121,7 +1186,7 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 8, + "observation_count": 5, "evidence": "facet_metadata", "dimensions": [ { @@ -1130,7 +1195,7 @@ }, { "label": "observations", - "count": 8 + "count": 5 }, { "label": "variables", @@ -1138,16 +1203,16 @@ } ], "window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 } }, "download": { - "rows": 8, + "rows": 5, "rows_exact": true, "series": 1, "window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 }, "licence": { @@ -1157,22 +1222,17 @@ "facets": { "provenance": { "basis": "fallback", - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census", "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "ref": "dc/s/OpenDataForAfrica", + "label": "Open Data for Africa" }, "data_commons": { "id": "base", "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" - }, - "unit": { - "basis": "fallback", - "ref": "InternationalDollar", - "label": "InternationalDollar" + "documentation": "/api/graph/documentation/dc/base/Kenya_Census" } }, "slot_options": [ @@ -1180,559 +1240,681 @@ "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + "ref": "ICD10/A00-B99", + "label": "A00-B99 (Certain infectious and parasitic diseases)" }, "value_kind": "enum_value" } - } - ], - "truncated": true, - "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ - { - "axis": "provenance", - "options": [ + }, { "value": { "ref": { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators" + "ref": "ICD10/D50-D89", + "label": "D50-D89 (Diseases of the blood and blood-forming organs and certain disorders involving the immune mechanism)" }, - "value_kind": "source" + "value_kind": "enum_value" } - } - ], - "truncated": false, - "source": "observed" - }, - { - "axis": "unit", - "options": [ + }, { "value": { "ref": { - "ref": "InternationalDollar", - "label": "InternationalDollar" + "ref": "ICD10/I00-I99", + "label": "I00-I99 (Diseases of the circulatory system)" }, "value_kind": "enum_value" } - } - ], - "truncated": false, - "source": "observed" - } - ], - "rendered_sentence": "Germany's gross national income based on purchasing power parity in international dollars, 2015 to 2022. World Development Indicators.", - "sentence_plan": [ - { - "kind": "slot", - "text": "Germany", - "axis": "where", - "segment": "heading", - "binding_ref": "where:", - "entity_refs": [], - "states": [ - "where:" - ] - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "gross national income based on purchasing power parity", - "axis": "what", - "segment": "heading", - "entity_refs": [], - "states": [ - "how:activitySource" - ], - "distinguishes": true - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "in international dollars", - "axis": "unit", - "segment": "heading", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:" - ] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "activitySource", - "binding_ref": "how:activitySource", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": ", ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "2015 to 2022", - "axis": "when", - "segment": "heading", - "binding_ref": "when:", - "entity_refs": [], - "states": [ - "when:" - ] - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "World Development Indicators", - "axis": "source", - "segment": "byline", - "entity_refs": [], - "states": [ - "source:" - ], - "distinguishes": true - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [] - } - ], - "trace": { - "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" - } - ], - "resolved_sources": [ - { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" + { + "value": { + "ref": { + "ref": "ICD10/K00-K92", + "label": "K00-K92 (Diseases of the digestive system)" + }, + "value_kind": "enum_value" + } }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" - } - ], - "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "activitySource", - "label": "activitySource" - }, - "label": "activity source" + { + "value": { + "ref": { + "ref": "ICD10/N00-N98", + "label": "N00-N98 (Diseases of the genitourinary system)" + }, + "value_kind": "enum_value" + } }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + { + "value": { + "ref": { + "ref": "ICD10/M00-M99", + "label": "M00-M99 (Diseases of the musculoskeletal system and connective tissue)" + }, + "value_kind": "enum_value" } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "where", - "label": "place" }, - "binding_kind": "value", - "refs": [ - { - "ref": "country/DEU", - "label": "Germany" + { + "value": { + "ref": { + "ref": "ICD10/G00-G98", + "label": "G00-G98 (Diseases of the nervous system)" + }, + "value_kind": "enum_value" } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "when", - "label": "time window" }, - "binding_kind": "value", - "refs": [], - "provenance": "binder" - }, - { - "key": { - "axis": "source", - "label": "data source" + { + "value": { + "ref": { + "ref": "ICD10/J00-J98", + "label": "J00-J98 (Diseases of the respiratory system)" + }, + "value_kind": "enum_value" + } }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - } - ], - "query_qualifiers": [], - "requested_window": { - "start_year": 2015, - "end_year": 2022 - }, - "capability_version": "cap_347a470e04c97eec", - "default_reading": { - "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] - } - }, - "confidence": "high", - "basis": "nominated", - "available_at_place": true, - "measure_label_axes": [], - "measure_axis_values": [] - } - }, - { - "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", - "definition": { - "schema_version": 1, - "spec_id": "spec_d94656e5d53b7b6c6b0c683145a1cd98", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "EconomicActivity", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "PurchasingPowerParity", - "measurement_denominator": { - "unresolved": true - } - }, - "slots": [ - { - "property": "activitySource", - "binding": { - "state": "value", - "ref": "GrossNationalIncome" - } - } - ], - "entities": { - "observationAbout": [ - "country/DEU" - ] - }, - "requested_window": { - "kind": "range", - "start_year": 2015, - "end_year": 2022 - } - } - }, - "resolved": { - "shape": { - "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity_per_unresolved", - "label": "Gross National Income Based on Purchasing Power Parity Per Capita", - "population_type": { - "ref": "EconomicActivity", - "label": "EconomicActivity" - }, - "measured_property": { - "ref": "amount", - "label": "amount" - }, - "stat_type": { - "ref": "measuredValue", - "label": "measuredValue" - }, - "measurement_qualifier": { - "ref": "PurchasingPowerParity", - "label": "PurchasingPowerParity" - }, - "measurement_denominator": { - "ref": "PerCapita", - "label": "PerCapita" - }, - "measurement_denominator_unresolved": true, - "slot_keys": [ - { - "axis": "how", - "property": { - "ref": "activitySource", - "label": "activitySource" + { + "value": { + "ref": { + "ref": "ICD10/L00-L98", + "label": "L00-L98 (Diseases of the skin and subcutaneous tissue)" + }, + "value_kind": "enum_value" + } }, - "label": "activity source" - }, - { - "axis": "where", - "label": "place" - }, - { - "axis": "when", - "label": "time window" - }, - { - "axis": "source", - "label": "data source" - } - ], - "member_count": 1, - "member_digest": "7b2d5b0fc09cfc0215c8d7c6c21a5195fa21e79f2a148a6bca9ce6c3af8bbb9f", - "refine_supported": true, - "data_commons": [ - { - "id": "base", - "label": "Data Commons by Google" - } - ], - "upstream": { - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" - } - } - }, - "slots": [ - { - "key": { - "axis": "how", - "property": { - "ref": "activitySource", - "label": "activitySource" + { + "value": { + "ref": { + "ref": "ICD10/E00-E88", + "label": "E00-E88 (Endocrine, nutritional and metabolic diseases)" + }, + "value_kind": "enum_value" + } }, - "label": "activity source" - }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - }, - "value_kind": "enum_value" - } - }, - "summable": false - }, - { - "key": { - "axis": "where", - "label": "place" - }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" - } - }, - "summable": false - }, - { - "key": { - "axis": "when", - "label": "time window" - }, - "binding": { - "kind": "value", - "value": { - "value_kind": "time_window", - "time_window": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "ICD10/F01-F99", + "label": "F01-F99 (Mental and behavioural disorders)" + }, + "value_kind": "enum_value" } - } - }, - "summable": false + }, + { + "value": { + "ref": { + "ref": "ICD10/O00-O99", + "label": "O00-O99 (Pregnancy, childbirth and the puerperium)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/U00-U99", + "label": "U00-U99 (Codes for special purposes)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Diabetes", + "label": "Diabetes" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Suicide", + "label": "Suicide" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/V01-Y89", + "label": "V01-Y89 (External causes of morbidity and mortality)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/C00-D48", + "label": "C00-D48 (Neoplasms)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/P00-P96", + "label": "P00-P96 (Certain conditions originating in the perinatal period)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/Q00-Q99", + "label": "Q00-Q99 (Congenital malformations, deformations and chromosomal abnormalities)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CerebrovascularDiseases", + "label": "CerebrovascularDiseases" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CongenitalAnomalies", + "label": "CongenitalAnomalies" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CongenitalHeartAnomalies", + "label": "CongenitalHeartAnomalies" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "GenitourinaryDiseases", + "label": "GenitourinaryDiseases" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "HypertensiveHeartDisease", + "label": "HypertensiveHeartDisease" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MalignantNeoplasms", + "label": "MalignantNeoplasms" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Neoplasms", + "label": "Neoplasms" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PerinatalInfection", + "label": "Perinatal Infection" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Pneumonia", + "label": "Pneumonia" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SGP_OtherDiseasesAndCauses", + "label": "SGP_OtherDiseasesAndCauses" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TransportAccidents", + "label": "TransportAccidents" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Tuberculosis", + "label": "Tuberculosis" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, { "key": { - "axis": "source", - "label": "data source" - }, - "binding": { - "kind": "unbound" + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" }, - "summable": false - } - ], - "inapplicable_slots": [], - "unresolved_slots": [], - "stat_vars": { - "member_count": 1, - "member_count_exact": false, - "served_count": 1, - "data_date_range": { - "start": "2015", - "end": "2022" - } - }, - "entities": [ + "options": [ + { + "value": { + "ref": { + "ref": "Female", + "label": "Female" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Male", + "label": "Male" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - } - ], - "coverage": { - "kind": "exact", - "has_data": true, - "observation_count": 8, - "evidence": "facet_metadata", - "dimensions": [ - { - "label": "sources", - "count": 1 - }, - { - "label": "observations", - "count": 8 + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" }, - { - "label": "variables", - "count": 1 - } - ], - "window": { - "start_year": 2015, - "end_year": 2022 - } - }, - "download": { - "rows": 8, - "rows_exact": true, - "series": 1, - "window": { - "start_year": 2015, - "end_year": 2022 + "options": [ + { + "value": { + "ref": { + "ref": "Years0To1", + "label": "Years 0 To 1" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Day0To27", + "label": "Day 0 To 27" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years10To14", + "label": "Years 10 To 14" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years15To19", + "label": "Years 15 To 19" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years15To24", + "label": "Years 15 To 24" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years1To4", + "label": "Years 1 To 4" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years20To24", + "label": "Years 20 To 24" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years25To29", + "label": "Years 25 To 29" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years25To34", + "label": "Years 25 To 34" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years30To34", + "label": "Years 30 To 34" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years35To39", + "label": "Years 35 To 39" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years35To44", + "label": "Years 35 To 44" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years40To44", + "label": "Years 40 To 44" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years45To49", + "label": "Years 45 To 49" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years45To54", + "label": "Years 45 To 54" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years50To54", + "label": "Years 50 To 54" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years55To59", + "label": "Years 55 To 59" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years55To64", + "label": "Years 55 To 64" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years5To9", + "label": "Years 5 To 9" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years60To64", + "label": "Years 60 To 64" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years65To69", + "label": "Years 65 To 69" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years65To74", + "label": "Years 65 To 74" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years70To74", + "label": "Years 70 To 74" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years75To79", + "label": "Years 75 To 79" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years75To84", + "label": "Years 75 To 84" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years80To84", + "label": "Years 80 To 84" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "USC_AgeNotStated", + "label": "USC_AgeNotStated" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years0To4", + "label": "Years 0 To 4" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, - "licence": { - "label": "Creative Commons Attribution License" - } - }, - "facets": { - "provenance": { - "basis": "fallback", - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + { + "key": { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" + "options": [ + { + "value": { + "ref": { + "ref": "CDC_AmericanIndianAndAlaskaNativeAlone", + "label": "American Indian and Alaska native alone" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + "options": [ + { + "value": { + "ref": { + "ref": "COVID_19", + "label": "COVID-19" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, - "unit": { - "basis": "fallback", - "ref": "InternationalDollar", - "label": "InternationalDollar" - } - }, - "slot_options": [ { "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "ethnicity", + "label": "ethnicity" }, - "label": "activity source" + "label": "ethnicity" }, "options": [ { "value": { "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + "ref": "Chinese", + "label": "Chinese" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Indian", + "label": "Indian" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Malay", + "label": "Malay" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SGP_OtherEthnicity", + "label": "SGP_OtherEthnicity" }, "value_kind": "enum_value" } @@ -1740,48 +1922,96 @@ ], "truncated": true, "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ + }, { - "axis": "provenance", + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, "options": [ { "value": { "ref": { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators" + "ref": "Citizen", + "label": "Citizen" }, - "value_kind": "source" + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Resident", + "label": "Resident" + }, + "value_kind": "enum_value" } } ], - "truncated": false, + "truncated": true, "source": "observed" }, { - "axis": "unit", + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, "options": [ { "value": { "ref": { - "ref": "InternationalDollar", - "label": "InternationalDollar" + "ref": "Infant", + "label": "Infant" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Newborn", + "label": "Newborn" }, "value_kind": "enum_value" } } ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" + }, + "value_kind": "source" + } + } + ], "truncated": false, "source": "observed" } ], - "rendered_sentence": "Germany's gross national income based on purchasing power parity per capita in international dollars, 2015 to 2022. World Development Indicators.", + "rendered_sentence": "Kenya's number of deaths, 2018 to 2022. Kenya Census.", "sentence_plan": [ { "kind": "slot", - "text": "Germany", + "text": "Kenya", "axis": "where", "segment": "heading", "binding_ref": "where:", @@ -1806,40 +2036,90 @@ }, { "kind": "slot", - "text": "gross national income based on purchasing power parity per capita", + "text": "number of deaths", "axis": "what", "segment": "heading", "entity_refs": [], - "states": [ - "how:activitySource" - ], + "states": [], "distinguishes": true }, { - "kind": "text", - "text": " ", + "kind": "slot", + "text": "", + "axis": "how", "segment": "heading", + "property_dcid": "age", + "binding_ref": "how:age", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "in international dollars", - "axis": "unit", + "text": "", + "axis": "how", "segment": "heading", - "binding_ref": "unit:", + "property_dcid": "ageGroupClassification", + "binding_ref": "how:ageGroupClassification", "entity_refs": [], - "states": [ - "unit:" - ] + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "ethnicity", + "binding_ref": "how:ethnicity", + "entity_refs": [], + "states": [] }, { "kind": "slot", "text": "", "axis": "how", "segment": "heading", - "property_dcid": "activitySource", - "binding_ref": "how:activitySource", + "property_dcid": "gender", + "binding_ref": "how:gender", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "incidentType", + "binding_ref": "how:incidentType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "race", + "binding_ref": "how:race", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "residentStatus", + "binding_ref": "how:residentStatus", "entity_refs": [], "states": [] }, @@ -1852,14 +2132,15 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2018 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", "entity_refs": [], "states": [ "when:" - ] + ], + "distinguishes": true }, { "kind": "text", @@ -1877,7 +2158,7 @@ }, { "kind": "slot", - "text": "World Development Indicators", + "text": "Kenya Census", "axis": "source", "segment": "byline", "entity_refs": [], @@ -1897,23 +2178,23 @@ "trace": { "resolved_entities": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "resolved_sources": [ { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census", "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "ref": "dc/s/OpenDataForAfrica", + "label": "Open Data for Africa" }, "data_commons": { "id": "base", "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + "documentation": "/api/graph/documentation/dc/base/Kenya_Census" } ], "slot_filters": [ @@ -1921,18 +2202,104 @@ "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" + }, + "label": "cause of death" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" }, - "label": "activity source" + "label": "age group classification" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -1943,8 +2310,8 @@ "binding_kind": "value", "refs": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "provenance": "binder" @@ -1970,42 +2337,17 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] + "removed_stat_vars": [] } }, - "confidence": "high", - "basis": "nominated", + "confidence": "low", + "basis": "structural", "available_at_place": true, "measure_label_axes": [], "measure_axis_values": [] @@ -2015,142 +2357,21 @@ "truncated": false }, "reading_assumptions": { - "spec_c0f61f3ca3558aac184973441a67601e": [], - "spec_403a96317ee8b97f1d8569c71015e5ce": [], - "spec_d94656e5d53b7b6c6b0c683145a1cd98": [] + "spec_10bf62f9687154286b463d206f03a086": [], + "spec_7923e67e0706d6d9738c78cb374ee8fb": [] } } ], - "rendered_sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", "sentence_plan": [ { "kind": "text", - "text": "3 readings.", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "Germany", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "primary income", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " for ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "gross of fixed capital consumption", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": ".", + "text": "2 readings.", "segment": "heading", "entity_refs": [], "states": [], "part_index": 0 }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "OECD DAC1", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "2015 to 2022", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "Current US dollars", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, { "kind": "text", "text": " ", @@ -2161,7 +2382,7 @@ }, { "kind": "text", - "text": "Germany", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [], @@ -2185,7 +2406,7 @@ }, { "kind": "text", - "text": "gross national income based on purchasing power parity", + "text": "deaths rate", "segment": "heading", "entity_refs": [], "states": [], @@ -2201,7 +2422,7 @@ }, { "kind": "text", - "text": "in international dollars", + "text": "per capita", "segment": "heading", "entity_refs": [], "states": [], @@ -2241,7 +2462,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2022", "segment": "byline", "entity_refs": [], "states": [], @@ -2265,7 +2486,7 @@ }, { "kind": "text", - "text": "Germany", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [], @@ -2289,23 +2510,7 @@ }, { "kind": "text", - "text": "gross national income based on purchasing power parity per capita", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "in international dollars", + "text": "number of deaths", "segment": "heading", "entity_refs": [], "states": [], @@ -2329,7 +2534,7 @@ }, { "kind": "text", - "text": "World Development Indicators", + "text": "Kenya Census", "segment": "byline", "entity_refs": [], "states": [], @@ -2345,7 +2550,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2018 to 2022", "segment": "byline", "entity_refs": [], "states": [], @@ -2379,33 +2584,34 @@ "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU" + "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, "assumptions": [], - "variable_text": "GNI" + "variable_text": "mortality" } ] } @@ -2415,7 +2621,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4386e87708a64f078f39a795faeb0100" + "x-dfo-trace-id": "8122d1bf0e034c8b833ac2f202e2a9c0" }, "json": { "schema_version": 1, @@ -2424,11 +2630,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "4386e87708a64f078f39a795faeb0100", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "8122d1bf0e034c8b833ac2f202e2a9c0", "warnings": [], "timing_ms": { - "total": 9, + "total": 637, "by_step": { "coverage": 0 } @@ -2438,20 +2644,20 @@ "kind": "resolution", "parts": [ { - "variable_text": "GNI", + "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 8, + "total": 590, "by_step": { "validate": 0, - "walk": 5, + "walk": 215, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 0, + "shape": 257, "bind": 0, - "where_places": 1, - "materialise": 0, + "where_places": 0, + "materialise": 116, "answer": 1, "options": 1 } @@ -2461,69 +2667,70 @@ "assumptions": [], "status": "definite", "spec": { - "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "definition": { "schema_version": 1, - "spec_id": "spec_c0f61f3ca3558aac184973441a67601e", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU" + "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicunit_primaryincome_measuredvalue_nominal", - "label": "Gross national income", + "shape_id": "mortalityevent_count_measuredvalue_per_count_person", + "label": "Deaths Rate", "population_type": { - "ref": "EconomicUnit", - "label": "economic unit" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "primaryIncome", - "label": "primary income" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "Nominal", - "label": "Nominal" + "measurement_denominator": { + "ref": "Count_Person", + "label": "Total population" }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, { "axis": "where", @@ -2538,13 +2745,13 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", - "refine_supported": true, + "member_count": 133, + "member_digest": "c090b56d31a596a8be16dafb518382db666c6b100a80534c3cb81dbfe3111c5d", + "refine_supported": false, "data_commons": [ { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" } ] }, @@ -2553,20 +2760,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - }, - "value_kind": "enum_value" - } + "kind": "unbound" }, "summable": false }, @@ -2579,8 +2779,8 @@ "kind": "value", "value": { "ref": { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" }, "value_kind": "entity" } @@ -2597,7 +2797,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } @@ -2615,21 +2815,23 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 2, "member_count_exact": true, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2013", "end": "2022" } }, "entities": [ { - "ref": "country/DEU", - "label": "Germany", + "ref": "country/KEN", + "label": "Kenya", "entity_type": "Country", "role": "observationAbout" } @@ -2637,7 +2839,7 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 8, + "observation_count": 10, "evidence": "facet_metadata", "dimensions": [ { @@ -2646,7 +2848,7 @@ }, { "label": "observations", - "count": 8 + "count": 10 }, { "label": "variables", @@ -2654,43 +2856,46 @@ } ], "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, "download": { - "rows": 8, + "rows": 10, "rows_exact": true, "series": 1, "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, "licence": { - "label": "OECD Terms and Conditions" + "label": "Creative Commons Attribution License" } }, "facets": { "provenance": { "basis": "fallback", - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1", - "account": "provider" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "measurementMethod": { + "basis": "fallback", + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" }, "unit": { "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" + "ref": "Per1000Persons", + "label": "Per 1000 people" } }, "slot_options": [ @@ -2698,17 +2903,17 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" + "ref": "ICD10/X60-X84", + "label": "X60-X84 (Intentional self-harm)" }, "value_kind": "enum_value" } @@ -2726,8 +2931,17 @@ { "value": { "ref": { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1" + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + }, + { + "value": { + "ref": { + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, "value_kind": "source" } @@ -2736,28 +2950,54 @@ "truncated": false, "source": "observed" }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "ref": { + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, { "axis": "unit", "options": [ { "value": { "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" + "ref": "Per1000Persons", + "label": "Per 1000 people" }, "value_kind": "enum_value" } + }, + { + "value": { + "value_kind": "enum_value" + } } ], "truncated": false, "source": "observed" } ], - "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "rendered_sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators.", "sentence_plan": [ { "kind": "slot", - "text": "Germany", + "text": "Kenya", "axis": "where", "segment": "heading", "binding_ref": "where:", @@ -2782,7 +3022,7 @@ }, { "kind": "slot", - "text": "primary income", + "text": "deaths rate", "axis": "what", "segment": "heading", "entity_refs": [], @@ -2790,22 +3030,28 @@ }, { "kind": "text", - "text": " for ", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "per capita", + "axis": "unit", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "gross of fixed capital consumption", + "text": "", "axis": "how", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ] + "states": [] }, { "kind": "text", @@ -2816,7 +3062,7 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -2841,26 +3087,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -2879,23 +3106,23 @@ "trace": { "resolved_entities": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "resolved_sources": [ { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" } ], "slot_filters": [ @@ -2903,18 +3130,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -2925,8 +3147,8 @@ "binding_kind": "value", "refs": [ { - "ref": "country/DEU", - "label": "Germany" + "ref": "country/KEN", + "label": "Kenya" } ], "provenance": "binder" @@ -2952,25 +3174,60 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec" + "capability_version": "cap_94e25737d859392c" }, "confidence": "high", "available_at_place": true, "measure_label_axes": [], "measure_axis_values": [], - "related_measures": [] + "related_group": { + "ref": "dc/g/MortalityEvent", + "label": "Mortality Event" + }, + "related_measures": [ + { + "stat_var": { + "ref": "Count_Death", + "label": "Number of Deaths" + }, + "definition": { + "schema_version": 1, + "spec_id": "spec_31961a9c9519bb4db004fa793f0457e5", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "MortalityEvent", + "measured_property": "count", + "stat_type": "measuredValue" + }, + "slots": [], + "entities": { + "observationAbout": [ + "country/KEN" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2013, + "end_year": 2022 + } + } + } + } + ] } } } ], - "rendered_sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "rendered_sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators.", "sentence_plan": [ { "kind": "slot", - "text": "Germany", + "text": "Kenya", "axis": "where", "segment": "heading", "binding_ref": "where:", @@ -2998,7 +3255,7 @@ }, { "kind": "slot", - "text": "primary income", + "text": "deaths rate", "axis": "what", "segment": "heading", "entity_refs": [], @@ -3007,7 +3264,16 @@ }, { "kind": "text", - "text": " for ", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "per capita", + "axis": "unit", "segment": "heading", "entity_refs": [], "states": [], @@ -3015,15 +3281,13 @@ }, { "kind": "slot", - "text": "gross of fixed capital consumption", + "text": "", "axis": "how", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ], + "states": [], "part_index": 0 }, { @@ -3035,7 +3299,7 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -3060,26 +3324,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -3105,14 +3350,14 @@ "answer": { "kind": "resolution", "status": "candidates", - "sentence": "3 readings. Germany's primary income for gross of fixed capital consumption. OECD DAC1 · 2015 to 2022 · Current US dollars. Germany's gross national income based on purchasing power parity in international dollars. World Development Indicators · 2015 to 2022. Germany's gross national income based on purchasing power parity per capita in international dollars. World Development Indicators · 2015 to 2022.", + "sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", "complete": false, "specs": [], "gaps": [ { "part": 0, "kind": "choice", - "options": 3 + "options": 2 } ] } @@ -3121,10 +3366,10 @@ "answer": { "kind": "resolution", "status": "definite", - "sentence": "Germany's primary income for gross of fixed capital consumption, 2015 to 2022. Current US dollars · OECD DAC1.", + "sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators.", "complete": true, "specs": [ - "spec_c0f61f3ca3558aac184973441a67601e" + "spec_10bf62f9687154286b463d206f03a086" ], "gaps": [] } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-echoes-assumptions.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-echoes-assumptions.json index 6c18b3a..eb1315d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-echoes-assumptions.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-echoes-assumptions.json @@ -4,14 +4,14 @@ "description": "Choosing candidate 0 on part 0 beside a definite part that states assumptions posts each identity entry with its reading's assumptions echoed: the chosen candidate's reading_assumptions entry, [] here, and the definite part's own assumptions. The rebuilt definite part states the same assumptions; an entry with no assumptions would be read as a fresh request.", "origin": { "kind": "recorded", - "base_url": "http://127.0.0.1:19493/api", - "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T13:07:25Z" + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "recorded_at": "2026-10-23T18:39:43Z" }, "call": [ { "op": "search", - "question": "GNI of Germany and aid flows to Kenya" + "question": "mortality in Kenya and aid flows to Kenya from 2013 to 2022" }, { "op": "choose", @@ -28,7 +28,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "GNI of Germany and aid flows to Kenya" + "query": "mortality in Kenya and aid flows to Kenya from 2013 to 2022" } } }, @@ -36,38 +36,41 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "810e4170976b4e69aade88273e59e8c2" + "x-dfo-trace-id": "25c71c81e1ca452e8b685116e6be540e" }, "json": { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "GNI of Germany and aid flows to Kenya", - "normalized_query": "GNI of Germany and aid flows to Kenya", + "raw_query": "mortality in Kenya and aid flows to Kenya from 2013 to 2022", + "normalized_query": "mortality in Kenya and aid flows to Kenya from 2013 to 2022", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "810e4170976b4e69aade88273e59e8c2", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "25c71c81e1ca452e8b685116e6be540e", "warnings": [], "timing_ms": { - "total": 3563, + "total": 3941, "by_step": { "coverage": 0, - "extract": 915 + "extract": 1292, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 11874, - "output_tokens": 489, - "cached_tokens": 860 + "input_tokens": 2242, + "output_tokens": 197, + "cached_tokens": 843, + "jev_input_tokens": 21367, + "jev_output_tokens": 4607 }, "timed_out": false }, "kind": "resolution", "parts": [ { - "variable_text": "GNI", + "variable_text": "mortality", "warnings": [ { "code": "direction_discarded", @@ -76,22 +79,31 @@ } ], "timing_ms": { - "total": 2206, + "total": 2646, "by_step": { "recall": 1, - "shape_arcs": 1, - "shape_probe_coverage": 3, - "shape_probe": 270, - "shape_groups": 201, - "shape_labels": 6, - "shape_admission": 0, - "shape": 1165, - "bind": 1038, - "materialise": 1, - "answer": 1 + "phase_resolve_places": 0, + "phase_check_entities": 0, + "shape_arcs": 4, + "shape_probe": 106, + "shape_groups": 5, + "shape_labels": 1, + "shape_admission": 1, + "phase_derive_shapes": 0, + "shape": 250, + "phase_prune_and_rank": 0, + "bind": 805, + "phase_bind": 4, + "phase_settle": 8, + "phase_place_bindings": 110, + "phase_facet_requests": 0, + "materialise": 167, + "phase_materialise": 0, + "answer": 26, + "phase_outcome": 1275 } }, - "rendered_sentence": "2 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 1960 to 2025 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 1990 to 2025. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", + "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", "sentence_plan": [ { "kind": "text", @@ -109,70 +121,63 @@ }, { "kind": "text", - "text": "Primary income", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": " for ", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": "gross of fixed capital consumption", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": " in ", + "text": "deaths rate", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": "Germany and Kenya", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": ".", + "text": "per capita", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "OECD DAC1", - "segment": "byline", + "text": ".", + "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": " · ", + "text": " ", "segment": "byline", "entity_refs": [], "states": [] }, { "kind": "text", - "text": "1960 to 2025", + "text": "World Development Indicators", "segment": "byline", "entity_refs": [], "states": [] @@ -186,7 +191,7 @@ }, { "kind": "text", - "text": "Current US dollars", + "text": "2013 to 2022", "segment": "byline", "entity_refs": [], "states": [] @@ -207,35 +212,28 @@ }, { "kind": "text", - "text": "Gross national income based on purchasing power parity", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": "in international dollars", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": "Germany and Kenya", + "text": "number of deaths", "segment": "heading", "entity_refs": [], "states": [] @@ -256,7 +254,7 @@ }, { "kind": "text", - "text": "World Development Indicators", + "text": "Kenya Census", "segment": "byline", "entity_refs": [], "states": [] @@ -270,7 +268,7 @@ }, { "kind": "text", - "text": "1990 to 2025", + "text": "2018 to 2022", "segment": "byline", "entity_refs": [], "states": [] @@ -298,16 +296,14 @@ } ], "restatement": { - "variable_text": "GNI", + "variable_text": "mortality", "entities": [ - { - "text": "Germany" - }, { "text": "Kenya", "role_text": "to" } ], + "time_text": "2013 to 2022", "sources": [], "operations": [] }, @@ -327,68 +323,70 @@ "max_candidates": 6, "specs": [ { - "spec_id": "spec_f0d0bb4841c0e55d6d4a353e45dcd52c", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "definition": { "schema_version": 1, - "spec_id": "spec_f0d0bb4841c0e55d6d4a353e45dcd52c", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU", "country/KEN" ] }, "requested_window": { - "kind": "all" + "kind": "range", + "start_year": 2013, + "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicunit_primaryincome_measuredvalue_nominal", - "label": "Gross national income", + "shape_id": "mortalityevent_count_measuredvalue_per_count_person", + "label": "Deaths Rate", "population_type": { - "ref": "EconomicUnit", - "label": "economic unit" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "primaryIncome", - "label": "primary income" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "Nominal", - "label": "Nominal" + "measurement_denominator": { + "ref": "Count_Person", + "label": "Total population" }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, { "axis": "where", @@ -403,13 +401,13 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", - "refine_supported": true, + "member_count": 133, + "member_digest": "c090b56d31a596a8be16dafb518382db666c6b100a80534c3cb81dbfe3111c5d", + "refine_supported": false, "data_commons": [ { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" } ] }, @@ -418,20 +416,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - }, - "value_kind": "enum_value" - } + "kind": "unbound" }, "summable": false }, @@ -441,23 +432,14 @@ "label": "place" }, "binding": { - "kind": "set", - "values": [ - { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" }, - { - "ref": { - "ref": "country/KEN", - "label": "Kenya" - }, - "value_kind": "entity" - } - ] + "value_kind": "entity" + } }, "summable": false }, @@ -467,7 +449,14 @@ "label": "time window" }, "binding": { - "kind": "unbound" + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2013, + "end_year": 2022 + } + } }, "summable": false }, @@ -482,24 +471,20 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 2, "member_count_exact": false, "served_count": 1, "data_date_range": { - "start": "1960", - "end": "2025" + "start": "2013", + "end": "2022" } }, "entities": [ - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/KEN", "label": "Kenya", @@ -510,56 +495,63 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 66, + "observation_count": 10, "evidence": "facet_metadata", "dimensions": [ { - "label": "countries", + "label": "sources", "count": 1 }, { "label": "observations", - "count": 66 + "count": 10 }, { "label": "variables", "count": 1 } - ] + ], + "window": { + "start_year": 2013, + "end_year": 2022 + } }, "download": { - "rows": 66, + "rows": 10, "rows_exact": true, "series": 1, "window": { - "start_year": 1960, - "end_year": 2025 + "start_year": 2013, + "end_year": 2022 }, "licence": { - "label": "OECD Terms and Conditions" + "label": "Creative Commons Attribution License" } }, "facets": { "provenance": { "basis": "fallback", - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1", - "account": "provider" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "measurementMethod": { + "basis": "fallback", + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" }, "unit": { "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" + "ref": "Per1000Persons", + "label": "Per 1000 people" } }, "slot_options": [ @@ -567,17 +559,17 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" + "ref": "ICD10/X60-X84", + "label": "X60-X84 (Intentional self-harm)" }, "value_kind": "enum_value" } @@ -595,8 +587,8 @@ { "value": { "ref": { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1" + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" }, "value_kind": "source" } @@ -604,8 +596,8 @@ { "value": { "ref": { - "ref": "provenance/WorldBankInternationalDebtStatistics", - "label": "World Bank International Debt Statistics (IDS)" + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, "value_kind": "source" } @@ -614,71 +606,109 @@ "truncated": false, "source": "observed" }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "ref": { + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, { "axis": "unit", "options": [ { "value": { "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" + "ref": "Per1000Persons", + "label": "Per 1000 people" }, "value_kind": "enum_value" } + }, + { + "value": { + "value_kind": "enum_value" + } } ], "truncated": false, "source": "observed" } ], - "rendered_sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 1960 to 2025. Current US dollars · OECD DAC1.", + "rendered_sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators.", "sentence_plan": [ { "kind": "slot", - "text": "Primary income", - "axis": "what", + "text": "Kenya", + "axis": "where", "segment": "heading", + "binding_ref": "where:", "entity_refs": [], - "states": [], - "distinguishes": true + "states": [ + "where:" + ] }, { "kind": "text", - "text": " for ", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "gross of fixed capital consumption", - "axis": "how", + "text": "deaths rate", + "axis": "what", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ], + "states": [], "distinguishes": true }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "Germany and Kenya", - "axis": "where", + "text": "per capita", + "axis": "unit", "segment": "heading", - "binding_ref": "where:", "entity_refs": [], - "states": [ - "where:" - ] + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", + "entity_refs": [], + "states": [] }, { "kind": "text", @@ -689,7 +719,7 @@ }, { "kind": "slot", - "text": "1960 to 2025", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -715,26 +745,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -753,10 +764,6 @@ ], "trace": { "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -764,17 +771,17 @@ ], "resolved_sources": [ { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" } ], "slot_filters": [ @@ -782,18 +789,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -801,12 +803,8 @@ "axis": "where", "label": "place" }, - "binding_kind": "set", + "binding_kind": "value", "refs": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -819,7 +817,7 @@ "axis": "when", "label": "time window" }, - "binding_kind": "unbound", + "binding_kind": "value", "refs": [], "provenance": "binder" }, @@ -834,35 +832,14 @@ } ], "query_qualifiers": [], - "capability_version": "cap_347a470e04c97eec", + "requested_window": { + "start_year": 2013, + "end_year": 2022 + }, + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] + "removed_stat_vars": [] } }, "confidence": "high", @@ -872,68 +849,161 @@ } }, { - "spec_id": "spec_c024875e07eee23ed7cb8d18b4436df1", + "spec_id": "spec_7923e67e0706d6d9738c78cb374ee8fb", "definition": { "schema_version": 1, - "spec_id": "spec_c024875e07eee23ed7cb8d18b4436df1", + "spec_id": "spec_7923e67e0706d6d9738c78cb374ee8fb", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicActivity", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "PurchasingPowerParity" + "population_type": "MortalityEvent", + "measured_property": "count", + "stat_type": "measuredValue" }, "slots": [ { - "property": "activitySource", + "property": "age", + "binding": { + "state": "unbound" + } + }, + { + "property": "ageGroupClassification", + "binding": { + "state": "unbound" + } + }, + { + "property": "causeOfDeath", + "binding": { + "state": "unbound" + } + }, + { + "property": "ethnicity", + "binding": { + "state": "unbound" + } + }, + { + "property": "gender", + "binding": { + "state": "unbound" + } + }, + { + "property": "incidentType", + "binding": { + "state": "unbound" + } + }, + { + "property": "race", + "binding": { + "state": "unbound" + } + }, + { + "property": "residentStatus", "binding": { - "state": "value", - "ref": "GrossNationalIncome" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU", "country/KEN" ] }, "requested_window": { - "kind": "all" + "kind": "range", + "start_year": 2013, + "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity", - "label": "Gross National Income Based on Purchasing Power Parity", + "shape_id": "mortalityevent_count_measuredvalue", + "label": "Number of Deaths", "population_type": { - "ref": "EconomicActivity", - "label": "EconomicActivity" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "amount", - "label": "amount" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "PurchasingPowerParity", - "label": "PurchasingPowerParity" - }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" + }, + "label": "cause of death" + }, + { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" }, - "label": "activity source" + "label": "age group classification" }, { "axis": "where", @@ -948,45 +1018,125 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "833b9da89613fa6c1775652daac2388f38204c6c9f9929ca113deed9a0d08369", + "member_count": 2978, "refine_supported": true, "data_commons": [ { "id": "base", "label": "Data Commons by Google" } - ], - "upstream": { - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" - } - } + ] }, "slots": [ { "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - }, - "value_kind": "enum_value" - } + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + "binding": { + "kind": "unbound" }, "summable": false }, @@ -996,23 +1146,14 @@ "label": "place" }, "binding": { - "kind": "set", - "values": [ - { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" }, - { - "ref": { - "ref": "country/KEN", - "label": "Kenya" - }, - "value_kind": "entity" - } - ] + "value_kind": "entity" + } }, "summable": false }, @@ -1022,7 +1163,14 @@ "label": "time window" }, "binding": { - "kind": "unbound" + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2018, + "end_year": 2022 + } + } }, "summable": false }, @@ -1037,24 +1185,27 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath", + "gender", + "age", + "race", + "incidentType", + "ethnicity", + "residentStatus", + "ageGroupClassification" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 37, "member_count_exact": false, "served_count": 1, "data_date_range": { - "start": "1990", - "end": "2025" + "start": "2018", + "end": "2022" } }, "entities": [ - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/KEN", "label": "Kenya", @@ -1065,30 +1216,34 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 72, + "observation_count": 5, "evidence": "facet_metadata", "dimensions": [ { - "label": "countries", - "count": 2 + "label": "sources", + "count": 1 }, { "label": "observations", - "count": 36 + "count": 5 }, { "label": "variables", "count": 1 } - ] + ], + "window": { + "start_year": 2018, + "end_year": 2022 + } }, "download": { - "rows": 72, + "rows": 5, "rows_exact": true, - "series": 2, + "series": 1, "window": { - "start_year": 1990, - "end_year": 2025 + "start_year": 2018, + "end_year": 2022 }, "licence": { "label": "Creative Commons Attribution License" @@ -1097,22 +1252,17 @@ "facets": { "provenance": { "basis": "fallback", - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census", "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "ref": "dc/s/OpenDataForAfrica", + "label": "Open Data for Africa" }, "data_commons": { "id": "base", "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" - }, - "unit": { - "basis": "fallback", - "ref": "InternationalDollar", - "label": "InternationalDollar" + "documentation": "/api/graph/documentation/dc/base/Kenya_Census" } }, "slot_options": [ @@ -1120,17 +1270,745 @@ "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" + }, + "label": "cause of death" + }, + "options": [ + { + "value": { + "ref": { + "ref": "ICD10/A00-B99", + "label": "A00-B99 (Certain infectious and parasitic diseases)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/D50-D89", + "label": "D50-D89 (Diseases of the blood and blood-forming organs and certain disorders involving the immune mechanism)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/I00-I99", + "label": "I00-I99 (Diseases of the circulatory system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/K00-K92", + "label": "K00-K92 (Diseases of the digestive system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/N00-N98", + "label": "N00-N98 (Diseases of the genitourinary system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/M00-M99", + "label": "M00-M99 (Diseases of the musculoskeletal system and connective tissue)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/G00-G98", + "label": "G00-G98 (Diseases of the nervous system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/J00-J98", + "label": "J00-J98 (Diseases of the respiratory system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/L00-L98", + "label": "L00-L98 (Diseases of the skin and subcutaneous tissue)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/E00-E88", + "label": "E00-E88 (Endocrine, nutritional and metabolic diseases)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/F01-F99", + "label": "F01-F99 (Mental and behavioural disorders)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/O00-O99", + "label": "O00-O99 (Pregnancy, childbirth and the puerperium)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/U00-U99", + "label": "U00-U99 (Codes for special purposes)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Diabetes", + "label": "Diabetes" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Suicide", + "label": "Suicide" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/V01-Y89", + "label": "V01-Y89 (External causes of morbidity and mortality)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/C00-D48", + "label": "C00-D48 (Neoplasms)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/P00-P96", + "label": "P00-P96 (Certain conditions originating in the perinatal period)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/Q00-Q99", + "label": "Q00-Q99 (Congenital malformations, deformations and chromosomal abnormalities)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CerebrovascularDiseases", + "label": "CerebrovascularDiseases" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CongenitalAnomalies", + "label": "CongenitalAnomalies" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CongenitalHeartAnomalies", + "label": "CongenitalHeartAnomalies" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "GenitourinaryDiseases", + "label": "GenitourinaryDiseases" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "HypertensiveHeartDisease", + "label": "HypertensiveHeartDisease" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MalignantNeoplasms", + "label": "MalignantNeoplasms" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Neoplasms", + "label": "Neoplasms" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PerinatalInfection", + "label": "Perinatal Infection" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Pneumonia", + "label": "Pneumonia" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SGP_OtherDiseasesAndCauses", + "label": "SGP_OtherDiseasesAndCauses" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TransportAccidents", + "label": "TransportAccidents" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Tuberculosis", + "label": "Tuberculosis" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Female", + "label": "Female" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Male", + "label": "Male" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Years0To1", + "label": "Years 0 To 1" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Day0To27", + "label": "Day 0 To 27" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years10To14", + "label": "Years 10 To 14" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years15To19", + "label": "Years 15 To 19" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years15To24", + "label": "Years 15 To 24" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years1To4", + "label": "Years 1 To 4" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years20To24", + "label": "Years 20 To 24" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years25To29", + "label": "Years 25 To 29" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years25To34", + "label": "Years 25 To 34" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years30To34", + "label": "Years 30 To 34" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years35To39", + "label": "Years 35 To 39" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years35To44", + "label": "Years 35 To 44" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years40To44", + "label": "Years 40 To 44" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years45To49", + "label": "Years 45 To 49" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years45To54", + "label": "Years 45 To 54" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years50To54", + "label": "Years 50 To 54" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years55To59", + "label": "Years 55 To 59" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years55To64", + "label": "Years 55 To 64" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years5To9", + "label": "Years 5 To 9" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years60To64", + "label": "Years 60 To 64" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years65To69", + "label": "Years 65 To 69" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years65To74", + "label": "Years 65 To 74" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years70To74", + "label": "Years 70 To 74" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years75To79", + "label": "Years 75 To 79" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years75To84", + "label": "Years 75 To 84" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years80To84", + "label": "Years 80 To 84" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "USC_AgeNotStated", + "label": "USC_AgeNotStated" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years0To4", + "label": "Years 0 To 4" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CDC_AmericanIndianAndAlaskaNativeAlone", + "label": "American Indian and Alaska native alone" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "COVID_19", + "label": "COVID-19" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Chinese", + "label": "Chinese" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Indian", + "label": "Indian" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Malay", + "label": "Malay" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SGP_OtherEthnicity", + "label": "SGP_OtherEthnicity" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Citizen", + "label": "Citizen" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Resident", + "label": "Resident" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Infant", + "label": "Infant" + }, + "value_kind": "enum_value" + } }, - "label": "activity source" - }, - "options": [ { "value": { "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + "ref": "Newborn", + "label": "Newborn" }, "value_kind": "enum_value" } @@ -1148,8 +2026,8 @@ { "value": { "ref": { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators" + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, "value_kind": "source" } @@ -1157,36 +2035,27 @@ ], "truncated": false, "source": "observed" - }, - { - "axis": "unit", - "options": [ - { - "value": { - "ref": { - "ref": "InternationalDollar", - "label": "InternationalDollar" - }, - "value_kind": "enum_value" - } - } - ], - "truncated": false, - "source": "observed" } ], - "rendered_sentence": "Gross national income based on purchasing power parity in international dollars in Germany and Kenya, 1990 to 2025. World Development Indicators.", + "rendered_sentence": "Kenya's number of deaths, 2018 to 2022. Kenya Census.", "sentence_plan": [ { "kind": "slot", - "text": "Gross national income based on purchasing power parity", - "axis": "what", + "text": "Kenya", + "axis": "where", "segment": "heading", + "binding_ref": "where:", "entity_refs": [], "states": [ - "how:activitySource" - ], - "distinguishes": true + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] }, { "kind": "text", @@ -1197,42 +2066,92 @@ }, { "kind": "slot", - "text": "in international dollars", - "axis": "unit", + "text": "number of deaths", + "axis": "what", "segment": "heading", - "binding_ref": "unit:", "entity_refs": [], - "states": [ - "unit:" - ] + "states": [], + "distinguishes": true }, { "kind": "slot", "text": "", "axis": "how", "segment": "heading", - "property_dcid": "activitySource", - "binding_ref": "how:activitySource", + "property_dcid": "age", + "binding_ref": "how:age", "entity_refs": [], "states": [] }, { - "kind": "text", - "text": " in ", + "kind": "slot", + "text": "", + "axis": "how", "segment": "heading", + "property_dcid": "ageGroupClassification", + "binding_ref": "how:ageGroupClassification", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "Germany and Kenya", - "axis": "where", + "text": "", + "axis": "how", "segment": "heading", - "binding_ref": "where:", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", "entity_refs": [], - "states": [ - "where:" - ] + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "ethnicity", + "binding_ref": "how:ethnicity", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "gender", + "binding_ref": "how:gender", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "incidentType", + "binding_ref": "how:incidentType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "race", + "binding_ref": "how:race", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "residentStatus", + "binding_ref": "how:residentStatus", + "entity_refs": [], + "states": [] }, { "kind": "text", @@ -1243,7 +2162,7 @@ }, { "kind": "slot", - "text": "1990 to 2025", + "text": "2018 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -1269,7 +2188,7 @@ }, { "kind": "slot", - "text": "World Development Indicators", + "text": "Kenya Census", "axis": "source", "segment": "byline", "entity_refs": [], @@ -1288,10 +2207,6 @@ ], "trace": { "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -1299,17 +2214,17 @@ ], "resolved_sources": [ { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census", "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "ref": "dc/s/OpenDataForAfrica", + "label": "Open Data for Africa" }, "data_commons": { "id": "base", "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + "documentation": "/api/graph/documentation/dc/base/Kenya_Census" } ], "slot_filters": [ @@ -1317,18 +2232,104 @@ "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - } - ], + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -1336,12 +2337,8 @@ "axis": "where", "label": "place" }, - "binding_kind": "set", + "binding_kind": "value", "refs": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -1354,7 +2351,7 @@ "axis": "when", "label": "time window" }, - "binding_kind": "unbound", + "binding_kind": "value", "refs": [], "provenance": "binder" }, @@ -1369,39 +2366,18 @@ } ], "query_qualifiers": [], - "capability_version": "cap_347a470e04c97eec", + "requested_window": { + "start_year": 2013, + "end_year": 2022 + }, + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] + "removed_stat_vars": [] } }, - "confidence": "high", - "basis": "nominated", + "confidence": "low", + "basis": "structural", "available_at_place": true, "measure_label_axes": [], "measure_axis_values": [] @@ -1411,8 +2387,8 @@ "truncated": false }, "reading_assumptions": { - "spec_f0d0bb4841c0e55d6d4a353e45dcd52c": [], - "spec_c024875e07eee23ed7cb8d18b4436df1": [] + "spec_10bf62f9687154286b463d206f03a086": [], + "spec_7923e67e0706d6d9738c78cb374ee8fb": [] } }, { @@ -1426,37 +2402,45 @@ { "code": "slot_defaulted", "severity": "warn", - "message": "No aid type was named, so the answer covers official development assistance." + "message": "The answer covers official development assistance of every aid type." } ], "timing_ms": { - "total": 2564, + "total": 1430, "by_step": { - "recall": 607, + "recall": 0, + "phase_resolve_places": 0, + "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe_coverage": 3, - "shape_probe": 218, - "shape_groups": 18, + "shape_probe_coverage": 6, + "shape_probe": 111, + "shape_groups": 50, "shape_labels": 0, - "shape_admission": 0, - "shape": 930, - "bind": 1014, - "materialise": 6, - "answer": 4, - "options": 3 + "shape_admission": 1, + "phase_derive_shapes": 0, + "shape": 565, + "phase_prune_and_rank": 0, + "bind": 135, + "phase_bind": 368, + "phase_settle": 11, + "phase_place_bindings": 91, + "phase_facet_requests": 0, + "materialise": 38, + "phase_materialise": 0, + "answer": 25, + "options": 7, + "phase_outcome": 190 } }, "restatement": { "variable_text": "aid flows", "entities": [ - { - "text": "Germany" - }, { "text": "Kenya", "role_text": "to" } ], + "time_text": "2013 to 2022", "sources": [], "operations": [] }, @@ -1469,10 +2453,9 @@ "text": "You asked for aid flows. This shows gross disbursements, the closest measure the data holds." }, { - "code": "direction_inferred", - "binding_ref": "where:", - "asked": "Germany", - "text": "You named Germany without a direction. Only the data with Germany as the provider holds values, so this reads it as the provider." + "code": "whole_total_read", + "binding_ref": "origin:", + "text": "No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, search again with open_roles ['donor']." } ], "assumptions": [ @@ -1487,10 +2470,10 @@ ], "status": "definite", "spec": { - "spec_id": "spec_473682ae7e62be173cac86a13815f0fa", + "spec_id": "spec_f24e46ae9854884308fc0f33d154361e", "definition": { "schema_version": 1, - "spec_id": "spec_473682ae7e62be173cac86a13815f0fa", + "spec_id": "spec_f24e46ae9854884308fc0f33d154361e", "identity": { "identity_version": "spec1", "shape": { @@ -1534,11 +2517,13 @@ "country/KEN" ], "origin": [ - "country/DEU" + "DACOfficialDonors" ] }, "requested_window": { - "kind": "all" + "kind": "range", + "start_year": 2013, + "end_year": 2022 } } }, @@ -1720,7 +2705,14 @@ "label": "time window" }, "binding": { - "kind": "unbound" + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2013, + "end_year": 2022 + } + } }, "summable": false }, @@ -1745,8 +2737,8 @@ "member_count_exact": true, "served_count": 1, "data_date_range": { - "start": "1960", - "end": "2024" + "start": "2013", + "end": "2022" } }, "entities": [ @@ -1757,16 +2749,30 @@ "role": "destination" }, { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", + "ref": "DACOfficialDonors", + "label": "official donors (DAC)", + "entity_type": "DACGroup", "role": "origin" } ], + "entity_groups": { + "origin": { + "label": "official donors (DAC)", + "total": "DACOfficialDonors", + "whole_of": [ + "official" + ], + "side_classes": [ + "official", + "private", + "residual" + ] + } + }, "coverage": { "kind": "exact", "has_data": true, - "observation_count": 65, + "observation_count": 10, "evidence": "facet_metadata", "dimensions": [ { @@ -1775,17 +2781,25 @@ }, { "label": "observations", - "count": 65 + "count": 10 }, { "label": "variables", "count": 1 } - ] + ], + "window": { + "start_year": 2013, + "end_year": 2022 + } }, "headline": { - "year": 2024, - "year_named": false, + "year": 2022, + "year_named": true, + "named_window": { + "start_year": 2013, + "end_year": 2022 + }, "observations": 1, "series": 1, "role_counts": { @@ -1794,7 +2808,7 @@ }, "recent_years": [ { - "year": 2024, + "year": 2022, "observations": 1, "series": 1, "role_counts": { @@ -1803,7 +2817,7 @@ } }, { - "year": 2023, + "year": 2021, "observations": 1, "series": 1, "role_counts": { @@ -1812,7 +2826,7 @@ } }, { - "year": 2022, + "year": 2020, "observations": 1, "series": 1, "role_counts": { @@ -1823,18 +2837,18 @@ ] }, "download": { - "rows": 65, + "rows": 10, "rows_exact": true, "series": 1, "window": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "licence": { "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "facets": { "provenance": { "basis": "fallback", @@ -1880,7 +2894,7 @@ "relation": "child", "parent": "DAC2aAidType206", "member_count": 2, - "served_rows": 61, + "served_rows": 10, "served_rows_exact": true }, { @@ -1894,7 +2908,7 @@ "relation": "child", "parent": "DAC2aAidType206", "member_count": 1, - "served_rows": 65, + "served_rows": 10, "served_rows_exact": true }, { @@ -1907,7 +2921,7 @@ }, "relation": "root", "member_count": 1, - "served_rows": 59, + "served_rows": 10, "served_rows_exact": true }, { @@ -1920,7 +2934,7 @@ }, "relation": "root", "member_count": 1, - "served_rows": 44, + "served_rows": 10, "served_rows_exact": true }, { @@ -1933,7 +2947,7 @@ }, "relation": "root", "member_count": 1, - "served_rows": 29, + "served_rows": 10, "served_rows_exact": true } ], @@ -1976,38 +2990,11 @@ "source": "observed" } ], - "rendered_sentence": "Germany's gross disbursements to Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", + "rendered_sentence": "Gross disbursements to Kenya from official donors (DAC) for official development assistance, 2013 to 2022. Current US dollars · OECD DAC2a.", "sentence_plan": [ { "kind": "slot", - "text": "Germany", - "segment": "heading", - "role": "origin", - "binding_ref": "origin:", - "entity_refs": [ - "country/DEU" - ], - "states": [ - "origin:" - ] - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "gross disbursements", + "text": "Gross disbursements", "axis": "what", "segment": "heading", "entity_refs": [], @@ -2039,6 +3026,26 @@ "where:" ] }, + { + "kind": "text", + "text": " from ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "official donors (DAC)", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "DACOfficialDonors" + ], + "states": [ + "origin:" + ] + }, { "kind": "text", "text": " for ", @@ -2097,7 +3104,7 @@ }, { "kind": "slot", - "text": "1960 to 2024", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -2164,8 +3171,8 @@ "label": "Kenya" }, { - "ref": "country/DEU", - "label": "Germany" + "ref": "DACOfficialDonors", + "label": "official donors (DAC)" } ], "resolved_sources": [ @@ -2270,7 +3277,7 @@ "axis": "when", "label": "time window" }, - "binding_kind": "unbound", + "binding_kind": "value", "refs": [], "provenance": "binder" }, @@ -2285,7 +3292,11 @@ } ], "query_qualifiers": [], - "capability_version": "cap_347a470e04c97eec", + "requested_window": { + "start_year": 2013, + "end_year": 2022 + }, + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2297,7 +3308,7 @@ { "definition": { "schema_version": 1, - "spec_id": "spec_433a5ca3b9aa482f8f332201570ef664", + "spec_id": "spec_f025379e211db08849c7f98c627e025c", "identity": { "identity_version": "spec1", "shape": { @@ -2341,11 +3352,13 @@ "country/KEN" ], "origin": [ - "country/DEU" + "DACOfficialDonors" ] }, "requested_window": { - "kind": "all" + "kind": "range", + "start_year": 2013, + "end_year": 2022 } } }, @@ -2388,7 +3401,7 @@ } } ], - "served_rows": 65, + "served_rows": 10, "served_rows_exact": true } ], @@ -2443,12 +3456,12 @@ "code": "AED", "noun": "UAE dirhams", "current_years": { - "start_year": 1997, + "start_year": 2013, "end_year": 2021 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2023, "base_year_max": 2023 @@ -2457,12 +3470,12 @@ "code": "AFN", "noun": "Afghan afghanis", "current_years": { - "start_year": 2002, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2002, "base_year_max": 2025 @@ -2471,12 +3484,12 @@ "code": "ALL", "noun": "Albanian leks", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2485,12 +3498,12 @@ "code": "AMD", "noun": "Armenian drams", "current_years": { - "start_year": 1992, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1992, "base_year_max": 2025 @@ -2499,12 +3512,12 @@ "code": "AOA", "noun": "Angolan kwanzas", "current_years": { - "start_year": 1991, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1991, "base_year_max": 2025 @@ -2513,12 +3526,12 @@ "code": "ARS", "noun": "Argentine pesos", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2527,12 +3540,12 @@ "code": "AUD", "noun": "Australian dollars", "current_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1960, "base_year_max": 2025 @@ -2541,12 +3554,12 @@ "code": "AWG", "noun": "Aruban florins", "current_years": { - "start_year": 1995, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1995, "base_year_max": 2025 @@ -2559,8 +3572,8 @@ "end_year": 2019 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2023, "base_year_max": 2023 @@ -2569,12 +3582,12 @@ "code": "BAM", "noun": "Bosnia-Herzegovina convertible marks", "current_years": { - "start_year": 1996, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1996, "base_year_max": 2025 @@ -2583,12 +3596,12 @@ "code": "BBD", "noun": "Barbadian dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2597,12 +3610,12 @@ "code": "BDT", "noun": "Bangladeshi taka", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2611,12 +3624,12 @@ "code": "BHD", "noun": "Bahraini dinars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2625,12 +3638,12 @@ "code": "BIF", "noun": "Burundian francs", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2639,12 +3652,12 @@ "code": "BND", "noun": "Brunei dollars", "current_years": { - "start_year": 1985, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1985, "base_year_max": 2025 @@ -2653,12 +3666,12 @@ "code": "BOB", "noun": "Bolivian bolivianos", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2667,12 +3680,12 @@ "code": "BRL", "noun": "Brazilian reais", "current_years": { - "start_year": 1986, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1986, "base_year_max": 2025 @@ -2681,12 +3694,12 @@ "code": "BSD", "noun": "Bahamian dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2695,12 +3708,12 @@ "code": "BTN", "noun": "Bhutanese ngultrums", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2709,12 +3722,12 @@ "code": "BWP", "noun": "Botswana pula", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2723,12 +3736,12 @@ "code": "BYN", "noun": "Belarusian rubles", "current_years": { - "start_year": 1992, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1992, "base_year_max": 2025 @@ -2737,12 +3750,12 @@ "code": "BZD", "noun": "Belize dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2751,12 +3764,12 @@ "code": "CAD", "noun": "Canadian dollars", "current_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1960, "base_year_max": 2025 @@ -2765,12 +3778,12 @@ "code": "CDF", "noun": "Congolese francs", "current_years": { - "start_year": 1991, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1991, "base_year_max": 2025 @@ -2779,12 +3792,12 @@ "code": "CHF", "noun": "Swiss francs", "current_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1960, "base_year_max": 2025 @@ -2793,12 +3806,12 @@ "code": "CLP", "noun": "Chilean pesos", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2807,12 +3820,12 @@ "code": "CNY", "noun": "Chinese yuan", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2821,12 +3834,12 @@ "code": "COP", "noun": "Colombian pesos", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2835,12 +3848,12 @@ "code": "CRC", "noun": "Costa Rican colones", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2849,12 +3862,12 @@ "code": "CVE", "noun": "Cape Verdean escudos", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2863,12 +3876,12 @@ "code": "CZK", "noun": "Czech korunas", "current_years": { - "start_year": 1998, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1998, "base_year_max": 2025 @@ -2877,12 +3890,12 @@ "code": "DJF", "noun": "Djiboutian francs", "current_years": { - "start_year": 1990, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1990, "base_year_max": 2025 @@ -2891,12 +3904,12 @@ "code": "DKK", "noun": "Danish kroner", "current_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1960, "base_year_max": 2025 @@ -2905,12 +3918,12 @@ "code": "DOP", "noun": "Dominican pesos", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2919,12 +3932,12 @@ "code": "DZD", "noun": "Algerian dinars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2933,12 +3946,12 @@ "code": "EGP", "noun": "Egyptian pounds", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2947,12 +3960,12 @@ "code": "ERN", "noun": "Eritrean nakfas", "current_years": { - "start_year": 1992, + "start_year": 2013, "end_year": 2019 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1992, "base_year_max": 2019 @@ -2961,12 +3974,12 @@ "code": "ETB", "noun": "Ethiopian birr", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -2975,12 +3988,12 @@ "code": "EUR", "noun": "euros", "current_years": { - "start_year": 1973, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1973, "base_year_max": 2025 @@ -2989,12 +4002,12 @@ "code": "FJD", "noun": "Fijian dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3003,12 +4016,12 @@ "code": "GBP", "noun": "British pounds", "current_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1960, "base_year_max": 2025 @@ -3017,12 +4030,12 @@ "code": "GEL", "noun": "Georgian lari", "current_years": { - "start_year": 1994, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1994, "base_year_max": 2025 @@ -3031,12 +4044,12 @@ "code": "GHS", "noun": "Ghanaian cedis", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3045,12 +4058,12 @@ "code": "GMD", "noun": "Gambian dalasis", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3059,12 +4072,12 @@ "code": "GNF", "noun": "Guinean francs", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3073,12 +4086,12 @@ "code": "GTQ", "noun": "Guatemalan quetzales", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3087,12 +4100,12 @@ "code": "GYD", "noun": "Guyanese dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3101,12 +4114,12 @@ "code": "HKD", "noun": "Hong Kong dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3115,12 +4128,12 @@ "code": "HNL", "noun": "Honduran lempiras", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3129,12 +4142,12 @@ "code": "HTG", "noun": "Haitian gourdes", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3143,12 +4156,12 @@ "code": "HUF", "noun": "Hungarian forints", "current_years": { - "start_year": 2003, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2003, "base_year_max": 2025 @@ -3157,12 +4170,12 @@ "code": "IDR", "noun": "Indonesian rupiahs", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3171,12 +4184,12 @@ "code": "ILS", "noun": "Israeli new shekels", "current_years": { - "start_year": 1997, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1997, "base_year_max": 2025 @@ -3185,12 +4198,12 @@ "code": "INR", "noun": "Indian rupees", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3199,12 +4212,12 @@ "code": "IQD", "noun": "Iraqi dinars", "current_years": { - "start_year": 2000, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2000, "base_year_max": 2025 @@ -3213,12 +4226,12 @@ "code": "IRR", "noun": "Iranian rials", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3227,12 +4240,12 @@ "code": "ISK", "noun": "Icelandic krónur", "current_years": { - "start_year": 1997, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1997, "base_year_max": 2025 @@ -3241,12 +4254,12 @@ "code": "JMD", "noun": "Jamaican dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3255,12 +4268,12 @@ "code": "JOD", "noun": "Jordanian dinars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3269,12 +4282,12 @@ "code": "JPY", "noun": "Japanese yen", "current_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1960, "base_year_max": 2025 @@ -3283,12 +4296,12 @@ "code": "KES", "noun": "Kenyan shillings", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3297,12 +4310,12 @@ "code": "KGS", "noun": "Kyrgyz soms", "current_years": { - "start_year": 1992, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1992, "base_year_max": 2025 @@ -3311,12 +4324,12 @@ "code": "KHR", "noun": "Cambodian riels", "current_years": { - "start_year": 1986, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1986, "base_year_max": 2025 @@ -3325,12 +4338,12 @@ "code": "KMF", "noun": "Comorian francs", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3339,12 +4352,12 @@ "code": "KRW", "noun": "South Korean won", "current_years": { - "start_year": 1987, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1987, "base_year_max": 2025 @@ -3353,12 +4366,12 @@ "code": "KWD", "noun": "Kuwaiti dinars", "current_years": { - "start_year": 1995, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1995, "base_year_max": 2024 @@ -3368,11 +4381,11 @@ "noun": "Kazakh tenge", "current_years": { "start_year": 2013, - "end_year": 2024 + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2013, "base_year_max": 2024 @@ -3381,12 +4394,12 @@ "code": "LAK", "noun": "Lao kip", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3395,12 +4408,12 @@ "code": "LBP", "noun": "Lebanese pounds", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3409,12 +4422,12 @@ "code": "LKR", "noun": "Sri Lankan rupees", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2024 @@ -3423,12 +4436,12 @@ "code": "LSL", "noun": "Lesotho maloti", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3437,12 +4450,12 @@ "code": "LYD", "noun": "Libyan dinars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3451,12 +4464,12 @@ "code": "MAD", "noun": "Moroccan dirhams", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3465,12 +4478,12 @@ "code": "MDL", "noun": "Moldovan lei", "current_years": { - "start_year": 1992, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1992, "base_year_max": 2025 @@ -3479,12 +4492,12 @@ "code": "MGA", "noun": "Malagasy ariary", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3493,12 +4506,12 @@ "code": "MKD", "noun": "Macedonian denars", "current_years": { - "start_year": 1992, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1992, "base_year_max": 2025 @@ -3507,12 +4520,12 @@ "code": "MMK", "noun": "Myanmar kyats", "current_years": { - "start_year": 1998, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1998, "base_year_max": 2025 @@ -3521,12 +4534,12 @@ "code": "MNT", "noun": "Mongolian tugriks", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3535,12 +4548,12 @@ "code": "MOP", "noun": "Macanese patacas", "current_years": { - "start_year": 2001, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2001, "base_year_max": 2025 @@ -3549,12 +4562,12 @@ "code": "MRU", "noun": "Mauritanian ouguiyas", "current_years": { - "start_year": 1990, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1990, "base_year_max": 2025 @@ -3563,12 +4576,12 @@ "code": "MUR", "noun": "Mauritian rupees", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3577,12 +4590,12 @@ "code": "MVR", "noun": "Maldivian rufiyaa", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3591,12 +4604,12 @@ "code": "MWK", "noun": "Malawian kwachas", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3605,12 +4618,12 @@ "code": "MXN", "noun": "Mexican pesos", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3619,12 +4632,12 @@ "code": "MYR", "noun": "Malaysian ringgits", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3633,12 +4646,12 @@ "code": "MZN", "noun": "Mozambican meticais", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3647,12 +4660,12 @@ "code": "NAD", "noun": "Namibian dollars", "current_years": { - "start_year": 1989, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1989, "base_year_max": 2025 @@ -3661,12 +4674,12 @@ "code": "NGN", "noun": "Nigerian naira", "current_years": { - "start_year": 1990, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1990, "base_year_max": 2025 @@ -3675,12 +4688,12 @@ "code": "NIO", "noun": "Nicaraguan córdobas", "current_years": { - "start_year": 1987, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1987, "base_year_max": 2025 @@ -3689,12 +4702,12 @@ "code": "NOK", "noun": "Norwegian kroner", "current_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1960, "base_year_max": 2025 @@ -3703,12 +4716,12 @@ "code": "NPR", "noun": "Nepalese rupees", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3717,12 +4730,12 @@ "code": "NZD", "noun": "New Zealand dollars", "current_years": { - "start_year": 1961, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1961, "base_year_max": 2025 @@ -3731,12 +4744,12 @@ "code": "OMR", "noun": "Omani rials", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3745,12 +4758,12 @@ "code": "PEN", "noun": "Peruvian soles", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3759,12 +4772,12 @@ "code": "PGK", "noun": "Papua New Guinean kina", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3773,12 +4786,12 @@ "code": "PHP", "noun": "Philippine pesos", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3787,12 +4800,12 @@ "code": "PKR", "noun": "Pakistani rupees", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3801,12 +4814,12 @@ "code": "PLN", "noun": "Polish zlotys", "current_years": { - "start_year": 1998, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1998, "base_year_max": 2025 @@ -3815,12 +4828,12 @@ "code": "PYG", "noun": "Paraguayan guaranís", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3829,12 +4842,12 @@ "code": "QAR", "noun": "Qatari riyals", "current_years": { - "start_year": 1985, - "end_year": 1990 + "start_year": 2020, + "end_year": 2020 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2023, "base_year_max": 2023 @@ -3844,11 +4857,11 @@ "noun": "Romanian lei", "current_years": { "start_year": 2013, - "end_year": 2024 + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2013, "base_year_max": 2025 @@ -3857,12 +4870,12 @@ "code": "RSD", "noun": "Serbian dinars", "current_years": { - "start_year": 1997, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1997, "base_year_max": 2025 @@ -3871,12 +4884,12 @@ "code": "RUB", "noun": "Russian rubles", "current_years": { - "start_year": 2010, + "start_year": 2013, "end_year": 2020 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2010, "base_year_max": 2020 @@ -3885,12 +4898,12 @@ "code": "RWF", "noun": "Rwandan francs", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3899,12 +4912,12 @@ "code": "SAR", "noun": "Saudi riyals", "current_years": { - "start_year": 2000, - "end_year": 2023 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2000, "base_year_max": 2023 @@ -3913,12 +4926,12 @@ "code": "SBD", "noun": "Solomon Islands dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3927,12 +4940,12 @@ "code": "SCR", "noun": "Seychellois rupees", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3941,12 +4954,12 @@ "code": "SDG", "noun": "Sudanese pounds", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3955,12 +4968,12 @@ "code": "SEK", "noun": "Swedish kronor", "current_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1960, "base_year_max": 2025 @@ -3969,12 +4982,12 @@ "code": "SGD", "noun": "Singapore dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3983,12 +4996,12 @@ "code": "SLE", "noun": "Sierra Leonean leones", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -3997,12 +5010,12 @@ "code": "SRD", "noun": "Surinamese dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -4011,12 +5024,12 @@ "code": "SSP", "noun": "South Sudanese pounds", "current_years": { - "start_year": 2011, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2011, "base_year_max": 2025 @@ -4025,12 +5038,12 @@ "code": "STN", "noun": "São Tomé and Príncipe dobras", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -4038,27 +5051,24 @@ { "code": "SYP", "noun": "Syrian pounds", - "current_years": { - "start_year": 1980, - "end_year": 2010 - }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, - "base_year_max": 2010 + "base_year_max": 2010, + "current_years": null }, { "code": "SZL", "noun": "Swazi emalangeni", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -4067,12 +5077,12 @@ "code": "THB", "noun": "Thai baht", "current_years": { - "start_year": 2006, - "end_year": 2016 + "start_year": 2018, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2018, "base_year_max": 2024 @@ -4081,12 +5091,12 @@ "code": "TJS", "noun": "Tajikistani somonis", "current_years": { - "start_year": 1992, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1992, "base_year_max": 2025 @@ -4095,12 +5105,12 @@ "code": "TMT", "noun": "Turkmenistani manat", "current_years": { - "start_year": 1992, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1992, "base_year_max": 2025 @@ -4109,12 +5119,12 @@ "code": "TND", "noun": "Tunisian dinars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -4123,12 +5133,12 @@ "code": "TOP", "noun": "Tongan paʻanga", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -4137,12 +5147,12 @@ "code": "TRY", "noun": "Turkish lira", "current_years": { - "start_year": 1990, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1990, "base_year_max": 2025 @@ -4151,12 +5161,12 @@ "code": "TTD", "noun": "Trinidad and Tobago dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -4165,12 +5175,12 @@ "code": "TWD", "noun": "New Taiwan dollars", "current_years": { - "start_year": 2006, - "end_year": 2016 + "start_year": 2018, + "end_year": 2021 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2023, "base_year_max": 2025 @@ -4179,12 +5189,12 @@ "code": "TZS", "noun": "Tanzanian shillings", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -4193,12 +5203,12 @@ "code": "UAH", "noun": "Ukrainian hryvnias", "current_years": { - "start_year": 1991, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1991, "base_year_max": 2025 @@ -4207,12 +5217,12 @@ "code": "UGX", "noun": "Ugandan shillings", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -4221,12 +5231,12 @@ "code": "USD", "noun": "US dollars", "current_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1960, "base_year_max": 2025 @@ -4235,12 +5245,12 @@ "code": "UYU", "noun": "Uruguayan pesos", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -4249,12 +5259,12 @@ "code": "UZS", "noun": "Uzbekistani soms", "current_years": { - "start_year": 1992, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1992, "base_year_max": 2025 @@ -4264,11 +5274,11 @@ "noun": "Venezuelan bolívares", "current_years": { "start_year": 2017, - "end_year": 2024 + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2017, "base_year_max": 2025 @@ -4277,12 +5287,12 @@ "code": "VND", "noun": "Vietnamese dong", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -4291,12 +5301,12 @@ "code": "VUV", "noun": "Vanuatu vatu", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -4305,12 +5315,12 @@ "code": "WST", "noun": "Samoan tala", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -4319,12 +5329,12 @@ "code": "XAF", "noun": "Central African CFA francs", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -4333,12 +5343,12 @@ "code": "XCD", "noun": "East Caribbean dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -4347,12 +5357,12 @@ "code": "XOF", "noun": "West African CFA francs", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -4362,11 +5372,11 @@ "noun": "Yemeni rials", "current_years": { "start_year": 2014, - "end_year": 2024 + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2014, "base_year_max": 2025 @@ -4375,12 +5385,12 @@ "code": "ZAR", "noun": "South African rand", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -4389,12 +5399,12 @@ "code": "ZMW", "noun": "Zambian kwachas", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -4402,15 +5412,14 @@ ], "default_base_year": 2024, "role_currencies": { - "destination": "KES", - "origin": "EUR" + "destination": "KES" } } } } } ], - "rendered_sentence": "Answered 1 of 2 parts. GNI has 2 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 1960 to 2025 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 1990 to 2025. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself. Germany's gross disbursements to Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a. You asked for aid flows. This shows gross disbursements, the closest measure the data holds. You named Germany without a direction. Only the data with Germany as the provider holds values, so this reads it as the provider. Assumed: official development assistance.", + "rendered_sentence": "Answered 1 of 2 parts. Mortality has 2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself. Gross disbursements to Kenya from official donors (DAC) for official development assistance, 2013 to 2022. Current US dollars · OECD DAC2a. You asked for aid flows. This shows gross disbursements, the closest measure the data holds. No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, search again with open_roles ['donor']. Assumed: official development assistance.", "sentence_plan": [ { "kind": "text", @@ -4428,7 +5437,7 @@ }, { "kind": "slot", - "text": "GNI", + "text": "Mortality", "axis": "what", "segment": "heading", "entity_refs": [], @@ -4453,7 +5462,7 @@ }, { "kind": "text", - "text": "Primary income", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [], @@ -4461,7 +5470,7 @@ }, { "kind": "text", - "text": " for ", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [], @@ -4469,7 +5478,7 @@ }, { "kind": "text", - "text": "gross of fixed capital consumption", + "text": " ", "segment": "heading", "entity_refs": [], "states": [], @@ -4477,7 +5486,7 @@ }, { "kind": "text", - "text": " in ", + "text": "deaths rate", "segment": "heading", "entity_refs": [], "states": [], @@ -4485,7 +5494,7 @@ }, { "kind": "text", - "text": "Germany and Kenya", + "text": " ", "segment": "heading", "entity_refs": [], "states": [], @@ -4493,7 +5502,7 @@ }, { "kind": "text", - "text": ".", + "text": "per capita", "segment": "heading", "entity_refs": [], "states": [], @@ -4501,23 +5510,15 @@ }, { "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "OECD DAC1", - "segment": "byline", + "text": ".", + "segment": "heading", "entity_refs": [], "states": [], "part_index": 0 }, { "kind": "text", - "text": " · ", + "text": " ", "segment": "byline", "entity_refs": [], "states": [], @@ -4525,7 +5526,7 @@ }, { "kind": "text", - "text": "1960 to 2025", + "text": "World Development Indicators", "segment": "byline", "entity_refs": [], "states": [], @@ -4541,7 +5542,7 @@ }, { "kind": "text", - "text": "Current US dollars", + "text": "2013 to 2022", "segment": "byline", "entity_refs": [], "states": [], @@ -4565,15 +5566,7 @@ }, { "kind": "text", - "text": "Gross national income based on purchasing power parity", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [], @@ -4581,7 +5574,7 @@ }, { "kind": "text", - "text": "in international dollars", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [], @@ -4589,7 +5582,7 @@ }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [], @@ -4597,7 +5590,7 @@ }, { "kind": "text", - "text": "Germany and Kenya", + "text": "number of deaths", "segment": "heading", "entity_refs": [], "states": [], @@ -4621,7 +5614,7 @@ }, { "kind": "text", - "text": "World Development Indicators", + "text": "Kenya Census", "segment": "byline", "entity_refs": [], "states": [], @@ -4637,7 +5630,7 @@ }, { "kind": "text", - "text": "1990 to 2025", + "text": "2018 to 2022", "segment": "byline", "entity_refs": [], "states": [], @@ -4676,29 +5669,21 @@ }, { "kind": "slot", - "text": "Germany", + "text": "Gross disbursements", + "axis": "what", "segment": "heading", - "role": "origin", - "binding_ref": "origin:", - "entity_refs": [ - "country/DEU" - ], + "entity_refs": [], "states": [ - "origin:" + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" ], "part_index": 1 }, { "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 1 - }, - { - "kind": "text", - "text": " ", + "text": " to ", "segment": "heading", "entity_refs": [], "states": [], @@ -4706,21 +5691,22 @@ }, { "kind": "slot", - "text": "gross disbursements", - "axis": "what", + "text": "Kenya", + "axis": "where", "segment": "heading", - "entity_refs": [], + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], "states": [ - "how:financialFlowType", - "how:nettingBasis", - "axis:populationType", - "axis:measuredProperty" + "where:" ], "part_index": 1 }, { "kind": "text", - "text": " to ", + "text": " from ", "segment": "heading", "entity_refs": [], "states": [], @@ -4728,16 +5714,15 @@ }, { "kind": "slot", - "text": "Kenya", - "axis": "where", + "text": "official donors (DAC)", "segment": "heading", - "role": "destination", - "binding_ref": "where:", + "role": "origin", + "binding_ref": "origin:", "entity_refs": [ - "country/KEN" + "DACOfficialDonors" ], "states": [ - "where:" + "origin:" ], "part_index": 1 }, @@ -4805,7 +5790,7 @@ }, { "kind": "slot", - "text": "1960 to 2024", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -4897,7 +5882,7 @@ }, { "kind": "text", - "text": "You named Germany without a direction. Only the data with Germany as the provider holds values, so this reads it as the provider.", + "text": "No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, search again with open_roles ['donor'].", "segment": "departure", "entity_refs": [], "states": [], @@ -4955,32 +5940,34 @@ "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU", "country/KEN" ] }, "requested_window": { - "kind": "all" + "kind": "range", + "start_year": 2013, + "end_year": 2022 } }, "assumptions": [], - "variable_text": "GNI" + "variable_text": "mortality" }, { "entry_kind": "identity", @@ -5027,11 +6014,27 @@ "country/KEN" ], "origin": [ - "country/DEU" + "DACOfficialDonors" ] }, "requested_window": { - "kind": "all" + "kind": "range", + "start_year": 2013, + "end_year": 2022 + } + }, + "entity_groups": { + "origin": { + "label": "official donors (DAC)", + "total": "DACOfficialDonors", + "whole_of": [ + "official" + ], + "side_classes": [ + "official", + "private", + "residual" + ] } }, "assumptions": [ @@ -5054,7 +6057,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "2e151fcdeb6f40b3be7b3da99c277765" + "x-dfo-trace-id": "bdcd09adc5d149ef9430710a445cb8ca" }, "json": { "schema_version": 1, @@ -5063,11 +6066,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "2e151fcdeb6f40b3be7b3da99c277765", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "bdcd09adc5d149ef9430710a445cb8ca", "warnings": [], "timing_ms": { - "total": 947, + "total": 1780, "by_step": { "coverage": 0 } @@ -5077,97 +6080,93 @@ "kind": "resolution", "parts": [ { - "variable_text": "GNI", + "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 2, + "total": 303, "by_step": { - "validate": 0, + "validate": 1, "walk": 0, - "reread_arcs": 1, + "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 0, + "shape": 209, "bind": 0, "where_places": 0, - "materialise": 0, + "materialise": 92, "answer": 1, "options": 0 } }, "operations": [], - "departures": [ - { - "code": "entity_unavailable", - "binding_ref": "where:", - "text": "You asked for Kenya. The data holds no values for it." - } - ], + "departures": [], "assumptions": [], "status": "definite", "spec": { - "spec_id": "spec_f0d0bb4841c0e55d6d4a353e45dcd52c", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "definition": { "schema_version": 1, - "spec_id": "spec_f0d0bb4841c0e55d6d4a353e45dcd52c", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU", "country/KEN" ] }, "requested_window": { - "kind": "all" + "kind": "range", + "start_year": 2013, + "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicunit_primaryincome_measuredvalue_nominal", - "label": "Gross national income", + "shape_id": "mortalityevent_count_measuredvalue_per_count_person", + "label": "Deaths Rate", "population_type": { - "ref": "EconomicUnit", - "label": "economic unit" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "primaryIncome", - "label": "primary income" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "Nominal", - "label": "Nominal" + "measurement_denominator": { + "ref": "Count_Person", + "label": "Total population" }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, { "axis": "where", @@ -5182,13 +6181,13 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", - "refine_supported": true, + "member_count": 133, + "member_digest": "c090b56d31a596a8be16dafb518382db666c6b100a80534c3cb81dbfe3111c5d", + "refine_supported": false, "data_commons": [ { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" } ] }, @@ -5197,20 +6196,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - }, - "value_kind": "enum_value" - } + "kind": "unbound" }, "summable": false }, @@ -5220,23 +6212,14 @@ "label": "place" }, "binding": { - "kind": "set", - "values": [ - { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" }, - { - "ref": { - "ref": "country/KEN", - "label": "Kenya" - }, - "value_kind": "entity" - } - ] + "value_kind": "entity" + } }, "summable": false }, @@ -5246,7 +6229,14 @@ "label": "time window" }, "binding": { - "kind": "unbound" + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2013, + "end_year": 2022 + } + } }, "summable": false }, @@ -5261,24 +6251,20 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 2, "member_count_exact": true, "served_count": 1, "data_date_range": { - "start": "1960", - "end": "2025" + "start": "2013", + "end": "2022" } }, "entities": [ - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/KEN", "label": "Kenya", @@ -5289,56 +6275,63 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 66, + "observation_count": 10, "evidence": "facet_metadata", "dimensions": [ { - "label": "countries", + "label": "sources", "count": 1 }, { "label": "observations", - "count": 66 + "count": 10 }, { "label": "variables", "count": 1 } - ] + ], + "window": { + "start_year": 2013, + "end_year": 2022 + } }, "download": { - "rows": 66, + "rows": 10, "rows_exact": true, "series": 1, "window": { - "start_year": 1960, - "end_year": 2025 + "start_year": 2013, + "end_year": 2022 }, "licence": { - "label": "OECD Terms and Conditions" + "label": "Creative Commons Attribution License" } }, "facets": { "provenance": { "basis": "fallback", - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1", - "account": "provider" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "measurementMethod": { + "basis": "fallback", + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" }, "unit": { "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" + "ref": "Per1000Persons", + "label": "Per 1000 people" } }, "slot_options": [ @@ -5346,17 +6339,17 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" + "ref": "ICD10/X60-X84", + "label": "X60-X84 (Intentional self-harm)" }, "value_kind": "enum_value" } @@ -5374,8 +6367,8 @@ { "value": { "ref": { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1" + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" }, "value_kind": "source" } @@ -5383,8 +6376,8 @@ { "value": { "ref": { - "ref": "provenance/WorldBankInternationalDebtStatistics", - "label": "World Bank International Debt Statistics (IDS)" + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, "value_kind": "source" } @@ -5393,69 +6386,108 @@ "truncated": false, "source": "observed" }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "ref": { + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, { "axis": "unit", "options": [ { "value": { "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" + "ref": "Per1000Persons", + "label": "Per 1000 people" }, "value_kind": "enum_value" } + }, + { + "value": { + "value_kind": "enum_value" + } } ], "truncated": false, "source": "observed" } ], - "rendered_sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 1960 to 2025. Current US dollars · OECD DAC1.", + "rendered_sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators.", "sentence_plan": [ { "kind": "slot", - "text": "Primary income", - "axis": "what", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": " for ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "gross of fixed capital consumption", - "axis": "how", + "text": "deaths rate", + "axis": "what", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ] + "states": [] }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "Germany and Kenya", - "axis": "where", + "text": "per capita", + "axis": "unit", "segment": "heading", - "binding_ref": "where:", "entity_refs": [], - "states": [ - "where:" - ] + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", + "entity_refs": [], + "states": [] }, { "kind": "text", @@ -5466,7 +6498,7 @@ }, { "kind": "slot", - "text": "1960 to 2025", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -5491,26 +6523,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -5528,10 +6541,6 @@ ], "trace": { "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -5539,17 +6548,17 @@ ], "resolved_sources": [ { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" } ], "slot_filters": [ @@ -5557,18 +6566,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -5576,12 +6580,8 @@ "axis": "where", "label": "place" }, - "binding_kind": "set", + "binding_kind": "value", "refs": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -5594,7 +6594,7 @@ "axis": "when", "label": "time window" }, - "binding_kind": "unbound", + "binding_kind": "value", "refs": [], "provenance": "binder" }, @@ -5609,13 +6609,52 @@ } ], "query_qualifiers": [], - "capability_version": "cap_347a470e04c97eec" + "requested_window": { + "start_year": 2013, + "end_year": 2022 + }, + "capability_version": "cap_94e25737d859392c" }, "confidence": "high", "available_at_place": true, "measure_label_axes": [], "measure_axis_values": [], - "related_measures": [] + "related_group": { + "ref": "dc/g/MortalityEvent", + "label": "Mortality Event" + }, + "related_measures": [ + { + "stat_var": { + "ref": "Count_Death", + "label": "Number of Deaths" + }, + "definition": { + "schema_version": 1, + "spec_id": "spec_31961a9c9519bb4db004fa793f0457e5", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "MortalityEvent", + "measured_property": "count", + "stat_type": "measuredValue" + }, + "slots": [], + "entities": { + "observationAbout": [ + "country/KEN" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2013, + "end_year": 2022 + } + } + } + } + ] } } }, @@ -5623,23 +6662,29 @@ "variable_text": "aid flows", "warnings": [], "timing_ms": { - "total": 924, + "total": 1732, "by_step": { "validate": 0, - "walk": 5, + "walk": 10, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 909, + "shape": 1699, "bind": 0, "where_places": 0, - "materialise": 4, - "answer": 5, - "options": 1 + "materialise": 14, + "answer": 7, + "options": 2 } }, "operations": [], - "departures": [], + "departures": [ + { + "code": "whole_total_read", + "binding_ref": "origin:", + "text": "This shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, search again with open_roles ['donor']." + } + ], "assumptions": [ { "kind": "declared_default", @@ -5652,10 +6697,10 @@ ], "status": "definite", "spec": { - "spec_id": "spec_473682ae7e62be173cac86a13815f0fa", + "spec_id": "spec_f24e46ae9854884308fc0f33d154361e", "definition": { "schema_version": 1, - "spec_id": "spec_473682ae7e62be173cac86a13815f0fa", + "spec_id": "spec_f24e46ae9854884308fc0f33d154361e", "identity": { "identity_version": "spec1", "shape": { @@ -5699,11 +6744,13 @@ "country/KEN" ], "origin": [ - "country/DEU" + "DACOfficialDonors" ] }, "requested_window": { - "kind": "all" + "kind": "range", + "start_year": 2013, + "end_year": 2022 } } }, @@ -5885,7 +6932,14 @@ "label": "time window" }, "binding": { - "kind": "unbound" + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2013, + "end_year": 2022 + } + } }, "summable": false }, @@ -5909,8 +6963,8 @@ "member_count_exact": true, "served_count": 1, "data_date_range": { - "start": "1960", - "end": "2024" + "start": "2013", + "end": "2022" } }, "entities": [ @@ -5921,16 +6975,30 @@ "role": "destination" }, { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", + "ref": "DACOfficialDonors", + "label": "official donors (DAC)", + "entity_type": "DACGroup", "role": "origin" } ], + "entity_groups": { + "origin": { + "label": "official donors (DAC)", + "total": "DACOfficialDonors", + "whole_of": [ + "official" + ], + "side_classes": [ + "official", + "private", + "residual" + ] + } + }, "coverage": { "kind": "exact", "has_data": true, - "observation_count": 65, + "observation_count": 10, "evidence": "facet_metadata", "dimensions": [ { @@ -5939,17 +7007,25 @@ }, { "label": "observations", - "count": 65 + "count": 10 }, { "label": "variables", "count": 1 } - ] + ], + "window": { + "start_year": 2013, + "end_year": 2022 + } }, "headline": { - "year": 2024, - "year_named": false, + "year": 2022, + "year_named": true, + "named_window": { + "start_year": 2013, + "end_year": 2022 + }, "observations": 1, "series": 1, "role_counts": { @@ -5958,7 +7034,7 @@ }, "recent_years": [ { - "year": 2024, + "year": 2022, "observations": 1, "series": 1, "role_counts": { @@ -5967,7 +7043,7 @@ } }, { - "year": 2023, + "year": 2021, "observations": 1, "series": 1, "role_counts": { @@ -5976,7 +7052,7 @@ } }, { - "year": 2022, + "year": 2020, "observations": 1, "series": 1, "role_counts": { @@ -5987,18 +7063,18 @@ ] }, "download": { - "rows": 65, + "rows": 10, "rows_exact": true, "series": 1, "window": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "licence": { "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "facets": { "provenance": { "basis": "fallback", @@ -6044,7 +7120,7 @@ "relation": "child", "parent": "DAC2aAidType206", "member_count": 2, - "served_rows": 61, + "served_rows": 10, "served_rows_exact": true }, { @@ -6058,7 +7134,7 @@ "relation": "child", "parent": "DAC2aAidType206", "member_count": 1, - "served_rows": 65, + "served_rows": 10, "served_rows_exact": true }, { @@ -6071,7 +7147,7 @@ }, "relation": "root", "member_count": 1, - "served_rows": 59, + "served_rows": 10, "served_rows_exact": true }, { @@ -6084,7 +7160,7 @@ }, "relation": "root", "member_count": 1, - "served_rows": 44, + "served_rows": 10, "served_rows_exact": true }, { @@ -6097,7 +7173,7 @@ }, "relation": "root", "member_count": 1, - "served_rows": 29, + "served_rows": 10, "served_rows_exact": true } ], @@ -6140,38 +7216,11 @@ "source": "observed" } ], - "rendered_sentence": "Germany's gross disbursements to Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a.", + "rendered_sentence": "Gross disbursements to Kenya from official donors (DAC) for official development assistance, 2013 to 2022. Current US dollars · OECD DAC2a.", "sentence_plan": [ { "kind": "slot", - "text": "Germany", - "segment": "heading", - "role": "origin", - "binding_ref": "origin:", - "entity_refs": [ - "country/DEU" - ], - "states": [ - "origin:" - ] - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "gross disbursements", + "text": "Gross disbursements", "axis": "what", "segment": "heading", "entity_refs": [], @@ -6203,6 +7252,26 @@ "where:" ] }, + { + "kind": "text", + "text": " from ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "official donors (DAC)", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [ + "DACOfficialDonors" + ], + "states": [ + "origin:" + ] + }, { "kind": "text", "text": " for ", @@ -6261,7 +7330,7 @@ }, { "kind": "slot", - "text": "1960 to 2024", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -6328,8 +7397,8 @@ "label": "Kenya" }, { - "ref": "country/DEU", - "label": "Germany" + "ref": "DACOfficialDonors", + "label": "official donors (DAC)" } ], "resolved_sources": [ @@ -6434,7 +7503,7 @@ "axis": "when", "label": "time window" }, - "binding_kind": "unbound", + "binding_kind": "value", "refs": [], "provenance": "binder" }, @@ -6449,7 +7518,11 @@ } ], "query_qualifiers": [], - "capability_version": "cap_347a470e04c97eec" + "requested_window": { + "start_year": 2013, + "end_year": 2022 + }, + "capability_version": "cap_94e25737d859392c" }, "confidence": "high", "available_at_place": true, @@ -6457,7 +7530,7 @@ { "definition": { "schema_version": 1, - "spec_id": "spec_433a5ca3b9aa482f8f332201570ef664", + "spec_id": "spec_f025379e211db08849c7f98c627e025c", "identity": { "identity_version": "spec1", "shape": { @@ -6501,11 +7574,13 @@ "country/KEN" ], "origin": [ - "country/DEU" + "DACOfficialDonors" ] }, "requested_window": { - "kind": "all" + "kind": "range", + "start_year": 2013, + "end_year": 2022 } } }, @@ -6548,7 +7623,7 @@ } } ], - "served_rows": 65, + "served_rows": 10, "served_rows_exact": true } ], @@ -6603,12 +7678,12 @@ "code": "AED", "noun": "UAE dirhams", "current_years": { - "start_year": 1997, + "start_year": 2013, "end_year": 2021 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2023, "base_year_max": 2023 @@ -6617,12 +7692,12 @@ "code": "AFN", "noun": "Afghan afghanis", "current_years": { - "start_year": 2002, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2002, "base_year_max": 2025 @@ -6631,12 +7706,12 @@ "code": "ALL", "noun": "Albanian leks", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -6645,12 +7720,12 @@ "code": "AMD", "noun": "Armenian drams", "current_years": { - "start_year": 1992, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1992, "base_year_max": 2025 @@ -6659,12 +7734,12 @@ "code": "AOA", "noun": "Angolan kwanzas", "current_years": { - "start_year": 1991, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1991, "base_year_max": 2025 @@ -6673,12 +7748,12 @@ "code": "ARS", "noun": "Argentine pesos", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -6687,12 +7762,12 @@ "code": "AUD", "noun": "Australian dollars", "current_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1960, "base_year_max": 2025 @@ -6701,12 +7776,12 @@ "code": "AWG", "noun": "Aruban florins", "current_years": { - "start_year": 1995, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1995, "base_year_max": 2025 @@ -6719,8 +7794,8 @@ "end_year": 2019 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2023, "base_year_max": 2023 @@ -6729,12 +7804,12 @@ "code": "BAM", "noun": "Bosnia-Herzegovina convertible marks", "current_years": { - "start_year": 1996, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1996, "base_year_max": 2025 @@ -6743,12 +7818,12 @@ "code": "BBD", "noun": "Barbadian dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -6757,12 +7832,12 @@ "code": "BDT", "noun": "Bangladeshi taka", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -6771,12 +7846,12 @@ "code": "BHD", "noun": "Bahraini dinars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -6785,12 +7860,12 @@ "code": "BIF", "noun": "Burundian francs", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -6799,12 +7874,12 @@ "code": "BND", "noun": "Brunei dollars", "current_years": { - "start_year": 1985, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1985, "base_year_max": 2025 @@ -6813,12 +7888,12 @@ "code": "BOB", "noun": "Bolivian bolivianos", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -6827,12 +7902,12 @@ "code": "BRL", "noun": "Brazilian reais", "current_years": { - "start_year": 1986, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1986, "base_year_max": 2025 @@ -6841,12 +7916,12 @@ "code": "BSD", "noun": "Bahamian dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -6855,12 +7930,12 @@ "code": "BTN", "noun": "Bhutanese ngultrums", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -6869,12 +7944,12 @@ "code": "BWP", "noun": "Botswana pula", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -6883,12 +7958,12 @@ "code": "BYN", "noun": "Belarusian rubles", "current_years": { - "start_year": 1992, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1992, "base_year_max": 2025 @@ -6897,12 +7972,12 @@ "code": "BZD", "noun": "Belize dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -6911,12 +7986,12 @@ "code": "CAD", "noun": "Canadian dollars", "current_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1960, "base_year_max": 2025 @@ -6925,12 +8000,12 @@ "code": "CDF", "noun": "Congolese francs", "current_years": { - "start_year": 1991, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1991, "base_year_max": 2025 @@ -6939,12 +8014,12 @@ "code": "CHF", "noun": "Swiss francs", "current_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1960, "base_year_max": 2025 @@ -6953,12 +8028,12 @@ "code": "CLP", "noun": "Chilean pesos", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -6967,12 +8042,12 @@ "code": "CNY", "noun": "Chinese yuan", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -6981,12 +8056,12 @@ "code": "COP", "noun": "Colombian pesos", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -6995,12 +8070,12 @@ "code": "CRC", "noun": "Costa Rican colones", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7009,12 +8084,12 @@ "code": "CVE", "noun": "Cape Verdean escudos", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7023,12 +8098,12 @@ "code": "CZK", "noun": "Czech korunas", "current_years": { - "start_year": 1998, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1998, "base_year_max": 2025 @@ -7037,12 +8112,12 @@ "code": "DJF", "noun": "Djiboutian francs", "current_years": { - "start_year": 1990, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1990, "base_year_max": 2025 @@ -7051,12 +8126,12 @@ "code": "DKK", "noun": "Danish kroner", "current_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1960, "base_year_max": 2025 @@ -7065,12 +8140,12 @@ "code": "DOP", "noun": "Dominican pesos", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7079,12 +8154,12 @@ "code": "DZD", "noun": "Algerian dinars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7093,12 +8168,12 @@ "code": "EGP", "noun": "Egyptian pounds", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7107,12 +8182,12 @@ "code": "ERN", "noun": "Eritrean nakfas", "current_years": { - "start_year": 1992, + "start_year": 2013, "end_year": 2019 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1992, "base_year_max": 2019 @@ -7121,12 +8196,12 @@ "code": "ETB", "noun": "Ethiopian birr", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7135,12 +8210,12 @@ "code": "EUR", "noun": "euros", "current_years": { - "start_year": 1973, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1973, "base_year_max": 2025 @@ -7149,12 +8224,12 @@ "code": "FJD", "noun": "Fijian dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7163,12 +8238,12 @@ "code": "GBP", "noun": "British pounds", "current_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1960, "base_year_max": 2025 @@ -7177,12 +8252,12 @@ "code": "GEL", "noun": "Georgian lari", "current_years": { - "start_year": 1994, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1994, "base_year_max": 2025 @@ -7191,12 +8266,12 @@ "code": "GHS", "noun": "Ghanaian cedis", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7205,12 +8280,12 @@ "code": "GMD", "noun": "Gambian dalasis", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7219,12 +8294,12 @@ "code": "GNF", "noun": "Guinean francs", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7233,12 +8308,12 @@ "code": "GTQ", "noun": "Guatemalan quetzales", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7247,12 +8322,12 @@ "code": "GYD", "noun": "Guyanese dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7261,12 +8336,12 @@ "code": "HKD", "noun": "Hong Kong dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7275,12 +8350,12 @@ "code": "HNL", "noun": "Honduran lempiras", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7289,12 +8364,12 @@ "code": "HTG", "noun": "Haitian gourdes", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7303,12 +8378,12 @@ "code": "HUF", "noun": "Hungarian forints", "current_years": { - "start_year": 2003, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2003, "base_year_max": 2025 @@ -7317,12 +8392,12 @@ "code": "IDR", "noun": "Indonesian rupiahs", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7331,12 +8406,12 @@ "code": "ILS", "noun": "Israeli new shekels", "current_years": { - "start_year": 1997, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1997, "base_year_max": 2025 @@ -7345,12 +8420,12 @@ "code": "INR", "noun": "Indian rupees", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7359,12 +8434,12 @@ "code": "IQD", "noun": "Iraqi dinars", "current_years": { - "start_year": 2000, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2000, "base_year_max": 2025 @@ -7373,12 +8448,12 @@ "code": "IRR", "noun": "Iranian rials", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7387,12 +8462,12 @@ "code": "ISK", "noun": "Icelandic krónur", "current_years": { - "start_year": 1997, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1997, "base_year_max": 2025 @@ -7401,12 +8476,12 @@ "code": "JMD", "noun": "Jamaican dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7415,12 +8490,12 @@ "code": "JOD", "noun": "Jordanian dinars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7429,12 +8504,12 @@ "code": "JPY", "noun": "Japanese yen", "current_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1960, "base_year_max": 2025 @@ -7443,12 +8518,12 @@ "code": "KES", "noun": "Kenyan shillings", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7457,12 +8532,12 @@ "code": "KGS", "noun": "Kyrgyz soms", "current_years": { - "start_year": 1992, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1992, "base_year_max": 2025 @@ -7471,12 +8546,12 @@ "code": "KHR", "noun": "Cambodian riels", "current_years": { - "start_year": 1986, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1986, "base_year_max": 2025 @@ -7485,12 +8560,12 @@ "code": "KMF", "noun": "Comorian francs", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7499,12 +8574,12 @@ "code": "KRW", "noun": "South Korean won", "current_years": { - "start_year": 1987, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1987, "base_year_max": 2025 @@ -7513,12 +8588,12 @@ "code": "KWD", "noun": "Kuwaiti dinars", "current_years": { - "start_year": 1995, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1995, "base_year_max": 2024 @@ -7528,11 +8603,11 @@ "noun": "Kazakh tenge", "current_years": { "start_year": 2013, - "end_year": 2024 + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2013, "base_year_max": 2024 @@ -7541,12 +8616,12 @@ "code": "LAK", "noun": "Lao kip", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7555,12 +8630,12 @@ "code": "LBP", "noun": "Lebanese pounds", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7569,12 +8644,12 @@ "code": "LKR", "noun": "Sri Lankan rupees", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2024 @@ -7583,12 +8658,12 @@ "code": "LSL", "noun": "Lesotho maloti", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7597,12 +8672,12 @@ "code": "LYD", "noun": "Libyan dinars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7611,12 +8686,12 @@ "code": "MAD", "noun": "Moroccan dirhams", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7625,12 +8700,12 @@ "code": "MDL", "noun": "Moldovan lei", "current_years": { - "start_year": 1992, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1992, "base_year_max": 2025 @@ -7639,12 +8714,12 @@ "code": "MGA", "noun": "Malagasy ariary", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7653,12 +8728,12 @@ "code": "MKD", "noun": "Macedonian denars", "current_years": { - "start_year": 1992, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1992, "base_year_max": 2025 @@ -7667,12 +8742,12 @@ "code": "MMK", "noun": "Myanmar kyats", "current_years": { - "start_year": 1998, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1998, "base_year_max": 2025 @@ -7681,12 +8756,12 @@ "code": "MNT", "noun": "Mongolian tugriks", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7695,12 +8770,12 @@ "code": "MOP", "noun": "Macanese patacas", "current_years": { - "start_year": 2001, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2001, "base_year_max": 2025 @@ -7709,12 +8784,12 @@ "code": "MRU", "noun": "Mauritanian ouguiyas", "current_years": { - "start_year": 1990, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1990, "base_year_max": 2025 @@ -7723,12 +8798,12 @@ "code": "MUR", "noun": "Mauritian rupees", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7737,12 +8812,12 @@ "code": "MVR", "noun": "Maldivian rufiyaa", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7751,12 +8826,12 @@ "code": "MWK", "noun": "Malawian kwachas", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7765,12 +8840,12 @@ "code": "MXN", "noun": "Mexican pesos", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7779,12 +8854,12 @@ "code": "MYR", "noun": "Malaysian ringgits", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7793,12 +8868,12 @@ "code": "MZN", "noun": "Mozambican meticais", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7807,12 +8882,12 @@ "code": "NAD", "noun": "Namibian dollars", "current_years": { - "start_year": 1989, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1989, "base_year_max": 2025 @@ -7821,12 +8896,12 @@ "code": "NGN", "noun": "Nigerian naira", "current_years": { - "start_year": 1990, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1990, "base_year_max": 2025 @@ -7835,12 +8910,12 @@ "code": "NIO", "noun": "Nicaraguan córdobas", "current_years": { - "start_year": 1987, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1987, "base_year_max": 2025 @@ -7849,12 +8924,12 @@ "code": "NOK", "noun": "Norwegian kroner", "current_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1960, "base_year_max": 2025 @@ -7863,12 +8938,12 @@ "code": "NPR", "noun": "Nepalese rupees", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7877,12 +8952,12 @@ "code": "NZD", "noun": "New Zealand dollars", "current_years": { - "start_year": 1961, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1961, "base_year_max": 2025 @@ -7891,12 +8966,12 @@ "code": "OMR", "noun": "Omani rials", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7905,12 +8980,12 @@ "code": "PEN", "noun": "Peruvian soles", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7919,12 +8994,12 @@ "code": "PGK", "noun": "Papua New Guinean kina", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7933,12 +9008,12 @@ "code": "PHP", "noun": "Philippine pesos", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7947,12 +9022,12 @@ "code": "PKR", "noun": "Pakistani rupees", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7961,12 +9036,12 @@ "code": "PLN", "noun": "Polish zlotys", "current_years": { - "start_year": 1998, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1998, "base_year_max": 2025 @@ -7975,12 +9050,12 @@ "code": "PYG", "noun": "Paraguayan guaranís", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -7989,12 +9064,12 @@ "code": "QAR", "noun": "Qatari riyals", "current_years": { - "start_year": 1985, - "end_year": 1990 + "start_year": 2020, + "end_year": 2020 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2023, "base_year_max": 2023 @@ -8004,11 +9079,11 @@ "noun": "Romanian lei", "current_years": { "start_year": 2013, - "end_year": 2024 + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2013, "base_year_max": 2025 @@ -8017,12 +9092,12 @@ "code": "RSD", "noun": "Serbian dinars", "current_years": { - "start_year": 1997, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1997, "base_year_max": 2025 @@ -8031,12 +9106,12 @@ "code": "RUB", "noun": "Russian rubles", "current_years": { - "start_year": 2010, + "start_year": 2013, "end_year": 2020 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2010, "base_year_max": 2020 @@ -8045,12 +9120,12 @@ "code": "RWF", "noun": "Rwandan francs", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8059,12 +9134,12 @@ "code": "SAR", "noun": "Saudi riyals", "current_years": { - "start_year": 2000, - "end_year": 2023 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2000, "base_year_max": 2023 @@ -8073,12 +9148,12 @@ "code": "SBD", "noun": "Solomon Islands dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8087,12 +9162,12 @@ "code": "SCR", "noun": "Seychellois rupees", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8101,12 +9176,12 @@ "code": "SDG", "noun": "Sudanese pounds", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8115,12 +9190,12 @@ "code": "SEK", "noun": "Swedish kronor", "current_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1960, "base_year_max": 2025 @@ -8129,12 +9204,12 @@ "code": "SGD", "noun": "Singapore dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8143,12 +9218,12 @@ "code": "SLE", "noun": "Sierra Leonean leones", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8157,12 +9232,12 @@ "code": "SRD", "noun": "Surinamese dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8171,12 +9246,12 @@ "code": "SSP", "noun": "South Sudanese pounds", "current_years": { - "start_year": 2011, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2011, "base_year_max": 2025 @@ -8185,12 +9260,12 @@ "code": "STN", "noun": "São Tomé and Príncipe dobras", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8198,27 +9273,24 @@ { "code": "SYP", "noun": "Syrian pounds", - "current_years": { - "start_year": 1980, - "end_year": 2010 - }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, - "base_year_max": 2010 + "base_year_max": 2010, + "current_years": null }, { "code": "SZL", "noun": "Swazi emalangeni", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8227,12 +9299,12 @@ "code": "THB", "noun": "Thai baht", "current_years": { - "start_year": 2006, - "end_year": 2016 + "start_year": 2018, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2018, "base_year_max": 2024 @@ -8241,12 +9313,12 @@ "code": "TJS", "noun": "Tajikistani somonis", "current_years": { - "start_year": 1992, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1992, "base_year_max": 2025 @@ -8255,12 +9327,12 @@ "code": "TMT", "noun": "Turkmenistani manat", "current_years": { - "start_year": 1992, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1992, "base_year_max": 2025 @@ -8269,12 +9341,12 @@ "code": "TND", "noun": "Tunisian dinars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8283,12 +9355,12 @@ "code": "TOP", "noun": "Tongan paʻanga", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8297,12 +9369,12 @@ "code": "TRY", "noun": "Turkish lira", "current_years": { - "start_year": 1990, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1990, "base_year_max": 2025 @@ -8311,12 +9383,12 @@ "code": "TTD", "noun": "Trinidad and Tobago dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8325,12 +9397,12 @@ "code": "TWD", "noun": "New Taiwan dollars", "current_years": { - "start_year": 2006, - "end_year": 2016 + "start_year": 2018, + "end_year": 2021 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2023, "base_year_max": 2025 @@ -8339,12 +9411,12 @@ "code": "TZS", "noun": "Tanzanian shillings", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8353,12 +9425,12 @@ "code": "UAH", "noun": "Ukrainian hryvnias", "current_years": { - "start_year": 1991, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1991, "base_year_max": 2025 @@ -8367,12 +9439,12 @@ "code": "UGX", "noun": "Ugandan shillings", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8381,12 +9453,12 @@ "code": "USD", "noun": "US dollars", "current_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1960, "base_year_max": 2025 @@ -8395,12 +9467,12 @@ "code": "UYU", "noun": "Uruguayan pesos", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8409,12 +9481,12 @@ "code": "UZS", "noun": "Uzbekistani soms", "current_years": { - "start_year": 1992, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1992, "base_year_max": 2025 @@ -8424,11 +9496,11 @@ "noun": "Venezuelan bolívares", "current_years": { "start_year": 2017, - "end_year": 2024 + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2017, "base_year_max": 2025 @@ -8437,12 +9509,12 @@ "code": "VND", "noun": "Vietnamese dong", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8451,12 +9523,12 @@ "code": "VUV", "noun": "Vanuatu vatu", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8465,12 +9537,12 @@ "code": "WST", "noun": "Samoan tala", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8479,12 +9551,12 @@ "code": "XAF", "noun": "Central African CFA francs", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8493,12 +9565,12 @@ "code": "XCD", "noun": "East Caribbean dollars", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8507,12 +9579,12 @@ "code": "XOF", "noun": "West African CFA francs", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8522,11 +9594,11 @@ "noun": "Yemeni rials", "current_years": { "start_year": 2014, - "end_year": 2024 + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 2014, "base_year_max": 2025 @@ -8535,12 +9607,12 @@ "code": "ZAR", "noun": "South African rand", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8549,12 +9621,12 @@ "code": "ZMW", "noun": "Zambian kwachas", "current_years": { - "start_year": 1980, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "constant_years": { - "start_year": 1960, - "end_year": 2024 + "start_year": 2013, + "end_year": 2022 }, "base_year_min": 1980, "base_year_max": 2025 @@ -8562,20 +9634,30 @@ ], "default_base_year": 2024, "role_currencies": { - "destination": "KES", - "origin": "EUR" + "destination": "KES" } } } } } ], - "rendered_sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 1960 to 2025. Current US dollars · OECD DAC1. You asked for Kenya. The data holds no values for it. Germany's gross disbursements to Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a. Assumed: official development assistance.", + "rendered_sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators. Gross disbursements to Kenya from official donors (DAC) for official development assistance, 2013 to 2022. Current US dollars · OECD DAC2a. This shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, search again with open_roles ['donor']. Assumed: official development assistance.", "sentence_plan": [ { "kind": "slot", - "text": "Primary income", - "axis": "what", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [], @@ -8583,7 +9665,7 @@ }, { "kind": "text", - "text": " for ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [], @@ -8591,20 +9673,16 @@ }, { "kind": "slot", - "text": "gross of fixed capital consumption", - "axis": "how", + "text": "deaths rate", + "axis": "what", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ], + "states": [], "part_index": 0 }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [], @@ -8612,14 +9690,22 @@ }, { "kind": "slot", - "text": "Germany and Kenya", - "axis": "where", + "text": "per capita", + "axis": "unit", "segment": "heading", - "binding_ref": "where:", "entity_refs": [], - "states": [ - "where:" - ], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", + "entity_refs": [], + "states": [], "part_index": 0 }, { @@ -8632,7 +9718,7 @@ }, { "kind": "slot", - "text": "1960 to 2025", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -8660,28 +9746,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ], - "part_index": 0 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -8698,22 +9763,6 @@ "states": [], "part_index": 0 }, - { - "kind": "text", - "text": " ", - "segment": "departure", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "You asked for Kenya. The data holds no values for it.", - "segment": "departure", - "entity_refs": [], - "states": [], - "part_index": 0 - }, { "kind": "text", "text": " ", @@ -8723,29 +9772,21 @@ }, { "kind": "slot", - "text": "Germany", + "text": "Gross disbursements", + "axis": "what", "segment": "heading", - "role": "origin", - "binding_ref": "origin:", - "entity_refs": [ - "country/DEU" - ], + "entity_refs": [], "states": [ - "origin:" + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" ], "part_index": 1 }, { "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 1 - }, - { - "kind": "text", - "text": " ", + "text": " to ", "segment": "heading", "entity_refs": [], "states": [], @@ -8753,21 +9794,22 @@ }, { "kind": "slot", - "text": "gross disbursements", - "axis": "what", + "text": "Kenya", + "axis": "where", "segment": "heading", - "entity_refs": [], + "role": "destination", + "binding_ref": "where:", + "entity_refs": [ + "country/KEN" + ], "states": [ - "how:financialFlowType", - "how:nettingBasis", - "axis:populationType", - "axis:measuredProperty" + "where:" ], "part_index": 1 }, { "kind": "text", - "text": " to ", + "text": " from ", "segment": "heading", "entity_refs": [], "states": [], @@ -8775,16 +9817,15 @@ }, { "kind": "slot", - "text": "Kenya", - "axis": "where", + "text": "official donors (DAC)", "segment": "heading", - "role": "destination", - "binding_ref": "where:", + "role": "origin", + "binding_ref": "origin:", "entity_refs": [ - "country/KEN" + "DACOfficialDonors" ], "states": [ - "where:" + "origin:" ], "part_index": 1 }, @@ -8852,7 +9893,7 @@ }, { "kind": "slot", - "text": "1960 to 2024", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -8918,6 +9959,22 @@ "states": [], "part_index": 1 }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "This shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, search again with open_roles ['donor'].", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + }, { "kind": "text", "text": " ", @@ -8961,10 +10018,10 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "Answered 1 of 2 parts. GNI has 2 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 1960 to 2025 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 1990 to 2025. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself. Germany's gross disbursements to Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a. You asked for aid flows. This shows gross disbursements, the closest measure the data holds. You named Germany without a direction. Only the data with Germany as the provider holds values, so this reads it as the provider. Assumed: official development assistance.", + "sentence": "Answered 1 of 2 parts. Mortality has 2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself. Gross disbursements to Kenya from official donors (DAC) for official development assistance, 2013 to 2022. Current US dollars · OECD DAC2a. You asked for aid flows. This shows gross disbursements, the closest measure the data holds. No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, search again with open_roles ['donor']. Assumed: official development assistance.", "complete": false, "specs": [ - "spec_473682ae7e62be173cac86a13815f0fa" + "spec_f24e46ae9854884308fc0f33d154361e" ], "gaps": [ { @@ -8979,11 +10036,11 @@ "answer": { "kind": "resolution", "status": "definite", - "sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 1960 to 2025. Current US dollars · OECD DAC1. You asked for Kenya. The data holds no values for it. Germany's gross disbursements to Kenya for official development assistance, 1960 to 2024. Current US dollars · OECD DAC2a. Assumed: official development assistance.", + "sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators. Gross disbursements to Kenya from official donors (DAC) for official development assistance, 2013 to 2022. Current US dollars · OECD DAC2a. This shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, search again with open_roles ['donor']. Assumed: official development assistance.", "complete": true, "specs": [ - "spec_f0d0bb4841c0e55d6d4a353e45dcd52c", - "spec_473682ae7e62be173cac86a13815f0fa" + "spec_10bf62f9687154286b463d206f03a086", + "spec_f24e46ae9854884308fc0f33d154361e" ], "gaps": [] } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts-2.parquet b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts-2.parquet index b4448d00980c0782da4317456de4789c00009ec5..81ccb11de8cf7d11da0fb6c7b6de3510afa783cc 100644 GIT binary patch literal 10233 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

g$ZhtN+>Y=>3f_M?3w8`{puL#VK5bXJIU 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 G-~R!*T2USV literal 10503 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 BQxgCH diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json index 951784d..7bbd5e0 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json @@ -4,14 +4,14 @@ "description": "Choosing candidate 0 on the candidates part of a two-part answer posts dataset_resubmit with one entry per part in part order: the chosen candidate's identity, and the definite part's identity with its entity_groups. Both parts answer definite, and the fetch stacks two members with each member's parts as its part column value.", "origin": { "kind": "recorded", - "base_url": "http://127.0.0.1:19493/api", - "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T13:07:05Z" + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "recorded_at": "2026-10-23T18:39:21Z" }, "call": [ { "op": "search", - "question": "GNI of Germany from 2015 to 2022, and ODA disbursements from Germany to sub-Saharan Africa" + "question": "mortality in Kenya from 2013 to 2022, and GDP of sub-Saharan Africa" }, { "op": "choose", @@ -31,7 +31,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "GNI of Germany from 2015 to 2022, and ODA disbursements from Germany to sub-Saharan Africa" + "query": "mortality in Kenya from 2013 to 2022, and GDP of sub-Saharan Africa" } } }, @@ -39,67 +39,68 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a9c284c85fd74d4283998be9c492aab4" + "x-dfo-trace-id": "fac5b4aa15d145e6b20db91a1cd7a24b" }, "json": { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "GNI of Germany from 2015 to 2022, and ODA disbursements from Germany to sub-Saharan Africa", - "normalized_query": "GNI of Germany from 2015 to 2022, and ODA disbursements from Germany to sub-Saharan Africa", + "raw_query": "mortality in Kenya from 2013 to 2022, and GDP of sub-Saharan Africa", + "normalized_query": "mortality in Kenya from 2013 to 2022, and GDP of sub-Saharan Africa", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "a9c284c85fd74d4283998be9c492aab4", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "fac5b4aa15d145e6b20db91a1cd7a24b", "warnings": [], "timing_ms": { - "total": 4415, + "total": 9120, "by_step": { "coverage": 0, - "extract": 1049 + "extract": 979, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 11567, - "output_tokens": 611, - "cached_tokens": 864 + "input_tokens": 2245, + "output_tokens": 202, + "cached_tokens": 844, + "jev_input_tokens": 26433, + "jev_output_tokens": 5561 }, "timed_out": false }, "kind": "resolution", "parts": [ { - "variable_text": "GNI", - "warnings": [ - { - "code": "direction_discarded", - "severity": "warn", - "message": "sub-Saharan Africa was named as the recipient; this shape reports the place as its own subject, so the direction was dropped." - }, - { - "code": "direction_discarded", - "severity": "warn", - "message": "Germany was named as the provider; this shape reports the place as its own subject, so the direction was dropped." - } - ], + "variable_text": "mortality", + "warnings": [], "timing_ms": { - "total": 2710, + "total": 8137, "by_step": { "recall": 0, - "shape_arcs": 2, - "shape_probe_coverage": 3, - "shape_probe": 4, - "shape_groups": 18, - "shape_labels": 7, - "shape_admission": 562, - "shape": 1553, - "bind": 893, - "materialise": 246, - "answer": 18 + "phase_resolve_places": 1, + "phase_check_entities": 0, + "shape_arcs": 3, + "shape_probe": 102, + "shape_groups": 5, + "shape_labels": 1, + "shape_admission": 1, + "phase_derive_shapes": 0, + "shape": 362, + "phase_prune_and_rank": 0, + "bind": 146, + "phase_bind": 4, + "phase_settle": 11, + "phase_place_bindings": 27, + "phase_facet_requests": 0, + "materialise": 896, + "phase_materialise": 0, + "answer": 45, + "phase_outcome": 6645 } }, - "rendered_sentence": "3 readings. Primary income for gross of fixed capital consumption in 49 places. World Bank International Debt Statistics (IDS) · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in 49 places. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in 49 places. World Development Indicators · 2015 to 2022. You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself.", + "rendered_sentence": "3 readings. Deaths rate per capita in the 48 countries in Sub-Saharan Africa. World Development Indicators · 2013 to 2022. Number of deaths in the 48 countries in Sub-Saharan Africa. Kenya Census · 2018 to 2022. Count of mortality event (as fraction of count birth event live birth) in the 48 countries in Sub-Saharan Africa. Nigeria Statistics · 2014.", "sentence_plan": [ { "kind": "text", @@ -117,21 +118,21 @@ }, { "kind": "text", - "text": "Primary income", + "text": "Deaths rate", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": " for ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": "gross of fixed capital consumption", + "text": "per capita", "segment": "heading", "entity_refs": [], "states": [] @@ -145,7 +146,7 @@ }, { "kind": "text", - "text": "49 places", + "text": "the 48 countries in Sub-Saharan Africa", "segment": "heading", "entity_refs": [], "states": [] @@ -166,21 +167,7 @@ }, { "kind": "text", - "text": "World Bank International Debt Statistics (IDS)", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "2015 to 2022", + "text": "World Development Indicators", "segment": "byline", "entity_refs": [], "states": [] @@ -194,7 +181,7 @@ }, { "kind": "text", - "text": "Current US dollars", + "text": "2013 to 2022", "segment": "byline", "entity_refs": [], "states": [] @@ -215,21 +202,7 @@ }, { "kind": "text", - "text": "Gross national income based on purchasing power parity", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "in international dollars", + "text": "Number of deaths", "segment": "heading", "entity_refs": [], "states": [] @@ -243,7 +216,7 @@ }, { "kind": "text", - "text": "49 places", + "text": "the 48 countries in Sub-Saharan Africa", "segment": "heading", "entity_refs": [], "states": [] @@ -264,7 +237,7 @@ }, { "kind": "text", - "text": "World Development Indicators", + "text": "Kenya Census", "segment": "byline", "entity_refs": [], "states": [] @@ -278,7 +251,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2018 to 2022", "segment": "byline", "entity_refs": [], "states": [] @@ -299,21 +272,7 @@ }, { "kind": "text", - "text": "Gross national income based on purchasing power parity per capita", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "in international dollars", + "text": "Count of mortality event (as fraction of count birth event live birth)", "segment": "heading", "entity_refs": [], "states": [] @@ -327,7 +286,7 @@ }, { "kind": "text", - "text": "49 places", + "text": "the 48 countries in Sub-Saharan Africa", "segment": "heading", "entity_refs": [], "states": [] @@ -348,7 +307,7 @@ }, { "kind": "text", - "text": "World Development Indicators", + "text": "Nigeria Statistics", "segment": "byline", "entity_refs": [], "states": [] @@ -362,7 +321,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2014", "segment": "byline", "entity_refs": [], "states": [] @@ -373,47 +332,24 @@ "segment": "byline", "entity_refs": [], "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "departure", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself.", - "segment": "departure", - "entity_refs": [], - "states": [] } ], "restatement": { - "variable_text": "GNI", + "variable_text": "mortality", "entities": [ { - "text": "Germany", - "role_text": "from" + "text": "Kenya" }, { - "text": "sub-Saharan Africa", - "role_text": "to" + "text": "Sub-Saharan Africa" } ], - "time_text": "2015 to 2022", + "time_text": "2013 to 2022", "sources": [], "operations": [] }, "operations": [], - "departures": [ - { - "code": "direction_discarded", - "binding_ref": "where:", - "asked": "sub-Saharan Africa", - "text": "You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself." - } - ], + "departures": [], "assumptions": [], "status": "candidates", "candidates": { @@ -421,25 +357,26 @@ "max_candidates": 6, "specs": [ { - "spec_id": "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", + "spec_id": "spec_176fd5e63bb2a122c4ad00831497b863", "definition": { "schema_version": 1, - "spec_id": "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", + "spec_id": "spec_176fd5e63bb2a122c4ad00831497b863", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], @@ -457,7 +394,6 @@ "country/COG", "country/COM", "country/CPV", - "country/DEU", "country/DJI", "country/ERI", "country/ETH", @@ -498,40 +434,40 @@ }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicunit_primaryincome_measuredvalue_nominal", - "label": "Gross national income", + "shape_id": "mortalityevent_count_measuredvalue_per_count_person", + "label": "Deaths Rate", "population_type": { - "ref": "EconomicUnit", - "label": "economic unit" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "primaryIncome", - "label": "primary income" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "Nominal", - "label": "Nominal" + "measurement_denominator": { + "ref": "Count_Person", + "label": "Total population" }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, { "axis": "where", @@ -546,13 +482,13 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", - "refine_supported": true, + "member_count": 133, + "member_digest": "c090b56d31a596a8be16dafb518382db666c6b100a80534c3cb81dbfe3111c5d", + "refine_supported": false, "data_commons": [ { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" } ] }, @@ -561,20 +497,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - }, - "value_kind": "enum_value" - } + "kind": "unbound" }, "summable": false }, @@ -670,13 +599,6 @@ }, "value_kind": "entity" }, - { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" - }, { "ref": { "ref": "country/DJI", @@ -943,7 +865,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } @@ -961,14 +883,16 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 2, "member_count_exact": false, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2013", "end": "2022" } }, @@ -1045,12 +969,6 @@ "entity_type": "Country", "role": "observationAbout" }, - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/DJI", "label": "Djibouti", @@ -1268,19 +1186,26 @@ "role": "observationAbout" } ], + "entity_groups": { + "observationAbout": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, "coverage": { "kind": "exact", "has_data": true, - "observation_count": 348, + "observation_count": 480, "evidence": "facet_metadata", "dimensions": [ { "label": "countries", - "count": 44 + "count": 48 }, { "label": "observations", - "count": 8 + "count": 10 }, { "label": "variables", @@ -1288,16 +1213,16 @@ } ], "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, "download": { - "rows": 348, + "rows": 480, "rows_exact": true, - "series": 44, + "series": 48, "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, "licence": { @@ -1307,23 +1232,27 @@ "facets": { "provenance": { "basis": "fallback", - "ref": "provenance/WorldBankInternationalDebtStatistics", - "label": "World Bank International Debt Statistics (IDS)", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { "ref": "dc/s/WorldBank", "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "measurementMethod": { + "basis": "fallback", + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" }, "unit": { "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" + "ref": "Per1000Persons", + "label": "Per 1000 people" } }, "slot_options": [ @@ -1331,17 +1260,17 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" + "ref": "ICD10/X60-X84", + "label": "X60-X84 (Intentional self-harm)" }, "value_kind": "enum_value" } @@ -1359,8 +1288,17 @@ { "value": { "ref": { - "ref": "provenance/WorldBankInternationalDebtStatistics", - "label": "World Bank International Debt Statistics (IDS)" + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + }, + { + "value": { + "ref": { + "ref": "dc/base/Cotedivoire_Census", + "label": "Ivory Coast Census" }, "value_kind": "source" } @@ -1368,8 +1306,8 @@ { "value": { "ref": { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1" + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, "value_kind": "source" } @@ -1378,28 +1316,54 @@ "truncated": false, "source": "observed" }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "ref": { + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, { "axis": "unit", "options": [ { "value": { "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" + "ref": "Per1000Persons", + "label": "Per 1000 people" }, "value_kind": "enum_value" } + }, + { + "value": { + "value_kind": "enum_value" + } } ], "truncated": false, "source": "observed" } ], - "rendered_sentence": "Primary income for gross of fixed capital consumption in 49 places, 2015 to 2022. Current US dollars · World Bank International Debt Statistics (IDS).", + "rendered_sentence": "Deaths rate per capita in the 48 countries in Sub-Saharan Africa, 2013 to 2022. World Development Indicators.", "sentence_plan": [ { "kind": "slot", - "text": "Primary income", + "text": "Deaths rate", "axis": "what", "segment": "heading", "entity_refs": [], @@ -1408,23 +1372,28 @@ }, { "kind": "text", - "text": " for ", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "per capita", + "axis": "unit", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "gross of fixed capital consumption", + "text": "", "axis": "how", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ], - "distinguishes": true + "states": [] }, { "kind": "text", @@ -1435,7 +1404,7 @@ }, { "kind": "slot", - "text": "49 places", + "text": "the 48 countries in Sub-Saharan Africa", "axis": "where", "segment": "heading", "binding_ref": "where:", @@ -1453,14 +1422,15 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", "entity_refs": [], "states": [ "when:" - ] + ], + "distinguishes": true }, { "kind": "text", @@ -1478,26 +1448,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "World Bank International Debt Statistics (IDS)", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -1564,10 +1515,6 @@ "ref": "country/CPV", "label": "Cape Verde" }, - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/DJI", "label": "Djibouti" @@ -1715,17 +1662,17 @@ ], "resolved_sources": [ { - "ref": "provenance/WorldBankInternationalDebtStatistics", - "label": "World Bank International Debt Statistics (IDS)", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { "ref": "dc/s/WorldBank", "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" } ], "slot_filters": [ @@ -1733,18 +1680,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -1802,10 +1744,6 @@ "ref": "country/CPV", "label": "Cape Verde" }, - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/DJI", "label": "Djibouti" @@ -1974,38 +1912,13 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] + "removed_stat_vars": [] } }, "confidence": "high", @@ -2015,25 +1928,65 @@ } }, { - "spec_id": "spec_07c78f9c1c511ed05a0f700b7f6c121e", + "spec_id": "spec_1ca4f4991f0c01309d33fed3fe0bae60", "definition": { "schema_version": 1, - "spec_id": "spec_07c78f9c1c511ed05a0f700b7f6c121e", + "spec_id": "spec_1ca4f4991f0c01309d33fed3fe0bae60", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicActivity", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "PurchasingPowerParity" + "population_type": "MortalityEvent", + "measured_property": "count", + "stat_type": "measuredValue" }, "slots": [ { - "property": "activitySource", + "property": "age", "binding": { - "state": "value", - "ref": "GrossNationalIncome" + "state": "unbound" + } + }, + { + "property": "ageGroupClassification", + "binding": { + "state": "unbound" + } + }, + { + "property": "causeOfDeath", + "binding": { + "state": "unbound" + } + }, + { + "property": "ethnicity", + "binding": { + "state": "unbound" + } + }, + { + "property": "gender", + "binding": { + "state": "unbound" + } + }, + { + "property": "incidentType", + "binding": { + "state": "unbound" + } + }, + { + "property": "race", + "binding": { + "state": "unbound" + } + }, + { + "property": "residentStatus", + "binding": { + "state": "unbound" } } ], @@ -2051,7 +2004,6 @@ "country/COG", "country/COM", "country/CPV", - "country/DEU", "country/DJI", "country/ERI", "country/ETH", @@ -2092,40 +2044,92 @@ }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity", - "label": "Gross National Income Based on Purchasing Power Parity", + "shape_id": "mortalityevent_count_measuredvalue", + "label": "Number of Deaths", "population_type": { - "ref": "EconomicActivity", - "label": "EconomicActivity" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "amount", - "label": "amount" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "PurchasingPowerParity", - "label": "PurchasingPowerParity" - }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" + }, + "label": "cause of death" + }, + { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" }, - "label": "activity source" + "label": "incident type" + }, + { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" }, { "axis": "where", @@ -2140,45 +2144,125 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "833b9da89613fa6c1775652daac2388f38204c6c9f9929ca113deed9a0d08369", + "member_count": 2978, "refine_supported": true, "data_commons": [ { "id": "base", "label": "Data Commons by Google" } - ], - "upstream": { - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" - } - } + ] }, "slots": [ { "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - }, - "value_kind": "enum_value" - } + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + "binding": { + "kind": "unbound" }, "summable": false }, @@ -2274,13 +2358,6 @@ }, "value_kind": "entity" }, - { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" - }, { "ref": { "ref": "country/DJI", @@ -2547,7 +2624,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 } } @@ -2565,14 +2642,23 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath", + "gender", + "age", + "race", + "incidentType", + "ethnicity", + "residentStatus", + "ageGroupClassification" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 37, "member_count_exact": false, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2018", "end": "2022" } }, @@ -2649,12 +2735,6 @@ "entity_type": "Country", "role": "observationAbout" }, - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/DJI", "label": "Djibouti", @@ -2872,19 +2952,26 @@ "role": "observationAbout" } ], + "entity_groups": { + "observationAbout": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, "coverage": { "kind": "exact", "has_data": true, - "observation_count": 377, + "observation_count": 5, "evidence": "facet_metadata", "dimensions": [ { "label": "countries", - "count": 48 + "count": 1 }, { "label": "observations", - "count": 8 + "count": 5 }, { "label": "variables", @@ -2892,16 +2979,16 @@ } ], "window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 } }, "download": { - "rows": 377, + "rows": 5, "rows_exact": true, - "series": 48, + "series": 1, "window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 }, "licence": { @@ -2911,22 +2998,17 @@ "facets": { "provenance": { "basis": "fallback", - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census", "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "ref": "dc/s/OpenDataForAfrica", + "label": "Open Data for Africa" }, "data_commons": { "id": "base", "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" - }, - "unit": { - "basis": "fallback", - "ref": "InternationalDollar", - "label": "InternationalDollar" + "documentation": "/api/graph/documentation/dc/base/Kenya_Census" } }, "slot_options": [ @@ -2934,1785 +3016,955 @@ "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + "ref": "ICD10/A00-B99", + "label": "A00-B99 (Certain infectious and parasitic diseases)" }, "value_kind": "enum_value" } - } - ], - "truncated": true, - "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ - { - "axis": "provenance", - "options": [ + }, { "value": { "ref": { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators" + "ref": "ICD10/D50-D89", + "label": "D50-D89 (Diseases of the blood and blood-forming organs and certain disorders involving the immune mechanism)" }, - "value_kind": "source" + "value_kind": "enum_value" } - } - ], - "truncated": false, - "source": "observed" - }, - { - "axis": "unit", - "options": [ + }, { "value": { "ref": { - "ref": "InternationalDollar", - "label": "InternationalDollar" + "ref": "ICD10/I00-I99", + "label": "I00-I99 (Diseases of the circulatory system)" }, "value_kind": "enum_value" } - } - ], - "truncated": false, - "source": "observed" - } - ], - "rendered_sentence": "Gross national income based on purchasing power parity in international dollars in 49 places, 2015 to 2022. World Development Indicators.", - "sentence_plan": [ - { - "kind": "slot", - "text": "Gross national income based on purchasing power parity", - "axis": "what", - "segment": "heading", - "entity_refs": [], - "states": [ - "how:activitySource" - ], - "distinguishes": true - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "in international dollars", - "axis": "unit", - "segment": "heading", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:" - ] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "activitySource", - "binding_ref": "how:activitySource", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " in ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "49 places", - "axis": "where", - "segment": "heading", - "binding_ref": "where:", - "entity_refs": [], - "states": [ - "where:" - ] - }, - { - "kind": "text", - "text": ", ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "2015 to 2022", - "axis": "when", - "segment": "heading", - "binding_ref": "when:", - "entity_refs": [], - "states": [ - "when:" - ] - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "World Development Indicators", - "axis": "source", - "segment": "byline", - "entity_refs": [], - "states": [ - "source:" - ], - "distinguishes": true - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [] - } - ], - "trace": { - "resolved_entities": [ - { - "ref": "country/AGO", - "label": "Angola" - }, - { - "ref": "country/BDI", - "label": "Burundi" - }, - { - "ref": "country/BEN", - "label": "Benin" - }, - { - "ref": "country/BFA", - "label": "Burkina Faso" - }, - { - "ref": "country/BWA", - "label": "Botswana" - }, - { - "ref": "country/CAF", - "label": "Central African Republic" - }, - { - "ref": "country/CIV", - "label": "Ivory Coast" - }, - { - "ref": "country/CMR", - "label": "Cameroon" - }, - { - "ref": "country/COD", - "label": "Democratic Republic of the Congo" - }, - { - "ref": "country/COG", - "label": "Republic of the Congo" - }, - { - "ref": "country/COM", - "label": "Comoros" - }, - { - "ref": "country/CPV", - "label": "Cape Verde" - }, - { - "ref": "country/DEU", - "label": "Germany" - }, - { - "ref": "country/DJI", - "label": "Djibouti" - }, - { - "ref": "country/ERI", - "label": "Eritrea" - }, - { - "ref": "country/ETH", - "label": "Ethiopia" - }, - { - "ref": "country/GAB", - "label": "Gabon" - }, - { - "ref": "country/GHA", - "label": "Ghana" - }, - { - "ref": "country/GIN", - "label": "Guinea" - }, - { - "ref": "country/GMB", - "label": "The Gambia" - }, - { - "ref": "country/GNB", - "label": "Guinea-Bissau" - }, - { - "ref": "country/GNQ", - "label": "Equatorial Guinea" - }, - { - "ref": "country/KEN", - "label": "Kenya" - }, - { - "ref": "country/LBR", - "label": "Liberia" - }, - { - "ref": "country/LSO", - "label": "Lesotho" - }, - { - "ref": "country/MDG", - "label": "Madagascar" - }, - { - "ref": "country/MLI", - "label": "Mali" - }, - { - "ref": "country/MOZ", - "label": "Mozambique" - }, - { - "ref": "country/MRT", - "label": "Mauritania" - }, - { - "ref": "country/MUS", - "label": "Mauritius" - }, - { - "ref": "country/MWI", - "label": "Malawi" - }, - { - "ref": "country/NAM", - "label": "Namibia" - }, - { - "ref": "country/NER", - "label": "Niger" - }, - { - "ref": "country/NGA", - "label": "Nigeria" - }, - { - "ref": "country/RWA", - "label": "Rwanda" - }, - { - "ref": "country/SEN", - "label": "Senegal" - }, - { - "ref": "country/SLE", - "label": "Sierra Leone" - }, - { - "ref": "country/SOM", - "label": "Somalia" - }, - { - "ref": "country/SSD", - "label": "South Sudan" - }, - { - "ref": "country/STP", - "label": "São Tomé and Príncipe" - }, - { - "ref": "country/SWZ", - "label": "Swaziland" - }, - { - "ref": "country/SYC", - "label": "Seychelles" - }, - { - "ref": "country/TCD", - "label": "Chad" - }, - { - "ref": "country/TGO", - "label": "Togo" - }, - { - "ref": "country/TZA", - "label": "Tanzania" - }, - { - "ref": "country/UGA", - "label": "Uganda" - }, - { - "ref": "country/ZAF", - "label": "South Africa" - }, - { - "ref": "country/ZMB", - "label": "Zambia" - }, - { - "ref": "country/ZWE", - "label": "Zimbabwe" - } - ], - "resolved_sources": [ - { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" + { + "value": { + "ref": { + "ref": "ICD10/K00-K92", + "label": "K00-K92 (Diseases of the digestive system)" + }, + "value_kind": "enum_value" + } }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" - } - ], - "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "activitySource", - "label": "activitySource" - }, - "label": "activity source" + { + "value": { + "ref": { + "ref": "ICD10/N00-N98", + "label": "N00-N98 (Diseases of the genitourinary system)" + }, + "value_kind": "enum_value" + } }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + { + "value": { + "ref": { + "ref": "ICD10/M00-M99", + "label": "M00-M99 (Diseases of the musculoskeletal system and connective tissue)" + }, + "value_kind": "enum_value" } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "where", - "label": "place" }, - "binding_kind": "set", - "refs": [ - { - "ref": "country/AGO", - "label": "Angola" - }, - { - "ref": "country/BDI", - "label": "Burundi" - }, - { - "ref": "country/BEN", - "label": "Benin" - }, - { - "ref": "country/BFA", - "label": "Burkina Faso" - }, - { - "ref": "country/BWA", - "label": "Botswana" - }, - { - "ref": "country/CAF", - "label": "Central African Republic" - }, - { - "ref": "country/CIV", - "label": "Ivory Coast" - }, - { - "ref": "country/CMR", - "label": "Cameroon" - }, - { - "ref": "country/COD", - "label": "Democratic Republic of the Congo" - }, - { - "ref": "country/COG", - "label": "Republic of the Congo" - }, - { - "ref": "country/COM", - "label": "Comoros" - }, - { - "ref": "country/CPV", - "label": "Cape Verde" - }, - { - "ref": "country/DEU", - "label": "Germany" - }, - { - "ref": "country/DJI", - "label": "Djibouti" - }, - { - "ref": "country/ERI", - "label": "Eritrea" - }, - { - "ref": "country/ETH", - "label": "Ethiopia" - }, - { - "ref": "country/GAB", - "label": "Gabon" - }, - { - "ref": "country/GHA", - "label": "Ghana" - }, - { - "ref": "country/GIN", - "label": "Guinea" - }, - { - "ref": "country/GMB", - "label": "The Gambia" - }, - { - "ref": "country/GNB", - "label": "Guinea-Bissau" - }, - { - "ref": "country/GNQ", - "label": "Equatorial Guinea" - }, - { - "ref": "country/KEN", - "label": "Kenya" - }, - { - "ref": "country/LBR", - "label": "Liberia" - }, - { - "ref": "country/LSO", - "label": "Lesotho" - }, - { - "ref": "country/MDG", - "label": "Madagascar" - }, - { - "ref": "country/MLI", - "label": "Mali" - }, - { - "ref": "country/MOZ", - "label": "Mozambique" - }, - { - "ref": "country/MRT", - "label": "Mauritania" - }, - { - "ref": "country/MUS", - "label": "Mauritius" - }, - { - "ref": "country/MWI", - "label": "Malawi" - }, - { - "ref": "country/NAM", - "label": "Namibia" - }, - { - "ref": "country/NER", - "label": "Niger" - }, - { - "ref": "country/NGA", - "label": "Nigeria" - }, - { - "ref": "country/RWA", - "label": "Rwanda" - }, - { - "ref": "country/SEN", - "label": "Senegal" - }, - { - "ref": "country/SLE", - "label": "Sierra Leone" - }, - { - "ref": "country/SOM", - "label": "Somalia" - }, - { - "ref": "country/SSD", - "label": "South Sudan" - }, - { - "ref": "country/STP", - "label": "São Tomé and Príncipe" - }, - { - "ref": "country/SWZ", - "label": "Swaziland" - }, - { - "ref": "country/SYC", - "label": "Seychelles" - }, - { - "ref": "country/TCD", - "label": "Chad" - }, - { - "ref": "country/TGO", - "label": "Togo" - }, - { - "ref": "country/TZA", - "label": "Tanzania" - }, - { - "ref": "country/UGA", - "label": "Uganda" - }, - { - "ref": "country/ZAF", - "label": "South Africa" - }, - { - "ref": "country/ZMB", - "label": "Zambia" - }, - { - "ref": "country/ZWE", - "label": "Zimbabwe" + { + "value": { + "ref": { + "ref": "ICD10/G00-G98", + "label": "G00-G98 (Diseases of the nervous system)" + }, + "value_kind": "enum_value" } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "when", - "label": "time window" }, - "binding_kind": "value", - "refs": [], - "provenance": "binder" - }, - { - "key": { - "axis": "source", - "label": "data source" + { + "value": { + "ref": { + "ref": "ICD10/J00-J98", + "label": "J00-J98 (Diseases of the respiratory system)" + }, + "value_kind": "enum_value" + } }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - } - ], - "query_qualifiers": [], - "requested_window": { - "start_year": 2015, - "end_year": 2022 - }, - "capability_version": "cap_347a470e04c97eec", - "default_reading": { - "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] - } - }, - "confidence": "high", - "basis": "nominated", - "available_at_place": true, - "measure_label_axes": [], - "measure_axis_values": [] - } - }, - { - "spec_id": "spec_62eeede92636290b4c10e207bd8bffbb", - "definition": { - "schema_version": 1, - "spec_id": "spec_62eeede92636290b4c10e207bd8bffbb", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "EconomicActivity", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "PurchasingPowerParity", - "measurement_denominator": { - "unresolved": true - } - }, - "slots": [ - { - "property": "activitySource", - "binding": { - "state": "value", - "ref": "GrossNationalIncome" - } - } - ], - "entities": { - "observationAbout": [ - "country/AGO", - "country/BDI", - "country/BEN", - "country/BFA", - "country/BWA", - "country/CAF", - "country/CIV", - "country/CMR", - "country/COD", - "country/COG", - "country/COM", - "country/CPV", - "country/DEU", - "country/DJI", - "country/ERI", - "country/ETH", - "country/GAB", - "country/GHA", - "country/GIN", - "country/GMB", - "country/GNB", - "country/GNQ", - "country/KEN", - "country/LBR", - "country/LSO", - "country/MDG", - "country/MLI", - "country/MOZ", - "country/MRT", - "country/MUS", - "country/MWI", - "country/NAM", - "country/NER", - "country/NGA", - "country/RWA", - "country/SEN", - "country/SLE", - "country/SOM", - "country/SSD", - "country/STP", - "country/SWZ", - "country/SYC", - "country/TCD", - "country/TGO", - "country/TZA", - "country/UGA", - "country/ZAF", - "country/ZMB", - "country/ZWE" - ] - }, - "requested_window": { - "kind": "range", - "start_year": 2015, - "end_year": 2022 - } - } - }, - "resolved": { - "shape": { - "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity_per_unresolved", - "label": "Gross National Income Based on Purchasing Power Parity Per Capita", - "population_type": { - "ref": "EconomicActivity", - "label": "EconomicActivity" - }, - "measured_property": { - "ref": "amount", - "label": "amount" - }, - "stat_type": { - "ref": "measuredValue", - "label": "measuredValue" - }, - "measurement_qualifier": { - "ref": "PurchasingPowerParity", - "label": "PurchasingPowerParity" - }, - "measurement_denominator": { - "ref": "PerCapita", - "label": "PerCapita" - }, - "measurement_denominator_unresolved": true, - "slot_keys": [ - { - "axis": "how", - "property": { - "ref": "activitySource", - "label": "activitySource" - }, - "label": "activity source" - }, - { - "axis": "where", - "label": "place" - }, - { - "axis": "when", - "label": "time window" - }, - { - "axis": "source", - "label": "data source" - } - ], - "member_count": 1, - "member_digest": "7b2d5b0fc09cfc0215c8d7c6c21a5195fa21e79f2a148a6bca9ce6c3af8bbb9f", - "refine_supported": true, - "data_commons": [ - { - "id": "base", - "label": "Data Commons by Google" - } - ], - "upstream": { - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" - } - } - }, - "slots": [ - { - "key": { - "axis": "how", - "property": { - "ref": "activitySource", - "label": "activitySource" - }, - "label": "activity source" - }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - }, - "value_kind": "enum_value" - } - }, - "summable": false - }, - { - "key": { - "axis": "where", - "label": "place" - }, - "binding": { - "kind": "set", - "values": [ - { + { + "value": { "ref": { - "ref": "country/AGO", - "label": "Angola" + "ref": "ICD10/L00-L98", + "label": "L00-L98 (Diseases of the skin and subcutaneous tissue)" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/BDI", - "label": "Burundi" + "ref": "ICD10/E00-E88", + "label": "E00-E88 (Endocrine, nutritional and metabolic diseases)" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/BEN", - "label": "Benin" + "ref": "ICD10/F01-F99", + "label": "F01-F99 (Mental and behavioural disorders)" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/BFA", - "label": "Burkina Faso" + "ref": "ICD10/O00-O99", + "label": "O00-O99 (Pregnancy, childbirth and the puerperium)" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/BWA", - "label": "Botswana" + "ref": "ICD10/U00-U99", + "label": "U00-U99 (Codes for special purposes)" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/CAF", - "label": "Central African Republic" + "ref": "Diabetes", + "label": "Diabetes" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/CIV", - "label": "Ivory Coast" + "ref": "Suicide", + "label": "Suicide" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/CMR", - "label": "Cameroon" + "ref": "ICD10/V01-Y89", + "label": "V01-Y89 (External causes of morbidity and mortality)" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/COD", - "label": "Democratic Republic of the Congo" + "ref": "ICD10/C00-D48", + "label": "C00-D48 (Neoplasms)" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/COG", - "label": "Republic of the Congo" + "ref": "ICD10/P00-P96", + "label": "P00-P96 (Certain conditions originating in the perinatal period)" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/COM", - "label": "Comoros" + "ref": "ICD10/Q00-Q99", + "label": "Q00-Q99 (Congenital malformations, deformations and chromosomal abnormalities)" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/CPV", - "label": "Cape Verde" + "ref": "CerebrovascularDiseases", + "label": "CerebrovascularDiseases" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/DEU", - "label": "Germany" + "ref": "CongenitalAnomalies", + "label": "CongenitalAnomalies" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/DJI", - "label": "Djibouti" + "ref": "CongenitalHeartAnomalies", + "label": "CongenitalHeartAnomalies" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/ERI", - "label": "Eritrea" + "ref": "GenitourinaryDiseases", + "label": "GenitourinaryDiseases" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/ETH", - "label": "Ethiopia" + "ref": "HypertensiveHeartDisease", + "label": "HypertensiveHeartDisease" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/GAB", - "label": "Gabon" + "ref": "MalignantNeoplasms", + "label": "MalignantNeoplasms" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/GHA", - "label": "Ghana" + "ref": "Neoplasms", + "label": "Neoplasms" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/GIN", - "label": "Guinea" + "ref": "PerinatalInfection", + "label": "Perinatal Infection" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/GMB", - "label": "The Gambia" + "ref": "Pneumonia", + "label": "Pneumonia" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/GNB", - "label": "Guinea-Bissau" + "ref": "SGP_OtherDiseasesAndCauses", + "label": "SGP_OtherDiseasesAndCauses" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/GNQ", - "label": "Equatorial Guinea" + "ref": "TransportAccidents", + "label": "TransportAccidents" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/KEN", - "label": "Kenya" + "ref": "Tuberculosis", + "label": "Tuberculosis" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "options": [ + { + "value": { "ref": { - "ref": "country/LBR", - "label": "Liberia" + "ref": "Female", + "label": "Female" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/LSO", - "label": "Lesotho" + "ref": "Male", + "label": "Male" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "options": [ + { + "value": { "ref": { - "ref": "country/MDG", - "label": "Madagascar" + "ref": "Years0To1", + "label": "Years 0 To 1" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/MLI", - "label": "Mali" + "ref": "Day0To27", + "label": "Day 0 To 27" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/MOZ", - "label": "Mozambique" + "ref": "Years10To14", + "label": "Years 10 To 14" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/MRT", - "label": "Mauritania" + "ref": "Years15To19", + "label": "Years 15 To 19" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/MUS", - "label": "Mauritius" + "ref": "Years15To24", + "label": "Years 15 To 24" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/MWI", - "label": "Malawi" + "ref": "Years1To4", + "label": "Years 1 To 4" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/NAM", - "label": "Namibia" + "ref": "Years20To24", + "label": "Years 20 To 24" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/NER", - "label": "Niger" + "ref": "Years25To29", + "label": "Years 25 To 29" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/NGA", - "label": "Nigeria" + "ref": "Years25To34", + "label": "Years 25 To 34" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/RWA", - "label": "Rwanda" + "ref": "Years30To34", + "label": "Years 30 To 34" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/SEN", - "label": "Senegal" + "ref": "Years35To39", + "label": "Years 35 To 39" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/SLE", - "label": "Sierra Leone" + "ref": "Years35To44", + "label": "Years 35 To 44" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/SOM", - "label": "Somalia" + "ref": "Years40To44", + "label": "Years 40 To 44" }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/SSD", - "label": "South Sudan" + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years45To49", + "label": "Years 45 To 49" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/STP", - "label": "São Tomé and Príncipe" + "ref": "Years45To54", + "label": "Years 45 To 54" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/SWZ", - "label": "Swaziland" + "ref": "Years50To54", + "label": "Years 50 To 54" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/SYC", - "label": "Seychelles" + "ref": "Years55To59", + "label": "Years 55 To 59" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/TCD", - "label": "Chad" + "ref": "Years55To64", + "label": "Years 55 To 64" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/TGO", - "label": "Togo" + "ref": "Years5To9", + "label": "Years 5 To 9" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/TZA", - "label": "Tanzania" + "ref": "Years60To64", + "label": "Years 60 To 64" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/UGA", - "label": "Uganda" + "ref": "Years65To69", + "label": "Years 65 To 69" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/ZAF", - "label": "South Africa" + "ref": "Years65To74", + "label": "Years 65 To 74" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/ZMB", - "label": "Zambia" + "ref": "Years70To74", + "label": "Years 70 To 74" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/ZWE", - "label": "Zimbabwe" + "ref": "Years75To79", + "label": "Years 75 To 79" }, - "value_kind": "entity" + "value_kind": "enum_value" } - ] - }, - "summable": false + }, + { + "value": { + "ref": { + "ref": "Years75To84", + "label": "Years 75 To 84" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years80To84", + "label": "Years 80 To 84" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "USC_AgeNotStated", + "label": "USC_AgeNotStated" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years0To4", + "label": "Years 0 To 4" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, { "key": { - "axis": "when", - "label": "time window" + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" }, - "binding": { - "kind": "value", - "value": { - "value_kind": "time_window", - "time_window": { - "start_year": 2015, - "end_year": 2022 + "options": [ + { + "value": { + "ref": { + "ref": "CDC_AmericanIndianAndAlaskaNativeAlone", + "label": "American Indian and Alaska native alone" + }, + "value_kind": "enum_value" } } - }, - "summable": false + ], + "truncated": true, + "source": "observed" }, { "key": { - "axis": "source", - "label": "data source" - }, - "binding": { - "kind": "unbound" + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" }, - "summable": false - } - ], - "inapplicable_slots": [], - "unresolved_slots": [], - "stat_vars": { - "member_count": 1, - "member_count_exact": false, - "served_count": 1, - "data_date_range": { - "start": "2015", - "end": "2022" - } - }, - "entities": [ - { - "ref": "country/AGO", - "label": "Angola", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/BDI", - "label": "Burundi", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/BEN", - "label": "Benin", - "entity_type": "Country", - "role": "observationAbout" + "options": [ + { + "value": { + "ref": { + "ref": "COVID_19", + "label": "COVID-19" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, { - "ref": "country/BFA", - "label": "Burkina Faso", - "entity_type": "Country", - "role": "observationAbout" + "key": { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Chinese", + "label": "Chinese" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Indian", + "label": "Indian" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Malay", + "label": "Malay" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SGP_OtherEthnicity", + "label": "SGP_OtherEthnicity" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, { - "ref": "country/BWA", - "label": "Botswana", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/CAF", - "label": "Central African Republic", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/CIV", - "label": "Ivory Coast", - "entity_type": "Country", - "role": "observationAbout" + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Citizen", + "label": "Citizen" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Resident", + "label": "Resident" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, { - "ref": "country/CMR", - "label": "Cameroon", - "entity_type": "Country", - "role": "observationAbout" - }, + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Infant", + "label": "Infant" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Newborn", + "label": "Newborn" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ { - "ref": "country/COD", - "label": "Democratic Republic of the Congo", - "entity_type": "Country", - "role": "observationAbout" - }, + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Number of deaths in the 48 countries in Sub-Saharan Africa, 2018 to 2022. Kenya Census.", + "sentence_plan": [ { - "ref": "country/COG", - "label": "Republic of the Congo", - "entity_type": "Country", - "role": "observationAbout" + "kind": "slot", + "text": "Number of deaths", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "distinguishes": true }, { - "ref": "country/COM", - "label": "Comoros", - "entity_type": "Country", - "role": "observationAbout" + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "age", + "binding_ref": "how:age", + "entity_refs": [], + "states": [] }, { - "ref": "country/CPV", - "label": "Cape Verde", - "entity_type": "Country", - "role": "observationAbout" + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "ageGroupClassification", + "binding_ref": "how:ageGroupClassification", + "entity_refs": [], + "states": [] }, { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", + "entity_refs": [], + "states": [] }, { - "ref": "country/DJI", - "label": "Djibouti", - "entity_type": "Country", - "role": "observationAbout" + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "ethnicity", + "binding_ref": "how:ethnicity", + "entity_refs": [], + "states": [] }, { - "ref": "country/ERI", - "label": "Eritrea", - "entity_type": "Country", - "role": "observationAbout" + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "gender", + "binding_ref": "how:gender", + "entity_refs": [], + "states": [] }, { - "ref": "country/ETH", - "label": "Ethiopia", - "entity_type": "Country", - "role": "observationAbout" + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "incidentType", + "binding_ref": "how:incidentType", + "entity_refs": [], + "states": [] }, { - "ref": "country/GAB", - "label": "Gabon", - "entity_type": "Country", - "role": "observationAbout" + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "race", + "binding_ref": "how:race", + "entity_refs": [], + "states": [] }, { - "ref": "country/GHA", - "label": "Ghana", - "entity_type": "Country", - "role": "observationAbout" + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "residentStatus", + "binding_ref": "how:residentStatus", + "entity_refs": [], + "states": [] }, { - "ref": "country/GIN", - "label": "Guinea", - "entity_type": "Country", - "role": "observationAbout" + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] }, { - "ref": "country/GMB", - "label": "The Gambia", - "entity_type": "Country", - "role": "observationAbout" + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] }, { - "ref": "country/GNB", - "label": "Guinea-Bissau", - "entity_type": "Country", - "role": "observationAbout" + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] }, { - "ref": "country/GNQ", - "label": "Equatorial Guinea", - "entity_type": "Country", - "role": "observationAbout" + "kind": "slot", + "text": "2018 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "distinguishes": true }, { - "ref": "country/KEN", - "label": "Kenya", - "entity_type": "Country", - "role": "observationAbout" + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] }, { - "ref": "country/LBR", - "label": "Liberia", - "entity_type": "Country", - "role": "observationAbout" + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] }, { - "ref": "country/LSO", - "label": "Lesotho", - "entity_type": "Country", - "role": "observationAbout" + "kind": "slot", + "text": "Kenya Census", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true }, { - "ref": "country/MDG", - "label": "Madagascar", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/MLI", - "label": "Mali", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/MOZ", - "label": "Mozambique", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/MRT", - "label": "Mauritania", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/MUS", - "label": "Mauritius", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/MWI", - "label": "Malawi", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/NAM", - "label": "Namibia", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/NER", - "label": "Niger", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/NGA", - "label": "Nigeria", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/RWA", - "label": "Rwanda", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/SEN", - "label": "Senegal", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/SLE", - "label": "Sierra Leone", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/SOM", - "label": "Somalia", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/SSD", - "label": "South Sudan", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/STP", - "label": "São Tomé and Príncipe", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/SWZ", - "label": "Swaziland", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/SYC", - "label": "Seychelles", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/TCD", - "label": "Chad", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/TGO", - "label": "Togo", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/TZA", - "label": "Tanzania", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/UGA", - "label": "Uganda", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/ZAF", - "label": "South Africa", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/ZMB", - "label": "Zambia", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/ZWE", - "label": "Zimbabwe", - "entity_type": "Country", - "role": "observationAbout" + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] } ], - "coverage": { - "kind": "exact", - "has_data": true, - "observation_count": 377, - "evidence": "facet_metadata", - "dimensions": [ + "trace": { + "resolved_entities": [ { - "label": "countries", - "count": 48 + "ref": "country/AGO", + "label": "Angola" }, { - "label": "observations", - "count": 8 + "ref": "country/BDI", + "label": "Burundi" }, { - "label": "variables", - "count": 1 - } - ], - "window": { - "start_year": 2015, - "end_year": 2022 - } - }, - "download": { - "rows": 377, - "rows_exact": true, - "series": 48, - "window": { - "start_year": 2015, - "end_year": 2022 - }, - "licence": { - "label": "Creative Commons Attribution License" - } - }, - "facets": { - "provenance": { - "basis": "fallback", - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "ref": "country/BEN", + "label": "Benin" }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" + { + "ref": "country/BFA", + "label": "Burkina Faso" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" - }, - "unit": { - "basis": "fallback", - "ref": "InternationalDollar", - "label": "InternationalDollar" - } - }, - "slot_options": [ - { - "key": { - "axis": "how", - "property": { - "ref": "activitySource", - "label": "activitySource" - }, - "label": "activity source" - }, - "options": [ - { - "value": { - "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - }, - "value_kind": "enum_value" - } - } - ], - "truncated": true, - "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ - { - "axis": "provenance", - "options": [ - { - "value": { - "ref": { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators" - }, - "value_kind": "source" - } - } - ], - "truncated": false, - "source": "observed" - }, - { - "axis": "unit", - "options": [ - { - "value": { - "ref": { - "ref": "InternationalDollar", - "label": "InternationalDollar" - }, - "value_kind": "enum_value" - } - } - ], - "truncated": false, - "source": "observed" - } - ], - "rendered_sentence": "Gross national income based on purchasing power parity per capita in international dollars in 49 places, 2015 to 2022. World Development Indicators.", - "sentence_plan": [ - { - "kind": "slot", - "text": "Gross national income based on purchasing power parity per capita", - "axis": "what", - "segment": "heading", - "entity_refs": [], - "states": [ - "how:activitySource" - ], - "distinguishes": true - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "in international dollars", - "axis": "unit", - "segment": "heading", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:" - ] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "activitySource", - "binding_ref": "how:activitySource", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " in ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "49 places", - "axis": "where", - "segment": "heading", - "binding_ref": "where:", - "entity_refs": [], - "states": [ - "where:" - ] - }, - { - "kind": "text", - "text": ", ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "2015 to 2022", - "axis": "when", - "segment": "heading", - "binding_ref": "when:", - "entity_refs": [], - "states": [ - "when:" - ] - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "World Development Indicators", - "axis": "source", - "segment": "byline", - "entity_refs": [], - "states": [ - "source:" - ], - "distinguishes": true - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [] - } - ], - "trace": { - "resolved_entities": [ - { - "ref": "country/AGO", - "label": "Angola" - }, - { - "ref": "country/BDI", - "label": "Burundi" - }, - { - "ref": "country/BEN", - "label": "Benin" - }, - { - "ref": "country/BFA", - "label": "Burkina Faso" - }, - { - "ref": "country/BWA", - "label": "Botswana" + { + "ref": "country/BWA", + "label": "Botswana" }, { "ref": "country/CAF", @@ -4742,10 +3994,6 @@ "ref": "country/CPV", "label": "Cape Verde" }, - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/DJI", "label": "Djibouti" @@ -4893,17 +4141,17 @@ ], "resolved_sources": [ { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census", "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "ref": "dc/s/OpenDataForAfrica", + "label": "Open Data for Africa" }, "data_commons": { "id": "base", "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + "documentation": "/api/graph/documentation/dc/base/Kenya_Census" } ], "slot_filters": [ @@ -4911,18 +4159,104 @@ "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - } - ], + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -4980,10 +4314,6 @@ "ref": "country/CPV", "label": "Cape Verde" }, - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/DJI", "label": "Djibouti" @@ -5152,10761 +4482,10191 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] + "removed_stat_vars": [] } }, - "confidence": "high", - "basis": "nominated", + "confidence": "low", + "basis": "structural", "available_at_place": true, "measure_label_axes": [], "measure_axis_values": [] } - } - ], - "truncated": false - }, - "reading_assumptions": { - "spec_bc87ff8e0f29960c38c96a4f4d2b0e20": [], - "spec_07c78f9c1c511ed05a0f700b7f6c121e": [], - "spec_62eeede92636290b4c10e207bd8bffbb": [] - } - }, - { - "variable_text": "ODA disbursements", - "warnings": [ - { - "code": "retrieval_score_weak", - "severity": "info", - "message": "the chosen reading's match to the query is weak; treat it with less confidence than a strong match." - } - ], - "timing_ms": { - "total": 2250, - "by_step": { - "recall": 0, - "shape_arcs": 0, - "shape_probe_coverage": 3, - "shape_probe": 3, - "shape_groups": 16, - "shape_labels": 0, - "shape_admission": 431, - "shape": 1214, - "bind": 1016, - "materialise": 10, - "answer": 7, - "options": 3 - } - }, - "restatement": { - "variable_text": "ODA disbursements", - "entities": [ - { - "text": "Germany", - "role_text": "from" }, { - "text": "sub-Saharan Africa", - "role_text": "to" - } - ], - "time_text": "2015 to 2022", - "sources": [], - "operations": [] - }, - "operations": [], - "departures": [ - { - "code": "group_read_as_members", - "binding_ref": "where:", - "asked": "sub-Saharan Africa", - "text": "You asked for sub-Saharan Africa. This shows the countries in it, each on its own." - } - ], - "assumptions": [], - "status": "definite", - "spec": { - "spec_id": "spec_941030940d23f46826acaa0c6fed8bbc", - "definition": { - "schema_version": 1, - "spec_id": "spec_941030940d23f46826acaa0c6fed8bbc", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "FinancialFlow", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" - }, - "slots": [ - { - "property": "dac2aAidType", - "binding": { - "state": "value", - "ref": "DAC2aAidType206" - } - }, - { - "property": "dacTypeOfFinance", - "binding": { - "state": "unbound" - } - }, - { - "property": "financialFlowType", - "binding": { - "state": "value", - "ref": "Disbursement" - } - }, - { - "property": "nettingBasis", - "binding": { - "state": "value", - "ref": "Gross" + "spec_id": "spec_66b488f4c8cd760c136a57ce16335332", + "definition": { + "schema_version": 1, + "spec_id": "spec_66b488f4c8cd760c136a57ce16335332", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "MortalityEvent", + "measured_property": "count", + "stat_type": "measuredValue", + "measurement_denominator": { + "ref": "Count_BirthEvent_LiveBirth" + } + }, + "slots": [ + { + "property": "age", + "binding": { + "state": "unbound" + } + }, + { + "property": "ageGroupClassification", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2013, + "end_year": 2022 } } - ], - "entities": { - "destination": [ - "country/AGO", - "country/BDI", - "country/BEN", - "country/BFA", - "country/BWA", - "country/CAF", - "country/CIV", - "country/CMR", - "country/COD", - "country/COG", - "country/COM", - "country/CPV", - "country/DJI", - "country/ERI", - "country/ETH", - "country/GAB", - "country/GHA", - "country/GIN", - "country/GMB", - "country/GNB", - "country/GNQ", - "country/KEN", - "country/LBR", - "country/LSO", - "country/MDG", - "country/MLI", - "country/MOZ", - "country/MRT", - "country/MUS", - "country/MWI", - "country/NAM", - "country/NER", - "country/NGA", - "country/RWA", - "country/SEN", - "country/SLE", - "country/SOM", - "country/SSD", - "country/STP", - "country/SWZ", - "country/SYC", - "country/TCD", - "country/TGO", - "country/TZA", - "country/UGA", - "country/ZAF", - "country/ZMB", - "country/ZWE" - ], - "origin": [ - "country/DEU" - ] - }, - "requested_window": { - "kind": "range", - "start_year": 2015, - "end_year": 2022 - } - } - }, - "resolved": { - "shape": { - "shape_id": "financialflow_amount_measuredvalue_nominal_family_f096b1ba", - "label": "gross disbursements (official development assistance)", - "population_type": { - "ref": "FinancialFlow", - "label": "financial flow" - }, - "measured_property": { - "ref": "amount", - "label": "amount" - }, - "stat_type": { - "ref": "measuredValue", - "label": "measuredValue" - }, - "measurement_qualifier": { - "ref": "Nominal", - "label": "Nominal" }, - "measurement_denominator_unresolved": false, - "slot_keys": [ - { - "axis": "how", - "property": { - "ref": "dac2aAidType", - "label": "DAC 2a aid type" - }, - "label": "aid type" - }, - { - "axis": "how", - "property": { - "ref": "dacTypeOfFinance", - "label": "DAC type of finance" + "resolved": { + "shape": { + "shape_id": "mortalityevent_count_measuredvalue_per_count_birthevent_livebirth", + "label": "Count Of Mortality Event (As Fraction Of Count Birth Event Live Birth)", + "population_type": { + "ref": "MortalityEvent", + "label": "MortalityEvent" }, - "label": "DAC type of finance" - }, - { - "axis": "how", - "property": { - "ref": "financialFlowType", - "label": "financial flow type" + "measured_property": { + "ref": "count", + "label": "count" }, - "label": "financial flow type" - }, - { - "axis": "how", - "property": { - "ref": "nettingBasis", - "label": "netting basis" + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" }, - "label": "netting basis" - }, - { - "axis": "where", - "label": "place" - }, - { - "axis": "when", - "label": "time window" - }, - { - "axis": "source", - "label": "data source" - } - ], - "member_count": 1, - "member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", - "refine_supported": true, - "data_commons": [ - { - "id": "dfo", - "label": "Development Finance Observatory" - } - ] - }, - "slots": [ - { - "key": { - "axis": "how", - "property": { - "ref": "dac2aAidType", - "label": "DAC 2a aid type" + "measurement_denominator": { + "ref": "Count_BirthEvent_LiveBirth", + "label": "Total number of reported live births" }, - "label": "aid type" - }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "DAC2aAidType206", - "label": "official development assistance" + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" }, - "value_kind": "enum_value" - } - }, - "summable": false - }, - { - "key": { - "axis": "how", - "property": { - "ref": "dacTypeOfFinance", - "label": "DAC type of finance" - }, - "label": "DAC type of finance" - }, - "binding": { - "kind": "unbound" - }, - "summable": false - }, - { - "key": { - "axis": "how", - "property": { - "ref": "financialFlowType", - "label": "financial flow type" - }, - "label": "financial flow type" - }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "Disbursement", - "label": "disbursement" - }, - "value_kind": "enum_value" - } - }, - "summable": false - }, - { - "key": { - "axis": "how", - "property": { - "ref": "nettingBasis", - "label": "netting basis" - }, - "label": "netting basis" - }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "Gross", - "label": "gross" - }, - "value_kind": "enum_value" - } - }, - "summable": false - }, - { - "key": { - "axis": "where", - "label": "place" - }, - "binding": { - "kind": "set", - "values": [ - { - "ref": { - "ref": "country/AGO", - "label": "Angola" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/BDI", - "label": "Burundi" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/BEN", - "label": "Benin" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/BFA", - "label": "Burkina Faso" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/BWA", - "label": "Botswana" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/CAF", - "label": "Central African Republic" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/CIV", - "label": "Ivory Coast" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/CMR", - "label": "Cameroon" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/COD", - "label": "Democratic Republic of the Congo" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/COG", - "label": "Republic of the Congo" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/COM", - "label": "Comoros" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/CPV", - "label": "Cape Verde" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/DJI", - "label": "Djibouti" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/ERI", - "label": "Eritrea" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/ETH", - "label": "Ethiopia" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/GAB", - "label": "Gabon" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/GHA", - "label": "Ghana" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/GIN", - "label": "Guinea" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/GMB", - "label": "The Gambia" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/GNB", - "label": "Guinea-Bissau" - }, - "value_kind": "entity" + { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" }, { - "ref": { - "ref": "country/GNQ", - "label": "Equatorial Guinea" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/KEN", - "label": "Kenya" - }, - "value_kind": "entity" + "axis": "where", + "label": "place" }, { - "ref": { - "ref": "country/LBR", - "label": "Liberia" - }, - "value_kind": "entity" + "axis": "when", + "label": "time window" }, { - "ref": { - "ref": "country/LSO", - "label": "Lesotho" - }, - "value_kind": "entity" - }, + "axis": "source", + "label": "data source" + } + ], + "member_count": 16, + "member_digest": "5ebf092c4e81dc781233afda0ba2bc0b2be42053aee9e92e7079e6b8b260099c", + "refine_supported": false, + "data_commons": [ { - "ref": { - "ref": "country/MDG", - "label": "Madagascar" + "id": "base", + "label": "Data Commons by Google" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" }, - "value_kind": "entity" + "label": "age" }, - { - "ref": { - "ref": "country/MLI", - "label": "Mali" - }, - "value_kind": "entity" + "binding": { + "kind": "unbound" }, - { - "ref": { - "ref": "country/MOZ", - "label": "Mozambique" + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" }, - "value_kind": "entity" + "label": "age group classification" }, - { - "ref": { - "ref": "country/MRT", - "label": "Mauritania" - }, - "value_kind": "entity" + "binding": { + "kind": "unbound" }, - { - "ref": { - "ref": "country/MUS", - "label": "Mauritius" - }, - "value_kind": "entity" + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" }, - { - "ref": { - "ref": "country/MWI", - "label": "Malawi" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/NAM", - "label": "Namibia" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/NER", - "label": "Niger" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/NGA", - "label": "Nigeria" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/RWA", - "label": "Rwanda" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/SEN", - "label": "Senegal" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/SLE", - "label": "Sierra Leone" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/SOM", - "label": "Somalia" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/SSD", - "label": "South Sudan" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/STP", - "label": "São Tomé and Príncipe" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/SWZ", - "label": "Swaziland" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/SYC", - "label": "Seychelles" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/TCD", - "label": "Chad" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/TGO", - "label": "Togo" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/TZA", - "label": "Tanzania" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/UGA", - "label": "Uganda" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/ZAF", - "label": "South Africa" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/ZMB", - "label": "Zambia" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/ZWE", - "label": "Zimbabwe" - }, - "value_kind": "entity" - } - ] - }, - "summable": false - }, - { - "key": { - "axis": "when", - "label": "time window" - }, - "binding": { - "kind": "value", - "value": { - "value_kind": "time_window", - "time_window": { - "start_year": 2015, - "end_year": 2022 - } - } - }, - "summable": false - }, - { - "key": { - "axis": "source", - "label": "data source" - }, - "binding": { - "kind": "unbound" - }, - "summable": false - } - ], - "inapplicable_slots": [ - "dacTypeOfFinance", - "financialObligationType" - ], - "unresolved_slots": [], - "stat_vars": { - "member_count": 1, - "member_count_exact": true, - "served_count": 1, - "data_date_range": { - "start": "2015", - "end": "2022" - } - }, - "entities": [ - { - "ref": "country/AGO", - "label": "Angola", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BDI", - "label": "Burundi", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BEN", - "label": "Benin", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BFA", - "label": "Burkina Faso", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BWA", - "label": "Botswana", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/CAF", - "label": "Central African Republic", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/CIV", - "label": "Ivory Coast", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/CMR", - "label": "Cameroon", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/COD", - "label": "Democratic Republic of the Congo", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/COG", - "label": "Republic of the Congo", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/COM", - "label": "Comoros", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/CPV", - "label": "Cape Verde", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/DJI", - "label": "Djibouti", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/ERI", - "label": "Eritrea", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/ETH", - "label": "Ethiopia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GAB", - "label": "Gabon", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GHA", - "label": "Ghana", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GIN", - "label": "Guinea", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GMB", - "label": "The Gambia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GNB", - "label": "Guinea-Bissau", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GNQ", - "label": "Equatorial Guinea", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/KEN", - "label": "Kenya", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/LBR", - "label": "Liberia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/LSO", - "label": "Lesotho", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MDG", - "label": "Madagascar", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MLI", - "label": "Mali", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MOZ", - "label": "Mozambique", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MRT", - "label": "Mauritania", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MUS", - "label": "Mauritius", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MWI", - "label": "Malawi", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/NAM", - "label": "Namibia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/NER", - "label": "Niger", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/NGA", - "label": "Nigeria", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/RWA", - "label": "Rwanda", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/SEN", - "label": "Senegal", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/SLE", - "label": "Sierra Leone", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/SOM", - "label": "Somalia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/SSD", - "label": "South Sudan", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/STP", - "label": "São Tomé and Príncipe", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/SWZ", - "label": "Swaziland", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/SYC", - "label": "Seychelles", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/TCD", - "label": "Chad", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/TGO", - "label": "Togo", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/TZA", - "label": "Tanzania", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/UGA", - "label": "Uganda", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/ZAF", - "label": "South Africa", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/ZMB", - "label": "Zambia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/ZWE", - "label": "Zimbabwe", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "origin" - } - ], - "entity_groups": { - "destination": { - "ref": "SubSaharanAfrica", - "label": "Sub-Saharan Africa", - "entity_type": "UNGeoRegion" - } - }, - "coverage": { - "kind": "exact", - "has_data": true, - "observation_count": 372, - "evidence": "facet_metadata", - "dimensions": [ - { - "label": "sources", - "count": 1 - }, - { - "label": "observations", - "count": 8 - }, - { - "label": "variables", - "count": 1 - } - ], - "window": { - "start_year": 2015, - "end_year": 2022 - } - }, - "headline": { - "year": 2022, - "year_named": true, - "named_window": { - "start_year": 2015, - "end_year": 2022 - }, - "observations": 46, - "series": 46, - "role_counts": { - "financingProvider": 1, - "financingRecipient": 46 - }, - "recent_years": [ - { - "year": 2022, - "observations": 46, - "series": 46, - "role_counts": { - "financingProvider": 1, - "financingRecipient": 46 - } - }, - { - "year": 2021, - "observations": 46, - "series": 46, - "role_counts": { - "financingProvider": 1, - "financingRecipient": 46 - } - }, - { - "year": 2020, - "observations": 47, - "series": 47, - "role_counts": { - "financingProvider": 1, - "financingRecipient": 47 - } - } - ] - }, - "download": { - "rows": 372, - "rows_exact": true, - "series": 48, - "window": { - "start_year": 2015, - "end_year": 2022 - }, - "licence": { - "label": "OECD Terms and Conditions" - } - }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", - "facets": { - "provenance": { - "basis": "fallback", - "ref": "provenance/OECDDAC2A", - "label": "OECD DAC2A", - "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" - }, - "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" - }, - "documentation": "/api/graph/documentation/provenance/OECDDAC2A", - "account": "provider" - }, - "unit": { - "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" - } - }, - "slot_options": [ - { - "key": { - "axis": "how", - "property": { - "ref": "dac2aAidType", - "label": "DAC 2a aid type" - }, - "label": "aid type" - }, - "options": [ - { - "value": { - "ref": { - "ref": "DAC2aAidType218", - "label": "ODA loans and other long-term capital" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "DAC2aAidType206", - "member_count": 2, - "served_rows": 68, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "DAC2aAidType201", - "label": "ODA grant" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "DAC2aAidType206", - "member_count": 1, - "served_rows": 372, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "DAC2aAidType207", - "label": "free-standing technical co-operation" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 1, - "served_rows": 372, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "DAC2aAidType213", - "label": "developmental food aid" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 1, - "served_rows": 129, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "DAC2aAidType216", - "label": "humanitarian aid" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 1, - "served_rows": 188, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ - { - "axis": "provenance", - "options": [ - { - "value": { - "ref": { - "ref": "provenance/OECDDAC2A", - "label": "OECD DAC2A" - }, - "value_kind": "source" - } - } - ], - "truncated": false, - "source": "observed" - }, - { - "axis": "unit", - "options": [ - { - "value": { - "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" - }, - "value_kind": "enum_value" - } - } - ], - "truncated": false, - "source": "observed" - } - ], - "rendered_sentence": "Germany's gross disbursements to the 48 countries in Sub-Saharan Africa for official development assistance, 2015 to 2022. Current US dollars · OECD DAC2a.", - "sentence_plan": [ - { - "kind": "slot", - "text": "Germany", - "segment": "heading", - "role": "origin", - "binding_ref": "origin:", - "entity_refs": [ - "country/DEU" - ], - "states": [ - "origin:" - ] - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "gross disbursements", - "axis": "what", - "segment": "heading", - "entity_refs": [], - "states": [ - "how:financialFlowType", - "how:nettingBasis", - "axis:populationType", - "axis:measuredProperty" - ] - }, - { - "kind": "text", - "text": " to ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "the 48 countries in Sub-Saharan Africa", - "axis": "where", - "segment": "heading", - "role": "destination", - "binding_ref": "where:", - "entity_refs": [ - "country/AGO", - "country/BDI", - "country/BEN", - "country/BFA", - "country/BWA", - "country/CAF", - "country/CIV", - "country/CMR", - "country/COD", - "country/COG", - "country/COM", - "country/CPV", - "country/DJI", - "country/ERI", - "country/ETH", - "country/GAB", - "country/GHA", - "country/GIN", - "country/GMB", - "country/GNB", - "country/GNQ", - "country/KEN", - "country/LBR", - "country/LSO", - "country/MDG", - "country/MLI", - "country/MOZ", - "country/MRT", - "country/MUS", - "country/MWI", - "country/NAM", - "country/NER", - "country/NGA", - "country/RWA", - "country/SEN", - "country/SLE", - "country/SOM", - "country/SSD", - "country/STP", - "country/SWZ", - "country/SYC", - "country/TCD", - "country/TGO", - "country/TZA", - "country/UGA", - "country/ZAF", - "country/ZMB", - "country/ZWE" - ], - "states": [ - "where:" - ] - }, - { - "kind": "text", - "text": " for ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "official development assistance", - "axis": "how", - "segment": "heading", - "property_dcid": "dac2aAidType", - "binding_ref": "how:dac2aAidType", - "entity_refs": [], - "states": [ - "how:dac2aAidType" - ] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "dacTypeOfFinance", - "binding_ref": "how:dacTypeOfFinance", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "financialFlowType", - "binding_ref": "how:financialFlowType", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "nettingBasis", - "binding_ref": "how:nettingBasis", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": ", ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "2015 to 2022", - "axis": "when", - "segment": "heading", - "binding_ref": "when:", - "entity_refs": [], - "states": [ - "when:" - ] - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "OECD DAC2a", - "axis": "source", - "segment": "byline", - "entity_refs": [], - "states": [ - "source:" - ] - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [] - } - ], - "trace": { - "resolved_entities": [ - { - "ref": "country/AGO", - "label": "Angola" - }, - { - "ref": "country/BDI", - "label": "Burundi" - }, - { - "ref": "country/BEN", - "label": "Benin" - }, - { - "ref": "country/BFA", - "label": "Burkina Faso" - }, - { - "ref": "country/BWA", - "label": "Botswana" - }, - { - "ref": "country/CAF", - "label": "Central African Republic" - }, - { - "ref": "country/CIV", - "label": "Ivory Coast" - }, - { - "ref": "country/CMR", - "label": "Cameroon" - }, - { - "ref": "country/COD", - "label": "Democratic Republic of the Congo" - }, - { - "ref": "country/COG", - "label": "Republic of the Congo" - }, - { - "ref": "country/COM", - "label": "Comoros" - }, - { - "ref": "country/CPV", - "label": "Cape Verde" - }, - { - "ref": "country/DJI", - "label": "Djibouti" - }, - { - "ref": "country/ERI", - "label": "Eritrea" - }, - { - "ref": "country/ETH", - "label": "Ethiopia" - }, - { - "ref": "country/GAB", - "label": "Gabon" - }, - { - "ref": "country/GHA", - "label": "Ghana" - }, - { - "ref": "country/GIN", - "label": "Guinea" - }, - { - "ref": "country/GMB", - "label": "The Gambia" - }, - { - "ref": "country/GNB", - "label": "Guinea-Bissau" - }, - { - "ref": "country/GNQ", - "label": "Equatorial Guinea" - }, - { - "ref": "country/KEN", - "label": "Kenya" - }, - { - "ref": "country/LBR", - "label": "Liberia" - }, - { - "ref": "country/LSO", - "label": "Lesotho" - }, - { - "ref": "country/MDG", - "label": "Madagascar" - }, - { - "ref": "country/MLI", - "label": "Mali" - }, - { - "ref": "country/MOZ", - "label": "Mozambique" - }, - { - "ref": "country/MRT", - "label": "Mauritania" - }, - { - "ref": "country/MUS", - "label": "Mauritius" - }, - { - "ref": "country/MWI", - "label": "Malawi" - }, - { - "ref": "country/NAM", - "label": "Namibia" - }, - { - "ref": "country/NER", - "label": "Niger" - }, - { - "ref": "country/NGA", - "label": "Nigeria" - }, - { - "ref": "country/RWA", - "label": "Rwanda" - }, - { - "ref": "country/SEN", - "label": "Senegal" - }, - { - "ref": "country/SLE", - "label": "Sierra Leone" - }, - { - "ref": "country/SOM", - "label": "Somalia" - }, - { - "ref": "country/SSD", - "label": "South Sudan" - }, - { - "ref": "country/STP", - "label": "São Tomé and Príncipe" - }, - { - "ref": "country/SWZ", - "label": "Swaziland" - }, - { - "ref": "country/SYC", - "label": "Seychelles" - }, - { - "ref": "country/TCD", - "label": "Chad" - }, - { - "ref": "country/TGO", - "label": "Togo" - }, - { - "ref": "country/TZA", - "label": "Tanzania" - }, - { - "ref": "country/UGA", - "label": "Uganda" - }, - { - "ref": "country/ZAF", - "label": "South Africa" - }, - { - "ref": "country/ZMB", - "label": "Zambia" - }, - { - "ref": "country/ZWE", - "label": "Zimbabwe" - }, - { - "ref": "country/DEU", - "label": "Germany" - } - ], - "resolved_sources": [ - { - "ref": "provenance/OECDDAC2A", - "label": "OECD DAC2a", - "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" - }, - "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" - }, - "documentation": "/api/graph/documentation/provenance/OECDDAC2A" - } - ], - "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "dac2aAidType", - "label": "DAC 2a aid type" - }, - "label": "aid type" - }, - "binding_kind": "value", - "refs": [ - { - "ref": "DAC2aAidType206", - "label": "official development assistance" - } - ], - "provenance": "text_recognized" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "dacTypeOfFinance", - "label": "DAC type of finance" - }, - "label": "DAC type of finance" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "financialFlowType", - "label": "financial flow type" - }, - "label": "financial flow type" - }, - "binding_kind": "value", - "refs": [ - { - "ref": "Disbursement", - "label": "disbursement" - } - ], - "provenance": "text_recognized" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "nettingBasis", - "label": "netting basis" - }, - "label": "netting basis" - }, - "binding_kind": "value", - "refs": [ - { - "ref": "Gross", - "label": "gross" - } - ], - "provenance": "measure_elected" - }, - { - "key": { - "axis": "where", - "label": "place" - }, - "binding_kind": "set", - "refs": [ - { - "ref": "country/AGO", - "label": "Angola" - }, - { - "ref": "country/BDI", - "label": "Burundi" - }, - { - "ref": "country/BEN", - "label": "Benin" - }, - { - "ref": "country/BFA", - "label": "Burkina Faso" - }, - { - "ref": "country/BWA", - "label": "Botswana" - }, - { - "ref": "country/CAF", - "label": "Central African Republic" - }, - { - "ref": "country/CIV", - "label": "Ivory Coast" - }, - { - "ref": "country/CMR", - "label": "Cameroon" - }, - { - "ref": "country/COD", - "label": "Democratic Republic of the Congo" - }, - { - "ref": "country/COG", - "label": "Republic of the Congo" - }, - { - "ref": "country/COM", - "label": "Comoros" - }, - { - "ref": "country/CPV", - "label": "Cape Verde" - }, - { - "ref": "country/DJI", - "label": "Djibouti" - }, - { - "ref": "country/ERI", - "label": "Eritrea" - }, - { - "ref": "country/ETH", - "label": "Ethiopia" - }, - { - "ref": "country/GAB", - "label": "Gabon" - }, - { - "ref": "country/GHA", - "label": "Ghana" - }, - { - "ref": "country/GIN", - "label": "Guinea" - }, - { - "ref": "country/GMB", - "label": "The Gambia" - }, - { - "ref": "country/GNB", - "label": "Guinea-Bissau" - }, - { - "ref": "country/GNQ", - "label": "Equatorial Guinea" - }, - { - "ref": "country/KEN", - "label": "Kenya" - }, - { - "ref": "country/LBR", - "label": "Liberia" - }, - { - "ref": "country/LSO", - "label": "Lesotho" - }, - { - "ref": "country/MDG", - "label": "Madagascar" - }, - { - "ref": "country/MLI", - "label": "Mali" - }, - { - "ref": "country/MOZ", - "label": "Mozambique" - }, - { - "ref": "country/MRT", - "label": "Mauritania" - }, - { - "ref": "country/MUS", - "label": "Mauritius" - }, - { - "ref": "country/MWI", - "label": "Malawi" - }, - { - "ref": "country/NAM", - "label": "Namibia" - }, - { - "ref": "country/NER", - "label": "Niger" - }, - { - "ref": "country/NGA", - "label": "Nigeria" - }, - { - "ref": "country/RWA", - "label": "Rwanda" - }, - { - "ref": "country/SEN", - "label": "Senegal" - }, - { - "ref": "country/SLE", - "label": "Sierra Leone" - }, - { - "ref": "country/SOM", - "label": "Somalia" - }, - { - "ref": "country/SSD", - "label": "South Sudan" - }, - { - "ref": "country/STP", - "label": "São Tomé and Príncipe" - }, - { - "ref": "country/SWZ", - "label": "Swaziland" - }, - { - "ref": "country/SYC", - "label": "Seychelles" - }, - { - "ref": "country/TCD", - "label": "Chad" - }, - { - "ref": "country/TGO", - "label": "Togo" - }, - { - "ref": "country/TZA", - "label": "Tanzania" - }, - { - "ref": "country/UGA", - "label": "Uganda" - }, - { - "ref": "country/ZAF", - "label": "South Africa" - }, - { - "ref": "country/ZMB", - "label": "Zambia" - }, - { - "ref": "country/ZWE", - "label": "Zimbabwe" - } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "when", - "label": "time window" - }, - "binding_kind": "value", - "refs": [], - "provenance": "binder" - }, - { - "key": { - "axis": "source", - "label": "data source" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - } - ], - "query_qualifiers": [ - { - "text": "ODA", - "named": [ - { - "ref": "DAC2aAidType206", - "label": "official development assistance" - } - ], - "slot": "dac2aAidType", - "disposition": "bound", - "selected": [] - } - ], - "requested_window": { - "start_year": 2015, - "end_year": 2022 - }, - "capability_version": "cap_347a470e04c97eec", - "default_reading": { - "applied": true, - "removed_stat_vars": [] - } - }, - "confidence": "high", - "available_at_place": true, - "alternative_measures": [ - { - "definition": { - "schema_version": 1, - "spec_id": "spec_f936496b58a844fc044d98a4255f48f2", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "FinancialFlow", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" - }, - "slots": [ - { - "property": "dac2aAidType", - "binding": { - "state": "value", - "ref": "DAC2aAidType206" - } - }, - { - "property": "dacTypeOfFinance", - "binding": { - "state": "unbound" - } - }, - { - "property": "financialFlowType", - "binding": { - "state": "value", - "ref": "Disbursement" - } - }, - { - "property": "nettingBasis", - "binding": { - "state": "value", - "ref": "Net" - } - } - ], - "entities": { - "destination": [ - "country/AGO", - "country/BDI", - "country/BEN", - "country/BFA", - "country/BWA", - "country/CAF", - "country/CIV", - "country/CMR", - "country/COD", - "country/COG", - "country/COM", - "country/CPV", - "country/DJI", - "country/ERI", - "country/ETH", - "country/GAB", - "country/GHA", - "country/GIN", - "country/GMB", - "country/GNB", - "country/GNQ", - "country/KEN", - "country/LBR", - "country/LSO", - "country/MDG", - "country/MLI", - "country/MOZ", - "country/MRT", - "country/MUS", - "country/MWI", - "country/NAM", - "country/NER", - "country/NGA", - "country/RWA", - "country/SEN", - "country/SLE", - "country/SOM", - "country/SSD", - "country/STP", - "country/SWZ", - "country/SYC", - "country/TCD", - "country/TGO", - "country/TZA", - "country/UGA", - "country/ZAF", - "country/ZMB", - "country/ZWE" - ], - "origin": [ - "country/DEU" - ] - }, - "requested_window": { - "kind": "range", - "start_year": 2015, - "end_year": 2022 - } - } - }, - "label": "net disbursements", - "axis": "what", - "measure_axis_values": [ - { - "axis": "populationType", - "value": { - "ref": "FinancialFlow", - "label": "financial flow" - } - }, - { - "axis": "measuredProperty", - "value": { - "ref": "amount", - "label": "amount" - } - }, - { - "axis": "measurementQualifier", - "value": { - "ref": "Nominal", - "label": "nominal" - } - }, - { - "axis": "financialFlowType", - "value": { - "ref": "Disbursement", - "label": "disbursement" - } - }, - { - "axis": "nettingBasis", - "value": { - "ref": "Net", - "label": "net" - } - } - ], - "served_rows": 372, - "served_rows_exact": true - } - ], - "measure_label": "gross disbursements", - "measure_label_axes": [ - "populationType", - "measuredProperty", - "measurementQualifier", - "financialFlowType", - "nettingBasis" - ], - "measure_axis_values": [ - { - "axis": "populationType", - "value": { - "ref": "FinancialFlow", - "label": "financial flow" - } - }, - { - "axis": "measuredProperty", - "value": { - "ref": "amount", - "label": "amount" - } - }, - { - "axis": "measurementQualifier", - "value": { - "ref": "Nominal", - "label": "nominal" - } - }, - { - "axis": "financialFlowType", - "value": { - "ref": "Disbursement", - "label": "disbursement" - } - }, - { - "axis": "nettingBasis", - "value": { - "ref": "Gross", - "label": "gross" - } - } - ], - "unit_conversion": { - "currencies": [ - { - "code": "AED", - "noun": "UAE dirhams", - "current_years": { - "start_year": 2015, - "end_year": 2021 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2023, - "base_year_max": 2023 - }, - { - "code": "AFN", - "noun": "Afghan afghanis", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2002, - "base_year_max": 2025 - }, - { - "code": "ALL", - "noun": "Albanian leks", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "AMD", - "noun": "Armenian drams", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1992, - "base_year_max": 2025 - }, - { - "code": "AOA", - "noun": "Angolan kwanzas", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1991, - "base_year_max": 2025 - }, - { - "code": "ARS", - "noun": "Argentine pesos", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "AUD", - "noun": "Australian dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1960, - "base_year_max": 2025 - }, - { - "code": "AWG", - "noun": "Aruban florins", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1995, - "base_year_max": 2025 - }, - { - "code": "AZN", - "noun": "Azerbaijani manats", - "current_years": { - "start_year": 2015, - "end_year": 2019 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2023, - "base_year_max": 2023 - }, - { - "code": "BAM", - "noun": "Bosnia-Herzegovina convertible marks", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1996, - "base_year_max": 2025 - }, - { - "code": "BBD", - "noun": "Barbadian dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "BDT", - "noun": "Bangladeshi taka", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "BHD", - "noun": "Bahraini dinars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "BIF", - "noun": "Burundian francs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "BND", - "noun": "Brunei dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1985, - "base_year_max": 2025 - }, - { - "code": "BOB", - "noun": "Bolivian bolivianos", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "BRL", - "noun": "Brazilian reais", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1986, - "base_year_max": 2025 - }, - { - "code": "BSD", - "noun": "Bahamian dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "BTN", - "noun": "Bhutanese ngultrums", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "BWP", - "noun": "Botswana pula", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "BYN", - "noun": "Belarusian rubles", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1992, - "base_year_max": 2025 - }, - { - "code": "BZD", - "noun": "Belize dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "CAD", - "noun": "Canadian dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1960, - "base_year_max": 2025 - }, - { - "code": "CDF", - "noun": "Congolese francs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1991, - "base_year_max": 2025 - }, - { - "code": "CHF", - "noun": "Swiss francs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1960, - "base_year_max": 2025 - }, - { - "code": "CLP", - "noun": "Chilean pesos", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "CNY", - "noun": "Chinese yuan", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "COP", - "noun": "Colombian pesos", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "CRC", - "noun": "Costa Rican colones", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "CVE", - "noun": "Cape Verdean escudos", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "CZK", - "noun": "Czech korunas", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1998, - "base_year_max": 2025 - }, - { - "code": "DJF", - "noun": "Djiboutian francs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1990, - "base_year_max": 2025 - }, - { - "code": "DKK", - "noun": "Danish kroner", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1960, - "base_year_max": 2025 - }, - { - "code": "DOP", - "noun": "Dominican pesos", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "DZD", - "noun": "Algerian dinars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "EGP", - "noun": "Egyptian pounds", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "ERN", - "noun": "Eritrean nakfas", - "current_years": { - "start_year": 2015, - "end_year": 2019 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1992, - "base_year_max": 2019 - }, - { - "code": "ETB", - "noun": "Ethiopian birr", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "EUR", - "noun": "euros", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1973, - "base_year_max": 2025 - }, - { - "code": "FJD", - "noun": "Fijian dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "GBP", - "noun": "British pounds", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1960, - "base_year_max": 2025 - }, - { - "code": "GEL", - "noun": "Georgian lari", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1994, - "base_year_max": 2025 - }, - { - "code": "GHS", - "noun": "Ghanaian cedis", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "GMD", - "noun": "Gambian dalasis", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "GNF", - "noun": "Guinean francs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "GTQ", - "noun": "Guatemalan quetzales", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "GYD", - "noun": "Guyanese dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "HKD", - "noun": "Hong Kong dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "HNL", - "noun": "Honduran lempiras", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "HTG", - "noun": "Haitian gourdes", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "HUF", - "noun": "Hungarian forints", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2003, - "base_year_max": 2025 - }, - { - "code": "IDR", - "noun": "Indonesian rupiahs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "ILS", - "noun": "Israeli new shekels", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1997, - "base_year_max": 2025 - }, - { - "code": "INR", - "noun": "Indian rupees", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "IQD", - "noun": "Iraqi dinars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2000, - "base_year_max": 2025 - }, - { - "code": "IRR", - "noun": "Iranian rials", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "ISK", - "noun": "Icelandic krónur", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1997, - "base_year_max": 2025 - }, - { - "code": "JMD", - "noun": "Jamaican dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "JOD", - "noun": "Jordanian dinars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "JPY", - "noun": "Japanese yen", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1960, - "base_year_max": 2025 - }, - { - "code": "KES", - "noun": "Kenyan shillings", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "KGS", - "noun": "Kyrgyz soms", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1992, - "base_year_max": 2025 - }, - { - "code": "KHR", - "noun": "Cambodian riels", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1986, - "base_year_max": 2025 - }, - { - "code": "KMF", - "noun": "Comorian francs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "KRW", - "noun": "South Korean won", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1987, - "base_year_max": 2025 - }, - { - "code": "KWD", - "noun": "Kuwaiti dinars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1995, - "base_year_max": 2024 - }, - { - "code": "KZT", - "noun": "Kazakh tenge", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2013, - "base_year_max": 2024 - }, - { - "code": "LAK", - "noun": "Lao kip", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "LBP", - "noun": "Lebanese pounds", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "LKR", - "noun": "Sri Lankan rupees", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2024 - }, - { - "code": "LSL", - "noun": "Lesotho maloti", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "LYD", - "noun": "Libyan dinars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MAD", - "noun": "Moroccan dirhams", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MDL", - "noun": "Moldovan lei", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1992, - "base_year_max": 2025 - }, - { - "code": "MGA", - "noun": "Malagasy ariary", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MKD", - "noun": "Macedonian denars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1992, - "base_year_max": 2025 - }, - { - "code": "MMK", - "noun": "Myanmar kyats", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1998, - "base_year_max": 2025 - }, - { - "code": "MNT", - "noun": "Mongolian tugriks", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MOP", - "noun": "Macanese patacas", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2001, - "base_year_max": 2025 - }, - { - "code": "MRU", - "noun": "Mauritanian ouguiyas", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1990, - "base_year_max": 2025 - }, - { - "code": "MUR", - "noun": "Mauritian rupees", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MVR", - "noun": "Maldivian rufiyaa", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MWK", - "noun": "Malawian kwachas", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MXN", - "noun": "Mexican pesos", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MYR", - "noun": "Malaysian ringgits", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MZN", - "noun": "Mozambican meticais", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "NAD", - "noun": "Namibian dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1989, - "base_year_max": 2025 - }, - { - "code": "NGN", - "noun": "Nigerian naira", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1990, - "base_year_max": 2025 - }, - { - "code": "NIO", - "noun": "Nicaraguan córdobas", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1987, - "base_year_max": 2025 - }, - { - "code": "NOK", - "noun": "Norwegian kroner", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1960, - "base_year_max": 2025 - }, - { - "code": "NPR", - "noun": "Nepalese rupees", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "NZD", - "noun": "New Zealand dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1961, - "base_year_max": 2025 - }, - { - "code": "OMR", - "noun": "Omani rials", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "PEN", - "noun": "Peruvian soles", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "PGK", - "noun": "Papua New Guinean kina", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "PHP", - "noun": "Philippine pesos", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "PKR", - "noun": "Pakistani rupees", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "PLN", - "noun": "Polish zlotys", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1998, - "base_year_max": 2025 - }, - { - "code": "PYG", - "noun": "Paraguayan guaranís", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "QAR", - "noun": "Qatari riyals", - "current_years": { - "start_year": 2020, - "end_year": 2020 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2023, - "base_year_max": 2023 - }, - { - "code": "RON", - "noun": "Romanian lei", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2013, - "base_year_max": 2025 - }, - { - "code": "RSD", - "noun": "Serbian dinars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1997, - "base_year_max": 2025 - }, - { - "code": "RUB", - "noun": "Russian rubles", - "current_years": { - "start_year": 2015, - "end_year": 2020 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2010, - "base_year_max": 2020 - }, - { - "code": "RWF", - "noun": "Rwandan francs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "SAR", - "noun": "Saudi riyals", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2000, - "base_year_max": 2023 - }, - { - "code": "SBD", - "noun": "Solomon Islands dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "SCR", - "noun": "Seychellois rupees", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "SDG", - "noun": "Sudanese pounds", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "SEK", - "noun": "Swedish kronor", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1960, - "base_year_max": 2025 - }, - { - "code": "SGD", - "noun": "Singapore dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "SLE", - "noun": "Sierra Leonean leones", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "SRD", - "noun": "Surinamese dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "SSP", - "noun": "South Sudanese pounds", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2011, - "base_year_max": 2025 - }, - { - "code": "STN", - "noun": "São Tomé and Príncipe dobras", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "SYP", - "noun": "Syrian pounds", - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2010, - "current_years": null - }, - { - "code": "SZL", - "noun": "Swazi emalangeni", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "THB", - "noun": "Thai baht", - "current_years": { - "start_year": 2018, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2018, - "base_year_max": 2024 - }, - { - "code": "TJS", - "noun": "Tajikistani somonis", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1992, - "base_year_max": 2025 - }, - { - "code": "TMT", - "noun": "Turkmenistani manat", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1992, - "base_year_max": 2025 - }, - { - "code": "TND", - "noun": "Tunisian dinars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "TOP", - "noun": "Tongan paʻanga", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "TRY", - "noun": "Turkish lira", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1990, - "base_year_max": 2025 - }, - { - "code": "TTD", - "noun": "Trinidad and Tobago dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "TWD", - "noun": "New Taiwan dollars", - "current_years": { - "start_year": 2018, - "end_year": 2021 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2023, - "base_year_max": 2025 - }, - { - "code": "TZS", - "noun": "Tanzanian shillings", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "UAH", - "noun": "Ukrainian hryvnias", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1991, - "base_year_max": 2025 - }, - { - "code": "UGX", - "noun": "Ugandan shillings", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "USD", - "noun": "US dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1960, - "base_year_max": 2025 - }, - { - "code": "UYU", - "noun": "Uruguayan pesos", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "UZS", - "noun": "Uzbekistani soms", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1992, - "base_year_max": 2025 - }, - { - "code": "VES", - "noun": "Venezuelan bolívares", - "current_years": { - "start_year": 2017, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2017, - "base_year_max": 2025 - }, - { - "code": "VND", - "noun": "Vietnamese dong", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "VUV", - "noun": "Vanuatu vatu", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "WST", - "noun": "Samoan tala", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "XAF", - "noun": "Central African CFA francs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "XCD", - "noun": "East Caribbean dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "XOF", - "noun": "West African CFA francs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "YER", - "noun": "Yemeni rials", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2014, - "base_year_max": 2025 - }, - { - "code": "ZAR", - "noun": "South African rand", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "ZMW", - "noun": "Zambian kwachas", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - } - ], - "default_base_year": 2024, - "role_currencies": { - "origin": "EUR" - } - } - } - } - } - ], - "rendered_sentence": "Answered 1 of 2 parts. GNI has 3 readings. Primary income for gross of fixed capital consumption in 49 places. World Bank International Debt Statistics (IDS) · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in 49 places. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in 49 places. World Development Indicators · 2015 to 2022. You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself. Germany's gross disbursements to the 48 countries in Sub-Saharan Africa for official development assistance, 2015 to 2022. Current US dollars · OECD DAC2a. You asked for sub-Saharan Africa. This shows the countries in it, each on its own.", - "sentence_plan": [ - { - "kind": "text", - "text": "Answered 1 of 2 parts.", - "segment": "coverage", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "coverage", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "GNI", - "axis": "what", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " has 3 readings.", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "Primary income", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " for ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "gross of fixed capital consumption", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " in ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "49 places", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "World Bank International Debt Statistics (IDS)", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "2015 to 2022", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "Current US dollars", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "Gross national income based on purchasing power parity", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "in international dollars", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " in ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "49 places", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "World Development Indicators", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "2015 to 2022", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "Gross national income based on purchasing power parity per capita", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "in international dollars", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " in ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "49 places", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "World Development Indicators", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "2015 to 2022", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "departure", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself.", - "segment": "departure", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "Germany", - "segment": "heading", - "role": "origin", - "binding_ref": "origin:", - "entity_refs": [ - "country/DEU" - ], - "states": [ - "origin:" - ], - "part_index": 1 - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 1 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 1 - }, - { - "kind": "slot", - "text": "gross disbursements", - "axis": "what", - "segment": "heading", - "entity_refs": [], - "states": [ - "how:financialFlowType", - "how:nettingBasis", - "axis:populationType", - "axis:measuredProperty" - ], - "part_index": 1 - }, - { - "kind": "text", - "text": " to ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 1 - }, - { - "kind": "slot", - "text": "the 48 countries in Sub-Saharan Africa", - "axis": "where", - "segment": "heading", - "role": "destination", - "binding_ref": "where:", - "entity_refs": [ - "country/AGO", - "country/BDI", - "country/BEN", - "country/BFA", - "country/BWA", - "country/CAF", - "country/CIV", - "country/CMR", - "country/COD", - "country/COG", - "country/COM", - "country/CPV", - "country/DJI", - "country/ERI", - "country/ETH", - "country/GAB", - "country/GHA", - "country/GIN", - "country/GMB", - "country/GNB", - "country/GNQ", - "country/KEN", - "country/LBR", - "country/LSO", - "country/MDG", - "country/MLI", - "country/MOZ", - "country/MRT", - "country/MUS", - "country/MWI", - "country/NAM", - "country/NER", - "country/NGA", - "country/RWA", - "country/SEN", - "country/SLE", - "country/SOM", - "country/SSD", - "country/STP", - "country/SWZ", - "country/SYC", - "country/TCD", - "country/TGO", - "country/TZA", - "country/UGA", - "country/ZAF", - "country/ZMB", - "country/ZWE" - ], - "states": [ - "where:" - ], - "part_index": 1 - }, - { - "kind": "text", - "text": " for ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 1 - }, - { - "kind": "slot", - "text": "official development assistance", - "axis": "how", - "segment": "heading", - "property_dcid": "dac2aAidType", - "binding_ref": "how:dac2aAidType", - "entity_refs": [], - "states": [ - "how:dac2aAidType" - ], - "part_index": 1 - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "dacTypeOfFinance", - "binding_ref": "how:dacTypeOfFinance", - "entity_refs": [], - "states": [], - "part_index": 1 - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "financialFlowType", - "binding_ref": "how:financialFlowType", - "entity_refs": [], - "states": [], - "part_index": 1 - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "nettingBasis", - "binding_ref": "how:nettingBasis", - "entity_refs": [], - "states": [], - "part_index": 1 - }, - { - "kind": "text", - "text": ", ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 1 - }, - { - "kind": "slot", - "text": "2015 to 2022", - "axis": "when", - "segment": "heading", - "binding_ref": "when:", - "entity_refs": [], - "states": [ - "when:" - ], - "part_index": 1 - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 1 - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 1 - }, - { - "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ], - "part_index": 1 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 1 - }, - { - "kind": "slot", - "text": "OECD DAC2a", - "axis": "source", - "segment": "byline", - "entity_refs": [], - "states": [ - "source:" - ], - "part_index": 1 - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 1 - }, - { - "kind": "text", - "text": " ", - "segment": "departure", - "entity_refs": [], - "states": [], - "part_index": 1 - }, - { - "kind": "text", - "text": "You asked for sub-Saharan Africa. This shows the countries in it, each on its own.", - "segment": "departure", - "entity_refs": [], - "states": [], - "part_index": 1 - } - ], - "status": "mixed" - } - } - }, - { - "request": { - "method": "POST", - "path": "/search/resolve", - "json": { - "schema_version": 1, - "input": { - "kind": "dataset_resubmit", - "entries": [ - { - "entry_kind": "identity", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", - "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" - }, - "slots": [ - { - "property": "fixedCapitalConsumptionBasis", - "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" - } - } - ], - "entities": { - "observationAbout": [ - "country/AGO", - "country/BDI", - "country/BEN", - "country/BFA", - "country/BWA", - "country/CAF", - "country/CIV", - "country/CMR", - "country/COD", - "country/COG", - "country/COM", - "country/CPV", - "country/DEU", - "country/DJI", - "country/ERI", - "country/ETH", - "country/GAB", - "country/GHA", - "country/GIN", - "country/GMB", - "country/GNB", - "country/GNQ", - "country/KEN", - "country/LBR", - "country/LSO", - "country/MDG", - "country/MLI", - "country/MOZ", - "country/MRT", - "country/MUS", - "country/MWI", - "country/NAM", - "country/NER", - "country/NGA", - "country/RWA", - "country/SEN", - "country/SLE", - "country/SOM", - "country/SSD", - "country/STP", - "country/SWZ", - "country/SYC", - "country/TCD", - "country/TGO", - "country/TZA", - "country/UGA", - "country/ZAF", - "country/ZMB", - "country/ZWE" - ] - }, - "requested_window": { - "kind": "range", - "start_year": 2015, - "end_year": 2022 - } - }, - "assumptions": [], - "variable_text": "GNI" - }, - { - "entry_kind": "identity", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "FinancialFlow", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" - }, - "slots": [ - { - "property": "dac2aAidType", - "binding": { - "state": "value", - "ref": "DAC2aAidType206" - } - }, - { - "property": "dacTypeOfFinance", - "binding": { - "state": "unbound" - } - }, - { - "property": "financialFlowType", - "binding": { - "state": "value", - "ref": "Disbursement" - } - }, - { - "property": "nettingBasis", - "binding": { - "state": "value", - "ref": "Gross" - } - } - ], - "entities": { - "destination": [ - "country/AGO", - "country/BDI", - "country/BEN", - "country/BFA", - "country/BWA", - "country/CAF", - "country/CIV", - "country/CMR", - "country/COD", - "country/COG", - "country/COM", - "country/CPV", - "country/DJI", - "country/ERI", - "country/ETH", - "country/GAB", - "country/GHA", - "country/GIN", - "country/GMB", - "country/GNB", - "country/GNQ", - "country/KEN", - "country/LBR", - "country/LSO", - "country/MDG", - "country/MLI", - "country/MOZ", - "country/MRT", - "country/MUS", - "country/MWI", - "country/NAM", - "country/NER", - "country/NGA", - "country/RWA", - "country/SEN", - "country/SLE", - "country/SOM", - "country/SSD", - "country/STP", - "country/SWZ", - "country/SYC", - "country/TCD", - "country/TGO", - "country/TZA", - "country/UGA", - "country/ZAF", - "country/ZMB", - "country/ZWE" - ], - "origin": [ - "country/DEU" - ] - }, - "requested_window": { - "kind": "range", - "start_year": 2015, - "end_year": 2022 - } - }, - "entity_groups": { - "destination": { - "ref": "SubSaharanAfrica", - "label": "Sub-Saharan Africa", - "entity_type": "UNGeoRegion" - } - }, - "assumptions": [], - "variable_text": "ODA disbursements" - } - ] - } - } - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "x-dfo-trace-id": "ab49f41a7e8a4bd3a52698f3b699ebfa" - }, - "json": { - "schema_version": 1, - "query_echo": { - "entry_path": "dataset_resubmit", - "extract_skipped": true - }, - "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "ab49f41a7e8a4bd3a52698f3b699ebfa", - "warnings": [], - "timing_ms": { - "total": 1163, - "by_step": { - "coverage": 0 - } - }, - "timed_out": false - }, - "kind": "resolution", - "parts": [ - { - "variable_text": "GNI", - "warnings": [], - "timing_ms": { - "total": 8, - "by_step": { - "validate": 0, - "walk": 0, - "reread_arcs": 0, - "detect_edits": 0, - "resolve_survivors": 0, - "shape": 0, - "bind": 0, - "where_places": 0, - "materialise": 4, - "answer": 3, - "options": 1 - } - }, - "operations": [], - "departures": [ - { - "code": "entity_unavailable", - "binding_ref": "where:", - "text": "You asked for Germany, Eritrea, Namibia, South Sudan, and Seychelles. The data holds no values for them." - } - ], - "assumptions": [], - "status": "definite", - "spec": { - "spec_id": "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", - "definition": { - "schema_version": 1, - "spec_id": "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", - "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" - }, - "slots": [ - { - "property": "fixedCapitalConsumptionBasis", - "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" - } - } - ], - "entities": { - "observationAbout": [ - "country/AGO", - "country/BDI", - "country/BEN", - "country/BFA", - "country/BWA", - "country/CAF", - "country/CIV", - "country/CMR", - "country/COD", - "country/COG", - "country/COM", - "country/CPV", - "country/DEU", - "country/DJI", - "country/ERI", - "country/ETH", - "country/GAB", - "country/GHA", - "country/GIN", - "country/GMB", - "country/GNB", - "country/GNQ", - "country/KEN", - "country/LBR", - "country/LSO", - "country/MDG", - "country/MLI", - "country/MOZ", - "country/MRT", - "country/MUS", - "country/MWI", - "country/NAM", - "country/NER", - "country/NGA", - "country/RWA", - "country/SEN", - "country/SLE", - "country/SOM", - "country/SSD", - "country/STP", - "country/SWZ", - "country/SYC", - "country/TCD", - "country/TGO", - "country/TZA", - "country/UGA", - "country/ZAF", - "country/ZMB", - "country/ZWE" - ] - }, - "requested_window": { - "kind": "range", - "start_year": 2015, - "end_year": 2022 - } - } - }, - "resolved": { - "shape": { - "shape_id": "economicunit_primaryincome_measuredvalue_nominal", - "label": "Gross national income", - "population_type": { - "ref": "EconomicUnit", - "label": "economic unit" - }, - "measured_property": { - "ref": "primaryIncome", - "label": "primary income" - }, - "stat_type": { - "ref": "measuredValue", - "label": "measuredValue" - }, - "measurement_qualifier": { - "ref": "Nominal", - "label": "Nominal" - }, - "measurement_denominator_unresolved": false, - "slot_keys": [ - { - "axis": "how", - "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" - }, - "label": "fixed capital consumption basis" - }, - { - "axis": "where", - "label": "place" - }, - { - "axis": "when", - "label": "time window" - }, - { - "axis": "source", - "label": "data source" - } - ], - "member_count": 1, - "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", - "refine_supported": true, - "data_commons": [ - { - "id": "dfo", - "label": "Development Finance Observatory" - } - ] - }, - "slots": [ - { - "key": { - "axis": "how", - "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" - }, - "label": "fixed capital consumption basis" - }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - }, - "value_kind": "enum_value" - } - }, - "summable": false - }, - { - "key": { - "axis": "where", - "label": "place" - }, - "binding": { - "kind": "set", - "values": [ - { - "ref": { - "ref": "country/AGO", - "label": "Angola" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/BDI", - "label": "Burundi" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/BEN", - "label": "Benin" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/BFA", - "label": "Burkina Faso" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/BWA", - "label": "Botswana" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/CAF", - "label": "Central African Republic" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/CIV", - "label": "Ivory Coast" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/CMR", - "label": "Cameroon" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/COD", - "label": "Democratic Republic of the Congo" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/COG", - "label": "Republic of the Congo" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/COM", - "label": "Comoros" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/CPV", - "label": "Cape Verde" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/DJI", - "label": "Djibouti" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/ERI", - "label": "Eritrea" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/ETH", - "label": "Ethiopia" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/GAB", - "label": "Gabon" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/GHA", - "label": "Ghana" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/GIN", - "label": "Guinea" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/GMB", - "label": "The Gambia" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/GNB", - "label": "Guinea-Bissau" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/GNQ", - "label": "Equatorial Guinea" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/KEN", - "label": "Kenya" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/LBR", - "label": "Liberia" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/LSO", - "label": "Lesotho" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/MDG", - "label": "Madagascar" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/MLI", - "label": "Mali" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/MOZ", - "label": "Mozambique" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/MRT", - "label": "Mauritania" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/MUS", - "label": "Mauritius" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/MWI", - "label": "Malawi" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/NAM", - "label": "Namibia" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/NER", - "label": "Niger" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/NGA", - "label": "Nigeria" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/RWA", - "label": "Rwanda" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/SEN", - "label": "Senegal" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/SLE", - "label": "Sierra Leone" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/SOM", - "label": "Somalia" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/SSD", - "label": "South Sudan" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/STP", - "label": "São Tomé and Príncipe" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/SWZ", - "label": "Swaziland" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/SYC", - "label": "Seychelles" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/TCD", - "label": "Chad" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/TGO", - "label": "Togo" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/TZA", - "label": "Tanzania" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/UGA", - "label": "Uganda" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/ZAF", - "label": "South Africa" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/ZMB", - "label": "Zambia" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/ZWE", - "label": "Zimbabwe" - }, - "value_kind": "entity" - } - ] - }, - "summable": false - }, - { - "key": { - "axis": "when", - "label": "time window" - }, - "binding": { - "kind": "value", - "value": { - "value_kind": "time_window", - "time_window": { - "start_year": 2015, - "end_year": 2022 - } - } - }, - "summable": false - }, - { - "key": { - "axis": "source", - "label": "data source" - }, - "binding": { - "kind": "unbound" - }, - "summable": false - } - ], - "inapplicable_slots": [], - "unresolved_slots": [], - "stat_vars": { - "member_count": 1, - "member_count_exact": true, - "served_count": 1, - "data_date_range": { - "start": "2015", - "end": "2022" - } - }, - "entities": [ - { - "ref": "country/AGO", - "label": "Angola", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/BDI", - "label": "Burundi", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/BEN", - "label": "Benin", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/BFA", - "label": "Burkina Faso", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/BWA", - "label": "Botswana", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/CAF", - "label": "Central African Republic", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/CIV", - "label": "Ivory Coast", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/CMR", - "label": "Cameroon", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/COD", - "label": "Democratic Republic of the Congo", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/COG", - "label": "Republic of the Congo", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/COM", - "label": "Comoros", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/CPV", - "label": "Cape Verde", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/DJI", - "label": "Djibouti", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/ERI", - "label": "Eritrea", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/ETH", - "label": "Ethiopia", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/GAB", - "label": "Gabon", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/GHA", - "label": "Ghana", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/GIN", - "label": "Guinea", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/GMB", - "label": "The Gambia", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/GNB", - "label": "Guinea-Bissau", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/GNQ", - "label": "Equatorial Guinea", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/KEN", - "label": "Kenya", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/LBR", - "label": "Liberia", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/LSO", - "label": "Lesotho", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/MDG", - "label": "Madagascar", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/MLI", - "label": "Mali", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/MOZ", - "label": "Mozambique", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/MRT", - "label": "Mauritania", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/MUS", - "label": "Mauritius", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/MWI", - "label": "Malawi", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/NAM", - "label": "Namibia", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/NER", - "label": "Niger", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/NGA", - "label": "Nigeria", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/RWA", - "label": "Rwanda", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/SEN", - "label": "Senegal", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/SLE", - "label": "Sierra Leone", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/SOM", - "label": "Somalia", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/SSD", - "label": "South Sudan", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/STP", - "label": "São Tomé and Príncipe", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/SWZ", - "label": "Swaziland", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/SYC", - "label": "Seychelles", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/TCD", - "label": "Chad", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/TGO", - "label": "Togo", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/TZA", - "label": "Tanzania", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/UGA", - "label": "Uganda", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/ZAF", - "label": "South Africa", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/ZMB", - "label": "Zambia", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/ZWE", - "label": "Zimbabwe", - "entity_type": "Country", - "role": "observationAbout" - } - ], - "coverage": { - "kind": "exact", - "has_data": true, - "observation_count": 348, - "evidence": "facet_metadata", - "dimensions": [ - { - "label": "countries", - "count": 44 - }, - { - "label": "observations", - "count": 8 - }, - { - "label": "variables", - "count": 1 - } - ], - "window": { - "start_year": 2015, - "end_year": 2022 - } - }, - "download": { - "rows": 348, - "rows_exact": true, - "series": 44, - "window": { - "start_year": 2015, - "end_year": 2022 - }, - "licence": { - "label": "Creative Commons Attribution License" - } - }, - "facets": { - "provenance": { - "basis": "fallback", - "ref": "provenance/WorldBankInternationalDebtStatistics", - "label": "World Bank International Debt Statistics (IDS)", - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" - }, - "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" - }, - "unit": { - "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" - } - }, - "slot_options": [ - { - "key": { - "axis": "how", - "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" - }, - "label": "fixed capital consumption basis" - }, - "options": [ - { - "value": { - "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - }, - "value_kind": "enum_value" - } - } - ], - "truncated": true, - "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ - { - "axis": "provenance", - "options": [ - { - "value": { - "ref": { - "ref": "provenance/WorldBankInternationalDebtStatistics", - "label": "World Bank International Debt Statistics (IDS)" - }, - "value_kind": "source" - } - }, - { - "value": { - "ref": { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1" - }, - "value_kind": "source" - } - } - ], - "truncated": false, - "source": "observed" - }, - { - "axis": "unit", - "options": [ - { - "value": { - "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" - }, - "value_kind": "enum_value" - } - } - ], - "truncated": false, - "source": "observed" - } - ], - "rendered_sentence": "Primary income for gross of fixed capital consumption in 49 places, 2015 to 2022. Current US dollars · World Bank International Debt Statistics (IDS).", - "sentence_plan": [ - { - "kind": "slot", - "text": "Primary income", - "axis": "what", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " for ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "gross of fixed capital consumption", - "axis": "how", - "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", - "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ] - }, - { - "kind": "text", - "text": " in ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "49 places", - "axis": "where", - "segment": "heading", - "binding_ref": "where:", - "entity_refs": [], - "states": [ - "where:" - ] - }, - { - "kind": "text", - "text": ", ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "2015 to 2022", - "axis": "when", - "segment": "heading", - "binding_ref": "when:", - "entity_refs": [], - "states": [ - "when:" - ] - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "World Bank International Debt Statistics (IDS)", - "axis": "source", - "segment": "byline", - "entity_refs": [], - "states": [ - "source:" - ] - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [] - } - ], - "trace": { - "resolved_entities": [ - { - "ref": "country/AGO", - "label": "Angola" - }, - { - "ref": "country/BDI", - "label": "Burundi" - }, - { - "ref": "country/BEN", - "label": "Benin" - }, - { - "ref": "country/BFA", - "label": "Burkina Faso" - }, - { - "ref": "country/BWA", - "label": "Botswana" - }, - { - "ref": "country/CAF", - "label": "Central African Republic" - }, - { - "ref": "country/CIV", - "label": "Ivory Coast" - }, - { - "ref": "country/CMR", - "label": "Cameroon" - }, - { - "ref": "country/COD", - "label": "Democratic Republic of the Congo" - }, - { - "ref": "country/COG", - "label": "Republic of the Congo" - }, - { - "ref": "country/COM", - "label": "Comoros" - }, - { - "ref": "country/CPV", - "label": "Cape Verde" - }, - { - "ref": "country/DEU", - "label": "Germany" - }, - { - "ref": "country/DJI", - "label": "Djibouti" - }, - { - "ref": "country/ERI", - "label": "Eritrea" - }, - { - "ref": "country/ETH", - "label": "Ethiopia" - }, - { - "ref": "country/GAB", - "label": "Gabon" - }, - { - "ref": "country/GHA", - "label": "Ghana" - }, - { - "ref": "country/GIN", - "label": "Guinea" - }, - { - "ref": "country/GMB", - "label": "The Gambia" - }, - { - "ref": "country/GNB", - "label": "Guinea-Bissau" - }, - { - "ref": "country/GNQ", - "label": "Equatorial Guinea" - }, - { - "ref": "country/KEN", - "label": "Kenya" - }, - { - "ref": "country/LBR", - "label": "Liberia" - }, - { - "ref": "country/LSO", - "label": "Lesotho" - }, - { - "ref": "country/MDG", - "label": "Madagascar" - }, - { - "ref": "country/MLI", - "label": "Mali" - }, - { - "ref": "country/MOZ", - "label": "Mozambique" - }, - { - "ref": "country/MRT", - "label": "Mauritania" - }, - { - "ref": "country/MUS", - "label": "Mauritius" - }, - { - "ref": "country/MWI", - "label": "Malawi" - }, - { - "ref": "country/NAM", - "label": "Namibia" - }, - { - "ref": "country/NER", - "label": "Niger" + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2014, + "end_year": 2014 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "age", + "ageGroupClassification" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 5, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2014", + "end": "2014" + } }, - { - "ref": "country/NGA", - "label": "Nigeria" + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "entity_groups": { + "observationAbout": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } }, - { - "ref": "country/RWA", - "label": "Rwanda" + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 1, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 1 + }, + { + "label": "observations", + "count": 1 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2014, + "end_year": 2014 + } }, - { - "ref": "country/SEN", - "label": "Senegal" + "download": { + "rows": 1, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2014, + "end_year": 2014 + }, + "licence": { + "label": "PublicDomain" + } }, - { - "ref": "country/SLE", - "label": "Sierra Leone" + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/NigeriaStatistics", + "label": "Nigeria Statistics", + "source": { + "ref": "dc/s/OpenDataForAfrica", + "label": "Open Data for Africa" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/NigeriaStatistics" + } }, - { - "ref": "country/SOM", - "label": "Somalia" + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Years0To1", + "label": "Years 0 To 1" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Day0To27", + "label": "Day 0 To 27" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "YearsUpto5", + "label": "Years UpTo 5" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Infant", + "label": "Infant" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Newborn", + "label": "Newborn" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/NigeriaStatistics", + "label": "Nigeria Statistics" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Count of mortality event (as fraction of count birth event live birth) in the 48 countries in Sub-Saharan Africa in 2014. Nigeria Statistics.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Count of mortality event (as fraction of count birth event live birth)", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "distinguishes": true + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "age", + "binding_ref": "how:age", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "ageGroupClassification", + "binding_ref": "how:ageGroupClassification", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "in 2014", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Nigeria Statistics", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "distinguishes": true + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/NigeriaStatistics", + "label": "Nigeria Statistics", + "source": { + "ref": "dc/s/OpenDataForAfrica", + "label": "Open Data for Africa" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/NigeriaStatistics" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2013, + "end_year": 2022 + }, + "capability_version": "cap_94e25737d859392c", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } }, + "confidence": "low", + "basis": "structural", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "truncated": false + }, + "reading_assumptions": { + "spec_176fd5e63bb2a122c4ad00831497b863": [], + "spec_1ca4f4991f0c01309d33fed3fe0bae60": [], + "spec_66b488f4c8cd760c136a57ce16335332": [] + } + }, + { + "variable_text": "GDP", + "warnings": [], + "timing_ms": { + "total": 1889, + "by_step": { + "recall": 1, + "phase_resolve_places": 0, + "phase_check_entities": 0, + "shape_arcs": 4, + "shape_probe_coverage": 8, + "shape_probe": 10, + "shape_groups": 46, + "shape_labels": 10, + "shape_admission": 1, + "phase_derive_shapes": 0, + "shape": 327, + "phase_prune_and_rank": 0, + "bind": 843, + "phase_bind": 4, + "phase_settle": 16, + "phase_place_bindings": 7, + "phase_facet_requests": 0, + "materialise": 377, + "phase_materialise": 0, + "answer": 32, + "options": 146, + "phase_outcome": 136 + } + }, + "restatement": { + "variable_text": "GDP", + "entities": [ + { + "text": "Kenya" + }, + { + "text": "Sub-Saharan Africa" + } + ], + "time_text": "2013 to 2022", + "sources": [], + "operations": [] + }, + "operations": [], + "departures": [ + { + "code": "entity_unavailable", + "binding_ref": "where:", + "asked": "sub-Saharan Africa", + "text": "The data holds no values for 1 of the 48 countries in Sub-Saharan Africa." + }, + { + "code": "group_read_as_members", + "binding_ref": "where:", + "asked": "sub-Saharan Africa", + "text": "You asked for sub-Saharan Africa. This shows the countries in it, each on its own." + } + ], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_310c03c5f99c73c41d12226098714f81", + "definition": { + "schema_version": 1, + "spec_id": "spec_310c03c5f99c73c41d12226098714f81", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ { - "ref": "country/SSD", - "label": "South Sudan" + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } }, { - "ref": "country/STP", - "label": "São Tomé and Príncipe" + "property": "economicSector", + "binding": { + "state": "unbound" + } }, { - "ref": "country/SWZ", - "label": "Swaziland" + "property": "naics", + "binding": { + "state": "unbound" + } }, { - "ref": "country/SYC", - "label": "Seychelles" - }, + "property": "schoolGradeLevel", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2013, + "end_year": 2022 + }, + "facets": { + "unit": { + "state": "value", + "ref": "USDollar" + } + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_nominal", + "label": "Nominal gross domestic product", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ { - "ref": "country/TCD", - "label": "Chad" + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" }, { - "ref": "country/TGO", - "label": "Togo" + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" }, { - "ref": "country/TZA", - "label": "Tanzania" + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" }, { - "ref": "country/UGA", - "label": "Uganda" + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" }, { - "ref": "country/ZAF", - "label": "South Africa" + "axis": "where", + "label": "place" }, { - "ref": "country/ZMB", - "label": "Zambia" + "axis": "when", + "label": "time window" }, { - "ref": "country/ZWE", - "label": "Zimbabwe" + "axis": "source", + "label": "data source" } ], - "resolved_sources": [ + "member_count": 65, + "member_digest": "73519eeb75639bdae33042fc844830cd46becc08e4f9122dfcd0886e9875f657", + "refine_supported": true, + "data_commons": [ { - "ref": "provenance/WorldBankInternationalDebtStatistics", - "label": "World Bank International Debt Statistics (IDS)", - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" - }, - "documentation": "/api/graph/documentation/provenance/WorldBankInternationalDebtStatistics" + "id": "base", + "label": "Data Commons by Google" } - ], - "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" }, - "label": "fixed capital consumption basis" + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - } - ], - "provenance": "binder" + "label": "economic sector" }, - { - "key": { - "axis": "where", - "label": "place" + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" }, - "binding_kind": "set", - "refs": [ - { - "ref": "country/AGO", - "label": "Angola" - }, + "label": "naics" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ { - "ref": "country/BDI", - "label": "Burundi" + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" }, { - "ref": "country/BEN", - "label": "Benin" + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" }, { - "ref": "country/BFA", - "label": "Burkina Faso" + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" }, { - "ref": "country/BWA", - "label": "Botswana" + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" }, { - "ref": "country/CAF", - "label": "Central African Republic" + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" }, { - "ref": "country/CIV", - "label": "Ivory Coast" + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" }, { - "ref": "country/CMR", - "label": "Cameroon" + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" }, { - "ref": "country/COD", - "label": "Democratic Republic of the Congo" + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" }, { - "ref": "country/COG", - "label": "Republic of the Congo" + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" }, { - "ref": "country/COM", - "label": "Comoros" + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" }, { - "ref": "country/CPV", - "label": "Cape Verde" + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" }, { - "ref": "country/DEU", - "label": "Germany" + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" }, { - "ref": "country/DJI", - "label": "Djibouti" + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" }, { - "ref": "country/ERI", - "label": "Eritrea" + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" }, { - "ref": "country/ETH", - "label": "Ethiopia" + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" }, { - "ref": "country/GAB", - "label": "Gabon" + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" }, { - "ref": "country/GHA", - "label": "Ghana" + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" }, { - "ref": "country/GIN", - "label": "Guinea" + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" }, { - "ref": "country/GMB", - "label": "The Gambia" + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" }, - { - "ref": "country/GNB", - "label": "Guinea-Bissau" + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" }, { - "ref": "country/GNQ", - "label": "Equatorial Guinea" + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" }, { - "ref": "country/KEN", - "label": "Kenya" + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" }, { - "ref": "country/LBR", - "label": "Liberia" + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" }, { - "ref": "country/LSO", - "label": "Lesotho" + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" }, { - "ref": "country/MDG", - "label": "Madagascar" + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" }, { - "ref": "country/MLI", - "label": "Mali" + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" }, { - "ref": "country/MOZ", - "label": "Mozambique" + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" }, { - "ref": "country/MRT", - "label": "Mauritania" + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" }, { - "ref": "country/MUS", - "label": "Mauritius" + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" }, { - "ref": "country/MWI", - "label": "Malawi" + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" }, { - "ref": "country/NAM", - "label": "Namibia" + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" }, { - "ref": "country/NER", - "label": "Niger" + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" }, { - "ref": "country/NGA", - "label": "Nigeria" + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" }, { - "ref": "country/RWA", - "label": "Rwanda" + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" }, { - "ref": "country/SEN", - "label": "Senegal" + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" }, { - "ref": "country/SLE", - "label": "Sierra Leone" + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" }, { - "ref": "country/SOM", - "label": "Somalia" + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" }, { - "ref": "country/SSD", - "label": "South Sudan" + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" }, { - "ref": "country/STP", - "label": "São Tomé and Príncipe" + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" }, { - "ref": "country/SWZ", - "label": "Swaziland" + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" }, { - "ref": "country/SYC", - "label": "Seychelles" + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" }, { - "ref": "country/TCD", - "label": "Chad" + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" }, { - "ref": "country/TGO", - "label": "Togo" + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" }, { - "ref": "country/TZA", - "label": "Tanzania" + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" }, { - "ref": "country/UGA", - "label": "Uganda" + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" }, { - "ref": "country/ZAF", - "label": "South Africa" + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" }, { - "ref": "country/ZMB", - "label": "Zambia" + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" }, { - "ref": "country/ZWE", - "label": "Zimbabwe" + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" } - ], - "provenance": "binder" + ] }, - { - "key": { - "axis": "when", - "label": "time window" - }, - "binding_kind": "value", - "refs": [], - "provenance": "binder" + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" }, - { - "key": { - "axis": "source", - "label": "data source" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - } - ], - "query_qualifiers": [], - "requested_window": { - "start_year": 2015, - "end_year": 2022 + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2013, + "end_year": 2022 + } + } + }, + "summable": false }, - "capability_version": "cap_347a470e04c97eec" + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "economicSector", + "naics", + "schoolGradeLevel" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 41, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2013", + "end": "2022" + } }, - "confidence": "high", - "available_at_place": true, - "measure_label_axes": [], - "measure_axis_values": [], - "related_measures": [] - } - } - }, - { - "variable_text": "ODA disbursements", - "warnings": [], - "timing_ms": { - "total": 946, - "by_step": { - "validate": 0, - "walk": 5, - "reread_arcs": 0, - "detect_edits": 0, - "resolve_survivors": 0, - "shape": 922, - "bind": 0, - "where_places": 0, - "materialise": 11, - "answer": 7, - "options": 1 - } - }, - "operations": [], - "departures": [ - { - "code": "group_read_as_members", - "binding_ref": "where:", - "text": "This shows the 48 countries in Sub-Saharan Africa, each on its own." - } - ], - "assumptions": [], - "status": "definite", - "spec": { - "spec_id": "spec_941030940d23f46826acaa0c6fed8bbc", - "definition": { - "schema_version": 1, - "spec_id": "spec_941030940d23f46826acaa0c6fed8bbc", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "FinancialFlow", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "observationAbout" }, - "slots": [ - { - "property": "dac2aAidType", - "binding": { - "state": "value", - "ref": "DAC2aAidType206" - } - }, - { - "property": "dacTypeOfFinance", - "binding": { - "state": "unbound" - } - }, - { - "property": "financialFlowType", - "binding": { - "state": "value", - "ref": "Disbursement" - } - }, - { - "property": "nettingBasis", - "binding": { - "state": "value", - "ref": "Gross" - } - } - ], - "entities": { - "destination": [ - "country/AGO", - "country/BDI", - "country/BEN", - "country/BFA", - "country/BWA", - "country/CAF", - "country/CIV", - "country/CMR", - "country/COD", - "country/COG", - "country/COM", - "country/CPV", - "country/DJI", - "country/ERI", - "country/ETH", - "country/GAB", - "country/GHA", - "country/GIN", - "country/GMB", - "country/GNB", - "country/GNQ", - "country/KEN", - "country/LBR", - "country/LSO", - "country/MDG", - "country/MLI", - "country/MOZ", - "country/MRT", - "country/MUS", - "country/MWI", - "country/NAM", - "country/NER", - "country/NGA", - "country/RWA", - "country/SEN", - "country/SLE", - "country/SOM", - "country/SSD", - "country/STP", - "country/SWZ", - "country/SYC", - "country/TCD", - "country/TGO", - "country/TZA", - "country/UGA", - "country/ZAF", - "country/ZMB", - "country/ZWE" - ], - "origin": [ - "country/DEU" - ] + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "observationAbout" }, - "requested_window": { - "kind": "range", - "start_year": 2015, - "end_year": 2022 - } - } - }, - "resolved": { - "shape": { - "shape_id": "financialflow_amount_measuredvalue_nominal_family_f096b1ba", - "label": "gross disbursements (official development assistance)", - "population_type": { - "ref": "FinancialFlow", - "label": "financial flow" + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "observationAbout" }, - "measured_property": { - "ref": "amount", - "label": "amount" + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "observationAbout" }, - "stat_type": { - "ref": "measuredValue", - "label": "measuredValue" + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" }, - "measurement_qualifier": { - "ref": "Nominal", - "label": "Nominal" + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "observationAbout" }, - "measurement_denominator_unresolved": false, - "slot_keys": [ - { - "axis": "how", - "property": { - "ref": "dac2aAidType", - "label": "DAC 2a aid type" - }, - "label": "aid type" - }, - { - "axis": "how", - "property": { - "ref": "financialFlowType", - "label": "financial flow type" - }, - "label": "financial flow type" - }, - { - "axis": "how", - "property": { - "ref": "nettingBasis", - "label": "netting basis" - }, - "label": "netting basis" - }, - { - "axis": "how", - "property": { - "ref": "dacTypeOfFinance", - "label": "DAC type of finance" - }, - "label": "DAC type of finance" - }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "entity_groups": { + "observationAbout": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 463, + "evidence": "facet_metadata", + "dimensions": [ { - "axis": "where", - "label": "place" + "label": "countries", + "count": 47 }, { - "axis": "when", - "label": "time window" + "label": "observations", + "count": 10 }, { - "axis": "source", - "label": "data source" + "label": "variables", + "count": 1 } ], - "member_count": 1, - "member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", - "refine_supported": true, - "data_commons": [ - { - "id": "dfo", - "label": "Development Finance Observatory" - } - ] + "window": { + "start_year": 2013, + "end_year": 2022 + } }, - "slots": [ - { - "key": { - "axis": "how", - "property": { - "ref": "dac2aAidType", - "label": "DAC 2a aid type" - }, - "label": "aid type" - }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "DAC2aAidType206", - "label": "official development assistance" - }, - "value_kind": "enum_value" - } - }, - "summable": false + "download": { + "rows": 463, + "rows_exact": true, + "series": 47, + "window": { + "start_year": 2013, + "end_year": 2022 }, - { - "key": { - "axis": "how", - "property": { - "ref": "financialFlowType", - "label": "financial flow type" - }, - "label": "financial flow type" - }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "Disbursement", - "label": "disbursement" - }, - "value_kind": "enum_value" - } + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" }, - "summable": false + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" }, + "unit": { + "basis": "bound", + "ref": "USDollar", + "label": "USDollar", + "currency": "USD" + } + }, + "slot_options": [ { "key": { "axis": "how", "property": { - "ref": "nettingBasis", - "label": "netting basis" + "ref": "activitySource", + "label": "activitySource" }, - "label": "netting basis" + "label": "activity source" }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "Gross", - "label": "gross" - }, - "value_kind": "enum_value" + "options": [ + { + "value": { + "ref": { + "ref": "GrossValueAdded", + "label": "GrossValueAdded" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NetDomesticProduction", + "label": "Net Domestic Production" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NetValueAdded", + "label": "Net Value Added" + }, + "value_kind": "enum_value" + } } - }, - "summable": false + ], + "truncated": true, + "source": "observed" }, { "key": { "axis": "how", "property": { - "ref": "dacTypeOfFinance", - "label": "DAC type of finance" + "ref": "economicSector", + "label": "economicSector" }, - "label": "DAC type of finance" - }, - "binding": { - "kind": "unbound" - }, - "summable": false - }, - { - "key": { - "axis": "where", - "label": "place" + "label": "economic sector" }, - "binding": { - "kind": "set", - "values": [ - { - "ref": { - "ref": "country/AGO", - "label": "Angola" - }, - "value_kind": "entity" - }, - { - "ref": { - "ref": "country/BDI", - "label": "Burundi" - }, - "value_kind": "entity" - }, - { + "options": [ + { + "value": { "ref": { - "ref": "country/BEN", - "label": "Benin" + "ref": "AgricultureForestryFishingSector", + "label": "Agriculture,Forestry and Fishing Sector" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/BFA", - "label": "Burkina Faso" + "ref": "ConstructionSector", + "label": "Construction Sector" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/BWA", - "label": "Botswana" + "ref": "ElectricityGasSteamAirConditionSupply", + "label": "Electric Gas Steam Air Condition Supply" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/CAF", - "label": "Central African Republic" + "ref": "FinanceService", + "label": "Finance Service" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/CIV", - "label": "Ivory Coast" + "ref": "MOSPI_OtherService", + "label": "MOSPI Other Service" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/CMR", - "label": "Cameroon" + "ref": "ManufacturingSector", + "label": "Manufacturing Sector" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/COD", - "label": "Democratic Republic of the Congo" + "ref": "MiningQuarrying", + "label": "Mining quarrying" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/COG", - "label": "Republic of the Congo" + "ref": "TradeSector", + "label": "Trade Sector" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/COM", - "label": "Comoros" + "ref": "AccommodationAndFoodSector", + "label": "Accommodation and food sector" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/CPV", - "label": "Cape Verde" + "ref": "AdministrativeAndSupportServices", + "label": "Administrative and support services" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/DJI", - "label": "Djibouti" + "ref": "AgriculturalSupportActivities", + "label": "Agricultural support activities" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/ERI", - "label": "Eritrea" + "ref": "Agriculture", + "label": "Agriculture" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/ETH", - "label": "Ethiopia" + "ref": "AirTransportAndSupportServices", + "label": "Air transport and support services" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/GAB", - "label": "Gabon" + "ref": "AllEconomicActivities", + "label": "All economic activities" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/GHA", - "label": "Ghana" + "ref": "AnimalProduction", + "label": "Animal production" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/GIN", - "label": "Guinea" + "ref": "ArtsEntertainmentRecreation", + "label": "Arts entertainment recreation" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/GMB", - "label": "The Gambia" + "ref": "Education", + "label": "Education" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/GNB", - "label": "Guinea-Bissau" - }, - "value_kind": "entity" - }, - { + "ref": "ElectricitySupply", + "label": "Electricity supply" + }, + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/GNQ", - "label": "Equatorial Guinea" + "ref": "EmployerHouseholdActivities", + "label": "Employer household activities" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/KEN", - "label": "Kenya" + "ref": "FinancialActivities", + "label": "FinancialActivities" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/LBR", - "label": "Liberia" + "ref": "FinancialAndInsuranceActivities", + "label": "Financial and insurance activities" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/LSO", - "label": "Lesotho" + "ref": "FinancialIntermediationServicesIndirectlyMeasured", + "label": "Financial intermediation services indirectly measured" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/MDG", - "label": "Madagascar" + "ref": "FishingAquaculture", + "label": "Fishing aquaculture" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/MLI", - "label": "Mali" + "ref": "FoodBeveragesTobaccoManufacture", + "label": "Food beverages tobacco manufacture" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/MOZ", - "label": "Mozambique" + "ref": "ForestryLogging", + "label": "Forestry logging" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/MRT", - "label": "Mauritania" + "ref": "HumanHealthAndSocialWork", + "label": "Human health and social work" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/MUS", - "label": "Mauritius" + "ref": "InformationAndCommunication", + "label": "Information and communication" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/MWI", - "label": "Malawi" + "ref": "InsuranceActivities", + "label": "Insurance activities" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/NAM", - "label": "Namibia" + "ref": "LandTransport", + "label": "Land transport" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/NER", - "label": "Niger" + "ref": "OtherManufacturingAndRepair", + "label": "Other manufacturing and repair" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/NGA", - "label": "Nigeria" + "ref": "OtherServiceSector", + "label": "Other service sector" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/RWA", - "label": "Rwanda" + "ref": "OtherTransportPostalCourierActivities", + "label": "Other transport postal courier activities" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/SEN", - "label": "Senegal" + "ref": "ProductTaxes", + "label": "Product taxes" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/SLE", - "label": "Sierra Leone" + "ref": "ProfessionalScientificTechnicalActivities", + "label": "Professional scientific technical activities" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/SOM", - "label": "Somalia" + "ref": "PublicAdministrationAndDefence", + "label": "Public administration and defence" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/SSD", - "label": "South Sudan" + "ref": "PublishingBroadcastingInformationActivities", + "label": "Publishing Broadcasting Information Activities" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/STP", - "label": "São Tomé and Príncipe" + "ref": "RealEstate", + "label": "Real estate" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/SWZ", - "label": "Swaziland" + "ref": "Telecommunications", + "label": "Telecommunications" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/SYC", - "label": "Seychelles" + "ref": "TransportStorageSector", + "label": "Transport and Storage" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/TCD", - "label": "Chad" + "ref": "WaterSupplySewerageWasteManagement", + "label": "Water supply sewerage waste management" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/TGO", - "label": "Togo" + "ref": "WholesaleRetailTradeAndRepair", + "label": "Wholesale retail trade and repair" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/TZA", - "label": "Tanzania" + "ref": "BankingAndInsuranceSector", + "label": "Banking And Insurance Sector" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/UGA", - "label": "Uganda" + "ref": "Construction", + "label": "Manufacturing" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/ZAF", - "label": "South Africa" + "ref": "FinancialServices", + "label": "Financial Services" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/ZMB", - "label": "Zambia" + "ref": "Industry", + "label": "Industry" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/ZWE", - "label": "Zimbabwe" + "ref": "Services", + "label": "Services" }, - "value_kind": "entity" - } - ] - }, - "summable": false - }, - { - "key": { - "axis": "when", - "label": "time window" - }, - "binding": { - "kind": "value", - "value": { - "value_kind": "time_window", - "time_window": { - "start_year": 2015, - "end_year": 2022 + "value_kind": "enum_value" } } - }, - "summable": false + ], + "truncated": true, + "source": "observed" }, { "key": { - "axis": "source", - "label": "data source" - }, - "binding": { - "kind": "unbound" + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" }, - "summable": false - } - ], - "inapplicable_slots": [ - "dacTypeOfFinance" - ], - "unresolved_slots": [], - "stat_vars": { - "member_count": 1, - "member_count_exact": true, - "served_count": 1, - "data_date_range": { - "start": "2015", - "end": "2022" - } - }, - "entities": [ - { - "ref": "country/AGO", - "label": "Angola", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BDI", - "label": "Burundi", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BEN", - "label": "Benin", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BFA", - "label": "Burkina Faso", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BWA", - "label": "Botswana", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/CAF", - "label": "Central African Republic", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/CIV", - "label": "Ivory Coast", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/CMR", - "label": "Cameroon", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/COD", - "label": "Democratic Republic of the Congo", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/COG", - "label": "Republic of the Congo", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/COM", - "label": "Comoros", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/CPV", - "label": "Cape Verde", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/DJI", - "label": "Djibouti", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/ERI", - "label": "Eritrea", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/ETH", - "label": "Ethiopia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GAB", - "label": "Gabon", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GHA", - "label": "Ghana", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GIN", - "label": "Guinea", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GMB", - "label": "The Gambia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GNB", - "label": "Guinea-Bissau", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GNQ", - "label": "Equatorial Guinea", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/KEN", - "label": "Kenya", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/LBR", - "label": "Liberia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/LSO", - "label": "Lesotho", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MDG", - "label": "Madagascar", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MLI", - "label": "Mali", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MOZ", - "label": "Mozambique", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MRT", - "label": "Mauritania", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MUS", - "label": "Mauritius", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MWI", - "label": "Malawi", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/NAM", - "label": "Namibia", - "entity_type": "Country", - "role": "destination" + "options": [ + { + "value": { + "ref": { + "ref": "NAICS/23", + "label": "Construction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/44-45", + "label": "Retail trade" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/53", + "label": "Real estate and rental and leasing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/22", + "label": "Utilities" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/55", + "label": "Management of companies and enterprises" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/48-49", + "label": "Transportation and warehousing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/61", + "label": "Educational services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/51", + "label": "Information" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/42", + "label": "Wholesale trade" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/21", + "label": "Mining, quarrying, and oil and gas extraction" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/11", + "label": "Agriculture, forestry, fishing and hunting" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/72", + "label": "Accommodation and food services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/52", + "label": "Finance and insurance" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/54", + "label": "Professional, Scientific, and Technical Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/71", + "label": "Arts, entertainment, and recreation" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/311-316_322-326", + "label": "Durable Goods Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/31-33", + "label": "Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/321_327-339", + "label": "Durable Goods Manufacturing" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/56", + "label": "Administrative and Support and Waste Management Services" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/62", + "label": "Health care and social assistance" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/81", + "label": "Other services, except public administration" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NAICS/92", + "label": "Public administration" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, { - "ref": "country/NER", - "label": "Niger", - "entity_type": "Country", - "role": "destination" - }, + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "options": [ + { + "value": { + "ref": { + "ref": "HigherSecondaryEducation", + "label": "Higher Secondary Education" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PrePrimaryAndPrimaryEducation", + "label": "PrePrimary and Primary" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SecondaryEducation", + "label": "SecondaryEducation" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ { - "ref": "country/NGA", - "label": "Nigeria", - "entity_type": "Country", - "role": "destination" + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" }, { - "ref": "country/RWA", - "label": "Rwanda", - "entity_type": "Country", - "role": "destination" - }, + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "USDollar", + "label": "USDollar" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "XAF", + "label": "XAF" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "GDP in the 48 countries in Sub-Saharan Africa, 2013 to 2022. Current US dollars · World Development Indicators.", + "sentence_plan": [ { - "ref": "country/SEN", - "label": "Senegal", - "entity_type": "Country", - "role": "destination" + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ] }, { - "ref": "country/SLE", - "label": "Sierra Leone", - "entity_type": "Country", - "role": "destination" + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [] }, { - "ref": "country/SOM", - "label": "Somalia", - "entity_type": "Country", - "role": "destination" + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [] }, { - "ref": "country/SSD", - "label": "South Sudan", - "entity_type": "Country", - "role": "destination" + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [] }, { - "ref": "country/STP", - "label": "São Tomé and Príncipe", - "entity_type": "Country", - "role": "destination" + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] }, { - "ref": "country/SWZ", - "label": "Swaziland", - "entity_type": "Country", - "role": "destination" + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] }, { - "ref": "country/SYC", - "label": "Seychelles", - "entity_type": "Country", - "role": "destination" + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] }, { - "ref": "country/TCD", - "label": "Chad", - "entity_type": "Country", - "role": "destination" + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] }, { - "ref": "country/TGO", - "label": "Togo", - "entity_type": "Country", - "role": "destination" + "kind": "slot", + "text": "2013 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] }, { - "ref": "country/TZA", - "label": "Tanzania", - "entity_type": "Country", - "role": "destination" + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] }, { - "ref": "country/UGA", - "label": "Uganda", - "entity_type": "Country", - "role": "destination" + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] }, { - "ref": "country/ZAF", - "label": "South Africa", - "entity_type": "Country", - "role": "destination" + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] }, { - "ref": "country/ZMB", - "label": "Zambia", - "entity_type": "Country", - "role": "destination" + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] }, { - "ref": "country/ZWE", - "label": "Zimbabwe", - "entity_type": "Country", - "role": "destination" + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] }, { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "origin" + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] } ], - "entity_groups": { - "destination": { - "ref": "SubSaharanAfrica", - "label": "Sub-Saharan Africa", - "entity_type": "UNGeoRegion" - } - }, - "coverage": { - "kind": "exact", - "has_data": true, - "observation_count": 372, - "evidence": "facet_metadata", - "dimensions": [ + "trace": { + "resolved_entities": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, { - "label": "sources", - "count": 1 + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" }, { - "label": "observations", - "count": 8 + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" }, { - "label": "variables", - "count": 1 + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" } ], - "window": { - "start_year": 2015, - "end_year": 2022 - } - }, - "headline": { - "year": 2022, - "year_named": true, - "named_window": { - "start_year": 2015, - "end_year": 2022 - }, - "observations": 46, - "series": 46, - "role_counts": { - "financingProvider": 1, - "financingRecipient": 46 - }, - "recent_years": [ - { - "year": 2022, - "observations": 46, - "series": 46, - "role_counts": { - "financingProvider": 1, - "financingRecipient": 46 - } - }, - { - "year": 2021, - "observations": 46, - "series": 46, - "role_counts": { - "financingProvider": 1, - "financingRecipient": 46 - } - }, - { - "year": 2020, - "observations": 47, - "series": 47, - "role_counts": { - "financingProvider": 1, - "financingRecipient": 47 - } - } - ] - }, - "download": { - "rows": 372, - "rows_exact": true, - "series": 48, - "window": { - "start_year": 2015, + "query_qualifiers": [], + "requested_window": { + "start_year": 2013, "end_year": 2022 }, - "licence": { - "label": "OECD Terms and Conditions" - } - }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", - "facets": { - "provenance": { - "basis": "fallback", - "ref": "provenance/OECDDAC2A", - "label": "OECD DAC2A", - "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" - }, - "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" - }, - "documentation": "/api/graph/documentation/provenance/OECDDAC2A", - "account": "provider" - }, - "unit": { - "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" + "capability_version": "cap_94e25737d859392c", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAccommodationFoodServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSFinanceInsurance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSMiningQuarryingOilGasExtraction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSProfessionalScientificTechnicalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSWholesaleTrade_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826", + "dc/zz6gwv838v9w" + ] } }, - "slot_options": [ + "confidence": "high", + "available_at_place": true, + "equivalent_readings": [ { - "key": { - "axis": "how", - "property": { - "ref": "dac2aAidType", - "label": "DAC 2a aid type" + "spec_id": "spec_de0dd3acae61e56a8a0e3bbc54e17594", + "definition": { + "schema_version": 1, + "spec_id": "spec_de0dd3acae61e56a8a0e3bbc54e17594", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicProduction", + "measured_property": "valueAdded", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "currencyConversionBasis", + "binding": { + "state": "unbound" + } + }, + { + "property": "fixedCapitalConsumptionBasis", + "binding": { + "state": "value", + "ref": "GrossOfFixedCapitalConsumption" + } + }, + { + "property": "productTaxBasis", + "binding": { + "state": "value", + "ref": "IncludingProductTaxes" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2013, + "end_year": 2022 + }, + "facets": { + "unit": { + "state": "value", + "ref": "CurrencyUSD" + } + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicproduction_valueadded_measuredvalue_nominal", + "label": "Gross domestic product (GDP)", + "population_type": { + "ref": "EconomicProduction", + "label": "economic production" + }, + "measured_property": { + "ref": "valueAdded", + "label": "value added" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 2, + "member_digest": "ef9c4356618ed98aab762248e68799d78c74ad249a6041dad0e8a345c85ee02f", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" + } + ] + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2013, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [ + "currencyConversionBasis" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 2, + "member_count_exact": false, + "served_count": 1, + "data_date_range": { + "start": "2013", + "end": "2022" + } }, - "label": "aid type" - }, - "options": [ - { - "value": { - "ref": { - "ref": "DAC2aAidType218", - "label": "ODA loans and other long-term capital" + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "entity_groups": { + "observationAbout": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 477, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "countries", + "count": 48 + }, + { + "label": "observations", + "count": 10 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2013, + "end_year": 2022 + } + }, + "download": { + "rows": 477, + "rows_exact": true, + "series": 48, + "window": { + "start_year": 2013, + "end_year": 2022 + }, + "licence": { + "label": "IMF Copyright and Usage" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "provenance/IMFWorldEconomicOutlook", + "label": "IMF World Economic Outlook (WEO)", + "source": { + "ref": "source/InternationalMonetaryFund", + "label": "International Monetary Fund (IMF)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/IMFWorldEconomicOutlook" + }, + "unit": { + "basis": "bound", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "options": [ + { + "value": { + "ref": { + "ref": "PurchasingPowerParityRate", + "label": "purchasing power parity rate" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [], + "trace": { + "resolved_entities": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "DAC2aAidType206", - "member_count": 2, - "served_rows": 68, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "DAC2aAidType201", - "label": "ODA grant" + { + "ref": "country/BEN", + "label": "Benin" }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "DAC2aAidType206", - "member_count": 1, - "served_rows": 372, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "DAC2aAidType207", - "label": "free-standing technical co-operation" + { + "ref": "country/BFA", + "label": "Burkina Faso" }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 1, - "served_rows": 372, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "DAC2aAidType213", - "label": "developmental food aid" + { + "ref": "country/BWA", + "label": "Botswana" }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 1, - "served_rows": 129, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "DAC2aAidType216", - "label": "humanitarian aid" + { + "ref": "country/CAF", + "label": "Central African Republic" }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 1, - "served_rows": 188, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ - { - "axis": "provenance", - "options": [ - { - "value": { - "ref": { - "ref": "provenance/OECDDAC2A", - "label": "OECD DAC2A" + { + "ref": "country/CIV", + "label": "Ivory Coast" }, - "value_kind": "source" - } - } - ], - "truncated": false, - "source": "observed" - }, - { - "axis": "unit", - "options": [ - { - "value": { - "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" + { + "ref": "country/CMR", + "label": "Cameroon" }, - "value_kind": "enum_value" - } - } - ], - "truncated": false, - "source": "observed" - } - ], - "rendered_sentence": "Germany's gross disbursements to the 48 countries in Sub-Saharan Africa for official development assistance, 2015 to 2022. Current US dollars · OECD DAC2a.", - "sentence_plan": [ - { - "kind": "slot", - "text": "Germany", - "segment": "heading", - "role": "origin", - "binding_ref": "origin:", - "entity_refs": [ - "country/DEU" - ], - "states": [ - "origin:" - ] - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "gross disbursements", - "axis": "what", - "segment": "heading", - "entity_refs": [], - "states": [ - "how:financialFlowType", - "how:nettingBasis", - "axis:populationType", - "axis:measuredProperty" - ] - }, - { - "kind": "text", - "text": " to ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "the 48 countries in Sub-Saharan Africa", - "axis": "where", - "segment": "heading", - "role": "destination", - "binding_ref": "where:", - "entity_refs": [ - "country/AGO", - "country/BDI", - "country/BEN", - "country/BFA", - "country/BWA", - "country/CAF", - "country/CIV", - "country/CMR", - "country/COD", - "country/COG", - "country/COM", - "country/CPV", - "country/DJI", - "country/ERI", - "country/ETH", - "country/GAB", - "country/GHA", - "country/GIN", - "country/GMB", - "country/GNB", - "country/GNQ", - "country/KEN", - "country/LBR", - "country/LSO", - "country/MDG", - "country/MLI", - "country/MOZ", - "country/MRT", - "country/MUS", - "country/MWI", - "country/NAM", - "country/NER", - "country/NGA", - "country/RWA", - "country/SEN", - "country/SLE", - "country/SOM", - "country/SSD", - "country/STP", - "country/SWZ", - "country/SYC", - "country/TCD", - "country/TGO", - "country/TZA", - "country/UGA", - "country/ZAF", - "country/ZMB", - "country/ZWE" - ], - "states": [ - "where:" - ] - }, - { - "kind": "text", - "text": " for ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "official development assistance", - "axis": "how", - "segment": "heading", - "property_dcid": "dac2aAidType", - "binding_ref": "how:dac2aAidType", - "entity_refs": [], - "states": [ - "how:dac2aAidType" - ] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "dacTypeOfFinance", - "binding_ref": "how:dacTypeOfFinance", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "financialFlowType", - "binding_ref": "how:financialFlowType", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "nettingBasis", - "binding_ref": "how:nettingBasis", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": ", ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "2015 to 2022", - "axis": "when", - "segment": "heading", - "binding_ref": "when:", - "entity_refs": [], - "states": [ - "when:" - ] - }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "provenance/IMFWorldEconomicOutlook", + "label": "IMF World Economic Outlook (WEO)", + "source": { + "ref": "source/InternationalMonetaryFund", + "label": "International Monetary Fund (IMF)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/IMFWorldEconomicOutlook" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "fixedCapitalConsumptionBasis", + "label": "fixed capital consumption basis" + }, + "label": "fixed capital consumption basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "GrossOfFixedCapitalConsumption", + "label": "gross of fixed capital consumption" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "productTaxBasis", + "label": "product tax basis" + }, + "label": "product tax basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "IncludingProductTaxes", + "label": "including taxes on products" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "currencyConversionBasis", + "label": "currency conversion basis" + }, + "label": "currency conversion basis" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2013, + "end_year": 2022 + }, + "capability_version": "cap_94e25737d859392c", + "default_reading": { + "applied": true, + "removed_stat_vars": [ + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAccommodationFoodServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSFinanceInsurance_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSMiningQuarryingOilGasExtraction_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSProfessionalScientificTechnicalServices_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_NAICSWholesaleTrade_RealValue", + "Amount_EconomicActivity_GrossDomesticProduction_RealValue", + "InflationAdjustedGDP", + "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", + "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", + "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", + "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", + "dc/qt7ewllmt3826", + "dc/zz6gwv838v9w" + ] + } + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [] + } + } + ], + "measure_label_axes": [], + "measure_axis_values": [], + "related_measures": [] + } + } + } + ], + "rendered_sentence": "Answered 1 of 2 parts. Mortality has 3 readings. Deaths rate per capita in the 48 countries in Sub-Saharan Africa. World Development Indicators · 2013 to 2022. Number of deaths in the 48 countries in Sub-Saharan Africa. Kenya Census · 2018 to 2022. Count of mortality event (as fraction of count birth event live birth) in the 48 countries in Sub-Saharan Africa. Nigeria Statistics · 2014. GDP in the 48 countries in Sub-Saharan Africa, 2013 to 2022. Current US dollars · World Development Indicators. The data holds no values for 1 of the 48 countries in Sub-Saharan Africa. You asked for sub-Saharan Africa. This shows the countries in it, each on its own.", + "sentence_plan": [ + { + "kind": "text", + "text": "Answered 1 of 2 parts.", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "coverage", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Mortality", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " has 3 readings.", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Deaths rate", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "per capita", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "World Development Indicators", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2013 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Number of deaths", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Kenya Census", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2018 to 2022", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Count of mortality event (as fraction of count birth event live birth)", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "the 48 countries in Sub-Saharan Africa", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Nigeria Statistics", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "2014", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "2013 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ], + "part_index": 1 + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "The data holds no values for 1 of the 48 countries in Sub-Saharan Africa.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "You asked for sub-Saharan Africa. This shows the countries in it, each on its own.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + } + ], + "status": "mixed" + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "dataset_resubmit", + "entries": [ + { + "entry_kind": "identity", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "MortalityEvent", + "measured_property": "count", + "stat_type": "measuredValue", + "measurement_denominator": { + "ref": "Count_Person" + } + }, + "slots": [ { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [] - }, + "property": "causeOfDeath", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2013, + "end_year": 2022 + } + }, + "entity_groups": { + "observationAbout": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "assumptions": [], + "variable_text": "mortality" + }, + { + "entry_kind": "identity", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } }, { - "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] + "property": "economicSector", + "binding": { + "state": "unbound" + } }, { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] + "property": "naics", + "binding": { + "state": "unbound" + } }, { - "kind": "slot", - "text": "OECD DAC2a", - "axis": "source", - "segment": "byline", - "entity_refs": [], - "states": [ - "source:" - ] + "property": "schoolGradeLevel", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2013, + "end_year": 2022 + }, + "facets": { + "unit": { + "state": "value", + "ref": "USDollar" + } + } + }, + "entity_groups": { + "observationAbout": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "assumptions": [], + "variable_text": "GDP" + } + ] + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "a307928119964968b55057dbf481949e" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "dataset_resubmit", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "a307928119964968b55057dbf481949e", + "warnings": [], + "timing_ms": { + "total": 1587, + "by_step": { + "coverage": 0 + } + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "mortality", + "warnings": [], + "timing_ms": { + "total": 1115, + "by_step": { + "validate": 1, + "walk": 0, + "reread_arcs": 0, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 192, + "bind": 0, + "where_places": 1, + "materialise": 780, + "answer": 17, + "options": 124 + } + }, + "operations": [], + "departures": [ + { + "code": "group_read_as_members", + "binding_ref": "where:", + "text": "This shows the 48 countries in Sub-Saharan Africa, each on its own." + } + ], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_176fd5e63bb2a122c4ad00831497b863", + "definition": { + "schema_version": 1, + "spec_id": "spec_176fd5e63bb2a122c4ad00831497b863", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "MortalityEvent", + "measured_property": "count", + "stat_type": "measuredValue", + "measurement_denominator": { + "ref": "Count_Person" + } }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [] - } - ], - "trace": { - "resolved_entities": [ - { - "ref": "country/AGO", - "label": "Angola" - }, - { - "ref": "country/BDI", - "label": "Burundi" - }, - { - "ref": "country/BEN", - "label": "Benin" - }, - { - "ref": "country/BFA", - "label": "Burkina Faso" - }, - { - "ref": "country/BWA", - "label": "Botswana" - }, - { - "ref": "country/CAF", - "label": "Central African Republic" - }, - { - "ref": "country/CIV", - "label": "Ivory Coast" - }, - { - "ref": "country/CMR", - "label": "Cameroon" - }, - { - "ref": "country/COD", - "label": "Democratic Republic of the Congo" - }, - { - "ref": "country/COG", - "label": "Republic of the Congo" - }, - { - "ref": "country/COM", - "label": "Comoros" - }, - { - "ref": "country/CPV", - "label": "Cape Verde" - }, - { - "ref": "country/DJI", - "label": "Djibouti" - }, - { - "ref": "country/ERI", - "label": "Eritrea" - }, - { - "ref": "country/ETH", - "label": "Ethiopia" - }, - { - "ref": "country/GAB", - "label": "Gabon" - }, - { - "ref": "country/GHA", - "label": "Ghana" - }, - { - "ref": "country/GIN", - "label": "Guinea" - }, - { - "ref": "country/GMB", - "label": "The Gambia" - }, - { - "ref": "country/GNB", - "label": "Guinea-Bissau" - }, - { - "ref": "country/GNQ", - "label": "Equatorial Guinea" - }, - { - "ref": "country/KEN", - "label": "Kenya" - }, - { - "ref": "country/LBR", - "label": "Liberia" - }, - { - "ref": "country/LSO", - "label": "Lesotho" - }, - { - "ref": "country/MDG", - "label": "Madagascar" - }, - { - "ref": "country/MLI", - "label": "Mali" - }, - { - "ref": "country/MOZ", - "label": "Mozambique" - }, - { - "ref": "country/MRT", - "label": "Mauritania" - }, - { - "ref": "country/MUS", - "label": "Mauritius" - }, - { - "ref": "country/MWI", - "label": "Malawi" - }, - { - "ref": "country/NAM", - "label": "Namibia" - }, - { - "ref": "country/NER", - "label": "Niger" - }, - { - "ref": "country/NGA", - "label": "Nigeria" - }, - { - "ref": "country/RWA", - "label": "Rwanda" - }, - { - "ref": "country/SEN", - "label": "Senegal" - }, - { - "ref": "country/SLE", - "label": "Sierra Leone" - }, - { - "ref": "country/SOM", - "label": "Somalia" - }, - { - "ref": "country/SSD", - "label": "South Sudan" - }, - { - "ref": "country/STP", - "label": "São Tomé and Príncipe" - }, - { - "ref": "country/SWZ", - "label": "Swaziland" - }, - { - "ref": "country/SYC", - "label": "Seychelles" - }, - { - "ref": "country/TCD", - "label": "Chad" - }, - { - "ref": "country/TGO", - "label": "Togo" - }, - { - "ref": "country/TZA", - "label": "Tanzania" - }, + "slots": [ { - "ref": "country/UGA", - "label": "Uganda" - }, + "property": "causeOfDeath", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2013, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "mortalityevent_count_measuredvalue_per_count_person", + "label": "Deaths Rate", + "population_type": { + "ref": "MortalityEvent", + "label": "MortalityEvent" + }, + "measured_property": { + "ref": "count", + "label": "count" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_denominator": { + "ref": "Count_Person", + "label": "Total population" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ { - "ref": "country/ZAF", - "label": "South Africa" + "axis": "how", + "property": { + "ref": "causeOfDeath", + "label": "causeOfDeath" + }, + "label": "cause of death" }, { - "ref": "country/ZMB", - "label": "Zambia" + "axis": "where", + "label": "place" }, { - "ref": "country/ZWE", - "label": "Zimbabwe" + "axis": "when", + "label": "time window" }, { - "ref": "country/DEU", - "label": "Germany" + "axis": "source", + "label": "data source" } ], - "resolved_sources": [ + "member_count": 133, + "member_digest": "c090b56d31a596a8be16dafb518382db666c6b100a80534c3cb81dbfe3111c5d", + "refine_supported": false, + "data_commons": [ { - "ref": "provenance/OECDDAC2A", - "label": "OECD DAC2a", - "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" - }, - "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" - }, - "documentation": "/api/graph/documentation/provenance/OECDDAC2A" + "id": "base", + "label": "Data Commons by Google" } - ], - "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "dac2aAidType", - "label": "DAC 2a aid type" + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "causeOfDeath", + "label": "causeOfDeath" + }, + "label": "cause of death" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" }, - "label": "aid type" - }, - "binding_kind": "value", - "refs": [ { - "ref": "DAC2aAidType206", - "label": "official development assistance" - } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "financialFlowType", - "label": "financial flow type" + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" }, - "label": "financial flow type" - }, - "binding_kind": "value", - "refs": [ { - "ref": "Disbursement", - "label": "disbursement" - } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "nettingBasis", - "label": "netting basis" + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" }, - "label": "netting basis" - }, - "binding_kind": "value", - "refs": [ { - "ref": "Gross", - "label": "gross" + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" } - ], - "provenance": "binder" + ] }, - { - "key": { - "axis": "how", - "property": { - "ref": "dacTypeOfFinance", - "label": "DAC type of finance" - }, - "label": "DAC type of finance" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2013, + "end_year": 2022 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" }, + "summable": false + } + ], + "inapplicable_slots": [ + "causeOfDeath" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 2, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "2013", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "entity_groups": { + "observationAbout": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 480, + "evidence": "facet_metadata", + "dimensions": [ { - "key": { - "axis": "where", - "label": "place" - }, - "binding_kind": "set", - "refs": [ - { - "ref": "country/AGO", - "label": "Angola" - }, - { - "ref": "country/BDI", - "label": "Burundi" - }, - { - "ref": "country/BEN", - "label": "Benin" - }, - { - "ref": "country/BFA", - "label": "Burkina Faso" - }, - { - "ref": "country/BWA", - "label": "Botswana" - }, - { - "ref": "country/CAF", - "label": "Central African Republic" - }, - { - "ref": "country/CIV", - "label": "Ivory Coast" - }, - { - "ref": "country/CMR", - "label": "Cameroon" - }, - { - "ref": "country/COD", - "label": "Democratic Republic of the Congo" - }, - { - "ref": "country/COG", - "label": "Republic of the Congo" - }, - { - "ref": "country/COM", - "label": "Comoros" - }, - { - "ref": "country/CPV", - "label": "Cape Verde" - }, - { - "ref": "country/DJI", - "label": "Djibouti" - }, - { - "ref": "country/ERI", - "label": "Eritrea" - }, - { - "ref": "country/ETH", - "label": "Ethiopia" - }, - { - "ref": "country/GAB", - "label": "Gabon" - }, - { - "ref": "country/GHA", - "label": "Ghana" - }, - { - "ref": "country/GIN", - "label": "Guinea" - }, - { - "ref": "country/GMB", - "label": "The Gambia" - }, - { - "ref": "country/GNB", - "label": "Guinea-Bissau" - }, - { - "ref": "country/GNQ", - "label": "Equatorial Guinea" - }, - { - "ref": "country/KEN", - "label": "Kenya" - }, - { - "ref": "country/LBR", - "label": "Liberia" - }, - { - "ref": "country/LSO", - "label": "Lesotho" - }, - { - "ref": "country/MDG", - "label": "Madagascar" - }, - { - "ref": "country/MLI", - "label": "Mali" - }, - { - "ref": "country/MOZ", - "label": "Mozambique" - }, - { - "ref": "country/MRT", - "label": "Mauritania" - }, - { - "ref": "country/MUS", - "label": "Mauritius" - }, - { - "ref": "country/MWI", - "label": "Malawi" - }, - { - "ref": "country/NAM", - "label": "Namibia" - }, - { - "ref": "country/NER", - "label": "Niger" - }, - { - "ref": "country/NGA", - "label": "Nigeria" - }, - { - "ref": "country/RWA", - "label": "Rwanda" - }, - { - "ref": "country/SEN", - "label": "Senegal" - }, - { - "ref": "country/SLE", - "label": "Sierra Leone" - }, - { - "ref": "country/SOM", - "label": "Somalia" - }, - { - "ref": "country/SSD", - "label": "South Sudan" - }, - { - "ref": "country/STP", - "label": "São Tomé and Príncipe" - }, - { - "ref": "country/SWZ", - "label": "Swaziland" - }, - { - "ref": "country/SYC", - "label": "Seychelles" - }, - { - "ref": "country/TCD", - "label": "Chad" - }, - { - "ref": "country/TGO", - "label": "Togo" - }, - { - "ref": "country/TZA", - "label": "Tanzania" - }, - { - "ref": "country/UGA", - "label": "Uganda" - }, - { - "ref": "country/ZAF", - "label": "South Africa" - }, - { - "ref": "country/ZMB", - "label": "Zambia" - }, - { - "ref": "country/ZWE", - "label": "Zimbabwe" - } - ], - "provenance": "binder" + "label": "countries", + "count": 48 }, { - "key": { - "axis": "when", - "label": "time window" - }, - "binding_kind": "value", - "refs": [], - "provenance": "binder" + "label": "observations", + "count": 10 }, { - "key": { - "axis": "source", - "label": "data source" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" + "label": "variables", + "count": 1 } ], - "query_qualifiers": [], - "requested_window": { - "start_year": 2015, + "window": { + "start_year": 2013, + "end_year": 2022 + } + }, + "download": { + "rows": 480, + "rows_exact": true, + "series": 48, + "window": { + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec" + "licence": { + "label": "Creative Commons Attribution License" + } }, - "confidence": "high", - "available_at_place": true, - "alternative_measures": [ + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" + }, + "data_commons": { + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "measurementMethod": { + "basis": "fallback", + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" + }, + "unit": { + "basis": "fallback", + "ref": "Per1000Persons", + "label": "Per 1000 people" + } + }, + "slot_options": [ { - "definition": { - "schema_version": 1, - "spec_id": "spec_f936496b58a844fc044d98a4255f48f2", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "FinancialFlow", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" - }, - "slots": [ - { - "property": "dac2aAidType", - "binding": { - "state": "value", - "ref": "DAC2aAidType206" - } - }, - { - "property": "dacTypeOfFinance", - "binding": { - "state": "unbound" - } - }, - { - "property": "financialFlowType", - "binding": { - "state": "value", - "ref": "Disbursement" - } + "key": { + "axis": "how", + "property": { + "ref": "causeOfDeath", + "label": "causeOfDeath" + }, + "label": "cause of death" + }, + "options": [ + { + "value": { + "ref": { + "ref": "ICD10/X60-X84", + "label": "X60-X84 (Intentional self-harm)" }, - { - "property": "nettingBasis", - "binding": { - "state": "value", - "ref": "Net" - } - } - ], - "entities": { - "destination": [ - "country/AGO", - "country/BDI", - "country/BEN", - "country/BFA", - "country/BWA", - "country/CAF", - "country/CIV", - "country/CMR", - "country/COD", - "country/COG", - "country/COM", - "country/CPV", - "country/DJI", - "country/ERI", - "country/ETH", - "country/GAB", - "country/GHA", - "country/GIN", - "country/GMB", - "country/GNB", - "country/GNQ", - "country/KEN", - "country/LBR", - "country/LSO", - "country/MDG", - "country/MLI", - "country/MOZ", - "country/MRT", - "country/MUS", - "country/MWI", - "country/NAM", - "country/NER", - "country/NGA", - "country/RWA", - "country/SEN", - "country/SLE", - "country/SOM", - "country/SSD", - "country/STP", - "country/SWZ", - "country/SYC", - "country/TCD", - "country/TGO", - "country/TZA", - "country/UGA", - "country/ZAF", - "country/ZMB", - "country/ZWE" - ], - "origin": [ - "country/DEU" - ] - }, - "requested_window": { - "kind": "range", - "start_year": 2015, - "end_year": 2022 + "value_kind": "enum_value" } } - }, - "label": "net disbursements", - "axis": "what", - "measure_axis_values": [ + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ { - "axis": "populationType", "value": { - "ref": "FinancialFlow", - "label": "financial flow" + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" } }, { - "axis": "measuredProperty", "value": { - "ref": "amount", - "label": "amount" + "ref": { + "ref": "dc/base/Cotedivoire_Census", + "label": "Ivory Coast Census" + }, + "value_kind": "source" } }, { - "axis": "measurementQualifier", "value": { - "ref": "Nominal", - "label": "nominal" + "ref": { + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "ref": { + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" + }, + "value_kind": "enum_value" } }, { - "axis": "financialFlowType", "value": { - "ref": "Disbursement", - "label": "disbursement" + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "Per1000Persons", + "label": "Per 1000 people" + }, + "value_kind": "enum_value" } }, { - "axis": "nettingBasis", "value": { - "ref": "Net", - "label": "net" + "value_kind": "enum_value" } } ], - "served_rows": 372, - "served_rows_exact": true + "truncated": false, + "source": "observed" } ], - "measure_label": "gross disbursements", - "measure_label_axes": [ - "populationType", - "measuredProperty", - "measurementQualifier", - "financialFlowType", - "nettingBasis" - ], - "measure_axis_values": [ + "rendered_sentence": "Deaths rate per capita in the 48 countries in Sub-Saharan Africa, 2013 to 2022. World Development Indicators.", + "sentence_plan": [ { - "axis": "populationType", - "value": { - "ref": "FinancialFlow", - "label": "financial flow" - } + "kind": "slot", + "text": "Deaths rate", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [] }, { - "axis": "measuredProperty", - "value": { - "ref": "amount", - "label": "amount" - } + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] }, { - "axis": "measurementQualifier", - "value": { - "ref": "Nominal", - "label": "nominal" - } + "kind": "slot", + "text": "per capita", + "axis": "unit", + "segment": "heading", + "entity_refs": [], + "states": [] }, { - "axis": "financialFlowType", - "value": { - "ref": "Disbursement", - "label": "disbursement" - } + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2013 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] }, { - "axis": "nettingBasis", - "value": { - "ref": "Gross", - "label": "gross" - } + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] } ], - "unit_conversion": { - "currencies": [ + "trace": { + "resolved_entities": [ { - "code": "AED", - "noun": "UAE dirhams", - "current_years": { - "start_year": 2015, - "end_year": 2021 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2023, - "base_year_max": 2023 + "ref": "country/AGO", + "label": "Angola" }, { - "code": "AFN", - "noun": "Afghan afghanis", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2002, - "base_year_max": 2025 + "ref": "country/BDI", + "label": "Burundi" }, { - "code": "ALL", - "noun": "Albanian leks", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/BEN", + "label": "Benin" }, { - "code": "AMD", - "noun": "Armenian drams", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1992, - "base_year_max": 2025 + "ref": "country/BFA", + "label": "Burkina Faso" }, { - "code": "AOA", - "noun": "Angolan kwanzas", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1991, - "base_year_max": 2025 + "ref": "country/BWA", + "label": "Botswana" }, { - "code": "ARS", - "noun": "Argentine pesos", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/CAF", + "label": "Central African Republic" }, { - "code": "AUD", - "noun": "Australian dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1960, - "base_year_max": 2025 + "ref": "country/CIV", + "label": "Ivory Coast" }, { - "code": "AWG", - "noun": "Aruban florins", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1995, - "base_year_max": 2025 + "ref": "country/CMR", + "label": "Cameroon" }, { - "code": "AZN", - "noun": "Azerbaijani manats", - "current_years": { - "start_year": 2015, - "end_year": 2019 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2023, - "base_year_max": 2023 + "ref": "country/COD", + "label": "Democratic Republic of the Congo" }, { - "code": "BAM", - "noun": "Bosnia-Herzegovina convertible marks", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1996, - "base_year_max": 2025 + "ref": "country/COG", + "label": "Republic of the Congo" }, { - "code": "BBD", - "noun": "Barbadian dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/COM", + "label": "Comoros" }, { - "code": "BDT", - "noun": "Bangladeshi taka", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/CPV", + "label": "Cape Verde" }, { - "code": "BHD", - "noun": "Bahraini dinars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/DJI", + "label": "Djibouti" }, { - "code": "BIF", - "noun": "Burundian francs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/ERI", + "label": "Eritrea" }, { - "code": "BND", - "noun": "Brunei dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1985, - "base_year_max": 2025 + "ref": "country/ETH", + "label": "Ethiopia" }, { - "code": "BOB", - "noun": "Bolivian bolivianos", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/GAB", + "label": "Gabon" }, { - "code": "BRL", - "noun": "Brazilian reais", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1986, - "base_year_max": 2025 + "ref": "country/GHA", + "label": "Ghana" }, { - "code": "BSD", - "noun": "Bahamian dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/GIN", + "label": "Guinea" }, { - "code": "BTN", - "noun": "Bhutanese ngultrums", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/GMB", + "label": "The Gambia" }, { - "code": "BWP", - "noun": "Botswana pula", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/GNB", + "label": "Guinea-Bissau" }, { - "code": "BYN", - "noun": "Belarusian rubles", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1992, - "base_year_max": 2025 + "ref": "country/GNQ", + "label": "Equatorial Guinea" }, { - "code": "BZD", - "noun": "Belize dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/KEN", + "label": "Kenya" }, { - "code": "CAD", - "noun": "Canadian dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1960, - "base_year_max": 2025 + "ref": "country/LBR", + "label": "Liberia" }, { - "code": "CDF", - "noun": "Congolese francs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1991, - "base_year_max": 2025 + "ref": "country/LSO", + "label": "Lesotho" }, { - "code": "CHF", - "noun": "Swiss francs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1960, - "base_year_max": 2025 + "ref": "country/MDG", + "label": "Madagascar" }, { - "code": "CLP", - "noun": "Chilean pesos", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/MLI", + "label": "Mali" }, { - "code": "CNY", - "noun": "Chinese yuan", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/MOZ", + "label": "Mozambique" }, { - "code": "COP", - "noun": "Colombian pesos", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/MRT", + "label": "Mauritania" }, { - "code": "CRC", - "noun": "Costa Rican colones", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" }, { - "code": "CVE", - "noun": "Cape Verdean escudos", - "current_years": { - "start_year": 2015, - "end_year": 2022 + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "data_commons": { + "id": "base", + "label": "Data Commons by Google" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ { - "code": "CZK", - "noun": "Czech korunas", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "key": { + "axis": "how", + "property": { + "ref": "causeOfDeath", + "label": "causeOfDeath" + }, + "label": "cause of death" }, - "base_year_min": 1998, - "base_year_max": 2025 + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" }, { - "code": "DJF", - "noun": "Djiboutian francs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "key": { + "axis": "where", + "label": "place" }, - "base_year_min": 1990, - "base_year_max": 2025 + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" }, { - "code": "DKK", - "noun": "Danish kroner", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "key": { + "axis": "when", + "label": "time window" }, - "base_year_min": 1960, - "base_year_max": 2025 + "binding_kind": "value", + "refs": [], + "provenance": "binder" }, { - "code": "DOP", - "noun": "Dominican pesos", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "key": { + "axis": "source", + "label": "data source" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2013, + "end_year": 2022 + }, + "capability_version": "cap_94e25737d859392c" + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [], + "related_measures": [] + } + } + }, + { + "variable_text": "GDP", + "warnings": [], + "timing_ms": { + "total": 1463, + "by_step": { + "validate": 0, + "walk": 0, + "reread_arcs": 1, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 980, + "bind": 0, + "where_places": 0, + "materialise": 197, + "answer": 8, + "options": 277 + } + }, + "operations": [], + "departures": [ + { + "code": "entity_unavailable", + "binding_ref": "where:", + "text": "The data holds no values for 1 of the 48 countries in Sub-Saharan Africa." + }, + { + "code": "group_read_as_members", + "binding_ref": "where:", + "text": "This shows the 48 countries in Sub-Saharan Africa, each on its own." + } + ], + "assumptions": [], + "status": "definite", + "spec": { + "spec_id": "spec_310c03c5f99c73c41d12226098714f81", + "definition": { + "schema_version": 1, + "spec_id": "spec_310c03c5f99c73c41d12226098714f81", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "EconomicActivity", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ { - "code": "DZD", - "noun": "Algerian dinars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "property": "activitySource", + "binding": { + "state": "value", + "ref": "GrossDomesticProduction" + } }, { - "code": "EGP", - "noun": "Egyptian pounds", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "property": "economicSector", + "binding": { + "state": "unbound" + } }, { - "code": "ERN", - "noun": "Eritrean nakfas", - "current_years": { - "start_year": 2015, - "end_year": 2019 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1992, - "base_year_max": 2019 + "property": "naics", + "binding": { + "state": "unbound" + } }, { - "code": "ETB", - "noun": "Ethiopian birr", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, + "property": "schoolGradeLevel", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2013, + "end_year": 2022 + }, + "facets": { + "unit": { + "state": "value", + "ref": "USDollar" + } + } + } + }, + "resolved": { + "shape": { + "shape_id": "economicactivity_amount_measuredvalue_nominal", + "label": "Nominal gross domestic product", + "population_type": { + "ref": "EconomicActivity", + "label": "EconomicActivity" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ { - "code": "EUR", - "noun": "euros", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" }, - "base_year_min": 1973, - "base_year_max": 2025 + "label": "activity source" }, { - "code": "FJD", - "noun": "Fijian dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" }, - "base_year_min": 1980, - "base_year_max": 2025 + "label": "economic sector" }, { - "code": "GBP", - "noun": "British pounds", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" }, - "base_year_min": 1960, - "base_year_max": 2025 + "label": "naics" }, { - "code": "GEL", - "noun": "Georgian lari", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" }, - "base_year_min": 1994, - "base_year_max": 2025 + "label": "school grade level" }, { - "code": "GHS", - "noun": "Ghanaian cedis", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "axis": "where", + "label": "place" }, { - "code": "GMD", - "noun": "Gambian dalasis", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "axis": "when", + "label": "time window" }, { - "code": "GNF", - "noun": "Guinean francs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 - }, + "axis": "source", + "label": "data source" + } + ], + "member_count": 65, + "member_digest": "73519eeb75639bdae33042fc844830cd46becc08e4f9122dfcd0886e9875f657", + "refine_supported": true, + "data_commons": [ { - "code": "GTQ", - "noun": "Guatemalan quetzales", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "id": "base", + "label": "Data Commons by Google" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" }, - "base_year_min": 1980, - "base_year_max": 2025 + "label": "activity source" }, - { - "code": "GYD", - "noun": "Guyanese dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } }, - { - "code": "HKD", - "noun": "Hong Kong dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" }, - "base_year_min": 1980, - "base_year_max": 2025 + "label": "economic sector" }, - { - "code": "HNL", - "noun": "Honduran lempiras", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "binding": { + "kind": "unbound" }, - { - "code": "HTG", - "noun": "Haitian gourdes", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" }, - "base_year_min": 1980, - "base_year_max": 2025 + "label": "naics" }, - { - "code": "HUF", - "noun": "Hungarian forints", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2003, - "base_year_max": 2025 + "binding": { + "kind": "unbound" }, - { - "code": "IDR", - "noun": "Indonesian rupiahs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" }, - "base_year_min": 1980, - "base_year_max": 2025 + "label": "school grade level" }, - { - "code": "ILS", - "noun": "Israeli new shekels", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1997, - "base_year_max": 2025 + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" + } + ] }, - { - "code": "INR", - "noun": "Indian rupees", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" }, - { - "code": "IQD", - "noun": "Iraqi dinars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2000, - "base_year_max": 2025 + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2013, + "end_year": 2022 + } + } }, - { - "code": "IRR", - "noun": "Iranian rials", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" }, - { - "code": "ISK", - "noun": "Icelandic krónur", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1997, - "base_year_max": 2025 + "binding": { + "kind": "unbound" }, + "summable": false + } + ], + "inapplicable_slots": [ + "economicSector", + "naics", + "schoolGradeLevel" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 41, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "2013", + "end": "2022" + } + }, + "entities": [ + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "observationAbout" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "entity_groups": { + "observationAbout": { + "ref": "SubSaharanAfrica", + "label": "Sub-Saharan Africa", + "entity_type": "UNGeoRegion" + } + }, + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 463, + "evidence": "facet_metadata", + "dimensions": [ { - "code": "JMD", - "noun": "Jamaican dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "label": "countries", + "count": 47 }, { - "code": "JOD", - "noun": "Jordanian dinars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "label": "observations", + "count": 10 }, { - "code": "JPY", - "noun": "Japanese yen", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1960, - "base_year_max": 2025 + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2013, + "end_year": 2022 + } + }, + "download": { + "rows": 463, + "rows_exact": true, + "series": 47, + "window": { + "start_year": 2013, + "end_year": 2022 + }, + "licence": { + "label": "Creative Commons Attribution License" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" }, - { - "code": "KES", - "noun": "Kenyan shillings", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "data_commons": { + "id": "base", + "label": "Data Commons by Google" }, - { - "code": "KGS", - "noun": "Kyrgyz soms", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "unit": { + "basis": "bound", + "ref": "USDollar", + "label": "USDollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" }, - "base_year_min": 1992, - "base_year_max": 2025 + "label": "activity source" }, - { - "code": "KHR", - "noun": "Cambodian riels", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "options": [ + { + "value": { + "ref": { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" }, - "base_year_min": 1986, - "base_year_max": 2025 + "label": "economic sector" }, - { - "code": "KMF", - "noun": "Comorian francs", - "current_years": { - "start_year": 2015, - "end_year": 2022 + "options": [ + { + "value": { + "ref": { + "ref": "AccommodationAndFoodSector", + "label": "Accommodation and food sector" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "AdministrativeAndSupportServices", + "label": "Administrative and support services" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "KRW", - "noun": "South Korean won", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "AgriculturalSupportActivities", + "label": "Agricultural support activities" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "Agriculture", + "label": "Agriculture" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1987, - "base_year_max": 2025 - }, - { - "code": "KWD", - "noun": "Kuwaiti dinars", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "AgricultureForestryFishingSector", + "label": "Agriculture,Forestry and Fishing Sector" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "AirTransportAndSupportServices", + "label": "Air transport and support services" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1995, - "base_year_max": 2024 - }, - { - "code": "KZT", - "noun": "Kazakh tenge", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "AllEconomicActivities", + "label": "All economic activities" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "AnimalProduction", + "label": "Animal production" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 2013, - "base_year_max": 2024 - }, - { - "code": "LAK", - "noun": "Lao kip", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "ArtsEntertainmentRecreation", + "label": "Arts entertainment recreation" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "ConstructionSector", + "label": "Construction Sector" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "LBP", - "noun": "Lebanese pounds", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "Education", + "label": "Education" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "ElectricitySupply", + "label": "Electricity supply" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "LKR", - "noun": "Sri Lankan rupees", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "EmployerHouseholdActivities", + "label": "Employer household activities" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "FinancialActivities", + "label": "FinancialActivities" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1980, - "base_year_max": 2024 - }, - { - "code": "LSL", - "noun": "Lesotho maloti", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "FinancialAndInsuranceActivities", + "label": "Financial and insurance activities" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "FinancialIntermediationServicesIndirectlyMeasured", + "label": "Financial intermediation services indirectly measured" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "LYD", - "noun": "Libyan dinars", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "FishingAquaculture", + "label": "Fishing aquaculture" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "FoodBeveragesTobaccoManufacture", + "label": "Food beverages tobacco manufacture" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MAD", - "noun": "Moroccan dirhams", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "ForestryLogging", + "label": "Forestry logging" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "HumanHealthAndSocialWork", + "label": "Human health and social work" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MDL", - "noun": "Moldovan lei", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "InformationAndCommunication", + "label": "Information and communication" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "InsuranceActivities", + "label": "Insurance activities" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1992, - "base_year_max": 2025 - }, - { - "code": "MGA", - "noun": "Malagasy ariary", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "LandTransport", + "label": "Land transport" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "ManufacturingSector", + "label": "Manufacturing Sector" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MKD", - "noun": "Macedonian denars", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "MiningQuarrying", + "label": "Mining quarrying" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "OtherManufacturingAndRepair", + "label": "Other manufacturing and repair" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1992, - "base_year_max": 2025 - }, - { - "code": "MMK", - "noun": "Myanmar kyats", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "OtherServiceSector", + "label": "Other service sector" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "OtherTransportPostalCourierActivities", + "label": "Other transport postal courier activities" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1998, - "base_year_max": 2025 - }, - { - "code": "MNT", - "noun": "Mongolian tugriks", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "ProductTaxes", + "label": "Product taxes" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "ProfessionalScientificTechnicalActivities", + "label": "Professional scientific technical activities" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MOP", - "noun": "Macanese patacas", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "PublicAdministrationAndDefence", + "label": "Public administration and defence" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "PublishingBroadcastingInformationActivities", + "label": "Publishing Broadcasting Information Activities" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 2001, - "base_year_max": 2025 - }, - { - "code": "MRU", - "noun": "Mauritanian ouguiyas", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "RealEstate", + "label": "Real estate" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "Telecommunications", + "label": "Telecommunications" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1990, - "base_year_max": 2025 - }, - { - "code": "MUR", - "noun": "Mauritian rupees", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "TransportStorageSector", + "label": "Transport and Storage" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "WaterSupplySewerageWasteManagement", + "label": "Water supply sewerage waste management" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MVR", - "noun": "Maldivian rufiyaa", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "WholesaleRetailTradeAndRepair", + "label": "Wholesale retail trade and repair" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "BankingAndInsuranceSector", + "label": "Banking And Insurance Sector" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MWK", - "noun": "Malawian kwachas", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "Construction", + "label": "Manufacturing" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "ElectricityGasSteamAirConditionSupply", + "label": "Electric Gas Steam Air Condition Supply" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" }, - "base_year_min": 1980, - "base_year_max": 2025 + "label": "school grade level" }, - { - "code": "MXN", - "noun": "Mexican pesos", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "options": [ + { + "value": { + "ref": { + "ref": "HigherSecondaryEducation", + "label": "Higher Secondary Education" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1980, - "base_year_max": 2025 - }, - { - "code": "MYR", - "noun": "Malaysian ringgits", - "current_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "PrePrimaryAndPrimaryEducation", + "label": "PrePrimary and Primary" + }, + "value_kind": "enum_value" + } }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + { + "value": { + "ref": { + "ref": "SecondaryEducation", + "label": "SecondaryEducation" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + } + ], + "entity_options": [], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "USDollar", + "label": "USDollar" + }, + "value_kind": "enum_value" + } }, - "base_year_min": 1980, - "base_year_max": 2025 - }, + { + "value": { + "ref": { + "ref": "XAF", + "label": "XAF" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "GDP in the 48 countries in Sub-Saharan Africa, 2013 to 2022. Current US dollars · World Development Indicators.", + "sentence_plan": [ + { + "kind": "slot", + "text": "GDP", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:activitySource", + "axis:populationType", + "axis:measuredProperty", + "axis:statType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " in ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2013 to 2022", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "World Development Indicators", + "axis": "source", + "segment": "byline", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [ { - "code": "MZN", - "noun": "Mozambican meticais", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/AGO", + "label": "Angola" }, { - "code": "NAD", - "noun": "Namibian dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1989, - "base_year_max": 2025 + "ref": "country/BDI", + "label": "Burundi" }, { - "code": "NGN", - "noun": "Nigerian naira", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1990, - "base_year_max": 2025 + "ref": "country/BEN", + "label": "Benin" }, { - "code": "NIO", - "noun": "Nicaraguan córdobas", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1987, - "base_year_max": 2025 + "ref": "country/BFA", + "label": "Burkina Faso" }, { - "code": "NOK", - "noun": "Norwegian kroner", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1960, - "base_year_max": 2025 + "ref": "country/BWA", + "label": "Botswana" }, { - "code": "NPR", - "noun": "Nepalese rupees", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/CAF", + "label": "Central African Republic" }, { - "code": "NZD", - "noun": "New Zealand dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1961, - "base_year_max": 2025 + "ref": "country/CIV", + "label": "Ivory Coast" }, { - "code": "OMR", - "noun": "Omani rials", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/CMR", + "label": "Cameroon" }, { - "code": "PEN", - "noun": "Peruvian soles", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/COD", + "label": "Democratic Republic of the Congo" }, { - "code": "PGK", - "noun": "Papua New Guinean kina", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/COG", + "label": "Republic of the Congo" }, { - "code": "PHP", - "noun": "Philippine pesos", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/COM", + "label": "Comoros" }, { - "code": "PKR", - "noun": "Pakistani rupees", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/CPV", + "label": "Cape Verde" }, { - "code": "PLN", - "noun": "Polish zlotys", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1998, - "base_year_max": 2025 + "ref": "country/DJI", + "label": "Djibouti" }, { - "code": "PYG", - "noun": "Paraguayan guaranís", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/ERI", + "label": "Eritrea" }, { - "code": "QAR", - "noun": "Qatari riyals", - "current_years": { - "start_year": 2020, - "end_year": 2020 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2023, - "base_year_max": 2023 + "ref": "country/ETH", + "label": "Ethiopia" }, { - "code": "RON", - "noun": "Romanian lei", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2013, - "base_year_max": 2025 + "ref": "country/GAB", + "label": "Gabon" }, { - "code": "RSD", - "noun": "Serbian dinars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1997, - "base_year_max": 2025 + "ref": "country/GHA", + "label": "Ghana" }, { - "code": "RUB", - "noun": "Russian rubles", - "current_years": { - "start_year": 2015, - "end_year": 2020 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2010, - "base_year_max": 2020 + "ref": "country/GIN", + "label": "Guinea" }, { - "code": "RWF", - "noun": "Rwandan francs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/GMB", + "label": "The Gambia" }, { - "code": "SAR", - "noun": "Saudi riyals", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2000, - "base_year_max": 2023 + "ref": "country/GNB", + "label": "Guinea-Bissau" }, { - "code": "SBD", - "noun": "Solomon Islands dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/GNQ", + "label": "Equatorial Guinea" }, { - "code": "SCR", - "noun": "Seychellois rupees", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/KEN", + "label": "Kenya" }, { - "code": "SDG", - "noun": "Sudanese pounds", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/LBR", + "label": "Liberia" }, { - "code": "SEK", - "noun": "Swedish kronor", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1960, - "base_year_max": 2025 + "ref": "country/LSO", + "label": "Lesotho" }, { - "code": "SGD", - "noun": "Singapore dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/MDG", + "label": "Madagascar" }, { - "code": "SLE", - "noun": "Sierra Leonean leones", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/MLI", + "label": "Mali" }, { - "code": "SRD", - "noun": "Surinamese dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/MOZ", + "label": "Mozambique" }, { - "code": "SSP", - "noun": "South Sudanese pounds", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2011, - "base_year_max": 2025 + "ref": "country/MRT", + "label": "Mauritania" }, { - "code": "STN", - "noun": "São Tomé and Príncipe dobras", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/MUS", + "label": "Mauritius" }, { - "code": "SYP", - "noun": "Syrian pounds", - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2010, - "current_years": null + "ref": "country/MWI", + "label": "Malawi" }, { - "code": "SZL", - "noun": "Swazi emalangeni", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/NAM", + "label": "Namibia" }, { - "code": "THB", - "noun": "Thai baht", - "current_years": { - "start_year": 2018, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2018, - "base_year_max": 2024 + "ref": "country/NER", + "label": "Niger" }, { - "code": "TJS", - "noun": "Tajikistani somonis", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1992, - "base_year_max": 2025 + "ref": "country/NGA", + "label": "Nigeria" }, { - "code": "TMT", - "noun": "Turkmenistani manat", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1992, - "base_year_max": 2025 + "ref": "country/RWA", + "label": "Rwanda" }, { - "code": "TND", - "noun": "Tunisian dinars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/SEN", + "label": "Senegal" }, { - "code": "TOP", - "noun": "Tongan paʻanga", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/SLE", + "label": "Sierra Leone" }, { - "code": "TRY", - "noun": "Turkish lira", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1990, - "base_year_max": 2025 + "ref": "country/SOM", + "label": "Somalia" }, { - "code": "TTD", - "noun": "Trinidad and Tobago dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/SSD", + "label": "South Sudan" }, { - "code": "TWD", - "noun": "New Taiwan dollars", - "current_years": { - "start_year": 2018, - "end_year": 2021 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2023, - "base_year_max": 2025 + "ref": "country/STP", + "label": "São Tomé and Príncipe" }, { - "code": "TZS", - "noun": "Tanzanian shillings", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/SWZ", + "label": "Swaziland" }, { - "code": "UAH", - "noun": "Ukrainian hryvnias", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1991, - "base_year_max": 2025 + "ref": "country/SYC", + "label": "Seychelles" }, { - "code": "UGX", - "noun": "Ugandan shillings", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/TCD", + "label": "Chad" }, { - "code": "USD", - "noun": "US dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1960, - "base_year_max": 2025 + "ref": "country/TGO", + "label": "Togo" }, { - "code": "UYU", - "noun": "Uruguayan pesos", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/TZA", + "label": "Tanzania" }, { - "code": "UZS", - "noun": "Uzbekistani soms", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1992, - "base_year_max": 2025 + "ref": "country/UGA", + "label": "Uganda" }, { - "code": "VES", - "noun": "Venezuelan bolívares", - "current_years": { - "start_year": 2017, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 2017, - "base_year_max": 2025 + "ref": "country/ZAF", + "label": "South Africa" }, { - "code": "VND", - "noun": "Vietnamese dong", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 - }, - "base_year_min": 1980, - "base_year_max": 2025 + "ref": "country/ZMB", + "label": "Zambia" }, { - "code": "VUV", - "noun": "Vanuatu vatu", - "current_years": { - "start_year": 2015, - "end_year": 2022 + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "resolved_sources": [ + { + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "source": { + "ref": "dc/s/WorldBank", + "label": "World Bank" }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "data_commons": { + "id": "base", + "label": "Data Commons by Google" }, - "base_year_min": 1980, - "base_year_max": 2025 - }, + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + } + ], + "slot_filters": [ { - "code": "WST", - "noun": "Samoan tala", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "key": { + "axis": "how", + "property": { + "ref": "activitySource", + "label": "activitySource" + }, + "label": "activity source" }, - "base_year_min": 1980, - "base_year_max": 2025 + "binding_kind": "value", + "refs": [ + { + "ref": "GrossDomesticProduction", + "label": "GrossDomesticProduction" + } + ], + "provenance": "binder" }, { - "code": "XAF", - "noun": "Central African CFA francs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "key": { + "axis": "how", + "property": { + "ref": "economicSector", + "label": "economicSector" + }, + "label": "economic sector" }, - "base_year_min": 1980, - "base_year_max": 2025 + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" }, { - "code": "XCD", - "noun": "East Caribbean dollars", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "key": { + "axis": "how", + "property": { + "ref": "naics", + "label": "naics" + }, + "label": "naics" }, - "base_year_min": 1980, - "base_year_max": 2025 + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" }, { - "code": "XOF", - "noun": "West African CFA francs", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "key": { + "axis": "how", + "property": { + "ref": "schoolGradeLevel", + "label": "schoolGradeLevel" + }, + "label": "school grade level" }, - "base_year_min": 1980, - "base_year_max": 2025 + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" }, { - "code": "YER", - "noun": "Yemeni rials", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "key": { + "axis": "where", + "label": "place" }, - "base_year_min": 2014, - "base_year_max": 2025 + "binding_kind": "set", + "refs": [ + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + } + ], + "provenance": "binder" }, { - "code": "ZAR", - "noun": "South African rand", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "key": { + "axis": "when", + "label": "time window" }, - "base_year_min": 1980, - "base_year_max": 2025 + "binding_kind": "value", + "refs": [], + "provenance": "binder" }, { - "code": "ZMW", - "noun": "Zambian kwachas", - "current_years": { - "start_year": 2015, - "end_year": 2022 - }, - "constant_years": { - "start_year": 2015, - "end_year": 2022 + "key": { + "axis": "source", + "label": "data source" }, - "base_year_min": 1980, - "base_year_max": 2025 + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" } ], - "default_base_year": 2024, - "role_currencies": { - "origin": "EUR" - } - } + "query_qualifiers": [], + "requested_window": { + "start_year": 2013, + "end_year": 2022 + }, + "capability_version": "cap_94e25737d859392c" + }, + "confidence": "high", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [], + "related_measures": [] } } } ], - "rendered_sentence": "Primary income for gross of fixed capital consumption in 49 places, 2015 to 2022. Current US dollars · World Bank International Debt Statistics (IDS). You asked for Germany, Eritrea, Namibia, South Sudan, and Seychelles. The data holds no values for them. Germany's gross disbursements to the 48 countries in Sub-Saharan Africa for official development assistance, 2015 to 2022. Current US dollars · OECD DAC2a. This shows the 48 countries in Sub-Saharan Africa, each on its own.", + "rendered_sentence": "Deaths rate per capita in the 48 countries in Sub-Saharan Africa, 2013 to 2022. World Development Indicators. This shows the 48 countries in Sub-Saharan Africa, each on its own. GDP in the 48 countries in Sub-Saharan Africa, 2013 to 2022. Current US dollars · World Development Indicators. The data holds no values for 1 of the 48 countries in Sub-Saharan Africa. This shows the 48 countries in Sub-Saharan Africa, each on its own.", "sentence_plan": [ { "kind": "slot", - "text": "Primary income", + "text": "Deaths rate", "axis": "what", "segment": "heading", "entity_refs": [], @@ -15915,7 +14675,16 @@ }, { "kind": "text", - "text": " for ", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "per capita", + "axis": "unit", "segment": "heading", "entity_refs": [], "states": [], @@ -15923,15 +14692,13 @@ }, { "kind": "slot", - "text": "gross of fixed capital consumption", + "text": "", "axis": "how", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ], + "states": [], "part_index": 0 }, { @@ -15944,7 +14711,7 @@ }, { "kind": "slot", - "text": "49 places", + "text": "the 48 countries in Sub-Saharan Africa", "axis": "where", "segment": "heading", "binding_ref": "where:", @@ -15964,7 +14731,7 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -15992,28 +14759,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ], - "part_index": 0 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "slot", - "text": "World Bank International Debt Statistics (IDS)", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -16040,7 +14786,7 @@ }, { "kind": "text", - "text": "You asked for Germany, Eritrea, Namibia, South Sudan, and Seychelles. The data holds no values for them.", + "text": "This shows the 48 countries in Sub-Saharan Africa, each on its own.", "segment": "departure", "entity_refs": [], "states": [], @@ -16055,137 +14801,49 @@ }, { "kind": "slot", - "text": "Germany", - "segment": "heading", - "role": "origin", - "binding_ref": "origin:", - "entity_refs": [ - "country/DEU" - ], - "states": [ - "origin:" - ], - "part_index": 1 - }, - { - "kind": "text", - "text": "'s", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 1 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 1 - }, - { - "kind": "slot", - "text": "gross disbursements", + "text": "GDP", "axis": "what", "segment": "heading", "entity_refs": [], "states": [ - "how:financialFlowType", - "how:nettingBasis", + "how:activitySource", "axis:populationType", - "axis:measuredProperty" + "axis:measuredProperty", + "axis:statType" ], "part_index": 1 }, { - "kind": "text", - "text": " to ", + "kind": "slot", + "text": "", + "axis": "how", "segment": "heading", + "property_dcid": "economicSector", + "binding_ref": "how:economicSector", "entity_refs": [], "states": [], "part_index": 1 }, { "kind": "slot", - "text": "the 48 countries in Sub-Saharan Africa", - "axis": "where", - "segment": "heading", - "role": "destination", - "binding_ref": "where:", - "entity_refs": [ - "country/AGO", - "country/BDI", - "country/BEN", - "country/BFA", - "country/BWA", - "country/CAF", - "country/CIV", - "country/CMR", - "country/COD", - "country/COG", - "country/COM", - "country/CPV", - "country/DJI", - "country/ERI", - "country/ETH", - "country/GAB", - "country/GHA", - "country/GIN", - "country/GMB", - "country/GNB", - "country/GNQ", - "country/KEN", - "country/LBR", - "country/LSO", - "country/MDG", - "country/MLI", - "country/MOZ", - "country/MRT", - "country/MUS", - "country/MWI", - "country/NAM", - "country/NER", - "country/NGA", - "country/RWA", - "country/SEN", - "country/SLE", - "country/SOM", - "country/SSD", - "country/STP", - "country/SWZ", - "country/SYC", - "country/TCD", - "country/TGO", - "country/TZA", - "country/UGA", - "country/ZAF", - "country/ZMB", - "country/ZWE" - ], - "states": [ - "where:" - ], - "part_index": 1 - }, - { - "kind": "text", - "text": " for ", + "text": "", + "axis": "how", "segment": "heading", + "property_dcid": "naics", + "binding_ref": "how:naics", "entity_refs": [], "states": [], "part_index": 1 }, { "kind": "slot", - "text": "official development assistance", + "text": "", "axis": "how", "segment": "heading", - "property_dcid": "dac2aAidType", - "binding_ref": "how:dac2aAidType", + "property_dcid": "schoolGradeLevel", + "binding_ref": "how:schoolGradeLevel", "entity_refs": [], - "states": [ - "how:dac2aAidType" - ], + "states": [], "part_index": 1 }, { @@ -16193,32 +14851,30 @@ "text": "", "axis": "how", "segment": "heading", - "property_dcid": "dacTypeOfFinance", - "binding_ref": "how:dacTypeOfFinance", + "property_dcid": "activitySource", + "binding_ref": "how:activitySource", "entity_refs": [], "states": [], "part_index": 1 }, { - "kind": "slot", - "text": "", - "axis": "how", + "kind": "text", + "text": " in ", "segment": "heading", - "property_dcid": "financialFlowType", - "binding_ref": "how:financialFlowType", "entity_refs": [], "states": [], "part_index": 1 }, { "kind": "slot", - "text": "", - "axis": "how", + "text": "the 48 countries in Sub-Saharan Africa", + "axis": "where", "segment": "heading", - "property_dcid": "nettingBasis", - "binding_ref": "how:nettingBasis", + "binding_ref": "where:", "entity_refs": [], - "states": [], + "states": [ + "where:" + ], "part_index": 1 }, { @@ -16231,7 +14887,7 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -16280,7 +14936,7 @@ }, { "kind": "slot", - "text": "OECD DAC2a", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -16305,6 +14961,22 @@ "states": [], "part_index": 1 }, + { + "kind": "text", + "text": "The data holds no values for 1 of the 48 countries in Sub-Saharan Africa.", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": " ", + "segment": "departure", + "entity_refs": [], + "states": [], + "part_index": 1 + }, { "kind": "text", "text": "This shows the 48 countries in Sub-Saharan Africa, each on its own.", @@ -16326,25 +14998,26 @@ "schema_version": 1, "input": { "kind": "spec_id", - "spec_id": "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", + "spec_id": "spec_176fd5e63bb2a122c4ad00831497b863", "definition": { "schema_version": 1, - "spec_id": "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", + "spec_id": "spec_176fd5e63bb2a122c4ad00831497b863", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], @@ -16362,7 +15035,6 @@ "country/COG", "country/COM", "country/CPV", - "country/DEU", "country/DJI", "country/ERI", "country/ETH", @@ -16403,7 +15075,7 @@ }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } @@ -16419,28 +15091,29 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "66f7b92c09b04f4eb11b0cf7c976f2be" + "x-dfo-trace-id": "56077c07b2ac447282af326922be9262" }, "json": { "schema_version": 1, "definition": { "schema_version": 1, - "spec_id": "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", + "spec_id": "spec_176fd5e63bb2a122c4ad00831497b863", "identity": { "shape": { "kind": "statvar_schema", "stat_type": "measuredValue", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", - "measurement_qualifier": "Nominal" + "population_type": "MortalityEvent", + "measured_property": "count", + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { "binding": { - "ref": "GrossOfFixedCapitalConsumption", - "state": "value" + "state": "unbound" }, - "property": "fixedCapitalConsumptionBasis" + "property": "causeOfDeath" } ], "entities": { @@ -16457,7 +15130,6 @@ "country/COG", "country/COM", "country/CPV", - "country/DEU", "country/DJI", "country/ERI", "country/ETH", @@ -16500,196 +15172,189 @@ "requested_window": { "kind": "range", "end_year": 2022, - "start_year": 2015 + "start_year": 2013 } } }, - "content_version": "cv_18a63cb9e24a4ce6dfcd1c60f0c5a470", - "prepared_at": "2026-10-21T13:07:13Z", + "content_version": "cv_6c43e754af661c87eb22e7a21595a732", + "prepared_at": "2026-10-23T17:40:51Z", "coverage": { - "rows": 348, + "rows": 480, "dimensions": [ { "label": "observationAbout", - "count": 44 + "count": 48 }, { "label": "years", - "count": 8 + "count": 10 } ], "window": { "kind": "range", - "start_year": 2015, + "origin": "query", "end_year": 2022, - "origin": "query" + "start_year": 2013 } }, "citation": { - "text": "World Bank International Debt Statistics (IDS) (2026), via the Development Finance Observatory", + "text": "World Development Indicators (2026), via the Development Finance Observatory", "sources": [ { - "ref": "provenance/WorldBankInternationalDebtStatistics", - "label": "World Bank International Debt Statistics (IDS)", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "license": "Creative Commons Attribution License", "license_type": "CreativeCommonsAttributionLicense", - "license_url": "https://datacatalog.worldbank.org/public-licenses?fragment=cc", - "url": "https://datacatalog.worldbank.org/search/dataset/0038015/international-debt-statistics", + "license_url": "https://datacatalog.worldbank.org/search/dataset/0037712", + "url": "https://datatopics.worldbank.org/world-development-indicators/", "source": { "ref": "dc/s/WorldBank", "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, "documentation": { "publisher": "World Bank", - "description": "International Debt Statistics (IDS) is the World Bank's annual dataset on the external debt of low- and middle-income countries. It reports debt stocks, disbursements, debt service and projected repayments by borrower and creditor type, with public and publicly guaranteed debt broken down by creditor, from 1970 onwards. The data come mainly from countries' loan-by-loan reporting of public and publicly guaranteed debt to the World Bank's Debtor Reporting System, which is a condition of borrowing from IBRD and IDA.", - "source_data_url": "https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092201/A_D.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092202/E_K.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092203/L_M.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0093225/N_Q.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092204/R_U.xlsx,https://datacatalogfiles.worldbank.org/ddh-published/0038015/DR0092205/V_Z.xlsx", - "attribution": "International Debt Statistics by the World Bank, https://datacatalog.worldbank.org/search/dataset/0038015/international-debt-statistics, licensed under CC BY 4.0. Modified by The ONE Campaign.", - "update_cadence": "Annual", + "description": "The primary World Bank collection of development indicators encompassing global economic and social data.", + "source_data_url": "http://api.worldbank.org/v2/en/country/AFG?downloadformat=csv", + "update_cadence": "Monthly", "last_update": "2026-10-13", - "years_covered": "1970-2032", - "granularity": "Annual, by provider and recipient", - "currencies": [ - "USD" - ], - "transformation_log": [ - { - "transformation": "Download the source data", - "description": "The World Bank publishes IDS as six bulk files, split by debtor name. All six are downloaded each time the pipeline runs, and replace the previous copy, so the data reflects the World Bank's latest release." - }, - { - "transformation": "Exclude series outside the debt statistics", - "description": "Non-debt statistics are excluded, including population, balance of payments, investment and reserves. GNI is kept, because some debt ratios are shares of it. Exports of goods, services and primary income, and the three debt ratios that are shares of it, are excluded until the ontology can describe them. Debt forgiveness grants, the stock-flow reconciliation residual, the annual changes in debt stocks and interest arrears, and the present value of debt are also excluded." - }, - { - "transformation": "Omit zeros where no lending took place", - "description": "IDS reports a value for every debtor, creditor and series, including pairs with no lending between them, so most figures are zero. Zeros are kept on world totals, and within or after a period of lending between a debtor and a creditor. They are omitted where a creditor has not lent to a debtor, for the years before lending began, and for averages in years with no new commitments, since there is nothing to average." - }, - { - "transformation": "Standardise debtors and creditors", - "description": "Debtor and creditor codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets. Where a series names a single lender in its code, such as debt owed to the IBRD, that lender becomes the creditor." - }, - { - "transformation": "Select dimensions", - "description": "Every figure is reported against the year, the debtor and the creditor, and the dimensions the World Bank encodes in each series code, such as type of flow, maturity and creditor type. GNI is the exception: it describes the debtor economy, so it is reported against the year and the economy alone. Ratios record what they are a share of: GNI or total external debt stocks. Every amount is reported in US dollars at current prices." - }, - { - "transformation": "Mark projections as estimated", - "description": "For the years after the last reported year, the World Bank projects debt service and disbursements on commitments already made. These values are marked as estimated, so they are kept apart from reported values." - } - ], - "version_history": [ - { - "date": "2026-10-14", - "title": "First release", - "changes": [ - { - "kind": "added", - "note": "External debt stocks, flows and debt service of low- and middle-income countries by borrower and creditor, with related ratios and gross national income." - } - ] - } - ] + "currencies": [], + "transformation_log": [], + "version_history": [] } } ] }, - "trace": { - "applied_window": { - "kind": "range", - "start_year": 2015, - "end_year": 2022, - "origin": "query" - }, - "graph_revision": null, - "code_index_stamp": { - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", - "exported_at": "2026-10-20T19:50:14Z", - "graph_endpoint": "graph_release" - }, - "origin_catalogue_build_id": "20261021T070020Z-7262111e", - "source_revisions": [ - { - "source": "provenance/WorldBankInternationalDebtStatistics", - "revision": "2026-10-13" - } - ], - "resolved_stat_vars": [ - { - "ref": "dcid:PrimaryIncome_EconomicUnit_GrossOfFixedCapitalConsumption_Nominal", - "roles": [ - "observationAbout" - ], - "observation_count": 348 - } - ], - "family_member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", - "family_member_count": 1, + "trace": { "facets": [ { + "ref": "dc/base/WorldDevelopmentIndicators", "axis": "provenance", - "ref": "provenance/WorldBankInternationalDebtStatistics", "basis": "deployment_fallback", "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", "selection_reason": "most_observations_over_disagreement", - "dispatch_facet_id": "2052749850102211920" + "dispatch_facet_id": "14219717798868772133", + "default_policy_version": "1" }, { + "ref": "WorldBankWeightedAverage", "axis": "measurementMethod", - "ref": null, "basis": "deployment_fallback", "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "absent_on_selected_facet", - "dispatch_facet_id": "2052749850102211920" + "selection_reason": "most_observations_over_disagreement", + "dispatch_facet_id": "14219717798868772133", + "default_policy_version": "1" }, { + "ref": "Per1000Persons", "axis": "unit", - "ref": "CurrencyUSD", "basis": "deployment_fallback", "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "most_observations", - "dispatch_facet_id": "2052749850102211920" + "selection_reason": "most_observations_over_disagreement", + "dispatch_facet_id": "14219717798868772133", + "default_policy_version": "1" } ], - "normalisations": [], "choices": [ { "axis": "provenance", "candidates": [ { - "ref": "provenance/WorldBankInternationalDebtStatistics", - "places": 44, - "years": 8, - "observations": 2249 + "ref": "dc/base/WorldDevelopmentIndicators", + "years": 10, + "places": 48, + "observations": 3120 + }, + { + "ref": "dc/base/Cotedivoire_Census", + "years": 6, + "places": 1, + "observations": 6 + }, + { + "ref": "dc/base/Kenya_Census", + "years": 1, + "places": 1, + "observations": 1 + } + ] + }, + { + "axis": "measurementMethod", + "candidates": [ + { + "ref": "WorldBankWeightedAverage", + "years": 10, + "places": 48, + "observations": 3120 + }, + { + "ref": null, + "years": 6, + "places": 1, + "observations": 6 + } + ] + }, + { + "axis": "unit", + "candidates": [ + { + "ref": "Per1000Persons", + "years": 10, + "places": 48, + "observations": 3120 }, { - "ref": "provenance/OECDDAC1", + "ref": null, + "years": 1, "places": 1, - "years": 8, - "observations": 66 + "observations": 1 } ] } ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2022, + "start_year": 2013 + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00260-6xk", + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-23T13:00:17Z", + "content_hash": "29eb81d7b6c88641b1d4e8eb5e850ca36de66b99d6e9e09680aac020507a6392", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "dc/base/WorldDevelopmentIndicators", + "revision": "2026-10-13" + } + ], + "capability_version": "dset_cc753cefa9199881", + "materialiser_build": "c7543c9d64fb0dbeea028b04da6c59c997e50fbc", + "resolved_stat_vars": [ + { + "ref": "dcid:Count_Death_AsAFractionOfCount_Person", + "roles": [ + "observationAbout" + ], + "observation_count": 480 + } + ], + "family_member_count": 133, + "family_member_digest": "c090b56d31a596a8be16dafb518382db666c6b100a80534c3cb81dbfe3111c5d", "frame_grammar_version": "1.1.0", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "capability_version": "dset_88fecfec3c5b89d1", - "served_from": "materialise", - "confirmed_at": "2026-10-21T13:07:13.393388+00:00" + "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", + "served_from": "head", + "confirmed_at": "2026-10-23T18:39:33.191814+00:00" }, - "warnings": [ - { - "code": "coverage_below_scope", - "severity": "warn", - "message": "The served coverage falls short of the requested scope. No observations were served for country/DEU, country/ERI, country/NAM, country/SSD, country/SYC." - } - ], + "warnings": [], "diagnostics": [ { "code": "processing_level_undeclared", @@ -16699,33 +15364,33 @@ ], "artifacts": [ { - "artifact_digest": "sha256:05184087a3031ed02bb45806f4a6c134b580ace5cada64878fca2aaa75acdb91", + "artifact_digest": "sha256:0652c59a04403a740ed0a4a75360cc04900bbcce57dfc4d7f7b7d2b21a9404dd", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9453, + "bytes": 9259, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:07:13.365418+00:00", + "created_at": "2026-10-23T17:40:52.293546+00:00", "tier": "working", - "url": "/api/datasets/spec_bc87ff8e0f29960c38c96a4f4d2b0e20/cv_18a63cb9e24a4ce6dfcd1c60f0c5a470/files/sha256:05184087a3031ed02bb45806f4a6c134b580ace5cada64878fca2aaa75acdb91" + "url": "/api/datasets/spec_176fd5e63bb2a122c4ad00831497b863/cv_6c43e754af661c87eb22e7a21595a732/files/sha256:0652c59a04403a740ed0a4a75360cc04900bbcce57dfc4d7f7b7d2b21a9404dd" }, { - "artifact_digest": "sha256:9f6cef75c54026bc957665229b19adb252d00d61f542483166394fa4aa273370", + "artifact_digest": "sha256:bd259d52a10e62d1a97e04ca5ad722c043dd38997750e8dc7a785dcd5b697056", "rendering": { "statistics": "series" }, - "bytes": 8146, + "bytes": 8267, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:07:13.365418+00:00", + "created_at": "2026-10-23T17:40:52.293546+00:00", "tier": "working", - "url": "/api/datasets/spec_bc87ff8e0f29960c38c96a4f4d2b0e20/cv_18a63cb9e24a4ce6dfcd1c60f0c5a470/files/sha256:9f6cef75c54026bc957665229b19adb252d00d61f542483166394fa4aa273370" + "url": "/api/datasets/spec_176fd5e63bb2a122c4ad00831497b863/cv_6c43e754af661c87eb22e7a21595a732/files/sha256:bd259d52a10e62d1a97e04ca5ad722c043dd38997750e8dc7a785dcd5b697056" } ], - "series_count": 44, + "series_count": 48, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -16737,13 +15402,13 @@ "name": "observationAbout", "kind": "role", "droppable": false, - "distinct": 44 + "distinct": 48 }, { "name": "time_period", "kind": "grain", "droppable": false, - "distinct": 8 + "distinct": 10 }, { "name": "value", @@ -16798,8 +15463,8 @@ "token": "observationAbout_iso3", "state": "available", "coverage": { - "entities": 44, - "covered": 44 + "entities": 48, + "covered": 48 }, "missing": [], "truncated": false @@ -16808,12 +15473,18 @@ "column": "observationAbout", "field": "iso2", "token": "observationAbout_iso2", - "state": "available", + "state": "partial", + "reason": "enrichment_unavailable", "coverage": { - "entities": 44, - "covered": 44 + "entities": 48, + "covered": 47 }, - "missing": [], + "missing": [ + { + "ref": "country/SSD", + "label": "South Sudan" + } + ], "truncated": false }, { @@ -16822,8 +15493,8 @@ "token": "observationAbout_label", "state": "available", "coverage": { - "entities": 44, - "covered": 44 + "entities": 48, + "covered": 48 }, "missing": [], "truncated": false @@ -16834,8 +15505,8 @@ "token": "observationAbout_type", "state": "available", "coverage": { - "entities": 44, - "covered": 44 + "entities": 48, + "covered": 48 }, "missing": [], "truncated": false @@ -16850,15 +15521,15 @@ "index": "observationAbout", "columns": "time_period", "state": "available", - "width": 9, - "cells": 396 + "width": 11, + "cells": 528 }, { "index": "time_period", "columns": "observationAbout", "state": "available", - "width": 45, - "cells": 360 + "width": 49, + "cells": 490 } ], "groupby": { @@ -16879,10 +15550,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:07:13.365465Z" + "held_until": "2026-11-22T17:40:52.293692Z" } } } @@ -16890,26 +15561,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_bc87ff8e0f29960c38c96a4f4d2b0e20/cv_18a63cb9e24a4ce6dfcd1c60f0c5a470/files/sha256:05184087a3031ed02bb45806f4a6c134b580ace5cada64878fca2aaa75acdb91" + "origin_path": "/api/datasets/spec_176fd5e63bb2a122c4ad00831497b863/cv_6c43e754af661c87eb22e7a21595a732/files/sha256:0652c59a04403a740ed0a4a75360cc04900bbcce57dfc4d7f7b7d2b21a9404dd" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A05184087a3031ed02bb45806f4a6c134b580ace5cada64878fca2aaa75acdb91?X-Goog-Signature=redacted", - "x-dfo-trace-id": "6ae6fbcb32de433b9c930ccae2a93638" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A0652c59a04403a740ed0a4a75360cc04900bbcce57dfc4d7f7b7d2b21a9404dd?X-Goog-Signature=redacted", + "x-dfo-trace-id": "cd6b8ede11cf4b3cbf3b5aef915f8d14" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3A05184087a3031ed02bb45806f4a6c134b580ace5cada64878fca2aaa75acdb91?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A0652c59a04403a740ed0a4a75360cc04900bbcce57dfc4d7f7b7d2b21a9404dd?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "62a06033b1da44e49a59a3cb04d69bab" + "content-type": "application/vnd.apache.parquet" }, "body_file": "choose-candidate-two-parts.parquet" } @@ -16922,50 +15593,48 @@ "schema_version": 1, "input": { "kind": "spec_id", - "spec_id": "spec_941030940d23f46826acaa0c6fed8bbc", + "spec_id": "spec_310c03c5f99c73c41d12226098714f81", "definition": { "schema_version": 1, - "spec_id": "spec_941030940d23f46826acaa0c6fed8bbc", + "spec_id": "spec_310c03c5f99c73c41d12226098714f81", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "FinancialFlow", + "population_type": "EconomicActivity", "measured_property": "amount", "stat_type": "measuredValue", "measurement_qualifier": "Nominal" }, "slots": [ { - "property": "dac2aAidType", + "property": "activitySource", "binding": { "state": "value", - "ref": "DAC2aAidType206" + "ref": "GrossDomesticProduction" } }, { - "property": "dacTypeOfFinance", + "property": "economicSector", "binding": { "state": "unbound" } }, { - "property": "financialFlowType", + "property": "naics", "binding": { - "state": "value", - "ref": "Disbursement" + "state": "unbound" } }, { - "property": "nettingBasis", + "property": "schoolGradeLevel", "binding": { - "state": "value", - "ref": "Gross" + "state": "unbound" } } ], "entities": { - "destination": [ + "observationAbout": [ "country/AGO", "country/BDI", "country/BEN", @@ -17014,15 +15683,18 @@ "country/ZAF", "country/ZMB", "country/ZWE" - ], - "origin": [ - "country/DEU" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 + }, + "facets": { + "unit": { + "state": "value", + "ref": "USDollar" + } } } } @@ -17037,55 +15709,56 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "59c41cc22b2c48969e22aa99e323d935" + "x-dfo-trace-id": "42d04700ff8e49ab9a21a3f778594017" }, "json": { "schema_version": 1, "definition": { "schema_version": 1, - "spec_id": "spec_941030940d23f46826acaa0c6fed8bbc", + "spec_id": "spec_310c03c5f99c73c41d12226098714f81", "identity": { "shape": { "kind": "statvar_schema", "stat_type": "measuredValue", - "population_type": "FinancialFlow", + "population_type": "EconomicActivity", "measured_property": "amount", "measurement_qualifier": "Nominal" }, "slots": [ { "binding": { - "ref": "DAC2aAidType206", + "ref": "GrossDomesticProduction", "state": "value" }, - "property": "dac2aAidType" + "property": "activitySource" }, { "binding": { "state": "unbound" }, - "property": "dacTypeOfFinance" + "property": "economicSector" }, { "binding": { - "ref": "Disbursement", - "state": "value" + "state": "unbound" }, - "property": "financialFlowType" + "property": "naics" }, { "binding": { - "ref": "Gross", - "state": "value" + "state": "unbound" }, - "property": "nettingBasis" + "property": "schoolGradeLevel" } ], + "facets": { + "unit": { + "ref": "USDollar", + "state": "value" + } + }, "entities": { - "origin": [ - "country/DEU" - ], - "destination": [ + "observationAbout": [ "country/AGO", "country/BDI", "country/BEN", @@ -17140,196 +15813,136 @@ "requested_window": { "kind": "range", "end_year": 2022, - "start_year": 2015 + "start_year": 2013 } } }, - "content_version": "cv_9362a741d742d00a0f4f5d671e0b400c", - "prepared_at": "2026-10-21T13:07:14Z", + "content_version": "cv_7a402f88c10de233e81d664ab22037a5", + "prepared_at": "2026-10-23T17:40:54Z", "coverage": { - "rows": 372, + "rows": 463, "dimensions": [ { - "label": "financingProvider", - "count": 1, - "axis": "origin", - "noun": { - "singular": "provider", - "plural": "providers" - } - }, - { - "label": "financingRecipient", - "count": 48, - "axis": "destination", - "noun": { - "singular": "recipient", - "plural": "recipients" - } + "label": "observationAbout", + "count": 47 }, { "label": "years", - "count": 8 + "count": 10 } ], "window": { "kind": "range", - "start_year": 2015, + "origin": "query", "end_year": 2022, - "origin": "query" + "start_year": 2013 } }, "citation": { - "text": "OECD DAC2A (2026), via the Development Finance Observatory", + "text": "World Development Indicators (2026), via the Development Finance Observatory", "sources": [ { - "ref": "provenance/OECDDAC2A", - "label": "OECD DAC2A", - "license": "OECD Terms and Conditions", - "license_type": "OECDTermsAndConditions", - "license_url": "https://www.oecd.org/en/about/terms-conditions.html", - "url": "https://data-explorer.oecd.org/vis?tm=dac2a&pg=0&snb=1&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_DAC2%40DF_DAC2A&df[ag]=OECD.DCD.FSD&df[vs]=1.6&dq=.DPGC.206.USD.Q&lom=LASTNPERIODS&lo=5&to[TIME_PERIOD]=false&isAvailabilityDisabled=false&page=0", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", + "license": "Creative Commons Attribution License", + "license_type": "CreativeCommonsAttributionLicense", + "license_url": "https://datacatalog.worldbank.org/search/dataset/0037712", + "url": "https://datatopics.worldbank.org/world-development-indicators/", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, "documentation": { - "publisher": "Organisation for Economic Co-operation and Development (OECD)", - "description": "DAC2A is the OECD Development Assistance Committee's table of ODA disbursements by donor and recipient country or region. It covers bilateral donors and multilateral agencies reporting their own outflows, and includes the OECD's estimate of each donor's core multilateral contributions attributed to recipients.", - "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip", - "attribution": "OECD (2026), OECD DAC2A, OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip (accessed on 2026-10-12)", - "update_cadence": "Quarterly", - "last_update": "2026-10-15", - "years_covered": "1960-2024", - "granularity": "Annual, by provider and recipient", - "currencies": [ - "USD" - ], - "transformation_log": [ - { - "transformation": "Download the source data", - "description": "The OECD publishes DAC2A in April, June, September and December. The complete table is downloaded from the OECD each time it is republished, and replaces the previous copy, so the data reflects the OECD's latest release." - }, - { - "transformation": "Exclude the partial preliminary year", - "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." - }, - { - "transformation": "Standardise providers and recipients", - "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets. The totals DAC2A reports for groups of providers, such as all DAC countries, and for groups of recipients, such as regions and income groups, are included as providers and recipients of their own. Where two provider codes name the same organisation and report the same figures, the figures are counted once. Where two recipient codes name the same organisation, such as IDA and IDA's Multilateral Debt Relief Initiative, their flows are added." - }, - { - "transformation": "Select figures", - "description": "Only figures in current US dollars are included, not constant US dollars. Only flows to recipients on Part I of the DAC List are included: the developing countries, and the multilateral organisations DAC2A reports as recipients, such as development banks and UN agencies. Flows to Part II recipients, the countries in transition, are excluded." - }, - { - "transformation": "Convert to whole units", - "description": "DAC2A reports amounts in millions, which are converted to whole units. ODA per person and ODA as a share of GNI are kept as reported." - }, - { - "transformation": "Select dimensions", - "description": "Each figure is reported by year, provider, recipient and type of aid, such as grants, repayments, interest received, or debt forgiven or rescheduled. DAC2A is a table of disbursements, so every figure, repayments and interest included, is recorded as a disbursement. Figures are marked as gross or net, except where DAC2A does not say which, and as grants or non-grants where the type of aid is wholly one or the other. Imputed multilateral ODA, the OECD's estimate of each provider's share of multilateral organisations' ODA, is marked as modelled. ODA as a share of GNI records the recipient's GNI as its denominator, and ODA per person records the recipient's population." - } - ], - "version_history": [ - { - "date": "2026-10-15", - "title": "Partial preliminary year excluded", - "changes": [ - { - "kind": "changed", - "note": "The partial preliminary year published ahead of the next full release is excluded." - } - ] - }, - { - "date": "2026-10-14", - "title": "First release", - "changes": [ - { - "kind": "added", - "note": "ODA disbursements by donor and recipient country or region, including the OECD's imputed multilateral contributions, and ODA per person and as a share of recipient GNI." - } - ] - } - ] + "publisher": "World Bank", + "description": "The primary World Bank collection of development indicators encompassing global economic and social data.", + "source_data_url": "http://api.worldbank.org/v2/en/country/AFG?downloadformat=csv", + "update_cadence": "Monthly", + "last_update": "2026-10-13", + "currencies": [], + "transformation_log": [], + "version_history": [] } } ] }, "trace": { - "applied_window": { - "kind": "range", - "start_year": 2015, - "end_year": 2022, - "origin": "query" - }, - "graph_revision": null, - "code_index_stamp": { - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", - "exported_at": "2026-10-20T19:50:14Z", - "graph_endpoint": "graph_release" - }, - "origin_catalogue_build_id": "20261021T070020Z-7262111e", - "source_revisions": [ - { - "source": "provenance/OECDDAC2A", - "revision": "2026-10-15" - } - ], - "resolved_stat_vars": [ - { - "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", - "roles": [ - "financingProvider", - "financingRecipient" - ], - "observation_count": 372 - } - ], - "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", - "family_member_count": 1, "facets": [ { + "ref": "dc/base/WorldDevelopmentIndicators", "axis": "provenance", - "ref": "provenance/OECDDAC2A", "basis": "deployment_fallback", "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", "selection_reason": "sole_candidate", - "dispatch_facet_id": "1962969911839422253" + "dispatch_facet_id": "8535402560764839853", + "default_policy_version": "1" }, { - "axis": "measurementMethod", "ref": null, + "axis": "measurementMethod", "basis": "deployment_fallback", "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", "selection_reason": "absent_on_selected_facet", - "dispatch_facet_id": "1962969911839422253" + "dispatch_facet_id": "8535402560764839853", + "default_policy_version": "1" }, { + "ref": "USDollar", "axis": "unit", - "ref": "CurrencyUSD", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "1962969911839422253" + "basis": "bound", + "default_policy": null, + "selection_reason": null, + "dispatch_facet_id": "8535402560764839853", + "default_policy_version": null } ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2022, + "start_year": 2013 + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00260-6xk", "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-23T13:00:17Z", + "content_hash": "29eb81d7b6c88641b1d4e8eb5e850ca36de66b99d6e9e09680aac020507a6392", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "dc/base/WorldDevelopmentIndicators", + "revision": "2026-10-13" + } + ], + "capability_version": "dset_cc753cefa9199881", + "materialiser_build": "c7543c9d64fb0dbeea028b04da6c59c997e50fbc", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_EconomicActivity_GrossDomesticProduction_Nominal", + "roles": [ + "observationAbout" + ], + "observation_count": 463 + } + ], + "family_member_count": 65, + "family_member_digest": "73519eeb75639bdae33042fc844830cd46becc08e4f9122dfcd0886e9875f657", "frame_grammar_version": "1.1.0", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "capability_version": "dset_88fecfec3c5b89d1", - "served_from": "materialise", - "confirmed_at": "2026-10-21T13:07:14.106516+00:00" + "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", + "served_from": "head", + "confirmed_at": "2026-10-23T18:39:34.359134+00:00" }, - "warnings": [], + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for country/ERI." + } + ], "diagnostics": [ { "code": "processing_level_undeclared", @@ -17339,33 +15952,33 @@ ], "artifacts": [ { - "artifact_digest": "sha256:8fd31163adf485e022515e99d523bd1b93a1274726800598df8583981bc0984d", + "artifact_digest": "sha256:18a2e84a4829808841c3967941a92c555ac6c8c30856fe2113ba38d89e121cf7", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 10503, + "bytes": 10233, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:07:14.069922+00:00", + "created_at": "2026-10-23T17:40:54.208385+00:00", "tier": "working", - "url": "/api/datasets/spec_941030940d23f46826acaa0c6fed8bbc/cv_9362a741d742d00a0f4f5d671e0b400c/files/sha256:8fd31163adf485e022515e99d523bd1b93a1274726800598df8583981bc0984d" + "url": "/api/datasets/spec_310c03c5f99c73c41d12226098714f81/cv_7a402f88c10de233e81d664ab22037a5/files/sha256:18a2e84a4829808841c3967941a92c555ac6c8c30856fe2113ba38d89e121cf7" }, { - "artifact_digest": "sha256:27b4eefb8edbb7ed613cf134d8df4fba5dfeab885ed8c2f210c26e35032df8bc", + "artifact_digest": "sha256:45c12e425c4cda8e0f4d577367ccb74e0613cb3b78fdc06b17a263fc4f803ae8", "rendering": { "statistics": "series" }, - "bytes": 8083, + "bytes": 8201, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:07:14.069922+00:00", + "created_at": "2026-10-23T17:40:54.208385+00:00", "tier": "working", - "url": "/api/datasets/spec_941030940d23f46826acaa0c6fed8bbc/cv_9362a741d742d00a0f4f5d671e0b400c/files/sha256:27b4eefb8edbb7ed613cf134d8df4fba5dfeab885ed8c2f210c26e35032df8bc" + "url": "/api/datasets/spec_310c03c5f99c73c41d12226098714f81/cv_7a402f88c10de233e81d664ab22037a5/files/sha256:45c12e425c4cda8e0f4d577367ccb74e0613cb3b78fdc06b17a263fc4f803ae8" } ], - "series_count": 48, + "series_count": 47, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -17374,22 +15987,16 @@ "distinct": 1 }, { - "name": "financingProvider", - "kind": "role", - "droppable": false, - "distinct": 1 - }, - { - "name": "financingRecipient", + "name": "observationAbout", "kind": "role", "droppable": false, - "distinct": 48 + "distinct": 47 }, { "name": "time_period", "kind": "grain", "droppable": false, - "distinct": 8 + "distinct": 10 }, { "name": "value", @@ -17439,86 +16046,26 @@ }, "enrichments": [ { - "column": "financingProvider", - "field": "iso3", - "token": "financingProvider_iso3", - "state": "available", - "coverage": { - "entities": 1, - "covered": 1 - }, - "missing": [], - "truncated": false - }, - { - "column": "financingProvider", - "field": "iso2", - "token": "financingProvider_iso2", - "state": "available", - "coverage": { - "entities": 1, - "covered": 1 - }, - "missing": [], - "truncated": false - }, - { - "column": "financingProvider", - "field": "label", - "token": "financingProvider_label", - "state": "available", - "coverage": { - "entities": 1, - "covered": 1 - }, - "missing": [], - "truncated": false - }, - { - "column": "financingProvider", - "field": "type", - "token": "financingProvider_type", - "state": "available", - "coverage": { - "entities": 1, - "covered": 1 - }, - "missing": [], - "truncated": false - }, - { - "column": "financingProvider", - "field": "party_kind", - "token": "financingProvider_party_kind", - "state": "available", - "coverage": { - "entities": 1, - "covered": 1 - }, - "missing": [], - "truncated": false - }, - { - "column": "financingRecipient", + "column": "observationAbout", "field": "iso3", - "token": "financingRecipient_iso3", + "token": "observationAbout_iso3", "state": "available", "coverage": { - "entities": 48, - "covered": 48 + "entities": 47, + "covered": 47 }, "missing": [], "truncated": false }, { - "column": "financingRecipient", + "column": "observationAbout", "field": "iso2", - "token": "financingRecipient_iso2", + "token": "observationAbout_iso2", "state": "partial", "reason": "enrichment_unavailable", "coverage": { - "entities": 48, - "covered": 47 + "entities": 47, + "covered": 46 }, "missing": [ { @@ -17529,63 +16076,48 @@ "truncated": false }, { - "column": "financingRecipient", + "column": "observationAbout", "field": "label", - "token": "financingRecipient_label", + "token": "observationAbout_label", "state": "available", "coverage": { - "entities": 48, - "covered": 48 + "entities": 47, + "covered": 47 }, "missing": [], "truncated": false }, { - "column": "financingRecipient", + "column": "observationAbout", "field": "type", - "token": "financingRecipient_type", - "state": "available", - "coverage": { - "entities": 48, - "covered": 48 - }, - "missing": [], - "truncated": false - }, - { - "column": "financingRecipient", - "field": "party_kind", - "token": "financingRecipient_party_kind", + "token": "observationAbout_type", "state": "available", "coverage": { - "entities": 48, - "covered": 48 + "entities": 47, + "covered": 47 }, "missing": [], "truncated": false } ], "long_layout_defaults": [ - "financingProvider_label", - "financingProvider_party_kind", - "financingRecipient_label", - "financingRecipient_party_kind" + "observationAbout_label" ], "long_layout_totals": [], "pivots": [ { - "index": "financingRecipient", + "index": "observationAbout", "columns": "time_period", "state": "available", - "width": 9, - "cells": 432 + "width": 11, + "cells": 517 }, { "index": "time_period", - "columns": "financingRecipient", + "columns": "observationAbout", "state": "available", - "width": 49, - "cells": 392 + "width": 48, + "cells": 480 } ], "groupby": { @@ -17606,10 +16138,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:07:14.070133Z" + "held_until": "2026-11-22T17:40:54.208730Z" } } } @@ -17617,26 +16149,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_941030940d23f46826acaa0c6fed8bbc/cv_9362a741d742d00a0f4f5d671e0b400c/files/sha256:8fd31163adf485e022515e99d523bd1b93a1274726800598df8583981bc0984d" + "origin_path": "/api/datasets/spec_310c03c5f99c73c41d12226098714f81/cv_7a402f88c10de233e81d664ab22037a5/files/sha256:18a2e84a4829808841c3967941a92c555ac6c8c30856fe2113ba38d89e121cf7" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A8fd31163adf485e022515e99d523bd1b93a1274726800598df8583981bc0984d?X-Goog-Signature=redacted", - "x-dfo-trace-id": "179d8bf5dffb4f048480c624923bd736" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A18a2e84a4829808841c3967941a92c555ac6c8c30856fe2113ba38d89e121cf7?X-Goog-Signature=redacted", + "x-dfo-trace-id": "8c9d245aa46c4b6e89b1cf2c79657eb3" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3A8fd31163adf485e022515e99d523bd1b93a1274726800598df8583981bc0984d?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A18a2e84a4829808841c3967941a92c555ac6c8c30856fe2113ba38d89e121cf7?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "51d43205f7bd45fb84ad04cf2c329a6d" + "content-type": "application/vnd.apache.parquet" }, "body_file": "choose-candidate-two-parts-2.parquet" } @@ -17647,10 +16179,10 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "Answered 1 of 2 parts. GNI has 3 readings. Primary income for gross of fixed capital consumption in 49 places. World Bank International Debt Statistics (IDS) · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in 49 places. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in 49 places. World Development Indicators · 2015 to 2022. You named sub-Saharan Africa as a recipient. This measure has no recipients, so this shows the place itself. Germany's gross disbursements to the 48 countries in Sub-Saharan Africa for official development assistance, 2015 to 2022. Current US dollars · OECD DAC2a. You asked for sub-Saharan Africa. This shows the countries in it, each on its own.", + "sentence": "Answered 1 of 2 parts. Mortality has 3 readings. Deaths rate per capita in the 48 countries in Sub-Saharan Africa. World Development Indicators · 2013 to 2022. Number of deaths in the 48 countries in Sub-Saharan Africa. Kenya Census · 2018 to 2022. Count of mortality event (as fraction of count birth event live birth) in the 48 countries in Sub-Saharan Africa. Nigeria Statistics · 2014. GDP in the 48 countries in Sub-Saharan Africa, 2013 to 2022. Current US dollars · World Development Indicators. The data holds no values for 1 of the 48 countries in Sub-Saharan Africa. You asked for sub-Saharan Africa. This shows the countries in it, each on its own.", "complete": false, "specs": [ - "spec_941030940d23f46826acaa0c6fed8bbc" + "spec_310c03c5f99c73c41d12226098714f81" ], "gaps": [ { @@ -17665,18 +16197,18 @@ "answer": { "kind": "resolution", "status": "definite", - "sentence": "Primary income for gross of fixed capital consumption in 49 places, 2015 to 2022. Current US dollars · World Bank International Debt Statistics (IDS). You asked for Germany, Eritrea, Namibia, South Sudan, and Seychelles. The data holds no values for them. Germany's gross disbursements to the 48 countries in Sub-Saharan Africa for official development assistance, 2015 to 2022. Current US dollars · OECD DAC2a. This shows the 48 countries in Sub-Saharan Africa, each on its own.", + "sentence": "Deaths rate per capita in the 48 countries in Sub-Saharan Africa, 2013 to 2022. World Development Indicators. This shows the 48 countries in Sub-Saharan Africa, each on its own. GDP in the 48 countries in Sub-Saharan Africa, 2013 to 2022. Current US dollars · World Development Indicators. The data holds no values for 1 of the 48 countries in Sub-Saharan Africa. This shows the 48 countries in Sub-Saharan Africa, each on its own.", "complete": true, "specs": [ - "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", - "spec_941030940d23f46826acaa0c6fed8bbc" + "spec_176fd5e63bb2a122c4ad00831497b863", + "spec_310c03c5f99c73c41d12226098714f81" ], "gaps": [] } }, { "dataset": { - "rows": 720, + "rows": 943, "columns": [ "part", "stat_var", @@ -17693,43 +16225,35 @@ "measurementMethod", "measurementMethod_label", "provenance", - "provenance_label", - "financingProvider", - "financingProvider_label", - "financingProvider_party_kind", - "financingRecipient", - "financingRecipient_label", - "financingRecipient_party_kind", - "dac2aAidType", - "dac2aAidType_label" + "provenance_label" ], "part_rows": [ { - "part": "GNI", - "rows": 348 + "part": "mortality", + "rows": 480 }, { - "part": "ODA disbursements", - "rows": 372 + "part": "GDP", + "rows": 463 } ], "complete": true, "members": [ { "parts": [ - "GNI" + "mortality" ], - "spec_id": "spec_bc87ff8e0f29960c38c96a4f4d2b0e20", - "content_version": "cv_18a63cb9e24a4ce6dfcd1c60f0c5a470", - "sentence": "Primary income for gross of fixed capital consumption in 49 places, 2015 to 2022. Current US dollars · World Bank International Debt Statistics (IDS)." + "spec_id": "spec_176fd5e63bb2a122c4ad00831497b863", + "content_version": "cv_6c43e754af661c87eb22e7a21595a732", + "sentence": "Deaths rate per capita in the 48 countries in Sub-Saharan Africa, 2013 to 2022. World Development Indicators." }, { "parts": [ - "ODA disbursements" + "GDP" ], - "spec_id": "spec_941030940d23f46826acaa0c6fed8bbc", - "content_version": "cv_9362a741d742d00a0f4f5d671e0b400c", - "sentence": "Germany's gross disbursements to the 48 countries in Sub-Saharan Africa for official development assistance, 2015 to 2022. Current US dollars · OECD DAC2a." + "spec_id": "spec_310c03c5f99c73c41d12226098714f81", + "content_version": "cv_7a402f88c10de233e81d664ab22037a5", + "sentence": "GDP in the 48 countries in Sub-Saharan Africa, 2013 to 2022. Current US dollars · World Development Indicators." } ], "missing": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.parquet b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.parquet index 6ef281866273f7980336c642de5b1441dc042e0a..088e609a3acf32561affbf0cfcc8b0e20dd2d0f8 100644 GIT binary patch literal 9259 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 S{;2uwf50HX#|rr0g#Hh>dmJbL literal 9453 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

(EL2txqt~;oCmK#a zi+iqItmF+^;goPuBW!8V?I!eIleM3D`QJ?+wHUO!S~zI;u|G7U-Dc1q5g~9a*08Nd z_u=hhq2M$1|EsXqg5GF(j)DPF1{ZtjMYPoln}&DTJpp}v6!gLk_Ld1fGQu5Ujs4Jq z?wP^KdtkjoV&Al(eJgy?vB@6T(G@$KG0w9)BKqC|*NoN1Z5P^eDthpjPJ};oolr8J zVILkx2X6SpRN%imfp%ZA8o_IBhm+j95ek+zXm0O-Z_EOF@g%y@4G+vE z_BKZEW0_d+fFT~#JLw9^o z)lb4{o5XGpppW{&+>(U5HoJR2B%DGz;imv&vKn6?$z(kJ%1Um&u$VRe){4~y7JJw> z91A4~NsdI^##=jR0J84)Jm-K&f^3#W~0irv@<|r1GvXmyvx6Vbc}lqhSi;7~FIPISJ2V zOn`Iu@v;I3R)Dz2c~Zx;uNipP9p*<$w6U%-#T}YFXgX~de4+VVCF#%fu2yFj>7B{& zl9KM1Y1eh?CMFb+j47KklgDdBIY*``C$cuxyRbIxjV{o$o=s1#X{ZJ(|eRbvSP-#Qv2bI+-zgcPnfMYjO;q==+&!^%cfQ?){M@Eo_A>Qk9$PhoPf zmQDN1Y9Lag#I6ar+3DEoY_pt=uICpQ%F~(X?951{IGwJOvQj^=f#GMnT_e#l<_k(k zF;y`^=<^t+O%Reh6s6DOiR|O)jH*iiOo!$Za(29DDwCYeFGkL*VLH91se}v-F-DR8 hH_K~<)$Uxi+MTV{mg?eqp$2;Nn(o&QhLK6q`#0cMhK2wD diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json index cdf2c56..b838bb6 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json @@ -33,7 +33,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "d09ca5f0ae574410bf93b5d905ea8009" + "x-dfo-trace-id": "8ff5daac36fe403ab946f5b02785cb0d" }, "json": { "schema_version": 1, @@ -44,47 +44,58 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d09ca5f0ae574410bf93b5d905ea8009", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "8ff5daac36fe403ab946f5b02785cb0d", "warnings": [], "timing_ms": { - "total": 5038, + "total": 4716, "by_step": { "coverage": 0, - "extract": 1141 + "extract": 1242, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 6116, - "output_tokens": 408, - "cached_tokens": 0 + "input_tokens": 6216, + "output_tokens": 423, + "cached_tokens": 841 }, "timed_out": false }, "kind": "resolution", "parts": [ { - "variable_text": "basic health care ODA disbursements", + "variable_text": "ODA disbursements for basic health care", "warnings": [], "timing_ms": { - "total": 3758, + "total": 3468, "by_step": { - "recall": 694, + "recall": 547, + "phase_resolve_places": 0, + "phase_check_entities": 0, "shape_arcs": 1, "shape_probe_coverage": 6, - "shape_probe": 489, - "shape_groups": 16, - "shape_labels": 0, - "shape_admission": 1, - "shape": 1365, - "bind": 1248, - "materialise": 11, - "answer": 423, - "options": 17 + "shape_probe": 136, + "shape_groups": 43, + "shape_labels": 1, + "shape_admission": 0, + "phase_derive_shapes": 0, + "shape": 1190, + "phase_prune_and_rank": 0, + "bind": 1278, + "phase_bind": 149, + "phase_settle": 50, + "phase_place_bindings": 19, + "phase_facet_requests": 0, + "materialise": 30, + "phase_materialise": 0, + "answer": 110, + "options": 38, + "phase_outcome": 57 } }, "restatement": { - "variable_text": "basic health care ODA disbursements", + "variable_text": "ODA disbursements for basic health care", "entities": [ { "text": "Germany", @@ -193,6 +204,14 @@ }, "measurement_denominator_unresolved": false, "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, { "axis": "how", "property": { @@ -233,14 +252,6 @@ }, "label": "netting basis" }, - { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, { "axis": "where", "label": "place" @@ -265,6 +276,20 @@ ] }, "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, { "key": { "axis": "how", @@ -363,20 +388,6 @@ }, "summable": false }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding": { - "kind": "unbound" - }, - "summable": true - }, { "key": { "axis": "where", @@ -513,7 +524,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "facets": { "provenance": { "basis": "fallback", @@ -538,102 +549,6 @@ } }, "slot_options": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsPurpose", - "label": "CRS purpose" - }, - "label": "sector" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSPurposeCode122", - "label": "basic health" - }, - "value_kind": "enum_value" - }, - "relation": "parent", - "parent": "CRSPurposeCode120", - "member_count": 4, - "served_rows": 88, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFinance", - "label": "CRS type of finance" - }, - "label": "instrument" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance100", - "label": "grant" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 30, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance110", - "label": "standard grant" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSTypeOfFinance100", - "member_count": 12672, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFlow", - "label": "CRS type of flow" - }, - "label": "flow" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 14098, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, { "key": { "axis": "how", @@ -742,6 +657,102 @@ ], "truncated": false, "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 88, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 30, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" } ], "entity_options": [], @@ -1009,6 +1020,19 @@ } ], "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "how", @@ -1094,19 +1118,6 @@ ], "provenance": "measure_elected" }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "where", @@ -1142,31 +1153,31 @@ ], "query_qualifiers": [ { - "text": "basic health care", + "text": "ODA", "named": [ { - "ref": "CRSPurposeCode12220", - "label": "basic health care" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" } ], - "slot": "crsPurpose", + "slot": "crsTypeOfFlow", "disposition": "bound", "selected": [] }, { - "text": "ODA", + "text": "basic health care", "named": [ { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode12220", + "label": "basic health care" } ], - "slot": "crsTypeOfFlow", + "slot": "crsPurpose", "disposition": "bound", "selected": [] } ], - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3764,7 +3775,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "90ec74fce6534d0d8e4142b0e1355782" + "x-dfo-trace-id": "c1f0030e84b5418d89553827b503d006" }, "json": { "schema_version": 1, @@ -3835,7 +3846,7 @@ } } }, - "prepared_at": "2026-10-21T13:05:05Z", + "prepared_at": "2026-10-11T20:09:36Z", "coverage": { "rows": 30, "dimensions": [ @@ -3864,13 +3875,13 @@ ], "window": { "kind": "all", - "start_year": 1995, + "origin": "default", "end_year": 2024, - "origin": "default" + "start_year": 1995 } }, "citation": { - "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "text": "OECD Creditor Reporting System (CRS)", "sources": [ { "ref": "provenance/OECDCreditorReportingSystem", @@ -3891,9 +3902,9 @@ "publisher": "Organisation for Economic Co-operation and Development (OECD)", "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", - "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-08)", "update_cadence": "Quarterly", - "last_update": "2026-10-15", + "last_update": "2026-10-08", "years_covered": "1973-2024", "granularity": "Annual, by provider and recipient", "currencies": [ @@ -3904,10 +3915,6 @@ "transformation": "Download the source data", "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." }, - { - "transformation": "Exclude the partial preliminary year", - "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." - }, { "transformation": "Exclude donor core contributions to multilaterals", "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." @@ -3927,22 +3934,22 @@ ], "version_history": [ { - "date": "2026-10-15", - "title": "Partial preliminary year excluded", + "date": "2026-09-22", + "title": "Exclude donor core contributions", "changes": [ { "kind": "changed", - "note": "The partial preliminary year published ahead of the next full release is excluded." + "note": "Donor core contributions to multilateral organisations (`bi_multi = 2`) are excluded from bilateral flows, since they would otherwise double count." } ] }, { - "date": "2026-10-14", + "date": "2026-08-20", "title": "First release", "changes": [ { "kind": "added", - "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + "note": "Dataset added to the graph." } ] } @@ -3952,25 +3959,47 @@ ] }, "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], "applied_window": { "kind": "all", - "start_year": 1995, + "origin": "default", "end_year": 2024, - "origin": "default" + "start_year": 1995 }, - "graph_revision": null, + "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", + "normalisations": [], "code_index_stamp": { - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", - "exported_at": "2026-10-20T19:50:14Z", - "graph_endpoint": "graph_release" + "exported_at": "2026-10-10T10:52:17Z", + "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", + "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" }, - "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", - "revision": "2026-10-15" + "revision": "2026-10-08" } ], + "capability_version": "dset_ac879dbf49857907", + "materialiser_build": "1f6ed6307bea979d38cc35c4e38e0da896c431ad", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -4141,36 +4170,20 @@ "observation_count": 0 } ], - "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "family_member_count": 21, - "facets": [ - { - "axis": "provenance", - "ref": "provenance/OECDCreditorReportingSystem", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868" - }, - { - "axis": "unit", - "ref": "CurrencyUSD", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868" - } - ], - "normalisations": [], + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "capability_version": "dset_88fecfec3c5b89d1", - "served_from": "materialise", - "confirmed_at": "2026-10-21T13:05:06.336796+00:00" + "origin_catalogue_build_id": "20261011T194155Z-80081f08", + "served_from": "head", + "confirmed_at": "2026-10-23T18:36:51.837863+00:00" }, - "warnings": [], + "warnings": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], "diagnostics": [ { "code": "processing_level_undeclared", @@ -4180,17 +4193,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "artifact_digest": "sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9785, + "bytes": 9842, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:06.298931+00:00", + "created_at": "2026-10-23T16:56:32.058938+00:00", "tier": "working", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", @@ -4199,14 +4213,14 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:06.298931+00:00", + "created_at": "2026-10-08T08:43:31.704442+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } ], "series_count": 5, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -4339,6 +4353,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -4398,13 +4436,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [ @@ -4441,10 +4503,9 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { - "pinned": false, - "held_until": "2026-11-20T13:05:06.298810Z" + "pinned": true }, "contentVersion": "cv_b92d94774702c7f05f2075d0b03dd756" } @@ -4468,7 +4529,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "90ec74fce6534d0d8e4142b0e1355782" + "trace_id": "c1f0030e84b5418d89553827b503d006" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json index 571bc2d..53d3564 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json @@ -33,7 +33,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "d09ca5f0ae574410bf93b5d905ea8009" + "x-dfo-trace-id": "8ff5daac36fe403ab946f5b02785cb0d" }, "json": { "schema_version": 1, @@ -44,47 +44,58 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d09ca5f0ae574410bf93b5d905ea8009", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "8ff5daac36fe403ab946f5b02785cb0d", "warnings": [], "timing_ms": { - "total": 5038, + "total": 4716, "by_step": { "coverage": 0, - "extract": 1141 + "extract": 1242, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 6116, - "output_tokens": 408, - "cached_tokens": 0 + "input_tokens": 6216, + "output_tokens": 423, + "cached_tokens": 841 }, "timed_out": false }, "kind": "resolution", "parts": [ { - "variable_text": "basic health care ODA disbursements", + "variable_text": "ODA disbursements for basic health care", "warnings": [], "timing_ms": { - "total": 3758, + "total": 3468, "by_step": { - "recall": 694, + "recall": 547, + "phase_resolve_places": 0, + "phase_check_entities": 0, "shape_arcs": 1, "shape_probe_coverage": 6, - "shape_probe": 489, - "shape_groups": 16, - "shape_labels": 0, - "shape_admission": 1, - "shape": 1365, - "bind": 1248, - "materialise": 11, - "answer": 423, - "options": 17 + "shape_probe": 136, + "shape_groups": 43, + "shape_labels": 1, + "shape_admission": 0, + "phase_derive_shapes": 0, + "shape": 1190, + "phase_prune_and_rank": 0, + "bind": 1278, + "phase_bind": 149, + "phase_settle": 50, + "phase_place_bindings": 19, + "phase_facet_requests": 0, + "materialise": 30, + "phase_materialise": 0, + "answer": 110, + "options": 38, + "phase_outcome": 57 } }, "restatement": { - "variable_text": "basic health care ODA disbursements", + "variable_text": "ODA disbursements for basic health care", "entities": [ { "text": "Germany", @@ -193,6 +204,14 @@ }, "measurement_denominator_unresolved": false, "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, { "axis": "how", "property": { @@ -233,14 +252,6 @@ }, "label": "netting basis" }, - { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, { "axis": "where", "label": "place" @@ -265,6 +276,20 @@ ] }, "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, { "key": { "axis": "how", @@ -363,20 +388,6 @@ }, "summable": false }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding": { - "kind": "unbound" - }, - "summable": true - }, { "key": { "axis": "where", @@ -513,7 +524,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "facets": { "provenance": { "basis": "fallback", @@ -538,102 +549,6 @@ } }, "slot_options": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsPurpose", - "label": "CRS purpose" - }, - "label": "sector" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSPurposeCode122", - "label": "basic health" - }, - "value_kind": "enum_value" - }, - "relation": "parent", - "parent": "CRSPurposeCode120", - "member_count": 4, - "served_rows": 88, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFinance", - "label": "CRS type of finance" - }, - "label": "instrument" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance100", - "label": "grant" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 30, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance110", - "label": "standard grant" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSTypeOfFinance100", - "member_count": 12672, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFlow", - "label": "CRS type of flow" - }, - "label": "flow" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 14098, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, { "key": { "axis": "how", @@ -742,6 +657,102 @@ ], "truncated": false, "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 88, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 30, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" } ], "entity_options": [], @@ -1009,6 +1020,19 @@ } ], "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "how", @@ -1094,19 +1118,6 @@ ], "provenance": "measure_elected" }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "where", @@ -1142,31 +1153,31 @@ ], "query_qualifiers": [ { - "text": "basic health care", + "text": "ODA", "named": [ { - "ref": "CRSPurposeCode12220", - "label": "basic health care" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" } ], - "slot": "crsPurpose", + "slot": "crsTypeOfFlow", "disposition": "bound", "selected": [] }, { - "text": "ODA", + "text": "basic health care", "named": [ { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode12220", + "label": "basic health care" } ], - "slot": "crsTypeOfFlow", + "slot": "crsPurpose", "disposition": "bound", "selected": [] } ], - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3864,7 +3875,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "90ec74fce6534d0d8e4142b0e1355782" + "x-dfo-trace-id": "c1f0030e84b5418d89553827b503d006" }, "json": { "schema_version": 1, @@ -3936,7 +3947,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-21T13:05:05Z", + "prepared_at": "2026-10-11T20:09:36Z", "coverage": { "rows": 30, "dimensions": [ @@ -3965,13 +3976,13 @@ ], "window": { "kind": "all", - "start_year": 1995, + "origin": "default", "end_year": 2024, - "origin": "default" + "start_year": 1995 } }, "citation": { - "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "text": "OECD Creditor Reporting System (CRS)", "sources": [ { "ref": "provenance/OECDCreditorReportingSystem", @@ -3992,9 +4003,9 @@ "publisher": "Organisation for Economic Co-operation and Development (OECD)", "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", - "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-08)", "update_cadence": "Quarterly", - "last_update": "2026-10-15", + "last_update": "2026-10-08", "years_covered": "1973-2024", "granularity": "Annual, by provider and recipient", "currencies": [ @@ -4005,10 +4016,6 @@ "transformation": "Download the source data", "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." }, - { - "transformation": "Exclude the partial preliminary year", - "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." - }, { "transformation": "Exclude donor core contributions to multilaterals", "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." @@ -4028,22 +4035,22 @@ ], "version_history": [ { - "date": "2026-10-15", - "title": "Partial preliminary year excluded", + "date": "2026-09-22", + "title": "Exclude donor core contributions", "changes": [ { "kind": "changed", - "note": "The partial preliminary year published ahead of the next full release is excluded." + "note": "Donor core contributions to multilateral organisations (`bi_multi = 2`) are excluded from bilateral flows, since they would otherwise double count." } ] }, { - "date": "2026-10-14", + "date": "2026-08-20", "title": "First release", "changes": [ { "kind": "added", - "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + "note": "Dataset added to the graph." } ] } @@ -4053,25 +4060,47 @@ ] }, "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], "applied_window": { "kind": "all", - "start_year": 1995, + "origin": "default", "end_year": 2024, - "origin": "default" + "start_year": 1995 }, - "graph_revision": null, + "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", + "normalisations": [], "code_index_stamp": { - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", - "exported_at": "2026-10-20T19:50:14Z", - "graph_endpoint": "graph_release" + "exported_at": "2026-10-10T10:52:17Z", + "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", + "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" }, - "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", - "revision": "2026-10-15" + "revision": "2026-10-08" } ], + "capability_version": "dset_ac879dbf49857907", + "materialiser_build": "1f6ed6307bea979d38cc35c4e38e0da896c431ad", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -4242,36 +4271,20 @@ "observation_count": 0 } ], - "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "family_member_count": 21, - "facets": [ - { - "axis": "provenance", - "ref": "provenance/OECDCreditorReportingSystem", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868" - }, - { - "axis": "unit", - "ref": "CurrencyUSD", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868" - } - ], - "normalisations": [], + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "capability_version": "dset_88fecfec3c5b89d1", - "served_from": "materialise", - "confirmed_at": "2026-10-21T13:05:06.336796+00:00" + "origin_catalogue_build_id": "20261011T194155Z-80081f08", + "served_from": "head", + "confirmed_at": "2026-10-23T18:36:51.837863+00:00" }, - "warnings": [], + "warnings": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], "diagnostics": [ { "code": "processing_level_undeclared", @@ -4281,17 +4294,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "artifact_digest": "sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9785, + "bytes": 9842, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:06.298931+00:00", + "created_at": "2026-10-23T16:56:32.058938+00:00", "tier": "working", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", @@ -4300,14 +4314,14 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:06.298931+00:00", + "created_at": "2026-10-08T08:43:31.704442+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } ], "series_count": 5, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -4440,6 +4454,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -4499,13 +4537,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [ @@ -4542,10 +4604,9 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { - "pinned": false, - "held_until": "2026-11-20T13:05:06.298810Z" + "pinned": true } } } @@ -4553,26 +4614,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + "origin_path": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted", - "x-dfo-trace-id": "d14640239a5a4ffa8f113140eb5b23a0" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db?X-Goog-Signature=redacted", + "x-dfo-trace-id": "b2396d674b5848e7b1828fca235d84a1" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "58cc82a3079f4e4298eb45378fdf10db" + "content-type": "application/vnd.apache.parquet" }, "body_file": "answer-definite-fetch.parquet" } @@ -4598,10 +4659,10 @@ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "crsCooperationModality", "crsCooperationModality_label", "crsPurpose", @@ -4626,7 +4687,7 @@ "members": [ { "parts": [ - "basic health care ODA disbursements" + "ODA disbursements for basic health care" ], "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-503-then-504.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-503-then-504.json index f7dafde..ed95d0e 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-503-then-504.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-503-then-504.json @@ -379,7 +379,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" + "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" }, "json": { "schema_version": 1, @@ -453,7 +453,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T13:05:35Z", + "prepared_at": "2026-10-20T13:59:17Z", "coverage": { "rows": 4, "dimensions": [ @@ -599,7 +599,7 @@ "graph_revision": null, "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", + "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "graph_endpoint": "graph_release" }, @@ -609,8 +609,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -784,9 +784,9 @@ "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + "confirmed_at": "2026-10-23T18:37:10.942106+00:00" }, "warnings": [ { @@ -804,17 +804,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "artifact_digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9541, + "bytes": 9599, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", - "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -823,14 +824,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-20T13:59:18.050980+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -963,6 +964,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -1022,13 +1047,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [], @@ -1050,10 +1099,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:35.038284Z" + "held_until": "2026-11-19T13:59:18.051742Z" } } } @@ -1061,26 +1110,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", - "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", + "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" + "content-type": "application/vnd.apache.parquet" }, "body_file": "fetch-spec-known-sentence.parquet" } @@ -1094,10 +1143,10 @@ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "crsCooperationModality", "crsCooperationModality_label", "crsPurpose", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-retry-after.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-retry-after.json index a9bedd9..00ce7f5 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-retry-after.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-retry-after.json @@ -278,7 +278,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" + "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" }, "json": { "schema_version": 1, @@ -352,7 +352,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T13:05:35Z", + "prepared_at": "2026-10-20T13:59:17Z", "coverage": { "rows": 4, "dimensions": [ @@ -498,7 +498,7 @@ "graph_revision": null, "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", + "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "graph_endpoint": "graph_release" }, @@ -508,8 +508,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -683,9 +683,9 @@ "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + "confirmed_at": "2026-10-23T18:37:10.942106+00:00" }, "warnings": [ { @@ -703,17 +703,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "artifact_digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9541, + "bytes": 9599, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", - "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -722,14 +723,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-20T13:59:18.050980+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -862,6 +863,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -921,13 +946,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [], @@ -949,10 +998,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:35.038284Z" + "held_until": "2026-11-19T13:59:18.051742Z" } } } @@ -960,26 +1009,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", - "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", + "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" + "content-type": "application/vnd.apache.parquet" }, "body_file": "fetch-spec-known-sentence.parquet" } @@ -993,10 +1042,10 @@ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "crsCooperationModality", "crsCooperationModality_label", "crsPurpose", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-async-build.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-async-build.json index 8313d2b..b1e43b7 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-async-build.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-async-build.json @@ -11,10 +11,10 @@ { "op": "fetch", "spec": { - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -53,21 +53,195 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } }, - "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a.", + "entity_groups": { + "destination": { + "label": "G77 countries", + "group_id": "groups/G77" + }, + "origin": { + "label": "DAC countries", + "group_id": "groups/OECD.DAC" + } + } } } ], @@ -80,10 +254,10 @@ "schema_version": 1, "input": { "kind": "spec_id", - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -122,17 +296,181 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } } @@ -147,15 +485,15 @@ "status": 202, "headers": { "content-type": "application/json", - "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry-after": "2", - "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" + "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "pending", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500 } } @@ -164,24 +502,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "621bdcc038e34f44bec226434f3f7378" + "x-dfo-trace-id": "043386d87ba247048aa921704d3ff030" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -190,24 +528,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "1df7b03572044eedaa412f6d2ad6b91f" + "x-dfo-trace-id": "c7ef77e57a864be6a4617b1aeae7c11d" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -216,24 +554,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "b5b2e2d98a4047be98aea852117381c7" + "x-dfo-trace-id": "cea2df9c98f94601a5e9976e76842f12" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -242,24 +580,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "686111d592f3451e8c55691d91a66663" + "x-dfo-trace-id": "7a800f2714b94a8482dc5fb553c669f5" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 1517, + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 1804, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -268,24 +606,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2", - "x-dfo-trace-id": "9acc0caab7e143d38b3ecbfbcd225707" + "retry-after": "3", + "x-dfo-trace-id": "f911f5f7ca244733b2da3d5ce6913f6d" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 1900, + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 2292, "progress": { - "rows_written": 16734, - "estimate_rows": 108798 + "rows_written": 0, + "estimate_rows": 109318 } } } @@ -294,24 +632,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "3", - "x-dfo-trace-id": "22c08bbaa1384833bd92f8dd9cc6312d" + "x-dfo-trace-id": "07d32bbe980e419eb9f8461492ff4c62" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 2377, + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 2903, "progress": { - "rows_written": 64341, - "estimate_rows": 108798 + "rows_written": 0, + "estimate_rows": 109318 } } } @@ -320,24 +658,154 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "227de800033b4185ae9b958d3fa2cec7" + "retry-after": "4", + "x-dfo-trace-id": "dd33ade549434abf82b662ab5251b0c1" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 3686, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "5", + "x-dfo-trace-id": "51d3664ad3e84fed8da1d94ce250d5de" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 4645, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "6", + "x-dfo-trace-id": "6a3b79b90c29464ca15c35d8eafecb96" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 5865, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "8", + "x-dfo-trace-id": "d7de7e24059f4d75ae14bd1778b984de" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 7391, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "8", + "x-dfo-trace-id": "cd1a9f894cbe4b6a9c1a7ee78315aff0" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 8000, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "8", + "x-dfo-trace-id": "e1c46fecd652459380163afea4dc35b7" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 2973, + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 8000, "progress": { - "rows_written": 106324, - "estimate_rows": 108798 + "rows_written": 105253, + "estimate_rows": 109318 } } } @@ -346,24 +814,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "retry-after": "4", - "x-dfo-trace-id": "3197d4d8b5094857afb9bbd14c49fcb0" + "retry-after": "8", + "x-dfo-trace-id": "3b9df177b0a94b069b47c8b441c6f232" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 3719, + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 8000, "progress": { - "rows_written": 108798, - "estimate_rows": 108798 + "rows_written": 109318, + "estimate_rows": 109318 } } } @@ -372,24 +840,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "29f271852cc04f1a8b287274f53105b6" + "x-dfo-trace-id": "cd6f7d2857a44f9c947573b696793564" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "done" }, "manifest": { "schema_version": 1, "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "shape": { "kind": "statvar_schema", @@ -427,29 +895,193 @@ "property": "nettingBasis" } ], - "facets": { - "provenance": { - "ref": "provenance/OECDDAC2A", - "state": "value" - } + "entities": { + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ], + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] }, - "entities": {}, "identity_version": "spec1", "requested_window": { "kind": "range", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 } } }, - "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "prepared_at": "2026-10-21T13:06:08Z", + "content_version": "cv_3d58d26a874dc30b1bba7d5ad6dd90ee", + "prepared_at": "2026-10-23T18:38:28Z", "coverage": { - "rows": 108798, + "rows": 109318, "dimensions": [ { "label": "financingProvider", - "count": 172, + "count": 32, "axis": "origin", "noun": { "singular": "provider", @@ -458,7 +1090,7 @@ }, { "label": "financingRecipient", - "count": 238, + "count": 133, "axis": "destination", "noun": { "singular": "recipient", @@ -467,14 +1099,14 @@ }, { "label": "years", - "count": 7 + "count": 62 } ], "window": { "kind": "range", "origin": "query", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 } }, "citation": { @@ -564,11 +1196,11 @@ { "ref": "provenance/OECDDAC2A", "axis": "provenance", - "basis": "bound", - "default_policy": null, - "selection_reason": null, + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", "dispatch_facet_id": "1962969911839422253", - "default_policy_version": null + "default_policy_version": "1" }, { "ref": null, @@ -593,13 +1225,13 @@ "kind": "range", "origin": "query", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 }, - "graph_revision": null, + "graph_revision": "dfo-dev-dc-datacommons-service-00264-2s9", "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-23T18:14:12Z", + "content_hash": "29eb81d7b6c88641b1d4e8eb5e850ca36de66b99d6e9e09680aac020507a6392", "graph_endpoint": "graph_release" }, "source_revisions": [ @@ -608,8 +1240,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_cc753cefa9199881", + "materialiser_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", @@ -617,15 +1249,15 @@ "financingProvider", "financingRecipient" ], - "observation_count": 108798 + "observation_count": 109318 } ], "family_member_count": 1, "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "materialise", - "confirmed_at": "2026-10-21T13:06:09.616741+00:00" + "confirmed_at": "2026-10-23T18:38:31.738121+00:00" }, "warnings": [], "diagnostics": [ @@ -637,33 +1269,34 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad", + "artifact_digest": "sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 913395, + "bytes": 473679, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:06:09.573990+00:00", + "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", - "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { - "artifact_digest": "sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93", + "artifact_digest": "sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39", "rendering": { "statistics": "series" }, - "bytes": 967921, + "bytes": 144274, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:06:09.573990+00:00", + "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", - "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" + "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39" } ], - "series_count": 21017, + "series_count": 3656, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -675,19 +1308,19 @@ "name": "financingProvider", "kind": "role", "droppable": false, - "distinct": 172 + "distinct": 32 }, { "name": "financingRecipient", "kind": "role", "droppable": false, - "distinct": 238 + "distinct": 133 }, { "name": "time_period", "kind": "grain", "droppable": false, - "distinct": 7 + "distinct": 62 }, { "name": "value", @@ -740,109 +1373,25 @@ "column": "financingProvider", "field": "iso3", "token": "financingProvider_iso3", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 172, - "covered": 50 + "entities": 32, + "covered": 32 }, - "missing": [ - { - "ref": "AdaptationFund", - "label": "Adaptation Fund" - }, - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentBankGroup", - "label": "African Development Bank Group" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AndrewCarnegieFoundation", - "label": "Andrew Carnegie Foundation" - }, - { - "ref": "ArabFundForEconomicAndSocialDevelopment", - "label": "Arab Fund for Economic and Social Development" - }, - { - "ref": "Arcadia", - "label": "Arcadia" - }, - { - "ref": "ArcusFoundation", - "label": "Arcus Foundation" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianInfrastructureInvestmentBank", - "label": "Asian Infrastructure Investment Bank" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingProvider", "field": "iso2", "token": "financingProvider_iso2", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 172, - "covered": 50 + "entities": 32, + "covered": 32 }, - "missing": [ - { - "ref": "AdaptationFund", - "label": "Adaptation Fund" - }, - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentBankGroup", - "label": "African Development Bank Group" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AndrewCarnegieFoundation", - "label": "Andrew Carnegie Foundation" - }, - { - "ref": "ArabFundForEconomicAndSocialDevelopment", - "label": "Arab Fund for Economic and Social Development" - }, - { - "ref": "Arcadia", - "label": "Arcadia" - }, - { - "ref": "ArcusFoundation", - "label": "Arcus Foundation" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianInfrastructureInvestmentBank", - "label": "Asian Infrastructure Investment Bank" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingProvider", @@ -850,8 +1399,8 @@ "token": "financingProvider_label", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -862,8 +1411,8 @@ "token": "financingProvider_type", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -874,8 +1423,32 @@ "token": "financingProvider_party_kind", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -884,55 +1457,13 @@ "column": "financingRecipient", "field": "iso3", "token": "financingRecipient_iso3", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 238, - "covered": 143 + "entities": 133, + "covered": 133 }, - "missing": [ - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianDevelopmentBankSpecialFunds", - "label": "Asian Development Bank Special Funds" - }, - { - "ref": "CaribbeanDevelopmentBank", - "label": "Caribbean Development Bank" - }, - { - "ref": "CentralAmericanBankForEconomicIntegration", - "label": "Central American Bank for Economic Integration" - }, - { - "ref": "DACACPCountries", - "label": "ACP countries (DAC)" - }, - { - "ref": "DACAfrica", - "label": "Africa (DAC)" - }, - { - "ref": "DACAfricaUnallocated", - "label": "Africa, unallocated by country (DAC)" - }, - { - "ref": "DACAllMultilateralRecipients", - "label": "all multilateral recipients (DAC)" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingRecipient", @@ -941,52 +1472,16 @@ "state": "partial", "reason": "enrichment_unavailable", "coverage": { - "entities": 238, - "covered": 141 + "entities": 133, + "covered": 132 }, "missing": [ { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianDevelopmentBankSpecialFunds", - "label": "Asian Development Bank Special Funds" - }, - { - "ref": "CaribbeanDevelopmentBank", - "label": "Caribbean Development Bank" - }, - { - "ref": "CentralAmericanBankForEconomicIntegration", - "label": "Central American Bank for Economic Integration" - }, - { - "ref": "DACACPCountries", - "label": "ACP countries (DAC)" - }, - { - "ref": "DACAfrica", - "label": "Africa (DAC)" - }, - { - "ref": "DACAfricaUnallocated", - "label": "Africa, unallocated by country (DAC)" - }, - { - "ref": "DACAllMultilateralRecipients", - "label": "all multilateral recipients (DAC)" + "ref": "country/SSD", + "label": "South Sudan" } ], - "truncated": true + "truncated": false }, { "column": "financingRecipient", @@ -994,8 +1489,8 @@ "token": "financingRecipient_label", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1006,8 +1501,8 @@ "token": "financingRecipient_type", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1018,8 +1513,32 @@ "token": "financingRecipient_party_kind", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1027,9 +1546,9 @@ ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [ @@ -1041,7 +1560,7 @@ "varying": [ { "column": "time_period", - "distinct": 7 + "distinct": 62 } ] }, @@ -1053,7 +1572,7 @@ "varying": [ { "column": "financingRecipient", - "distinct": 238 + "distinct": 133 } ] }, @@ -1065,7 +1584,7 @@ "varying": [ { "column": "time_period", - "distinct": 7 + "distinct": 62 } ] }, @@ -1077,7 +1596,7 @@ "varying": [ { "column": "financingProvider", - "distinct": 172 + "distinct": 32 } ] }, @@ -1089,7 +1608,7 @@ "varying": [ { "column": "financingRecipient", - "distinct": 238 + "distinct": 133 } ] }, @@ -1101,7 +1620,7 @@ "varying": [ { "column": "financingProvider", - "distinct": 172 + "distinct": 32 } ] } @@ -1124,10 +1643,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:06:09.573841Z" + "held_until": "2026-11-22T18:38:31.579178Z" } } } @@ -1136,26 +1655,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + "origin_path": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted", - "x-dfo-trace-id": "155fa981459c464482aea52657f99e8b" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted", + "x-dfo-trace-id": "b0cef6f918794d048a8a5056022de7cc" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "228feaabf1f3473cad055088084dc378" + "content-type": "application/vnd.apache.parquet" }, "body_file": "mint-async-build.parquet" } @@ -1164,15 +1683,15 @@ "expect": [ { "dataset": { - "rows": 108798, + "rows": 109318, "columns": [ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "dac2aAidType", "dac2aAidType_label", "time_period", @@ -1191,25 +1710,30 @@ "members": [ { "parts": [], - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", - "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "content_version": "cv_3d58d26a874dc30b1bba7d5ad6dd90ee", + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a." } ], "missing": [], "long_builds": [ { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "poll_waits": [ 1.5, 1.5, 1.5, 1.5, - 1.517, - 1.9, - 2.377, - 2.973, - 3.719 + 1.804, + 2.292, + 2.903, + 3.686, + 4.645, + 5.865, + 7.391, + 8.0, + 8.0, + 8.0 ], "resubmissions": 0 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json index e8d5f61..c69fc38 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json @@ -175,7 +175,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" + "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" }, "json": { "schema_version": 1, @@ -249,7 +249,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T13:05:35Z", + "prepared_at": "2026-10-20T13:59:17Z", "coverage": { "rows": 4, "dimensions": [ @@ -395,7 +395,7 @@ "graph_revision": null, "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", + "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "graph_endpoint": "graph_release" }, @@ -405,8 +405,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -580,9 +580,9 @@ "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + "confirmed_at": "2026-10-23T18:37:10.942106+00:00" }, "warnings": [ { @@ -600,17 +600,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "artifact_digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9541, + "bytes": 9599, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", - "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -619,14 +620,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-20T13:59:18.050980+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -759,6 +760,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -818,13 +843,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [], @@ -846,10 +895,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:35.038284Z" + "held_until": "2026-11-19T13:59:18.051742Z" } } } @@ -857,26 +906,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", - "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", + "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" + "content-type": "application/vnd.apache.parquet" }, "body_file": "fetch-spec-digest-mismatch.bin" } @@ -884,26 +933,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", - "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", + "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" + "content-type": "application/vnd.apache.parquet" }, "body_file": "fetch-spec-digest-mismatch.bin" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-empty-narrowing.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-empty-narrowing.json index 36e8750..23e0622 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-empty-narrowing.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-empty-narrowing.json @@ -177,7 +177,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" + "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" }, "json": { "schema_version": 1, @@ -251,7 +251,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T13:05:35Z", + "prepared_at": "2026-10-20T13:59:17Z", "coverage": { "rows": 4, "dimensions": [ @@ -397,7 +397,7 @@ "graph_revision": null, "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", + "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "graph_endpoint": "graph_release" }, @@ -407,8 +407,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -582,9 +582,9 @@ "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + "confirmed_at": "2026-10-23T18:37:10.942106+00:00" }, "warnings": [ { @@ -602,17 +602,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "artifact_digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9541, + "bytes": 9599, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", - "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -621,14 +622,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-20T13:59:18.050980+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -761,6 +762,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -820,13 +845,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [], @@ -848,10 +897,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:35.038284Z" + "held_until": "2026-11-19T13:59:18.051742Z" } } } @@ -859,26 +908,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", - "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", + "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" + "content-type": "application/vnd.apache.parquet" }, "body_file": "fetch-spec-known-sentence.parquet" } @@ -892,10 +941,10 @@ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "crsCooperationModality", "crsCooperationModality_label", "crsPurpose", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json index 019164b..bea5f54 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json @@ -4,9 +4,9 @@ "description": "Fetching a two-role spec with entities binding origin to null posts input.scope.entities with origin dropped and destination kept, and the build answers a new spec_id bound to destination alone.", "origin": { "kind": "recorded", - "base_url": "http://127.0.0.1:19493/api", - "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T13:05:36Z" + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "recorded_at": "2026-10-23T18:37:14Z" }, "call": [ { @@ -182,7 +182,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "65233075c02f4a259e853322a41a615e" + "x-dfo-trace-id": "5de76faaaff84624ac1026e8e9beb150" }, "json": { "schema_version": 1, @@ -190,21 +190,12 @@ "schema_version": 1, "spec_id": "spec_4c228c73be6c18efd0939eabb3b3c456", "identity": { - "entities": { - "destination": [ - "country/NGA" - ] - }, - "identity_version": "spec1", - "requested_window": { - "kind": "all" - }, "shape": { "kind": "statvar_schema", - "measured_property": "amount", - "measurement_qualifier": "Nominal", + "stat_type": "measuredValue", "population_type": "FinancialFlow", - "stat_type": "measuredValue" + "measured_property": "amount", + "measurement_qualifier": "Nominal" }, "slots": [ { @@ -247,11 +238,20 @@ }, "property": "nettingBasis" } - ] + ], + "entities": { + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } } }, "content_version": "cv_1868d697e8e7d56da6a83740a940c2e5", - "prepared_at": "2026-10-21T13:05:38Z", + "prepared_at": "2026-10-21T06:50:59Z", "coverage": { "rows": 309, "dimensions": [ @@ -280,9 +280,9 @@ ], "window": { "kind": "all", - "start_year": 1995, + "origin": "default", "end_year": 2024, - "origin": "default" + "start_year": 1995 } }, "citation": { @@ -368,25 +368,47 @@ ] }, "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], "applied_window": { "kind": "all", - "start_year": 1995, + "origin": "default", "end_year": 2024, - "origin": "default" + "start_year": 1995 }, - "graph_revision": null, + "graph_revision": "dfo-dev-dc-datacommons-service-00260-6xk", + "normalisations": [], "code_index_stamp": { - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "graph_endpoint": "graph_release" }, - "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", "revision": "2026-10-15" } ], + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "687d48bf1bbeffce437765ae950a2ba755137b98", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -557,34 +579,12 @@ "observation_count": 0 } ], - "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "family_member_count": 21, - "facets": [ - { - "axis": "provenance", - "ref": "provenance/OECDCreditorReportingSystem", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868" - }, - { - "axis": "unit", - "ref": "CurrencyUSD", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868" - } - ], - "normalisations": [], + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "capability_version": "dset_88fecfec3c5b89d1", - "served_from": "materialise", - "confirmed_at": "2026-10-21T13:05:38.830186+00:00" + "origin_catalogue_build_id": "20261020T170016Z-691bf0da", + "served_from": "head", + "confirmed_at": "2026-10-23T18:37:15.216372+00:00" }, "warnings": [], "diagnostics": [ @@ -596,17 +596,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:da9aa46394801d54e23b886528b98b609d8fda2ed46a2eb9e365575ee73ddf3a", + "artifact_digest": "sha256:582f586bcb05d6807c91e6b5d88779c13c5c0962cd42e793184e8c6c8c90d2d9", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 13341, + "bytes": 13398, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:38.797066+00:00", + "created_at": "2026-10-23T16:58:55.692876+00:00", "tier": "working", - "url": "/api/datasets/spec_4c228c73be6c18efd0939eabb3b3c456/cv_1868d697e8e7d56da6a83740a940c2e5/files/sha256:da9aa46394801d54e23b886528b98b609d8fda2ed46a2eb9e365575ee73ddf3a" + "url": "/api/datasets/spec_4c228c73be6c18efd0939eabb3b3c456/cv_1868d697e8e7d56da6a83740a940c2e5/files/sha256:582f586bcb05d6807c91e6b5d88779c13c5c0962cd42e793184e8c6c8c90d2d9", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:ffd0e9eaabfc35d3113188c82648ce0bf809307a01a024b52b0baa133ef63d18", @@ -615,14 +616,14 @@ }, "bytes": 9074, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:38.797066+00:00", + "created_at": "2026-10-21T06:50:59.873948+00:00", "tier": "working", "url": "/api/datasets/spec_4c228c73be6c18efd0939eabb3b3c456/cv_1868d697e8e7d56da6a83740a940c2e5/files/sha256:ffd0e9eaabfc35d3113188c82648ce0bf809307a01a024b52b0baa133ef63d18" } ], "series_count": 58, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -815,6 +816,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 25, + "covered": 25 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 25, + "covered": 25 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -874,13 +899,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [ @@ -975,10 +1024,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:38.797229Z" + "held_until": "2026-11-20T06:50:59.874372Z" } } } @@ -996,21 +1045,12 @@ "entry_kind": "identity", "variable_text": "dataset", "identity": { - "entities": { - "destination": [ - "country/NGA" - ] - }, - "identity_version": "spec1", - "requested_window": { - "kind": "all" - }, "shape": { "kind": "statvar_schema", - "measured_property": "amount", - "measurement_qualifier": "Nominal", + "stat_type": "measuredValue", "population_type": "FinancialFlow", - "stat_type": "measuredValue" + "measured_property": "amount", + "measurement_qualifier": "Nominal" }, "slots": [ { @@ -1053,7 +1093,16 @@ }, "property": "nettingBasis" } - ] + ], + "entities": { + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } } } ] @@ -1064,7 +1113,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "d1929c3ccdc84f0ab8eb63b2aa22bfce" + "x-dfo-trace-id": "fb2aa42a24b34e7eb4ceda53dd1ba402" }, "json": { "schema_version": 1, @@ -1073,11 +1122,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d1929c3ccdc84f0ab8eb63b2aa22bfce", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "fb2aa42a24b34e7eb4ceda53dd1ba402", "warnings": [], "timing_ms": { - "total": 139, + "total": 400, "by_step": { "coverage": 0 } @@ -1096,19 +1145,19 @@ } ], "timing_ms": { - "total": 99, + "total": 258, "by_step": { - "validate": 2, - "walk": 68, - "reread_arcs": 1, + "validate": 7, + "walk": 190, + "reread_arcs": 2, "detect_edits": 0, "resolve_survivors": 0, - "shape": 2, + "shape": 3, "bind": 0, "where_places": 0, - "materialise": 12, - "answer": 11, - "options": 3 + "materialise": 31, + "answer": 15, + "options": 10 } }, "operations": [], @@ -1522,7 +1571,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "facets": { "provenance": { "basis": "fallback", @@ -2251,7 +2300,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_347a470e04c97eec" + "capability_version": "cap_94e25737d859392c" }, "confidence": "high", "available_at_place": true, @@ -4876,26 +4925,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_4c228c73be6c18efd0939eabb3b3c456/cv_1868d697e8e7d56da6a83740a940c2e5/files/sha256:da9aa46394801d54e23b886528b98b609d8fda2ed46a2eb9e365575ee73ddf3a" + "origin_path": "/api/datasets/spec_4c228c73be6c18efd0939eabb3b3c456/cv_1868d697e8e7d56da6a83740a940c2e5/files/sha256:582f586bcb05d6807c91e6b5d88779c13c5c0962cd42e793184e8c6c8c90d2d9" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ada9aa46394801d54e23b886528b98b609d8fda2ed46a2eb9e365575ee73ddf3a?X-Goog-Signature=redacted", - "x-dfo-trace-id": "6a47e9cde4fb494da9fa8aa1973d2e55" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A582f586bcb05d6807c91e6b5d88779c13c5c0962cd42e793184e8c6c8c90d2d9?X-Goog-Signature=redacted", + "x-dfo-trace-id": "cee12ff09673464d98d98632db4244b1" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Ada9aa46394801d54e23b886528b98b609d8fda2ed46a2eb9e365575ee73ddf3a?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A582f586bcb05d6807c91e6b5d88779c13c5c0962cd42e793184e8c6c8c90d2d9?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "74cf2f077d1e4218a74b4913461d26d0" + "content-type": "application/vnd.apache.parquet" }, "body_file": "fetch-spec-entity-dropped.parquet" } @@ -4909,10 +4958,10 @@ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "crsCooperationModality", "crsCooperationModality_label", "crsPurpose", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.parquet b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.parquet index bc5adcd90c1f0974ebf0182a188d2b156a1bdf57..878d0023f88f555099edb80e8982ca2bc87ff2d1 100644 GIT binary patch delta 1358 zcmaJ_^(3rcIiY?otq{%G5uN! z>X^kJ{utW#mxF=~6e&^)lQKcDh>ki$_G9`>WP|<~LHlbz{4vCHf-4oRhs(L|dEWE9 z&-1?bZsmT??S7|d*Q#}|s2kK=Gsm4ZsW^@+Winz?j2A%G-rAyideR<8P;OGgdF8Ib zr5=6C?8voIX0o&*Emx}Dr3!traYp;jie)h^E#LY^SCV`GegE>JD5ca5nwng5Q>NLLp|3j7Mu*PD z8IHR;(ceRZy5Syzo^B0n^>oR9)1e*M?MUPYdvZn!?|R5%#wf$xVM%GuBeMYA9`I}`z79b*f;Y<4Q# zSim?9RWnw^80vx@vsX3)N9NfxWZeT7@dYIbd1w^^8`z`t*JCP={fdNOXN2c0Ugae} zy@HbvvUnBqID>HjKC(EJ#7_;l-EiMBqx2C>ePv+K>TjIPQ`~65tFULoi^YX}JmM?I z!cI%Xwp>mW=g5*k-5S>!n@%AxP6t9qvc~p$$O7WavaJ{oJ9CNR4CSR>i-l*($%#TC zAq6vuiE%L&u5-u;t5?lqxN7P&O#Kgyj(g0{hL*$_?qIzkRxGSU!_GWak>)3-S5w8p zVk|P9iQ5V*FJ5 a`jO>NPzm9*-Q_rZVlS(Rmg58xwEhJK&$9{u delta 1310 zcmb7CZD?Cn7`~}HxviZzOB0hO{aCx4W%)Wuo7<&>5>J|&w4rToLehNrqo(=1`7Hek ztH@M}zxU(thSzU*Y>*2VrA;fXqa&BeqB3$NspFnD8INsnRqYnD`-Ty_n zIonBk4d#;E%r*0Jvn;K&HsnHaW%1bLHFMI~|DYHz=H+F%*jziV-u%VfI^lm9cd;fn z3%U;d;R*d^jsBVj-!kDXlX;x8{=4g^hIJiR4Dgaw4+p0Q(RXINZH5p(1iiyi^!fn) zrXSws4e;Wy?U{#m@*l4ogZPhuM|ue(Bk1GP`05bsc22_ekp#MH!#73%b;lrhCeZbz z6K^>c1-R4Q3kTf>`0z{^?Gb#>1&)&r)?E*X76I*e@PQjHSzbWzjN#8mL4#%Vs~7Kj zp@mnv4#)Ao&qovEg!sy! zb9%L+v_Xg)qE1meV`owoxbF08OA2}(esBufmVye<=koINiSvvXgQUx=rP3xLoA8E9 z(5@1RkR0s0h;~6i1vql~HFMx6(Z{4sAG}E>c`4yz)HZxYCitnu1R)d5-W}AYr7?xD z==SrGAcM&qyzBOBMN%S!!lB#COA72;1&e2%r)|ReT7peakPlZ`WA+-u2QL-aHEFg{ zU(ck3YAz)-lZ}OHE*)6TrUZ9-EKtce<3f6LZF#A|W diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json index cef8b0b..4703609 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json @@ -4,9 +4,9 @@ "description": "Fetching a two-role spec with entities naming only origin posts input.scope.entities with origin replaced and destination kept from the spec's definition, because the server's scope.entities replaces the spec's whole entity binding. The build answers a new spec_id bound to both roles.", "origin": { "kind": "recorded", - "base_url": "http://127.0.0.1:19493/api", - "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T13:05:35Z" + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "recorded_at": "2026-10-23T18:37:12Z" }, "call": [ { @@ -187,7 +187,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "c62c3fdb28e14a459e5111ba626dd898" + "x-dfo-trace-id": "58ed6d83ebac443ab3da3ef0a085c7f5" }, "json": { "schema_version": 1, @@ -195,24 +195,12 @@ "schema_version": 1, "spec_id": "spec_1ee5f6648c9e46ddcc806fa0034bb6a8", "identity": { - "entities": { - "destination": [ - "country/NGA" - ], - "origin": [ - "country/FRA" - ] - }, - "identity_version": "spec1", - "requested_window": { - "kind": "all" - }, "shape": { "kind": "statvar_schema", - "measured_property": "amount", - "measurement_qualifier": "Nominal", + "stat_type": "measuredValue", "population_type": "FinancialFlow", - "stat_type": "measuredValue" + "measured_property": "amount", + "measurement_qualifier": "Nominal" }, "slots": [ { @@ -255,11 +243,23 @@ }, "property": "nettingBasis" } - ] + ], + "entities": { + "origin": [ + "country/FRA" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } } }, "content_version": "cv_7947f7ed828c0b23b8df4c601d463c09", - "prepared_at": "2026-10-21T13:05:36Z", + "prepared_at": "2026-10-21T06:50:58Z", "coverage": { "rows": 2, "dimensions": [ @@ -288,9 +288,9 @@ ], "window": { "kind": "all", - "start_year": 2019, + "origin": "default", "end_year": 2021, - "origin": "default" + "start_year": 2019 } }, "citation": { @@ -376,25 +376,47 @@ ] }, "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], "applied_window": { "kind": "all", - "start_year": 2019, + "origin": "default", "end_year": 2021, - "origin": "default" + "start_year": 2019 }, - "graph_revision": null, + "graph_revision": "dfo-dev-dc-datacommons-service-00260-6xk", + "normalisations": [], "code_index_stamp": { - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "graph_endpoint": "graph_release" }, - "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", "revision": "2026-10-15" } ], + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "687d48bf1bbeffce437765ae950a2ba755137b98", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -565,34 +587,12 @@ "observation_count": 0 } ], - "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "family_member_count": 21, - "facets": [ - { - "axis": "provenance", - "ref": "provenance/OECDCreditorReportingSystem", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868" - }, - { - "axis": "unit", - "ref": "CurrencyUSD", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868" - } - ], - "normalisations": [], + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "capability_version": "dset_88fecfec3c5b89d1", - "served_from": "materialise", - "confirmed_at": "2026-10-21T13:05:36.077679+00:00" + "origin_catalogue_build_id": "20261020T170016Z-691bf0da", + "served_from": "head", + "confirmed_at": "2026-10-23T18:37:13.103333+00:00" }, "warnings": [], "diagnostics": [ @@ -604,17 +604,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:3f42e71fd7f6c7dde3c7294e7eb1eb6525ab0748650d41948ba054114025b297", + "artifact_digest": "sha256:13a775f3b4811a104717ac226f173d614d685e533def09482b83c55e06505c4c", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9059, + "bytes": 9116, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:36.037061+00:00", + "created_at": "2026-10-23T16:58:51.358637+00:00", "tier": "working", - "url": "/api/datasets/spec_1ee5f6648c9e46ddcc806fa0034bb6a8/cv_7947f7ed828c0b23b8df4c601d463c09/files/sha256:3f42e71fd7f6c7dde3c7294e7eb1eb6525ab0748650d41948ba054114025b297" + "url": "/api/datasets/spec_1ee5f6648c9e46ddcc806fa0034bb6a8/cv_7947f7ed828c0b23b8df4c601d463c09/files/sha256:13a775f3b4811a104717ac226f173d614d685e533def09482b83c55e06505c4c", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:36616ef68df33904cc9dfa37fb145d8fd1563b1b3701710dcd8d9e04ed50d79a", @@ -623,14 +624,14 @@ }, "bytes": 5628, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:36.037061+00:00", + "created_at": "2026-10-21T06:50:59.083645+00:00", "tier": "working", "url": "/api/datasets/spec_1ee5f6648c9e46ddcc806fa0034bb6a8/cv_7947f7ed828c0b23b8df4c601d463c09/files/sha256:36616ef68df33904cc9dfa37fb145d8fd1563b1b3701710dcd8d9e04ed50d79a" } ], "series_count": 2, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -763,6 +764,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -822,13 +847,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [ @@ -865,10 +914,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:36.037239Z" + "held_until": "2026-11-20T06:50:59.083841Z" } } } @@ -886,24 +935,12 @@ "entry_kind": "identity", "variable_text": "dataset", "identity": { - "entities": { - "destination": [ - "country/NGA" - ], - "origin": [ - "country/FRA" - ] - }, - "identity_version": "spec1", - "requested_window": { - "kind": "all" - }, "shape": { "kind": "statvar_schema", - "measured_property": "amount", - "measurement_qualifier": "Nominal", + "stat_type": "measuredValue", "population_type": "FinancialFlow", - "stat_type": "measuredValue" + "measured_property": "amount", + "measurement_qualifier": "Nominal" }, "slots": [ { @@ -946,7 +983,19 @@ }, "property": "nettingBasis" } - ] + ], + "entities": { + "origin": [ + "country/FRA" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "all" + } } } ] @@ -957,7 +1006,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a59d23d595924f7695a10d939638112b" + "x-dfo-trace-id": "3ea2202f586b47b48906c83b42b9a4fe" }, "json": { "schema_version": 1, @@ -966,11 +1015,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "a59d23d595924f7695a10d939638112b", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "3ea2202f586b47b48906c83b42b9a4fe", "warnings": [], "timing_ms": { - "total": 674, + "total": 340, "by_step": { "coverage": 0 } @@ -983,19 +1032,19 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 652, + "total": 288, "by_step": { - "validate": 2, - "walk": 76, - "reread_arcs": 1, + "validate": 3, + "walk": 225, + "reread_arcs": 2, "detect_edits": 0, "resolve_survivors": 0, "shape": 3, "bind": 0, - "where_places": 359, - "materialise": 10, - "answer": 200, - "options": 1 + "where_places": 0, + "materialise": 12, + "answer": 41, + "options": 2 } }, "operations": [], @@ -1408,7 +1457,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "facets": { "provenance": { "basis": "fallback", @@ -2007,7 +2056,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_347a470e04c97eec" + "capability_version": "cap_94e25737d859392c" }, "confidence": "high", "available_at_place": true, @@ -4607,26 +4656,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_1ee5f6648c9e46ddcc806fa0034bb6a8/cv_7947f7ed828c0b23b8df4c601d463c09/files/sha256:3f42e71fd7f6c7dde3c7294e7eb1eb6525ab0748650d41948ba054114025b297" + "origin_path": "/api/datasets/spec_1ee5f6648c9e46ddcc806fa0034bb6a8/cv_7947f7ed828c0b23b8df4c601d463c09/files/sha256:13a775f3b4811a104717ac226f173d614d685e533def09482b83c55e06505c4c" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A3f42e71fd7f6c7dde3c7294e7eb1eb6525ab0748650d41948ba054114025b297?X-Goog-Signature=redacted", - "x-dfo-trace-id": "b94e3c7dd2fe45fdb401820e689a9098" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A13a775f3b4811a104717ac226f173d614d685e533def09482b83c55e06505c4c?X-Goog-Signature=redacted", + "x-dfo-trace-id": "037ba569f0d64fd7a230db5c74978c3f" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3A3f42e71fd7f6c7dde3c7294e7eb1eb6525ab0748650d41948ba054114025b297?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A13a775f3b4811a104717ac226f173d614d685e533def09482b83c55e06505c4c?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "9e5771b287d64ab18a4a6c98c484570a" + "content-type": "application/vnd.apache.parquet" }, "body_file": "fetch-spec-entity-rebound.parquet" } @@ -4640,10 +4689,10 @@ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "crsCooperationModality", "crsCooperationModality_label", "crsPurpose", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.parquet b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.parquet index bd415ce58a6b791fce03022f96894472feb55e0c..d99bba60766454b4d032825554aaf94e163b595a 100644 GIT binary patch delta 1304 zcmaJ>U1%d!6i(9IN!n&@n|3CX=D+P;QyabgNxMna#+xRoyJ|YkrpCsfl1!6yYMO-p zZu=mM6kVjC_Q;Rf=wX5Vpru$UZD63Vm1?S=PFU6!lJ^RnR&Nmvg^! zzVCeJFwBp!&5`%c>OvxKf0Wnp8nZ@Y@)B!~9(!$(|yFAC1FvZuZr0b;CUUY;QF5h)?eiw8ANqIY7H^Y;S0=(1Ip?~QZz6#$o z(Wfnkt`1H7-RzE5_(O|7zYE_!rZzij#-oQZ;o`5e4;A^R%uSL8j!W%8CXsZ?9u!5T}px*fla^=DwGO=A0s9QU zWw{?+#Q5fM=oUxO+jryJ7}mtoXv>RV@xpa+1fA=|H`K@nNvj9_(1~|CtGBnT0@~=p zm+pa2tgoZpd+{9~WLhij?{*7%Y!p5u8mnD2(L`c2H8?L%=VmkF_YFjSx?rz0;s^)A zW0c0}IHgh{O6hPQOevkF42+J!xUHm>V8<3RNXY?00?SZm_j4zuB|>^2VvlkYT}-J6 zFWW=hjEV-}s=c4{t7s4!9Dc)S@&rQ*aLVE5qS7iM-LU59=K@3`BnKZm2$xpT0oZed zv~ln|M{DS65MFRTXrRd;Q=#ysGiZoZW7ggk;j&VnN=UjwhDRc-gvfBw72?K8o{%Vf z=kgn9gc%3~pw%5WgehUZ@=$h1Y9F3qcvm-Bf_)ExpWLR&-i1nbc8tzT%w^ZA%3{+; zV{8#@70c>b4b^~#3+geON%c=>XXA`Fbvm7jSLBgmFTe){F7f2WuYE8+1&bRwGX80XKaoK$wV%bujF&( z&4cXK&+3V8Y2Y~%NA=&lvch|ByvJ9^&^x5PF6j*Om@Auhed|LjD2PPirI_)p#Fc{fxHeXwQm z@o%)DZ(Cu{@)Uog9lg>Hj~n|`Pp7QM`AePXrw(}58sje`^lK+vx1KWWb)nrZ*{6f= z8k^x&n*{T=7Q;?Ax_by5GW^huu5}+~{ce+t7av7$A6M;<*t=lZUa7s)i}rgM(gCr$ z4!CKLw!eoZ9WqEC^>H@YT2B&*SnA|PW+hijTlX8Vx**&Va*R!l#tBJ~8A8Z%gpg2p zl%7@z1;bT%x23F!fhY&{v7`@U|1vx&dxWrZ7UO<+T@DN5J+#yc+?IpF5<`ce)8Q4? z80v+m9UlF3a)|2U@Rq|P5M>+VZMaSu8(6_O4UJAL%revqVP{Y?1ur;bHOjUhzHtug zm873atI*;K=*N-)j03d2D6$bk^px~a? zlPadZ7U5%eNFQCL#(D}AcWJWF)9P3`F}ji|C%kimo0Y{9eKQ$bV|1@VU03NfKEpsV z$pV|n{S{?%>@Y7p35@rQLED-gmo<^Cg(Na3)U0EzmQv=y}rW6=VrxL|XF;JbKo9NHY2G(i5 zpz-q;hHOf=u*LDQ zD1W+v+l6krtf!kQ-Kh6tC*P!pb<(SI=Ir!BusY3lDQ_Ax`B|fCey*{n0ak8QsLMXJ z$!j-AMZ?USx?z^m)77KK_{21&qPTNR2Oh^~J=V?lcgdByCN^D1X zdMlJv%@T(n)FDd>-m98DIklCglMo9;*X*g^I~d{DAc56@b1XDlD^!N*Ogh3qiwxPr zj3iS@cG5oPfd%}iFXoC_tK_p?lZDD4r~u?A~&L_6_q# zUrZBd^0)Qo*bu3?QO?;OUnqogwOs$m0w4Am=O3dqMd<*gqclFxKcnu3=~4?S jO7(DNay%6cjUK3nl>H>LTnEMAN~`WT?iPeJ&20Y{pz~u{ delta 1192 zcmb7BOKcNY6dfmhwrP`)pv-t|k3T{56*W>`;(YJ~i1Q}?^lC*a=R; zD3K7KN+_xTAzd2LibaJG3lrV%PVW}w63uhnW0>{;G|95maEQx z@c$HwP5w|;X7Z(UDU&bF#>>54_VX2JJt_^eIo5)S^`HkBKzrJJ?zRC0h{^rFW#_?jL1tNjp`8-O%A z;ga|kiH+%4f9+pMWcOm?H4}4l5 zfM$0LU8Q)Z7rv_Z!k2E}fz4sIO>CDgXo6FbYpAY|CA*h1bGc$#{-%cT(+NB7h+=4z z(k?ne>5vhoR9mD5Wf{xk6jWu@5{3;WWb2y`5~3F1fzn}}h_7?C-4n5nkT@Z0aLg03 z8@x)^gYdPd-MY-{L-5ekVbkVSrW}VlZ--Tnw-eF<{a#i!$P6K6_}ojZMP63ndvC}> z;gxsH5`lhS$QGV&X6076>{CC9@wmA_P7%WVYMRcFa;q%iP&rw6;q#nn*XA-My>l|K zvNT;xFs5&j>pJ6y2;qvvI4{y+4%7_ID8?~1#Wc~?RA6Css%>zA-9|b&v6_vl%c`tW9H2uGRt7MhMeLJ+Kw{_^4HM_L(2XEJ7#D`ngPxx#ciY} z2U~L!YB`BvGba9k@ zTQ-p?s)2M;U&wHKBj)%7)e^LiIifUEaln@P-ox8{4VYv9-WPjMY5! Z&Gz|DD#-q&G(2ni%znB-5aLvC`wN5EWGesw diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json index 5e278f1..dd8a271 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json @@ -4,9 +4,9 @@ "description": "Fetching a spec of Germany's flows to the least developed countries group with entities naming only origin rebinds origin to France. The identity entry that asks Search for the built sentence carries the destination's group, whose binding the build kept, and the sentence names the group.", "origin": { "kind": "recorded", - "base_url": "http://127.0.0.1:19493/api", - "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T13:05:48Z" + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "recorded_at": "2026-10-23T18:37:23Z" }, "call": [ { @@ -296,7 +296,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4f36947ae53548928cf48b3ef6375841" + "x-dfo-trace-id": "c13351d375404401a8266f1009cb72a5" }, "json": { "schema_version": 1, @@ -304,7 +304,46 @@ "schema_version": 1, "spec_id": "spec_c2f21170dfa9f31705e47ed60c8fa305", "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "ref": "DAC2aAidType206", + "state": "value" + }, + "property": "dac2aAidType" + }, + { + "binding": { + "state": "unbound" + }, + "property": "dacTypeOfFinance" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], "entities": { + "origin": [ + "country/FRA" + ], "destination": [ "country/AFG", "country/AGO", @@ -350,55 +389,16 @@ "country/UGA", "country/YEM", "country/ZMB" - ], - "origin": [ - "country/FRA" ] }, "identity_version": "spec1", "requested_window": { "kind": "all" - }, - "shape": { - "kind": "statvar_schema", - "measured_property": "amount", - "measurement_qualifier": "Nominal", - "population_type": "FinancialFlow", - "stat_type": "measuredValue" - }, - "slots": [ - { - "binding": { - "ref": "DAC2aAidType206", - "state": "value" - }, - "property": "dac2aAidType" - }, - { - "binding": { - "state": "unbound" - }, - "property": "dacTypeOfFinance" - }, - { - "binding": { - "ref": "Disbursement", - "state": "value" - }, - "property": "financialFlowType" - }, - { - "binding": { - "ref": "Gross", - "state": "value" - }, - "property": "nettingBasis" - } - ] + } } }, "content_version": "cv_66a0a4a0331d59b519aa1629dade3d99", - "prepared_at": "2026-10-21T13:05:48Z", + "prepared_at": "2026-10-21T07:08:52Z", "coverage": { "rows": 2114, "dimensions": [ @@ -427,9 +427,9 @@ ], "window": { "kind": "all", - "start_year": 1960, + "origin": "default", "end_year": 2024, - "origin": "default" + "start_year": 1960 } }, "citation": { @@ -515,25 +515,56 @@ ] }, "trace": { + "facets": [ + { + "ref": "provenance/OECDDAC2A", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + }, + { + "ref": null, + "axis": "measurementMethod", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + } + ], "applied_window": { "kind": "all", - "start_year": 1960, + "origin": "default", "end_year": 2024, - "origin": "default" + "start_year": 1960 }, - "graph_revision": null, + "graph_revision": "dfo-dev-dc-datacommons-service-00260-6xk", + "normalisations": [], "code_index_stamp": { - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "graph_endpoint": "graph_release" }, - "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDDAC2A", "revision": "2026-10-15" } ], + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "36b9f48d83282bcd5d99cb8f67b83e57a00216fd", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", @@ -544,43 +575,12 @@ "observation_count": 2114 } ], - "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", "family_member_count": 1, - "facets": [ - { - "axis": "provenance", - "ref": "provenance/OECDDAC2A", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "1962969911839422253" - }, - { - "axis": "measurementMethod", - "ref": null, - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "absent_on_selected_facet", - "dispatch_facet_id": "1962969911839422253" - }, - { - "axis": "unit", - "ref": "CurrencyUSD", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "1962969911839422253" - } - ], - "normalisations": [], + "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", "frame_grammar_version": "1.1.0", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "capability_version": "dset_88fecfec3c5b89d1", - "served_from": "materialise", - "confirmed_at": "2026-10-21T13:05:48.882315+00:00" + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "head", + "confirmed_at": "2026-10-23T18:37:23.648030+00:00" }, "warnings": [], "diagnostics": [ @@ -592,17 +592,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:1ea84fd402e660f640baf08b43a6ef4ed031c01b7dc8a781237c1c3006a3f934", + "artifact_digest": "sha256:a382b8f9e3ba634c150c6588e21f79413722d53f7bcdcb9dfd4e929aa4f80993", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 21027, + "bytes": 21088, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:48.852766+00:00", + "created_at": "2026-10-23T16:59:11.517434+00:00", "tier": "working", - "url": "/api/datasets/spec_c2f21170dfa9f31705e47ed60c8fa305/cv_66a0a4a0331d59b519aa1629dade3d99/files/sha256:1ea84fd402e660f640baf08b43a6ef4ed031c01b7dc8a781237c1c3006a3f934" + "url": "/api/datasets/spec_c2f21170dfa9f31705e47ed60c8fa305/cv_66a0a4a0331d59b519aa1629dade3d99/files/sha256:a382b8f9e3ba634c150c6588e21f79413722d53f7bcdcb9dfd4e929aa4f80993", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:b1f80f2d3df16b6cda3831730ee4749b13e1eb3fff82cdf2f479e71f087bfe2b", @@ -611,14 +612,14 @@ }, "bytes": 8093, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:48.852766+00:00", + "created_at": "2026-10-21T07:08:52.857494+00:00", "tier": "working", "url": "/api/datasets/spec_c2f21170dfa9f31705e47ed60c8fa305/cv_66a0a4a0331d59b519aa1629dade3d99/files/sha256:b1f80f2d3df16b6cda3831730ee4749b13e1eb3fff82cdf2f479e71f087bfe2b" } ], "series_count": 44, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -751,6 +752,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -816,13 +841,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 44, + "covered": 44 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 44, + "covered": 44 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [ @@ -859,10 +908,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:48.852599Z" + "held_until": "2026-11-20T07:08:52.858156Z" } } } @@ -880,7 +929,46 @@ "entry_kind": "identity", "variable_text": "dataset", "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "ref": "DAC2aAidType206", + "state": "value" + }, + "property": "dac2aAidType" + }, + { + "binding": { + "state": "unbound" + }, + "property": "dacTypeOfFinance" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], "entities": { + "origin": [ + "country/FRA" + ], "destination": [ "country/AFG", "country/AGO", @@ -926,51 +1014,12 @@ "country/UGA", "country/YEM", "country/ZMB" - ], - "origin": [ - "country/FRA" ] }, "identity_version": "spec1", "requested_window": { "kind": "all" - }, - "shape": { - "kind": "statvar_schema", - "measured_property": "amount", - "measurement_qualifier": "Nominal", - "population_type": "FinancialFlow", - "stat_type": "measuredValue" - }, - "slots": [ - { - "binding": { - "ref": "DAC2aAidType206", - "state": "value" - }, - "property": "dac2aAidType" - }, - { - "binding": { - "state": "unbound" - }, - "property": "dacTypeOfFinance" - }, - { - "binding": { - "ref": "Disbursement", - "state": "value" - }, - "property": "financialFlowType" - }, - { - "binding": { - "ref": "Gross", - "state": "value" - }, - "property": "nettingBasis" - } - ] + } }, "entity_groups": { "destination": { @@ -987,7 +1036,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4f01e12f49de482f8674fe65b685601f" + "x-dfo-trace-id": "94e2938030144075b73ca71182f9377a" }, "json": { "schema_version": 1, @@ -996,11 +1045,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "4f01e12f49de482f8674fe65b685601f", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "94e2938030144075b73ca71182f9377a", "warnings": [], "timing_ms": { - "total": 957, + "total": 1785, "by_step": { "coverage": 0 } @@ -1013,19 +1062,19 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 937, + "total": 1737, "by_step": { - "validate": 1, - "walk": 5, + "validate": 0, + "walk": 10, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 918, + "shape": 1700, "bind": 0, - "where_places": 0, - "materialise": 7, - "answer": 5, - "options": 1 + "where_places": 1, + "materialise": 16, + "answer": 8, + "options": 2 } }, "operations": [], @@ -1995,7 +2044,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "facets": { "provenance": { "basis": "fallback", @@ -2833,7 +2882,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_347a470e04c97eec" + "capability_version": "cap_94e25737d859392c" }, "confidence": "high", "available_at_place": true, @@ -5254,26 +5303,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_c2f21170dfa9f31705e47ed60c8fa305/cv_66a0a4a0331d59b519aa1629dade3d99/files/sha256:1ea84fd402e660f640baf08b43a6ef4ed031c01b7dc8a781237c1c3006a3f934" + "origin_path": "/api/datasets/spec_c2f21170dfa9f31705e47ed60c8fa305/cv_66a0a4a0331d59b519aa1629dade3d99/files/sha256:a382b8f9e3ba634c150c6588e21f79413722d53f7bcdcb9dfd4e929aa4f80993" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A1ea84fd402e660f640baf08b43a6ef4ed031c01b7dc8a781237c1c3006a3f934?X-Goog-Signature=redacted", - "x-dfo-trace-id": "f00d62be1abb42d9ae15319676c66876" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Aa382b8f9e3ba634c150c6588e21f79413722d53f7bcdcb9dfd4e929aa4f80993?X-Goog-Signature=redacted", + "x-dfo-trace-id": "40d3efef54434905ad56dd99d8835067" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3A1ea84fd402e660f640baf08b43a6ef4ed031c01b7dc8a781237c1c3006a3f934?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Aa382b8f9e3ba634c150c6588e21f79413722d53f7bcdcb9dfd4e929aa4f80993?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "2c16e3201afc4262a3a2219cafc506b4" + "content-type": "application/vnd.apache.parquet" }, "body_file": "fetch-spec-group-origin-rebound.parquet" } @@ -5287,10 +5336,10 @@ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "dac2aAidType", "dac2aAidType_label", "time_period", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.parquet b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.parquet index 7ef63db695671fde6c755c03768f477e526359bd..accd075e300499a72131aad1cebd91e3e42cce16 100644 GIT binary patch delta 1246 zcmZ`$O>7%Q6yDj!Yqz!f7wp)wp@E>GB8YLEIE^DwcN}~D{}YqO_5uRiv7PmQoH%K6 zpcM6hQ0bwsLJ*0nqB)@o6?(4%Ck{~r5<(mhDyZTBQY7F2g^)0_B2gsdr`7Dd_vZV) z`QF@KLl4%_-F0NOnCwxLXcA5dg7GBfT4 zl#}h|qB>J-gGev*_U)Hb#e&*Wi;abQEvh@@`TzM>t7>D$B$}^0Y5owIKSKCZJ^o9w zj|yk@Z5=R(WYeKrZ;96DRXretR3iujedqDdf>@{DbhvPz^ia_mEw>vxD%p9jJu~ z_`**~S9cNK;;F2^`G$x$cM&}BIN_IYP``ay#Os$uNSuEHGLe4#`S<({u))0brYKnL z79&li66x{z!fdggvs^V29wTrw;+Q5s(IQR*$zB}yYaPn2Od5=VZBM?HF9 zWsDHF18zh|Bqg~*$S7<^{ZfG>32}lo<}o;Ub!o*7uf>L?F_%IM8(aJRroqK zB26cU330)(I4e_9B4iOlaU#v}@*un(_aHCak0+1}#}XdBzcR?mewa$Q4+piqg8{xt zl4^arlFN8oO4{YfI2T&^`XrrCo@Iwu7-EbW^2>g<(h25;C4A9>xnmaVxwLCGUyn1~ z%!^7o-YNuYwR|I0$_HdsNoyE-mh&xF2%Ja^)Vm-inSzf^(p}*5txfe3R7=f2!

b0tp372xtT1R31G#eRlO%eDqIsmtmmJ{>YbhwtM6O){M zB}u>*8@QyfTg#m+#|(Lw^TSF@2~00@{)-%cky4q`5T#k_UE;5(*=HBkV()%@35rM%B3r$Jv3Ed8xqd#+Q2&n6Ya2PXv~NmE1r0$==)=l}o! delta 1163 zcmb7BUuaWT7{4c)dm~hwc8O^l+bHue*0GbOjcZhh=Qj5y&EK0~nm=T4tPO~5gGlk~a1#tS_-fcEgd;5ZelJ$<&dsBD5T5goACfoUg zwu{L2DZ*b$_^IePBE0)gqi^}Grpq_sl7Bx~l|J)>4*anN!aJOhRkWQy*zgj3r3Bit z?;AG$HF&iPZ`uEIa7*nn|JaQ$cf;pubJw~9KkDKA@R{UJ!(u5WckqcS8jHA&0p79N~-4jq;PwA#rIN;SFA@($yCT z-`_^icft+F!$E1gWx{JM6D*zRg)hQR{PjN9QF>HOvckkXNzYh>jnGO z4#JNI{s=1$U8a;Cp;1c1x}Q>cn(CBQtkx)Kkr?vBm55IosSFe1t->#nA#qGwDqsdp`>ByuV8331NO^ImsgBR$0MA`;_>VtJmhT zX-}n)_B2xUu}UE$&*ah`S7uN?Q*0zX8TZ+liF$%{j!g4;9_>Ry_@qRNgEYbeHBuuB zut;bi$4Kg2)?J&+4TNg!)(h#exsvLg&89=O38U3-7#!6I)S|uWX@yfgri5#WjN7RMmJ;D~#BmA_N}BNl!2|U#i!txlCwk zBA}LYX`NR2_~AtY*CM@ap{_)Co*Rl9f(a@o=m_&bX|b)zw)mIot3`|&LVquU^-~&* exw4t$RH?2m7|(1`uc`1jQM6pyD+n4*4!i_YIBmB8 diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json index 3e103c9..076139d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json @@ -4,9 +4,9 @@ "description": "Fetching a spec whose sentence the client holds builds bare Parquet, follows the files route's redirect with a bare request, and returns one member with that sentence and no Search call.", "origin": { "kind": "recorded", - "base_url": "http://127.0.0.1:19493/api", - "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T13:05:49Z" + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "recorded_at": "2026-10-23T18:37:26Z" }, "call": [ { @@ -176,7 +176,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" + "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" }, "json": { "schema_version": 1, @@ -250,7 +250,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T13:05:35Z", + "prepared_at": "2026-10-20T13:59:17Z", "coverage": { "rows": 4, "dimensions": [ @@ -396,7 +396,7 @@ "graph_revision": null, "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", + "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "graph_endpoint": "graph_release" }, @@ -406,8 +406,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -581,9 +581,9 @@ "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + "confirmed_at": "2026-10-23T18:37:10.942106+00:00" }, "warnings": [ { @@ -601,17 +601,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "artifact_digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9541, + "bytes": 9599, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", - "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -620,14 +621,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-20T13:59:18.050980+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -760,6 +761,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -819,13 +844,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [], @@ -847,10 +896,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:35.038284Z" + "held_until": "2026-11-19T13:59:18.051742Z" } } } @@ -858,26 +907,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", - "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", + "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" + "content-type": "application/vnd.apache.parquet" }, "body_file": "fetch-spec-known-sentence.parquet" } @@ -891,10 +940,10 @@ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "crsCooperationModality", "crsCooperationModality_label", "crsPurpose", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.parquet b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.parquet index e9df5e79ccfa45682c8d8e2b716ce5cb25a955d4..7aaf5ba949a56d523dd1e0e944c06d3eba3d5a99 100644 GIT binary patch delta 1290 zcmaJ@how2FetxiSDk$cfUdl&dUke%LzF_{_iS&%P{GvU&xt=C8>4YjSk889it+ zdS#CNp`IA;l0h#&33F|FNNUa8mn~?m1%6am;T`Si#@{sPGkB;aFaAgKf13O%=O4?_ z)>CMwl{GnN!h=Vr78Ez-bq{apy11K%(Y-@(OZO)C#u4KD1) z4s@*pn)$iLuZ-w1yuzR7Hq7Y0Y28rZezBnI7AP62+>Q*;(Rw$0CuF(pW9ZdmaI*a+?)9h9mIKFUX9fJ{Q+6KQP7Y?Vmx_bUM%LyX<_FOW}g%88bhX_ zFBm5zN~Q>j6~cs!_=1FxBB5Y74nwAjJO=NZ0;<@g7h~Tt{ABVdPsNrnb^$VnmD5hD zRDwBkKsm!uA8eTil^%xr;b*f)H9k2+(E{{ZJj!rv731TOw+t$MIEHZ!-m_q3ilJV( zYYE7sz+1-~$f_TT)?pQy^ivfA*R6h4s2BFOR5p)&H?5>9_Ai)B=%IV}_F;k9GUUnjtjLwRYQYlkO=m&zfjdVR)vpOMS&SrHe*rebk^%q# delta 1307 zcmb7CU1*zS6i(WF`RTvO@-_cS)9y8G?B1kpwnS*-o8L9A$(NWkZ4pNP+NAkum;Pi6 zVuy&#p#yhBWEVpmcrj20^`Z=!RnZHcKv&ikD6 zoaelU_hIDA$c;t|t5mb6)Gca}QY2DX7?DV{oT;y#1Jb7IWQ0(2;NYoN6?`Ms!kw14 z{ugQUx7NBsW0)`1GPPW(w!qbw)=T+9{q%v*dS^;&e4I=aa;4=`p|*OE-Tc1OFPS)u zd%9ez<<%{$oV_S!FN@KYHuR&ya9m{j=ip~_YOxJ&E7fpOX=1k8(fu~~P+5`eb)Xwy zR1xo?^8Xe%--UKM|4ZPm%F5jAMz_15>&TnT8!Gfu&*pna#>LDf4chL7l+*#MIwcIS zqs+b*eV~OG*)x(IJvtBHvM({$jcCsR*JKFJ_7dg~6Z*&mw|bYDI~Me(88+l6p{aR} zd0<7?t?;R)Ap3a$y**&i0MV*oLK|bY5qbr|uL_GG@`I9vT`kMJYC~I31J`y;KwY{a z=Bq*U?jYoKG3L7=bae=}bT2TwcJzrIdh}t*$Iqa5pj$r-7xaCSOT%bixa{g#=GHOv z^)UR>J`K+sf{M#d^uB{%27K0W6t+7C;jY2d|GATuBRRV_BGMW(9VC&6rJr5N6${mj z=3X}z4%mzVqkqa5CnP~qgph?0A%UQeMvH`k!3Ml;tchcA&*+uKlE*Q2FTjLpOd90Y zF?PUNQ&2i-r>%|(;Qy9a(6~n{+_MU7wRGLdSNSW{JZeqA^G;Q#md{xRS zW~)*9wtPHS^^9cFiAs(iZ%UAl6Z&ENbRt4>2NTc_^LU0w`b)M=$iaBjY!0ig!3=U4~cmI diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json index 8d5f10f..c0149d5 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json @@ -175,7 +175,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" + "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" }, "json": { "schema_version": 1, @@ -184,7 +184,7 @@ "spec_id": "spec_cb5baa4161de718f18583060674dbca6" }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T13:05:35Z", + "prepared_at": "2026-10-20T13:59:17Z", "coverage": { "rows": 4, "dimensions": [ @@ -330,7 +330,7 @@ "graph_revision": null, "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", + "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "graph_endpoint": "graph_release" }, @@ -340,8 +340,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -515,9 +515,9 @@ "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + "confirmed_at": "2026-10-23T18:37:10.942106+00:00" }, "warnings": [ { @@ -535,17 +535,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "artifact_digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9541, + "bytes": 9599, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", - "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -554,14 +555,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-20T13:59:18.050980+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -694,6 +695,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -753,13 +778,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [], @@ -781,10 +830,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:35.038284Z" + "held_until": "2026-11-19T13:59:18.051742Z" } } } @@ -795,7 +844,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "72492035a830492dba11a29fa89ded8c" + "trace_id": "e1bfd7e1ab67428e9dc923e28d07d4f9" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-schema-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-schema-version.json index daeb3ba..55f8856 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-schema-version.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-schema-version.json @@ -175,7 +175,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" + "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" }, "json": { "schema_version": 1, @@ -248,7 +248,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T13:05:35Z", + "prepared_at": "2026-10-20T13:59:17Z", "coverage": { "rows": 4, "dimensions": [ @@ -394,7 +394,7 @@ "graph_revision": null, "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", + "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "graph_endpoint": "graph_release" }, @@ -404,8 +404,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -579,9 +579,9 @@ "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + "confirmed_at": "2026-10-23T18:37:10.942106+00:00" }, "warnings": [ { @@ -599,17 +599,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "artifact_digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9541, + "bytes": 9599, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", - "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -618,14 +619,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-20T13:59:18.050980+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -758,6 +759,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -817,13 +842,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [], @@ -845,10 +894,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:35.038284Z" + "held_until": "2026-11-19T13:59:18.051742Z" } } } @@ -859,7 +908,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "72492035a830492dba11a29fa89ded8c" + "trace_id": "e1bfd7e1ab67428e9dc923e28d07d4f9" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.json index f1f0924..5144675 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.json @@ -4,9 +4,9 @@ "description": "Fetching a spec with window=(2020, 2023) posts the window as input.scope, and the build answers a new spec_id. The client stores the built spec_id and content_version, takes the sentence from Search by posting the built definition's identity as a dataset_resubmit identity entry (variable_text \"dataset\" for a spec no answer part names), checks the answer's spec_id equals the built one, then downloads the file.", "origin": { "kind": "recorded", - "base_url": "http://127.0.0.1:19493/api", - "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T13:05:30Z" + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "recorded_at": "2026-10-23T18:37:10Z" }, "call": [ { @@ -183,7 +183,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a72e52f677934a84bf84cdaee5c6c696" + "x-dfo-trace-id": "52642a89ff44404fb61540fe78b1ca94" }, "json": { "schema_version": 1, @@ -191,26 +191,12 @@ "schema_version": 1, "spec_id": "spec_cb5baa4161de718f18583060674dbca6", "identity": { - "entities": { - "destination": [ - "country/NGA" - ], - "origin": [ - "country/DEU" - ] - }, - "identity_version": "spec1", - "requested_window": { - "end_year": 2023, - "kind": "range", - "start_year": 2020 - }, "shape": { "kind": "statvar_schema", - "measured_property": "amount", - "measurement_qualifier": "Nominal", + "stat_type": "measuredValue", "population_type": "FinancialFlow", - "stat_type": "measuredValue" + "measured_property": "amount", + "measurement_qualifier": "Nominal" }, "slots": [ { @@ -253,11 +239,25 @@ }, "property": "nettingBasis" } - ] + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T13:05:35Z", + "prepared_at": "2026-10-20T13:59:17Z", "coverage": { "rows": 4, "dimensions": [ @@ -286,9 +286,9 @@ ], "window": { "kind": "range", - "start_year": 2020, + "origin": "query", "end_year": 2023, - "origin": "query" + "start_year": 2020 } }, "citation": { @@ -374,25 +374,47 @@ ] }, "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], "applied_window": { "kind": "range", - "start_year": 2020, + "origin": "query", "end_year": 2023, - "origin": "query" + "start_year": 2020 }, "graph_revision": null, + "normalisations": [], "code_index_stamp": { + "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", - "exported_at": "2026-10-20T19:50:14Z", "graph_endpoint": "graph_release" }, - "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", "revision": "2026-10-15" } ], + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -563,34 +585,12 @@ "observation_count": 0 } ], - "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "family_member_count": 21, - "facets": [ - { - "axis": "provenance", - "ref": "provenance/OECDCreditorReportingSystem", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868" - }, - { - "axis": "unit", - "ref": "CurrencyUSD", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868" - } - ], - "normalisations": [], + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "capability_version": "dset_88fecfec3c5b89d1", - "served_from": "materialise", - "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "served_from": "head", + "confirmed_at": "2026-10-23T18:37:10.942106+00:00" }, "warnings": [ { @@ -608,17 +608,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "artifact_digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9541, + "bytes": 9599, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", - "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -627,14 +628,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-20T13:59:18.050980+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -767,6 +768,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -826,13 +851,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [], @@ -854,10 +903,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:35.038284Z" + "held_until": "2026-11-19T13:59:18.051742Z" } } } @@ -875,26 +924,12 @@ "entry_kind": "identity", "variable_text": "dataset", "identity": { - "entities": { - "destination": [ - "country/NGA" - ], - "origin": [ - "country/DEU" - ] - }, - "identity_version": "spec1", - "requested_window": { - "end_year": 2023, - "kind": "range", - "start_year": 2020 - }, "shape": { "kind": "statvar_schema", - "measured_property": "amount", - "measurement_qualifier": "Nominal", + "stat_type": "measuredValue", "population_type": "FinancialFlow", - "stat_type": "measuredValue" + "measured_property": "amount", + "measurement_qualifier": "Nominal" }, "slots": [ { @@ -937,7 +972,21 @@ }, "property": "nettingBasis" } - ] + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } } } ] @@ -948,7 +997,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e7b9afd7f94f41eb85716597d0432612" + "x-dfo-trace-id": "0d356c6a142c45b5a4e8ea173623cc40" }, "json": { "schema_version": 1, @@ -957,11 +1006,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "e7b9afd7f94f41eb85716597d0432612", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "0d356c6a142c45b5a4e8ea173623cc40", "warnings": [], "timing_ms": { - "total": 145, + "total": 341, "by_step": { "coverage": 0 } @@ -974,18 +1023,18 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 110, + "total": 269, "by_step": { - "validate": 3, - "walk": 81, - "reread_arcs": 2, + "validate": 4, + "walk": 217, + "reread_arcs": 1, "detect_edits": 0, "resolve_survivors": 0, - "shape": 3, + "shape": 4, "bind": 0, "where_places": 0, - "materialise": 5, - "answer": 15, + "materialise": 13, + "answer": 29, "options": 1 } }, @@ -1419,7 +1468,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "facets": { "provenance": { "basis": "fallback", @@ -1982,7 +2031,7 @@ "start_year": 2020, "end_year": 2023 }, - "capability_version": "cap_347a470e04c97eec" + "capability_version": "cap_94e25737d859392c" }, "confidence": "high", "available_at_place": true, @@ -4583,26 +4632,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", - "x-dfo-trace-id": "bcb796babc2947ada1b42afa03a19f2a" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", + "x-dfo-trace-id": "577ae3aa962c474cadcd801c357ba73e" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "a340dab2e965428fa1b99507c6d6dbd4" + "content-type": "application/vnd.apache.parquet" }, "body_file": "fetch-spec-narrowed.parquet" } @@ -4616,10 +4665,10 @@ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "crsCooperationModality", "crsCooperationModality_label", "crsPurpose", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.parquet b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.parquet index e9df5e79ccfa45682c8d8e2b716ce5cb25a955d4..7aaf5ba949a56d523dd1e0e944c06d3eba3d5a99 100644 GIT binary patch delta 1290 zcmaJ@how2FetxiSDk$cfUdl&dUke%LzF_{_iS&%P{GvU&xt=C8>4YjSk889it+ zdS#CNp`IA;l0h#&33F|FNNUa8mn~?m1%6am;T`Si#@{sPGkB;aFaAgKf13O%=O4?_ z)>CMwl{GnN!h=Vr78Ez-bq{apy11K%(Y-@(OZO)C#u4KD1) z4s@*pn)$iLuZ-w1yuzR7Hq7Y0Y28rZezBnI7AP62+>Q*;(Rw$0CuF(pW9ZdmaI*a+?)9h9mIKFUX9fJ{Q+6KQP7Y?Vmx_bUM%LyX<_FOW}g%88bhX_ zFBm5zN~Q>j6~cs!_=1FxBB5Y74nwAjJO=NZ0;<@g7h~Tt{ABVdPsNrnb^$VnmD5hD zRDwBkKsm!uA8eTil^%xr;b*f)H9k2+(E{{ZJj!rv731TOw+t$MIEHZ!-m_q3ilJV( zYYE7sz+1-~$f_TT)?pQy^ivfA*R6h4s2BFOR5p)&H?5>9_Ai)B=%IV}_F;k9GUUnjtjLwRYQYlkO=m&zfjdVR)vpOMS&SrHe*rebk^%q# delta 1307 zcmb7CU1*zS6i(WF`RTvO@-_cS)9y8G?B1kpwnS*-o8L9A$(NWkZ4pNP+NAkum;Pi6 zVuy&#p#yhBWEVpmcrj20^`Z=!RnZHcKv&ikD6 zoaelU_hIDA$c;t|t5mb6)Gca}QY2DX7?DV{oT;y#1Jb7IWQ0(2;NYoN6?`Ms!kw14 z{ugQUx7NBsW0)`1GPPW(w!qbw)=T+9{q%v*dS^;&e4I=aa;4=`p|*OE-Tc1OFPS)u zd%9ez<<%{$oV_S!FN@KYHuR&ya9m{j=ip~_YOxJ&E7fpOX=1k8(fu~~P+5`eb)Xwy zR1xo?^8Xe%--UKM|4ZPm%F5jAMz_15>&TnT8!Gfu&*pna#>LDf4chL7l+*#MIwcIS zqs+b*eV~OG*)x(IJvtBHvM({$jcCsR*JKFJ_7dg~6Z*&mw|bYDI~Me(88+l6p{aR} zd0<7?t?;R)Ap3a$y**&i0MV*oLK|bY5qbr|uL_GG@`I9vT`kMJYC~I31J`y;KwY{a z=Bq*U?jYoKG3L7=bae=}bT2TwcJzrIdh}t*$Iqa5pj$r-7xaCSOT%bixa{g#=GHOv z^)UR>J`K+sf{M#d^uB{%27K0W6t+7C;jY2d|GATuBRRV_BGMW(9VC&6rJr5N6${mj z=3X}z4%mzVqkqa5CnP~qgph?0A%UQeMvH`k!3Ml;tchcA&*+uKlE*Q2FTjLpOd90Y zF?PUNQ&2i-r>%|(;Qy9a(6~n{+_MU7wRGLdSNSW{JZeqA^G;Q#md{xRS zW~)*9wtPHS^^9cFiAs(iZ%UAl6Z&ENbRt4>2NTc_^LU0w`b)M=$iaBjY!0ig!3=U4~cmI diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-operation-failed-resubmitted.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-operation-failed-resubmitted.json index bb6f561..84c9646 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-operation-failed-resubmitted.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-operation-failed-resubmitted.json @@ -11,10 +11,10 @@ { "op": "fetch", "spec": { - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -53,21 +53,195 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } }, - "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a.", + "entity_groups": { + "destination": { + "label": "G77 countries", + "group_id": "groups/G77" + }, + "origin": { + "label": "DAC countries", + "group_id": "groups/OECD.DAC" + } + } } } ], @@ -80,10 +254,10 @@ "schema_version": 1, "input": { "kind": "spec_id", - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -122,17 +296,181 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } } @@ -147,15 +485,15 @@ "status": 202, "headers": { "content-type": "application/json", - "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry-after": "2", - "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" + "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "pending", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500 } } @@ -164,20 +502,20 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "621bdcc038e34f44bec226434f3f7378" + "x-dfo-trace-id": "043386d87ba247048aa921704d3ff030" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "failed", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500 }, "error": { @@ -201,10 +539,10 @@ "schema_version": 1, "input": { "kind": "spec_id", - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -243,17 +581,181 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } } @@ -268,15 +770,15 @@ "status": 202, "headers": { "content-type": "application/json", - "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry-after": "2", - "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" + "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "pending", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500 } } @@ -285,24 +787,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "621bdcc038e34f44bec226434f3f7378" + "x-dfo-trace-id": "043386d87ba247048aa921704d3ff030" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -311,24 +813,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "1df7b03572044eedaa412f6d2ad6b91f" + "x-dfo-trace-id": "c7ef77e57a864be6a4617b1aeae7c11d" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -337,24 +839,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "b5b2e2d98a4047be98aea852117381c7" + "x-dfo-trace-id": "cea2df9c98f94601a5e9976e76842f12" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -363,24 +865,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "686111d592f3451e8c55691d91a66663" + "x-dfo-trace-id": "7a800f2714b94a8482dc5fb553c669f5" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 1517, + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 1804, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -389,24 +891,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2", - "x-dfo-trace-id": "9acc0caab7e143d38b3ecbfbcd225707" + "retry-after": "3", + "x-dfo-trace-id": "f911f5f7ca244733b2da3d5ce6913f6d" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 1900, + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 2292, "progress": { - "rows_written": 16734, - "estimate_rows": 108798 + "rows_written": 0, + "estimate_rows": 109318 } } } @@ -415,24 +917,50 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "3", - "x-dfo-trace-id": "22c08bbaa1384833bd92f8dd9cc6312d" + "x-dfo-trace-id": "07d32bbe980e419eb9f8461492ff4c62" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 2377, + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 2903, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "4", + "x-dfo-trace-id": "dd33ade549434abf82b662ab5251b0c1" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 3686, "progress": { - "rows_written": 64341, - "estimate_rows": 108798 + "rows_written": 0, + "estimate_rows": 109318 } } } @@ -441,24 +969,128 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "227de800033b4185ae9b958d3fa2cec7" + "retry-after": "5", + "x-dfo-trace-id": "51d3664ad3e84fed8da1d94ce250d5de" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 4645, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "6", + "x-dfo-trace-id": "6a3b79b90c29464ca15c35d8eafecb96" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 5865, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "8", + "x-dfo-trace-id": "d7de7e24059f4d75ae14bd1778b984de" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 7391, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "8", + "x-dfo-trace-id": "cd1a9f894cbe4b6a9c1a7ee78315aff0" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 8000, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "8", + "x-dfo-trace-id": "e1c46fecd652459380163afea4dc35b7" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 2973, + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 8000, "progress": { - "rows_written": 106324, - "estimate_rows": 108798 + "rows_written": 105253, + "estimate_rows": 109318 } } } @@ -467,24 +1099,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "retry-after": "4", - "x-dfo-trace-id": "3197d4d8b5094857afb9bbd14c49fcb0" + "retry-after": "8", + "x-dfo-trace-id": "3b9df177b0a94b069b47c8b441c6f232" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 3719, + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 8000, "progress": { - "rows_written": 108798, - "estimate_rows": 108798 + "rows_written": 109318, + "estimate_rows": 109318 } } } @@ -493,24 +1125,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "29f271852cc04f1a8b287274f53105b6" + "x-dfo-trace-id": "cd6f7d2857a44f9c947573b696793564" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "done" }, "manifest": { "schema_version": 1, "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "shape": { "kind": "statvar_schema", @@ -548,29 +1180,193 @@ "property": "nettingBasis" } ], - "facets": { - "provenance": { - "ref": "provenance/OECDDAC2A", - "state": "value" - } + "entities": { + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ], + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] }, - "entities": {}, "identity_version": "spec1", "requested_window": { "kind": "range", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 } } }, - "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "prepared_at": "2026-10-21T13:06:08Z", + "content_version": "cv_3d58d26a874dc30b1bba7d5ad6dd90ee", + "prepared_at": "2026-10-23T18:38:28Z", "coverage": { - "rows": 108798, + "rows": 109318, "dimensions": [ { "label": "financingProvider", - "count": 172, + "count": 32, "axis": "origin", "noun": { "singular": "provider", @@ -579,7 +1375,7 @@ }, { "label": "financingRecipient", - "count": 238, + "count": 133, "axis": "destination", "noun": { "singular": "recipient", @@ -588,14 +1384,14 @@ }, { "label": "years", - "count": 7 + "count": 62 } ], "window": { "kind": "range", "origin": "query", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 } }, "citation": { @@ -685,11 +1481,11 @@ { "ref": "provenance/OECDDAC2A", "axis": "provenance", - "basis": "bound", - "default_policy": null, - "selection_reason": null, + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", "dispatch_facet_id": "1962969911839422253", - "default_policy_version": null + "default_policy_version": "1" }, { "ref": null, @@ -714,13 +1510,13 @@ "kind": "range", "origin": "query", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 }, - "graph_revision": null, + "graph_revision": "dfo-dev-dc-datacommons-service-00264-2s9", "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-23T18:14:12Z", + "content_hash": "29eb81d7b6c88641b1d4e8eb5e850ca36de66b99d6e9e09680aac020507a6392", "graph_endpoint": "graph_release" }, "source_revisions": [ @@ -729,8 +1525,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_cc753cefa9199881", + "materialiser_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", @@ -738,15 +1534,15 @@ "financingProvider", "financingRecipient" ], - "observation_count": 108798 + "observation_count": 109318 } ], "family_member_count": 1, "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "materialise", - "confirmed_at": "2026-10-21T13:06:09.616741+00:00" + "confirmed_at": "2026-10-23T18:38:31.738121+00:00" }, "warnings": [], "diagnostics": [ @@ -758,33 +1554,34 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad", + "artifact_digest": "sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 913395, + "bytes": 473679, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:06:09.573990+00:00", + "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", - "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { - "artifact_digest": "sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93", + "artifact_digest": "sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39", "rendering": { "statistics": "series" }, - "bytes": 967921, + "bytes": 144274, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:06:09.573990+00:00", + "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", - "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" + "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39" } ], - "series_count": 21017, + "series_count": 3656, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -796,19 +1593,19 @@ "name": "financingProvider", "kind": "role", "droppable": false, - "distinct": 172 + "distinct": 32 }, { "name": "financingRecipient", "kind": "role", "droppable": false, - "distinct": 238 + "distinct": 133 }, { "name": "time_period", "kind": "grain", "droppable": false, - "distinct": 7 + "distinct": 62 }, { "name": "value", @@ -861,109 +1658,25 @@ "column": "financingProvider", "field": "iso3", "token": "financingProvider_iso3", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 172, - "covered": 50 + "entities": 32, + "covered": 32 }, - "missing": [ - { - "ref": "AdaptationFund", - "label": "Adaptation Fund" - }, - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentBankGroup", - "label": "African Development Bank Group" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AndrewCarnegieFoundation", - "label": "Andrew Carnegie Foundation" - }, - { - "ref": "ArabFundForEconomicAndSocialDevelopment", - "label": "Arab Fund for Economic and Social Development" - }, - { - "ref": "Arcadia", - "label": "Arcadia" - }, - { - "ref": "ArcusFoundation", - "label": "Arcus Foundation" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianInfrastructureInvestmentBank", - "label": "Asian Infrastructure Investment Bank" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingProvider", "field": "iso2", "token": "financingProvider_iso2", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 172, - "covered": 50 + "entities": 32, + "covered": 32 }, - "missing": [ - { - "ref": "AdaptationFund", - "label": "Adaptation Fund" - }, - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentBankGroup", - "label": "African Development Bank Group" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AndrewCarnegieFoundation", - "label": "Andrew Carnegie Foundation" - }, - { - "ref": "ArabFundForEconomicAndSocialDevelopment", - "label": "Arab Fund for Economic and Social Development" - }, - { - "ref": "Arcadia", - "label": "Arcadia" - }, - { - "ref": "ArcusFoundation", - "label": "Arcus Foundation" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianInfrastructureInvestmentBank", - "label": "Asian Infrastructure Investment Bank" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingProvider", @@ -971,8 +1684,8 @@ "token": "financingProvider_label", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -983,8 +1696,8 @@ "token": "financingProvider_type", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -995,8 +1708,32 @@ "token": "financingProvider_party_kind", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -1005,55 +1742,13 @@ "column": "financingRecipient", "field": "iso3", "token": "financingRecipient_iso3", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 238, - "covered": 143 + "entities": 133, + "covered": 133 }, - "missing": [ - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianDevelopmentBankSpecialFunds", - "label": "Asian Development Bank Special Funds" - }, - { - "ref": "CaribbeanDevelopmentBank", - "label": "Caribbean Development Bank" - }, - { - "ref": "CentralAmericanBankForEconomicIntegration", - "label": "Central American Bank for Economic Integration" - }, - { - "ref": "DACACPCountries", - "label": "ACP countries (DAC)" - }, - { - "ref": "DACAfrica", - "label": "Africa (DAC)" - }, - { - "ref": "DACAfricaUnallocated", - "label": "Africa, unallocated by country (DAC)" - }, - { - "ref": "DACAllMultilateralRecipients", - "label": "all multilateral recipients (DAC)" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingRecipient", @@ -1062,52 +1757,16 @@ "state": "partial", "reason": "enrichment_unavailable", "coverage": { - "entities": 238, - "covered": 141 + "entities": 133, + "covered": 132 }, "missing": [ { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianDevelopmentBankSpecialFunds", - "label": "Asian Development Bank Special Funds" - }, - { - "ref": "CaribbeanDevelopmentBank", - "label": "Caribbean Development Bank" - }, - { - "ref": "CentralAmericanBankForEconomicIntegration", - "label": "Central American Bank for Economic Integration" - }, - { - "ref": "DACACPCountries", - "label": "ACP countries (DAC)" - }, - { - "ref": "DACAfrica", - "label": "Africa (DAC)" - }, - { - "ref": "DACAfricaUnallocated", - "label": "Africa, unallocated by country (DAC)" - }, - { - "ref": "DACAllMultilateralRecipients", - "label": "all multilateral recipients (DAC)" + "ref": "country/SSD", + "label": "South Sudan" } ], - "truncated": true + "truncated": false }, { "column": "financingRecipient", @@ -1115,8 +1774,8 @@ "token": "financingRecipient_label", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1127,8 +1786,8 @@ "token": "financingRecipient_type", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1139,8 +1798,32 @@ "token": "financingRecipient_party_kind", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1148,9 +1831,9 @@ ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [ @@ -1162,7 +1845,7 @@ "varying": [ { "column": "time_period", - "distinct": 7 + "distinct": 62 } ] }, @@ -1174,7 +1857,7 @@ "varying": [ { "column": "financingRecipient", - "distinct": 238 + "distinct": 133 } ] }, @@ -1186,7 +1869,7 @@ "varying": [ { "column": "time_period", - "distinct": 7 + "distinct": 62 } ] }, @@ -1198,7 +1881,7 @@ "varying": [ { "column": "financingProvider", - "distinct": 172 + "distinct": 32 } ] }, @@ -1210,7 +1893,7 @@ "varying": [ { "column": "financingRecipient", - "distinct": 238 + "distinct": 133 } ] }, @@ -1222,7 +1905,7 @@ "varying": [ { "column": "financingProvider", - "distinct": 172 + "distinct": 32 } ] } @@ -1245,10 +1928,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:06:09.573841Z" + "held_until": "2026-11-22T18:38:31.579178Z" } } } @@ -1257,26 +1940,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + "origin_path": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted", - "x-dfo-trace-id": "155fa981459c464482aea52657f99e8b" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted", + "x-dfo-trace-id": "b0cef6f918794d048a8a5056022de7cc" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "228feaabf1f3473cad055088084dc378" + "content-type": "application/vnd.apache.parquet" }, "body_file": "mint-async-build.parquet" } @@ -1285,15 +1968,15 @@ "expect": [ { "dataset": { - "rows": 108798, + "rows": 109318, "columns": [ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "dac2aAidType", "dac2aAidType_label", "time_period", @@ -1312,26 +1995,31 @@ "members": [ { "parts": [], - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", - "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "content_version": "cv_3d58d26a874dc30b1bba7d5ad6dd90ee", + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a." } ], "missing": [], "long_builds": [ { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "poll_waits": [ 1.5, 1.5, 1.5, 1.5, 1.5, - 1.517, - 1.9, - 2.377, - 2.973, - 3.719 + 1.804, + 2.292, + 2.903, + 3.686, + 4.645, + 5.865, + 7.391, + 8.0, + 8.0, + 8.0 ], "resubmissions": 1 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json index ad8f98a..a414d60 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json @@ -11,10 +11,10 @@ { "op": "fetch", "spec": { - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -53,21 +53,195 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } }, - "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a.", + "entity_groups": { + "destination": { + "label": "G77 countries", + "group_id": "groups/G77" + }, + "origin": { + "label": "DAC countries", + "group_id": "groups/OECD.DAC" + } + } } } ], @@ -80,10 +254,10 @@ "schema_version": 1, "input": { "kind": "spec_id", - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -122,17 +296,181 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } } @@ -147,15 +485,15 @@ "status": 202, "headers": { "content-type": "application/json", - "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry-after": "2", - "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" + "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "pending", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500 } } @@ -164,7 +502,7 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 404, @@ -192,7 +530,7 @@ "trace_id": "00000000000000000000000000000000", "long_builds": [ { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "poll_waits": [ 1.5 ], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited-not-retryable.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited-not-retryable.json index e1d7cee..ee97d16 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited-not-retryable.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited-not-retryable.json @@ -11,10 +11,10 @@ { "op": "fetch", "spec": { - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -53,21 +53,195 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } }, - "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a.", + "entity_groups": { + "destination": { + "label": "G77 countries", + "group_id": "groups/G77" + }, + "origin": { + "label": "DAC countries", + "group_id": "groups/OECD.DAC" + } + } } } ], @@ -80,10 +254,10 @@ "schema_version": 1, "input": { "kind": "spec_id", - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -122,17 +296,181 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } } @@ -147,15 +485,15 @@ "status": 202, "headers": { "content-type": "application/json", - "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry-after": "2", - "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" + "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "pending", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500 } } @@ -164,7 +502,7 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 429, @@ -189,7 +527,7 @@ "trace_id": "00000000000000000000000000000000", "long_builds": [ { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "poll_waits": [ 1.5 ], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited.json index 91b20d9..7929226 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited.json @@ -11,10 +11,10 @@ { "op": "fetch", "spec": { - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -53,21 +53,195 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } }, - "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a.", + "entity_groups": { + "destination": { + "label": "G77 countries", + "group_id": "groups/G77" + }, + "origin": { + "label": "DAC countries", + "group_id": "groups/OECD.DAC" + } + } } } ], @@ -80,10 +254,10 @@ "schema_version": 1, "input": { "kind": "spec_id", - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -122,17 +296,181 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } } @@ -147,15 +485,15 @@ "status": 202, "headers": { "content-type": "application/json", - "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry-after": "2", - "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" + "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "pending", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500 } } @@ -164,7 +502,7 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 429, @@ -176,24 +514,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "621bdcc038e34f44bec226434f3f7378" + "x-dfo-trace-id": "043386d87ba247048aa921704d3ff030" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -202,24 +540,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "1df7b03572044eedaa412f6d2ad6b91f" + "x-dfo-trace-id": "c7ef77e57a864be6a4617b1aeae7c11d" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -228,24 +566,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "b5b2e2d98a4047be98aea852117381c7" + "x-dfo-trace-id": "cea2df9c98f94601a5e9976e76842f12" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -254,24 +592,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "686111d592f3451e8c55691d91a66663" + "x-dfo-trace-id": "7a800f2714b94a8482dc5fb553c669f5" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 1517, + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 1804, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -280,24 +618,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2", - "x-dfo-trace-id": "9acc0caab7e143d38b3ecbfbcd225707" + "retry-after": "3", + "x-dfo-trace-id": "f911f5f7ca244733b2da3d5ce6913f6d" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 1900, + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 2292, "progress": { - "rows_written": 16734, - "estimate_rows": 108798 + "rows_written": 0, + "estimate_rows": 109318 } } } @@ -306,24 +644,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "3", - "x-dfo-trace-id": "22c08bbaa1384833bd92f8dd9cc6312d" + "x-dfo-trace-id": "07d32bbe980e419eb9f8461492ff4c62" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 2377, + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 2903, "progress": { - "rows_written": 64341, - "estimate_rows": 108798 + "rows_written": 0, + "estimate_rows": 109318 } } } @@ -332,24 +670,154 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "227de800033b4185ae9b958d3fa2cec7" + "retry-after": "4", + "x-dfo-trace-id": "dd33ade549434abf82b662ab5251b0c1" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 3686, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "5", + "x-dfo-trace-id": "51d3664ad3e84fed8da1d94ce250d5de" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 4645, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "6", + "x-dfo-trace-id": "6a3b79b90c29464ca15c35d8eafecb96" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 5865, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "8", + "x-dfo-trace-id": "d7de7e24059f4d75ae14bd1778b984de" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 7391, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "8", + "x-dfo-trace-id": "cd1a9f894cbe4b6a9c1a7ee78315aff0" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 8000, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "8", + "x-dfo-trace-id": "e1c46fecd652459380163afea4dc35b7" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 2973, + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 8000, "progress": { - "rows_written": 106324, - "estimate_rows": 108798 + "rows_written": 105253, + "estimate_rows": 109318 } } } @@ -358,24 +826,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "retry-after": "4", - "x-dfo-trace-id": "3197d4d8b5094857afb9bbd14c49fcb0" + "retry-after": "8", + "x-dfo-trace-id": "3b9df177b0a94b069b47c8b441c6f232" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 3719, + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 8000, "progress": { - "rows_written": 108798, - "estimate_rows": 108798 + "rows_written": 109318, + "estimate_rows": 109318 } } } @@ -384,24 +852,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "29f271852cc04f1a8b287274f53105b6" + "x-dfo-trace-id": "cd6f7d2857a44f9c947573b696793564" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "done" }, "manifest": { "schema_version": 1, "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "shape": { "kind": "statvar_schema", @@ -439,29 +907,193 @@ "property": "nettingBasis" } ], - "facets": { - "provenance": { - "ref": "provenance/OECDDAC2A", - "state": "value" - } + "entities": { + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ], + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] }, - "entities": {}, "identity_version": "spec1", "requested_window": { "kind": "range", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 } } }, - "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "prepared_at": "2026-10-21T13:06:08Z", + "content_version": "cv_3d58d26a874dc30b1bba7d5ad6dd90ee", + "prepared_at": "2026-10-23T18:38:28Z", "coverage": { - "rows": 108798, + "rows": 109318, "dimensions": [ { "label": "financingProvider", - "count": 172, + "count": 32, "axis": "origin", "noun": { "singular": "provider", @@ -470,7 +1102,7 @@ }, { "label": "financingRecipient", - "count": 238, + "count": 133, "axis": "destination", "noun": { "singular": "recipient", @@ -479,14 +1111,14 @@ }, { "label": "years", - "count": 7 + "count": 62 } ], "window": { "kind": "range", "origin": "query", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 } }, "citation": { @@ -576,11 +1208,11 @@ { "ref": "provenance/OECDDAC2A", "axis": "provenance", - "basis": "bound", - "default_policy": null, - "selection_reason": null, + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", "dispatch_facet_id": "1962969911839422253", - "default_policy_version": null + "default_policy_version": "1" }, { "ref": null, @@ -605,13 +1237,13 @@ "kind": "range", "origin": "query", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 }, - "graph_revision": null, + "graph_revision": "dfo-dev-dc-datacommons-service-00264-2s9", "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-23T18:14:12Z", + "content_hash": "29eb81d7b6c88641b1d4e8eb5e850ca36de66b99d6e9e09680aac020507a6392", "graph_endpoint": "graph_release" }, "source_revisions": [ @@ -620,8 +1252,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_cc753cefa9199881", + "materialiser_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", @@ -629,15 +1261,15 @@ "financingProvider", "financingRecipient" ], - "observation_count": 108798 + "observation_count": 109318 } ], "family_member_count": 1, "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "materialise", - "confirmed_at": "2026-10-21T13:06:09.616741+00:00" + "confirmed_at": "2026-10-23T18:38:31.738121+00:00" }, "warnings": [], "diagnostics": [ @@ -649,33 +1281,34 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad", + "artifact_digest": "sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 913395, + "bytes": 473679, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:06:09.573990+00:00", + "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", - "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { - "artifact_digest": "sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93", + "artifact_digest": "sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39", "rendering": { "statistics": "series" }, - "bytes": 967921, + "bytes": 144274, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:06:09.573990+00:00", + "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", - "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" + "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39" } ], - "series_count": 21017, + "series_count": 3656, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -687,19 +1320,19 @@ "name": "financingProvider", "kind": "role", "droppable": false, - "distinct": 172 + "distinct": 32 }, { "name": "financingRecipient", "kind": "role", "droppable": false, - "distinct": 238 + "distinct": 133 }, { "name": "time_period", "kind": "grain", "droppable": false, - "distinct": 7 + "distinct": 62 }, { "name": "value", @@ -752,109 +1385,25 @@ "column": "financingProvider", "field": "iso3", "token": "financingProvider_iso3", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 172, - "covered": 50 + "entities": 32, + "covered": 32 }, - "missing": [ - { - "ref": "AdaptationFund", - "label": "Adaptation Fund" - }, - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentBankGroup", - "label": "African Development Bank Group" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AndrewCarnegieFoundation", - "label": "Andrew Carnegie Foundation" - }, - { - "ref": "ArabFundForEconomicAndSocialDevelopment", - "label": "Arab Fund for Economic and Social Development" - }, - { - "ref": "Arcadia", - "label": "Arcadia" - }, - { - "ref": "ArcusFoundation", - "label": "Arcus Foundation" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianInfrastructureInvestmentBank", - "label": "Asian Infrastructure Investment Bank" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingProvider", "field": "iso2", "token": "financingProvider_iso2", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 172, - "covered": 50 + "entities": 32, + "covered": 32 }, - "missing": [ - { - "ref": "AdaptationFund", - "label": "Adaptation Fund" - }, - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentBankGroup", - "label": "African Development Bank Group" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AndrewCarnegieFoundation", - "label": "Andrew Carnegie Foundation" - }, - { - "ref": "ArabFundForEconomicAndSocialDevelopment", - "label": "Arab Fund for Economic and Social Development" - }, - { - "ref": "Arcadia", - "label": "Arcadia" - }, - { - "ref": "ArcusFoundation", - "label": "Arcus Foundation" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianInfrastructureInvestmentBank", - "label": "Asian Infrastructure Investment Bank" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingProvider", @@ -862,8 +1411,8 @@ "token": "financingProvider_label", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -874,8 +1423,8 @@ "token": "financingProvider_type", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -886,8 +1435,32 @@ "token": "financingProvider_party_kind", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -896,55 +1469,13 @@ "column": "financingRecipient", "field": "iso3", "token": "financingRecipient_iso3", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 238, - "covered": 143 + "entities": 133, + "covered": 133 }, - "missing": [ - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianDevelopmentBankSpecialFunds", - "label": "Asian Development Bank Special Funds" - }, - { - "ref": "CaribbeanDevelopmentBank", - "label": "Caribbean Development Bank" - }, - { - "ref": "CentralAmericanBankForEconomicIntegration", - "label": "Central American Bank for Economic Integration" - }, - { - "ref": "DACACPCountries", - "label": "ACP countries (DAC)" - }, - { - "ref": "DACAfrica", - "label": "Africa (DAC)" - }, - { - "ref": "DACAfricaUnallocated", - "label": "Africa, unallocated by country (DAC)" - }, - { - "ref": "DACAllMultilateralRecipients", - "label": "all multilateral recipients (DAC)" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingRecipient", @@ -953,52 +1484,16 @@ "state": "partial", "reason": "enrichment_unavailable", "coverage": { - "entities": 238, - "covered": 141 + "entities": 133, + "covered": 132 }, "missing": [ { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianDevelopmentBankSpecialFunds", - "label": "Asian Development Bank Special Funds" - }, - { - "ref": "CaribbeanDevelopmentBank", - "label": "Caribbean Development Bank" - }, - { - "ref": "CentralAmericanBankForEconomicIntegration", - "label": "Central American Bank for Economic Integration" - }, - { - "ref": "DACACPCountries", - "label": "ACP countries (DAC)" - }, - { - "ref": "DACAfrica", - "label": "Africa (DAC)" - }, - { - "ref": "DACAfricaUnallocated", - "label": "Africa, unallocated by country (DAC)" - }, - { - "ref": "DACAllMultilateralRecipients", - "label": "all multilateral recipients (DAC)" + "ref": "country/SSD", + "label": "South Sudan" } ], - "truncated": true + "truncated": false }, { "column": "financingRecipient", @@ -1006,8 +1501,8 @@ "token": "financingRecipient_label", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1018,8 +1513,8 @@ "token": "financingRecipient_type", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1030,8 +1525,32 @@ "token": "financingRecipient_party_kind", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1039,9 +1558,9 @@ ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [ @@ -1053,7 +1572,7 @@ "varying": [ { "column": "time_period", - "distinct": 7 + "distinct": 62 } ] }, @@ -1065,7 +1584,7 @@ "varying": [ { "column": "financingRecipient", - "distinct": 238 + "distinct": 133 } ] }, @@ -1077,7 +1596,7 @@ "varying": [ { "column": "time_period", - "distinct": 7 + "distinct": 62 } ] }, @@ -1089,7 +1608,7 @@ "varying": [ { "column": "financingProvider", - "distinct": 172 + "distinct": 32 } ] }, @@ -1101,7 +1620,7 @@ "varying": [ { "column": "financingRecipient", - "distinct": 238 + "distinct": 133 } ] }, @@ -1113,7 +1632,7 @@ "varying": [ { "column": "financingProvider", - "distinct": 172 + "distinct": 32 } ] } @@ -1136,10 +1655,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:06:09.573841Z" + "held_until": "2026-11-22T18:38:31.579178Z" } } } @@ -1148,26 +1667,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + "origin_path": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted", - "x-dfo-trace-id": "155fa981459c464482aea52657f99e8b" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted", + "x-dfo-trace-id": "b0cef6f918794d048a8a5056022de7cc" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "228feaabf1f3473cad055088084dc378" + "content-type": "application/vnd.apache.parquet" }, "body_file": "mint-async-build.parquet" } @@ -1176,15 +1695,15 @@ "expect": [ { "dataset": { - "rows": 108798, + "rows": 109318, "columns": [ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "dac2aAidType", "dac2aAidType_label", "time_period", @@ -1203,26 +1722,31 @@ "members": [ { "parts": [], - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", - "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "content_version": "cv_3d58d26a874dc30b1bba7d5ad6dd90ee", + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a." } ], "missing": [], "long_builds": [ { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "poll_waits": [ 1.5, 3.0, 1.5, 1.5, 1.5, - 1.517, - 1.9, - 2.377, - 2.973, - 3.719 + 1.804, + 2.292, + 2.903, + 3.686, + 4.645, + 5.865, + 7.391, + 8.0, + 8.0, + 8.0 ], "resubmissions": 0 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-backoff.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-backoff.json index 3ff38ef..7c36fd8 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-backoff.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-backoff.json @@ -11,10 +11,10 @@ { "op": "fetch", "spec": { - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -53,21 +53,195 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } }, - "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a.", + "entity_groups": { + "destination": { + "label": "G77 countries", + "group_id": "groups/G77" + }, + "origin": { + "label": "DAC countries", + "group_id": "groups/OECD.DAC" + } + } } } ], @@ -80,10 +254,10 @@ "schema_version": 1, "input": { "kind": "spec_id", - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -122,17 +296,181 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } } @@ -147,14 +485,14 @@ "status": 202, "headers": { "content-type": "application/json", - "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" + "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "pending", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" } } } @@ -162,22 +500,22 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "621bdcc038e34f44bec226434f3f7378" + "x-dfo-trace-id": "043386d87ba247048aa921704d3ff030" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -186,7 +524,7 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 503, @@ -208,22 +546,22 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "1df7b03572044eedaa412f6d2ad6b91f" + "x-dfo-trace-id": "c7ef77e57a864be6a4617b1aeae7c11d" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -232,22 +570,22 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "b5b2e2d98a4047be98aea852117381c7" + "x-dfo-trace-id": "cea2df9c98f94601a5e9976e76842f12" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -256,22 +594,22 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "686111d592f3451e8c55691d91a66663" + "x-dfo-trace-id": "7a800f2714b94a8482dc5fb553c669f5" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -280,22 +618,22 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "9acc0caab7e143d38b3ecbfbcd225707" + "x-dfo-trace-id": "f911f5f7ca244733b2da3d5ce6913f6d" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "progress": { - "rows_written": 16734, - "estimate_rows": 108798 + "rows_written": 0, + "estimate_rows": 109318 } } } @@ -304,22 +642,22 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "22c08bbaa1384833bd92f8dd9cc6312d" + "x-dfo-trace-id": "07d32bbe980e419eb9f8461492ff4c62" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "progress": { - "rows_written": 64341, - "estimate_rows": 108798 + "rows_written": 0, + "estimate_rows": 109318 } } } @@ -328,22 +666,142 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "227de800033b4185ae9b958d3fa2cec7" + "x-dfo-trace-id": "dd33ade549434abf82b662ab5251b0c1" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "51d3664ad3e84fed8da1d94ce250d5de" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "6a3b79b90c29464ca15c35d8eafecb96" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "d7de7e24059f4d75ae14bd1778b984de" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "cd1a9f894cbe4b6a9c1a7ee78315aff0" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "e1c46fecd652459380163afea4dc35b7" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "progress": { - "rows_written": 106324, - "estimate_rows": 108798 + "rows_written": 105253, + "estimate_rows": 109318 } } } @@ -352,22 +810,22 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "3197d4d8b5094857afb9bbd14c49fcb0" + "x-dfo-trace-id": "3b9df177b0a94b069b47c8b441c6f232" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "progress": { - "rows_written": 108798, - "estimate_rows": 108798 + "rows_written": 109318, + "estimate_rows": 109318 } } } @@ -376,24 +834,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "29f271852cc04f1a8b287274f53105b6" + "x-dfo-trace-id": "cd6f7d2857a44f9c947573b696793564" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "done" }, "manifest": { "schema_version": 1, "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "shape": { "kind": "statvar_schema", @@ -431,29 +889,193 @@ "property": "nettingBasis" } ], - "facets": { - "provenance": { - "ref": "provenance/OECDDAC2A", - "state": "value" - } + "entities": { + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ], + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] }, - "entities": {}, "identity_version": "spec1", "requested_window": { "kind": "range", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 } } }, - "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "prepared_at": "2026-10-21T13:06:08Z", + "content_version": "cv_3d58d26a874dc30b1bba7d5ad6dd90ee", + "prepared_at": "2026-10-23T18:38:28Z", "coverage": { - "rows": 108798, + "rows": 109318, "dimensions": [ { "label": "financingProvider", - "count": 172, + "count": 32, "axis": "origin", "noun": { "singular": "provider", @@ -462,7 +1084,7 @@ }, { "label": "financingRecipient", - "count": 238, + "count": 133, "axis": "destination", "noun": { "singular": "recipient", @@ -471,14 +1093,14 @@ }, { "label": "years", - "count": 7 + "count": 62 } ], "window": { "kind": "range", "origin": "query", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 } }, "citation": { @@ -568,11 +1190,11 @@ { "ref": "provenance/OECDDAC2A", "axis": "provenance", - "basis": "bound", - "default_policy": null, - "selection_reason": null, + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", "dispatch_facet_id": "1962969911839422253", - "default_policy_version": null + "default_policy_version": "1" }, { "ref": null, @@ -597,13 +1219,13 @@ "kind": "range", "origin": "query", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 }, - "graph_revision": null, + "graph_revision": "dfo-dev-dc-datacommons-service-00264-2s9", "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-23T18:14:12Z", + "content_hash": "29eb81d7b6c88641b1d4e8eb5e850ca36de66b99d6e9e09680aac020507a6392", "graph_endpoint": "graph_release" }, "source_revisions": [ @@ -612,8 +1234,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_cc753cefa9199881", + "materialiser_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", @@ -621,15 +1243,15 @@ "financingProvider", "financingRecipient" ], - "observation_count": 108798 + "observation_count": 109318 } ], "family_member_count": 1, "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "materialise", - "confirmed_at": "2026-10-21T13:06:09.616741+00:00" + "confirmed_at": "2026-10-23T18:38:31.738121+00:00" }, "warnings": [], "diagnostics": [ @@ -641,33 +1263,34 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad", + "artifact_digest": "sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 913395, + "bytes": 473679, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:06:09.573990+00:00", + "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", - "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { - "artifact_digest": "sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93", + "artifact_digest": "sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39", "rendering": { "statistics": "series" }, - "bytes": 967921, + "bytes": 144274, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:06:09.573990+00:00", + "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", - "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" + "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39" } ], - "series_count": 21017, + "series_count": 3656, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -679,19 +1302,19 @@ "name": "financingProvider", "kind": "role", "droppable": false, - "distinct": 172 + "distinct": 32 }, { "name": "financingRecipient", "kind": "role", "droppable": false, - "distinct": 238 + "distinct": 133 }, { "name": "time_period", "kind": "grain", "droppable": false, - "distinct": 7 + "distinct": 62 }, { "name": "value", @@ -744,109 +1367,25 @@ "column": "financingProvider", "field": "iso3", "token": "financingProvider_iso3", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 172, - "covered": 50 + "entities": 32, + "covered": 32 }, - "missing": [ - { - "ref": "AdaptationFund", - "label": "Adaptation Fund" - }, - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentBankGroup", - "label": "African Development Bank Group" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AndrewCarnegieFoundation", - "label": "Andrew Carnegie Foundation" - }, - { - "ref": "ArabFundForEconomicAndSocialDevelopment", - "label": "Arab Fund for Economic and Social Development" - }, - { - "ref": "Arcadia", - "label": "Arcadia" - }, - { - "ref": "ArcusFoundation", - "label": "Arcus Foundation" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianInfrastructureInvestmentBank", - "label": "Asian Infrastructure Investment Bank" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingProvider", "field": "iso2", "token": "financingProvider_iso2", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 172, - "covered": 50 + "entities": 32, + "covered": 32 }, - "missing": [ - { - "ref": "AdaptationFund", - "label": "Adaptation Fund" - }, - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentBankGroup", - "label": "African Development Bank Group" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AndrewCarnegieFoundation", - "label": "Andrew Carnegie Foundation" - }, - { - "ref": "ArabFundForEconomicAndSocialDevelopment", - "label": "Arab Fund for Economic and Social Development" - }, - { - "ref": "Arcadia", - "label": "Arcadia" - }, - { - "ref": "ArcusFoundation", - "label": "Arcus Foundation" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianInfrastructureInvestmentBank", - "label": "Asian Infrastructure Investment Bank" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingProvider", @@ -854,8 +1393,8 @@ "token": "financingProvider_label", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -866,8 +1405,8 @@ "token": "financingProvider_type", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -878,8 +1417,32 @@ "token": "financingProvider_party_kind", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -888,55 +1451,13 @@ "column": "financingRecipient", "field": "iso3", "token": "financingRecipient_iso3", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 238, - "covered": 143 + "entities": 133, + "covered": 133 }, - "missing": [ - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianDevelopmentBankSpecialFunds", - "label": "Asian Development Bank Special Funds" - }, - { - "ref": "CaribbeanDevelopmentBank", - "label": "Caribbean Development Bank" - }, - { - "ref": "CentralAmericanBankForEconomicIntegration", - "label": "Central American Bank for Economic Integration" - }, - { - "ref": "DACACPCountries", - "label": "ACP countries (DAC)" - }, - { - "ref": "DACAfrica", - "label": "Africa (DAC)" - }, - { - "ref": "DACAfricaUnallocated", - "label": "Africa, unallocated by country (DAC)" - }, - { - "ref": "DACAllMultilateralRecipients", - "label": "all multilateral recipients (DAC)" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingRecipient", @@ -945,52 +1466,16 @@ "state": "partial", "reason": "enrichment_unavailable", "coverage": { - "entities": 238, - "covered": 141 + "entities": 133, + "covered": 132 }, "missing": [ { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianDevelopmentBankSpecialFunds", - "label": "Asian Development Bank Special Funds" - }, - { - "ref": "CaribbeanDevelopmentBank", - "label": "Caribbean Development Bank" - }, - { - "ref": "CentralAmericanBankForEconomicIntegration", - "label": "Central American Bank for Economic Integration" - }, - { - "ref": "DACACPCountries", - "label": "ACP countries (DAC)" - }, - { - "ref": "DACAfrica", - "label": "Africa (DAC)" - }, - { - "ref": "DACAfricaUnallocated", - "label": "Africa, unallocated by country (DAC)" - }, - { - "ref": "DACAllMultilateralRecipients", - "label": "all multilateral recipients (DAC)" + "ref": "country/SSD", + "label": "South Sudan" } ], - "truncated": true + "truncated": false }, { "column": "financingRecipient", @@ -998,8 +1483,8 @@ "token": "financingRecipient_label", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1010,8 +1495,8 @@ "token": "financingRecipient_type", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1022,8 +1507,32 @@ "token": "financingRecipient_party_kind", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1031,9 +1540,9 @@ ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [ @@ -1045,7 +1554,7 @@ "varying": [ { "column": "time_period", - "distinct": 7 + "distinct": 62 } ] }, @@ -1057,7 +1566,7 @@ "varying": [ { "column": "financingRecipient", - "distinct": 238 + "distinct": 133 } ] }, @@ -1069,7 +1578,7 @@ "varying": [ { "column": "time_period", - "distinct": 7 + "distinct": 62 } ] }, @@ -1081,7 +1590,7 @@ "varying": [ { "column": "financingProvider", - "distinct": 172 + "distinct": 32 } ] }, @@ -1093,7 +1602,7 @@ "varying": [ { "column": "financingRecipient", - "distinct": 238 + "distinct": 133 } ] }, @@ -1105,7 +1614,7 @@ "varying": [ { "column": "financingProvider", - "distinct": 172 + "distinct": 32 } ] } @@ -1128,10 +1637,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:06:09.573841Z" + "held_until": "2026-11-22T18:38:31.579178Z" } } } @@ -1140,26 +1649,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + "origin_path": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted", - "x-dfo-trace-id": "155fa981459c464482aea52657f99e8b" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted", + "x-dfo-trace-id": "b0cef6f918794d048a8a5056022de7cc" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "228feaabf1f3473cad055088084dc378" + "content-type": "application/vnd.apache.parquet" }, "body_file": "mint-async-build.parquet" } @@ -1168,15 +1677,15 @@ "expect": [ { "dataset": { - "rows": 108798, + "rows": 109318, "columns": [ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "dac2aAidType", "dac2aAidType_label", "time_period", @@ -1195,15 +1704,15 @@ "members": [ { "parts": [], - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", - "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "content_version": "cv_3d58d26a874dc30b1bba7d5ad6dd90ee", + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a." } ], "missing": [], "long_builds": [ { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "poll_waits": [ 1.0, 2.0, @@ -1214,6 +1723,11 @@ 8.0, 8.0, 8.0, + 8.0, + 8.0, + 8.0, + 8.0, + 8.0, 8.0 ], "resubmissions": 0 diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-retry-after.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-retry-after.json index 4fe3f7e..94cf7d7 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-retry-after.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-retry-after.json @@ -11,10 +11,10 @@ { "op": "fetch", "spec": { - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -53,21 +53,195 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } }, - "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a.", + "entity_groups": { + "destination": { + "label": "G77 countries", + "group_id": "groups/G77" + }, + "origin": { + "label": "DAC countries", + "group_id": "groups/OECD.DAC" + } + } } } ], @@ -80,10 +254,10 @@ "schema_version": 1, "input": { "kind": "spec_id", - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -122,17 +296,181 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } } @@ -147,15 +485,15 @@ "status": 202, "headers": { "content-type": "application/json", - "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry-after": "2", - "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" + "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "pending", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500 } } @@ -164,7 +502,7 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 503, @@ -187,24 +525,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "621bdcc038e34f44bec226434f3f7378" + "x-dfo-trace-id": "043386d87ba247048aa921704d3ff030" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -213,24 +551,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "1df7b03572044eedaa412f6d2ad6b91f" + "x-dfo-trace-id": "c7ef77e57a864be6a4617b1aeae7c11d" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -239,24 +577,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "b5b2e2d98a4047be98aea852117381c7" + "x-dfo-trace-id": "cea2df9c98f94601a5e9976e76842f12" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -265,24 +603,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "686111d592f3451e8c55691d91a66663" + "x-dfo-trace-id": "7a800f2714b94a8482dc5fb553c669f5" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 1517, + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 1804, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -291,24 +629,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2", - "x-dfo-trace-id": "9acc0caab7e143d38b3ecbfbcd225707" + "retry-after": "3", + "x-dfo-trace-id": "f911f5f7ca244733b2da3d5ce6913f6d" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 1900, + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 2292, "progress": { - "rows_written": 16734, - "estimate_rows": 108798 + "rows_written": 0, + "estimate_rows": 109318 } } } @@ -317,24 +655,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "3", - "x-dfo-trace-id": "22c08bbaa1384833bd92f8dd9cc6312d" + "x-dfo-trace-id": "07d32bbe980e419eb9f8461492ff4c62" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 2377, + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 2903, "progress": { - "rows_written": 64341, - "estimate_rows": 108798 + "rows_written": 0, + "estimate_rows": 109318 } } } @@ -343,24 +681,154 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "227de800033b4185ae9b958d3fa2cec7" + "retry-after": "4", + "x-dfo-trace-id": "dd33ade549434abf82b662ab5251b0c1" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 3686, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "5", + "x-dfo-trace-id": "51d3664ad3e84fed8da1d94ce250d5de" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 4645, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "6", + "x-dfo-trace-id": "6a3b79b90c29464ca15c35d8eafecb96" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 5865, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "8", + "x-dfo-trace-id": "d7de7e24059f4d75ae14bd1778b984de" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 7391, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "8", + "x-dfo-trace-id": "cd1a9f894cbe4b6a9c1a7ee78315aff0" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 8000, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "8", + "x-dfo-trace-id": "e1c46fecd652459380163afea4dc35b7" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 2973, + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 8000, "progress": { - "rows_written": 106324, - "estimate_rows": 108798 + "rows_written": 105253, + "estimate_rows": 109318 } } } @@ -369,24 +837,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "retry-after": "4", - "x-dfo-trace-id": "3197d4d8b5094857afb9bbd14c49fcb0" + "retry-after": "8", + "x-dfo-trace-id": "3b9df177b0a94b069b47c8b441c6f232" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 3719, + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 8000, "progress": { - "rows_written": 108798, - "estimate_rows": 108798 + "rows_written": 109318, + "estimate_rows": 109318 } } } @@ -395,24 +863,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "29f271852cc04f1a8b287274f53105b6" + "x-dfo-trace-id": "cd6f7d2857a44f9c947573b696793564" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "done" }, "manifest": { "schema_version": 1, "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "shape": { "kind": "statvar_schema", @@ -450,29 +918,193 @@ "property": "nettingBasis" } ], - "facets": { - "provenance": { - "ref": "provenance/OECDDAC2A", - "state": "value" - } + "entities": { + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ], + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] }, - "entities": {}, "identity_version": "spec1", "requested_window": { "kind": "range", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 } } }, - "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "prepared_at": "2026-10-21T13:06:08Z", + "content_version": "cv_3d58d26a874dc30b1bba7d5ad6dd90ee", + "prepared_at": "2026-10-23T18:38:28Z", "coverage": { - "rows": 108798, + "rows": 109318, "dimensions": [ { "label": "financingProvider", - "count": 172, + "count": 32, "axis": "origin", "noun": { "singular": "provider", @@ -481,7 +1113,7 @@ }, { "label": "financingRecipient", - "count": 238, + "count": 133, "axis": "destination", "noun": { "singular": "recipient", @@ -490,14 +1122,14 @@ }, { "label": "years", - "count": 7 + "count": 62 } ], "window": { "kind": "range", "origin": "query", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 } }, "citation": { @@ -587,11 +1219,11 @@ { "ref": "provenance/OECDDAC2A", "axis": "provenance", - "basis": "bound", - "default_policy": null, - "selection_reason": null, + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", "dispatch_facet_id": "1962969911839422253", - "default_policy_version": null + "default_policy_version": "1" }, { "ref": null, @@ -616,13 +1248,13 @@ "kind": "range", "origin": "query", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 }, - "graph_revision": null, + "graph_revision": "dfo-dev-dc-datacommons-service-00264-2s9", "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-23T18:14:12Z", + "content_hash": "29eb81d7b6c88641b1d4e8eb5e850ca36de66b99d6e9e09680aac020507a6392", "graph_endpoint": "graph_release" }, "source_revisions": [ @@ -631,8 +1263,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_cc753cefa9199881", + "materialiser_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", @@ -640,15 +1272,15 @@ "financingProvider", "financingRecipient" ], - "observation_count": 108798 + "observation_count": 109318 } ], "family_member_count": 1, "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "materialise", - "confirmed_at": "2026-10-21T13:06:09.616741+00:00" + "confirmed_at": "2026-10-23T18:38:31.738121+00:00" }, "warnings": [], "diagnostics": [ @@ -660,33 +1292,34 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad", + "artifact_digest": "sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 913395, + "bytes": 473679, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:06:09.573990+00:00", + "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", - "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { - "artifact_digest": "sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93", + "artifact_digest": "sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39", "rendering": { "statistics": "series" }, - "bytes": 967921, + "bytes": 144274, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:06:09.573990+00:00", + "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", - "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" + "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39" } ], - "series_count": 21017, + "series_count": 3656, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -698,19 +1331,19 @@ "name": "financingProvider", "kind": "role", "droppable": false, - "distinct": 172 + "distinct": 32 }, { "name": "financingRecipient", "kind": "role", "droppable": false, - "distinct": 238 + "distinct": 133 }, { "name": "time_period", "kind": "grain", "droppable": false, - "distinct": 7 + "distinct": 62 }, { "name": "value", @@ -763,109 +1396,25 @@ "column": "financingProvider", "field": "iso3", "token": "financingProvider_iso3", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 172, - "covered": 50 + "entities": 32, + "covered": 32 }, - "missing": [ - { - "ref": "AdaptationFund", - "label": "Adaptation Fund" - }, - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentBankGroup", - "label": "African Development Bank Group" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AndrewCarnegieFoundation", - "label": "Andrew Carnegie Foundation" - }, - { - "ref": "ArabFundForEconomicAndSocialDevelopment", - "label": "Arab Fund for Economic and Social Development" - }, - { - "ref": "Arcadia", - "label": "Arcadia" - }, - { - "ref": "ArcusFoundation", - "label": "Arcus Foundation" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianInfrastructureInvestmentBank", - "label": "Asian Infrastructure Investment Bank" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingProvider", "field": "iso2", "token": "financingProvider_iso2", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 172, - "covered": 50 + "entities": 32, + "covered": 32 }, - "missing": [ - { - "ref": "AdaptationFund", - "label": "Adaptation Fund" - }, - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentBankGroup", - "label": "African Development Bank Group" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AndrewCarnegieFoundation", - "label": "Andrew Carnegie Foundation" - }, - { - "ref": "ArabFundForEconomicAndSocialDevelopment", - "label": "Arab Fund for Economic and Social Development" - }, - { - "ref": "Arcadia", - "label": "Arcadia" - }, - { - "ref": "ArcusFoundation", - "label": "Arcus Foundation" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianInfrastructureInvestmentBank", - "label": "Asian Infrastructure Investment Bank" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingProvider", @@ -873,8 +1422,8 @@ "token": "financingProvider_label", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -885,8 +1434,8 @@ "token": "financingProvider_type", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -897,8 +1446,32 @@ "token": "financingProvider_party_kind", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -907,55 +1480,13 @@ "column": "financingRecipient", "field": "iso3", "token": "financingRecipient_iso3", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 238, - "covered": 143 + "entities": 133, + "covered": 133 }, - "missing": [ - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianDevelopmentBankSpecialFunds", - "label": "Asian Development Bank Special Funds" - }, - { - "ref": "CaribbeanDevelopmentBank", - "label": "Caribbean Development Bank" - }, - { - "ref": "CentralAmericanBankForEconomicIntegration", - "label": "Central American Bank for Economic Integration" - }, - { - "ref": "DACACPCountries", - "label": "ACP countries (DAC)" - }, - { - "ref": "DACAfrica", - "label": "Africa (DAC)" - }, - { - "ref": "DACAfricaUnallocated", - "label": "Africa, unallocated by country (DAC)" - }, - { - "ref": "DACAllMultilateralRecipients", - "label": "all multilateral recipients (DAC)" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingRecipient", @@ -964,52 +1495,16 @@ "state": "partial", "reason": "enrichment_unavailable", "coverage": { - "entities": 238, - "covered": 141 + "entities": 133, + "covered": 132 }, "missing": [ { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianDevelopmentBankSpecialFunds", - "label": "Asian Development Bank Special Funds" - }, - { - "ref": "CaribbeanDevelopmentBank", - "label": "Caribbean Development Bank" - }, - { - "ref": "CentralAmericanBankForEconomicIntegration", - "label": "Central American Bank for Economic Integration" - }, - { - "ref": "DACACPCountries", - "label": "ACP countries (DAC)" - }, - { - "ref": "DACAfrica", - "label": "Africa (DAC)" - }, - { - "ref": "DACAfricaUnallocated", - "label": "Africa, unallocated by country (DAC)" - }, - { - "ref": "DACAllMultilateralRecipients", - "label": "all multilateral recipients (DAC)" + "ref": "country/SSD", + "label": "South Sudan" } ], - "truncated": true + "truncated": false }, { "column": "financingRecipient", @@ -1017,8 +1512,8 @@ "token": "financingRecipient_label", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1029,8 +1524,8 @@ "token": "financingRecipient_type", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1041,8 +1536,32 @@ "token": "financingRecipient_party_kind", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1050,9 +1569,9 @@ ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [ @@ -1064,7 +1583,7 @@ "varying": [ { "column": "time_period", - "distinct": 7 + "distinct": 62 } ] }, @@ -1076,7 +1595,7 @@ "varying": [ { "column": "financingRecipient", - "distinct": 238 + "distinct": 133 } ] }, @@ -1088,7 +1607,7 @@ "varying": [ { "column": "time_period", - "distinct": 7 + "distinct": 62 } ] }, @@ -1100,7 +1619,7 @@ "varying": [ { "column": "financingProvider", - "distinct": 172 + "distinct": 32 } ] }, @@ -1112,7 +1631,7 @@ "varying": [ { "column": "financingRecipient", - "distinct": 238 + "distinct": 133 } ] }, @@ -1124,7 +1643,7 @@ "varying": [ { "column": "financingProvider", - "distinct": 172 + "distinct": 32 } ] } @@ -1147,10 +1666,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:06:09.573841Z" + "held_until": "2026-11-22T18:38:31.579178Z" } } } @@ -1159,26 +1678,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + "origin_path": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted", - "x-dfo-trace-id": "155fa981459c464482aea52657f99e8b" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted", + "x-dfo-trace-id": "b0cef6f918794d048a8a5056022de7cc" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "228feaabf1f3473cad055088084dc378" + "content-type": "application/vnd.apache.parquet" }, "body_file": "mint-async-build.parquet" } @@ -1187,15 +1706,15 @@ "expect": [ { "dataset": { - "rows": 108798, + "rows": 109318, "columns": [ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "dac2aAidType", "dac2aAidType_label", "time_period", @@ -1214,26 +1733,31 @@ "members": [ { "parts": [], - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", - "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "content_version": "cv_3d58d26a874dc30b1bba7d5ad6dd90ee", + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a." } ], "missing": [], "long_builds": [ { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "poll_waits": [ 1.5, 5.0, 1.5, 1.5, 1.5, - 1.517, - 1.9, - 2.377, - 2.973, - 3.719 + 1.804, + 2.292, + 2.903, + 3.686, + 4.645, + 5.865, + 7.391, + 8.0, + 8.0, + 8.0 ], "resubmissions": 0 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused.json index 4530dea..8110b3d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused.json @@ -11,10 +11,10 @@ { "op": "fetch", "spec": { - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -53,21 +53,195 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } }, - "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a.", + "entity_groups": { + "destination": { + "label": "G77 countries", + "group_id": "groups/G77" + }, + "origin": { + "label": "DAC countries", + "group_id": "groups/OECD.DAC" + } + } } } ], @@ -80,10 +254,10 @@ "schema_version": 1, "input": { "kind": "spec_id", - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -122,17 +296,181 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } } @@ -147,15 +485,15 @@ "status": 202, "headers": { "content-type": "application/json", - "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry-after": "2", - "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" + "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "pending", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500 } } @@ -164,7 +502,7 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 503, @@ -186,24 +524,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "621bdcc038e34f44bec226434f3f7378" + "x-dfo-trace-id": "043386d87ba247048aa921704d3ff030" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -212,24 +550,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "1df7b03572044eedaa412f6d2ad6b91f" + "x-dfo-trace-id": "c7ef77e57a864be6a4617b1aeae7c11d" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -238,7 +576,7 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 503, @@ -260,7 +598,7 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 503, @@ -282,24 +620,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "b5b2e2d98a4047be98aea852117381c7" + "x-dfo-trace-id": "cea2df9c98f94601a5e9976e76842f12" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -308,24 +646,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "686111d592f3451e8c55691d91a66663" + "x-dfo-trace-id": "7a800f2714b94a8482dc5fb553c669f5" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 1517, + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 1804, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -334,24 +672,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2", - "x-dfo-trace-id": "9acc0caab7e143d38b3ecbfbcd225707" + "retry-after": "3", + "x-dfo-trace-id": "f911f5f7ca244733b2da3d5ce6913f6d" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 1900, + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 2292, "progress": { - "rows_written": 16734, - "estimate_rows": 108798 + "rows_written": 0, + "estimate_rows": 109318 } } } @@ -360,24 +698,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "3", - "x-dfo-trace-id": "22c08bbaa1384833bd92f8dd9cc6312d" + "x-dfo-trace-id": "07d32bbe980e419eb9f8461492ff4c62" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 2377, + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 2903, "progress": { - "rows_written": 64341, - "estimate_rows": 108798 + "rows_written": 0, + "estimate_rows": 109318 } } } @@ -386,24 +724,154 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "227de800033b4185ae9b958d3fa2cec7" + "retry-after": "4", + "x-dfo-trace-id": "dd33ade549434abf82b662ab5251b0c1" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 3686, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "5", + "x-dfo-trace-id": "51d3664ad3e84fed8da1d94ce250d5de" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 4645, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "6", + "x-dfo-trace-id": "6a3b79b90c29464ca15c35d8eafecb96" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 5865, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "8", + "x-dfo-trace-id": "d7de7e24059f4d75ae14bd1778b984de" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 7391, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "8", + "x-dfo-trace-id": "cd1a9f894cbe4b6a9c1a7ee78315aff0" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 8000, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "8", + "x-dfo-trace-id": "e1c46fecd652459380163afea4dc35b7" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 2973, + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 8000, "progress": { - "rows_written": 106324, - "estimate_rows": 108798 + "rows_written": 105253, + "estimate_rows": 109318 } } } @@ -412,24 +880,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "retry-after": "4", - "x-dfo-trace-id": "3197d4d8b5094857afb9bbd14c49fcb0" + "retry-after": "8", + "x-dfo-trace-id": "3b9df177b0a94b069b47c8b441c6f232" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 3719, + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 8000, "progress": { - "rows_written": 108798, - "estimate_rows": 108798 + "rows_written": 109318, + "estimate_rows": 109318 } } } @@ -438,24 +906,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "29f271852cc04f1a8b287274f53105b6" + "x-dfo-trace-id": "cd6f7d2857a44f9c947573b696793564" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "done" }, "manifest": { "schema_version": 1, "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "shape": { "kind": "statvar_schema", @@ -493,29 +961,193 @@ "property": "nettingBasis" } ], - "facets": { - "provenance": { - "ref": "provenance/OECDDAC2A", - "state": "value" - } + "entities": { + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ], + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] }, - "entities": {}, "identity_version": "spec1", "requested_window": { "kind": "range", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 } } }, - "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "prepared_at": "2026-10-21T13:06:08Z", + "content_version": "cv_3d58d26a874dc30b1bba7d5ad6dd90ee", + "prepared_at": "2026-10-23T18:38:28Z", "coverage": { - "rows": 108798, + "rows": 109318, "dimensions": [ { "label": "financingProvider", - "count": 172, + "count": 32, "axis": "origin", "noun": { "singular": "provider", @@ -524,7 +1156,7 @@ }, { "label": "financingRecipient", - "count": 238, + "count": 133, "axis": "destination", "noun": { "singular": "recipient", @@ -533,14 +1165,14 @@ }, { "label": "years", - "count": 7 + "count": 62 } ], "window": { "kind": "range", "origin": "query", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 } }, "citation": { @@ -630,11 +1262,11 @@ { "ref": "provenance/OECDDAC2A", "axis": "provenance", - "basis": "bound", - "default_policy": null, - "selection_reason": null, + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", "dispatch_facet_id": "1962969911839422253", - "default_policy_version": null + "default_policy_version": "1" }, { "ref": null, @@ -659,13 +1291,13 @@ "kind": "range", "origin": "query", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 }, - "graph_revision": null, + "graph_revision": "dfo-dev-dc-datacommons-service-00264-2s9", "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-23T18:14:12Z", + "content_hash": "29eb81d7b6c88641b1d4e8eb5e850ca36de66b99d6e9e09680aac020507a6392", "graph_endpoint": "graph_release" }, "source_revisions": [ @@ -674,8 +1306,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_cc753cefa9199881", + "materialiser_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", @@ -683,15 +1315,15 @@ "financingProvider", "financingRecipient" ], - "observation_count": 108798 + "observation_count": 109318 } ], "family_member_count": 1, "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "materialise", - "confirmed_at": "2026-10-21T13:06:09.616741+00:00" + "confirmed_at": "2026-10-23T18:38:31.738121+00:00" }, "warnings": [], "diagnostics": [ @@ -703,33 +1335,34 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad", + "artifact_digest": "sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 913395, + "bytes": 473679, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:06:09.573990+00:00", + "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", - "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { - "artifact_digest": "sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93", + "artifact_digest": "sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39", "rendering": { "statistics": "series" }, - "bytes": 967921, + "bytes": 144274, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:06:09.573990+00:00", + "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", - "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" + "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39" } ], - "series_count": 21017, + "series_count": 3656, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -741,19 +1374,19 @@ "name": "financingProvider", "kind": "role", "droppable": false, - "distinct": 172 + "distinct": 32 }, { "name": "financingRecipient", "kind": "role", "droppable": false, - "distinct": 238 + "distinct": 133 }, { "name": "time_period", "kind": "grain", "droppable": false, - "distinct": 7 + "distinct": 62 }, { "name": "value", @@ -806,109 +1439,25 @@ "column": "financingProvider", "field": "iso3", "token": "financingProvider_iso3", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 172, - "covered": 50 + "entities": 32, + "covered": 32 }, - "missing": [ - { - "ref": "AdaptationFund", - "label": "Adaptation Fund" - }, - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentBankGroup", - "label": "African Development Bank Group" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AndrewCarnegieFoundation", - "label": "Andrew Carnegie Foundation" - }, - { - "ref": "ArabFundForEconomicAndSocialDevelopment", - "label": "Arab Fund for Economic and Social Development" - }, - { - "ref": "Arcadia", - "label": "Arcadia" - }, - { - "ref": "ArcusFoundation", - "label": "Arcus Foundation" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianInfrastructureInvestmentBank", - "label": "Asian Infrastructure Investment Bank" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingProvider", "field": "iso2", "token": "financingProvider_iso2", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 172, - "covered": 50 + "entities": 32, + "covered": 32 }, - "missing": [ - { - "ref": "AdaptationFund", - "label": "Adaptation Fund" - }, - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentBankGroup", - "label": "African Development Bank Group" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AndrewCarnegieFoundation", - "label": "Andrew Carnegie Foundation" - }, - { - "ref": "ArabFundForEconomicAndSocialDevelopment", - "label": "Arab Fund for Economic and Social Development" - }, - { - "ref": "Arcadia", - "label": "Arcadia" - }, - { - "ref": "ArcusFoundation", - "label": "Arcus Foundation" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianInfrastructureInvestmentBank", - "label": "Asian Infrastructure Investment Bank" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingProvider", @@ -916,8 +1465,8 @@ "token": "financingProvider_label", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -928,8 +1477,8 @@ "token": "financingProvider_type", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -940,8 +1489,32 @@ "token": "financingProvider_party_kind", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -950,55 +1523,13 @@ "column": "financingRecipient", "field": "iso3", "token": "financingRecipient_iso3", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 238, - "covered": 143 + "entities": 133, + "covered": 133 }, - "missing": [ - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianDevelopmentBankSpecialFunds", - "label": "Asian Development Bank Special Funds" - }, - { - "ref": "CaribbeanDevelopmentBank", - "label": "Caribbean Development Bank" - }, - { - "ref": "CentralAmericanBankForEconomicIntegration", - "label": "Central American Bank for Economic Integration" - }, - { - "ref": "DACACPCountries", - "label": "ACP countries (DAC)" - }, - { - "ref": "DACAfrica", - "label": "Africa (DAC)" - }, - { - "ref": "DACAfricaUnallocated", - "label": "Africa, unallocated by country (DAC)" - }, - { - "ref": "DACAllMultilateralRecipients", - "label": "all multilateral recipients (DAC)" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingRecipient", @@ -1007,52 +1538,16 @@ "state": "partial", "reason": "enrichment_unavailable", "coverage": { - "entities": 238, - "covered": 141 + "entities": 133, + "covered": 132 }, "missing": [ { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianDevelopmentBankSpecialFunds", - "label": "Asian Development Bank Special Funds" - }, - { - "ref": "CaribbeanDevelopmentBank", - "label": "Caribbean Development Bank" - }, - { - "ref": "CentralAmericanBankForEconomicIntegration", - "label": "Central American Bank for Economic Integration" - }, - { - "ref": "DACACPCountries", - "label": "ACP countries (DAC)" - }, - { - "ref": "DACAfrica", - "label": "Africa (DAC)" - }, - { - "ref": "DACAfricaUnallocated", - "label": "Africa, unallocated by country (DAC)" - }, - { - "ref": "DACAllMultilateralRecipients", - "label": "all multilateral recipients (DAC)" + "ref": "country/SSD", + "label": "South Sudan" } ], - "truncated": true + "truncated": false }, { "column": "financingRecipient", @@ -1060,8 +1555,8 @@ "token": "financingRecipient_label", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1072,8 +1567,8 @@ "token": "financingRecipient_type", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1084,8 +1579,32 @@ "token": "financingRecipient_party_kind", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1093,9 +1612,9 @@ ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [ @@ -1107,7 +1626,7 @@ "varying": [ { "column": "time_period", - "distinct": 7 + "distinct": 62 } ] }, @@ -1119,7 +1638,7 @@ "varying": [ { "column": "financingRecipient", - "distinct": 238 + "distinct": 133 } ] }, @@ -1131,7 +1650,7 @@ "varying": [ { "column": "time_period", - "distinct": 7 + "distinct": 62 } ] }, @@ -1143,7 +1662,7 @@ "varying": [ { "column": "financingProvider", - "distinct": 172 + "distinct": 32 } ] }, @@ -1155,7 +1674,7 @@ "varying": [ { "column": "financingRecipient", - "distinct": 238 + "distinct": 133 } ] }, @@ -1167,7 +1686,7 @@ "varying": [ { "column": "financingProvider", - "distinct": 172 + "distinct": 32 } ] } @@ -1190,10 +1709,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:06:09.573841Z" + "held_until": "2026-11-22T18:38:31.579178Z" } } } @@ -1202,26 +1721,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + "origin_path": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted", - "x-dfo-trace-id": "155fa981459c464482aea52657f99e8b" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted", + "x-dfo-trace-id": "b0cef6f918794d048a8a5056022de7cc" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "228feaabf1f3473cad055088084dc378" + "content-type": "application/vnd.apache.parquet" }, "body_file": "mint-async-build.parquet" } @@ -1230,15 +1749,15 @@ "expect": [ { "dataset": { - "rows": 108798, + "rows": 109318, "columns": [ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "dac2aAidType", "dac2aAidType_label", "time_period", @@ -1257,15 +1776,15 @@ "members": [ { "parts": [], - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", - "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "content_version": "cv_3d58d26a874dc30b1bba7d5ad6dd90ee", + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a." } ], "missing": [], "long_builds": [ { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "poll_waits": [ 1.5, 1.5, @@ -1274,11 +1793,16 @@ 1.5, 1.5, 1.5, - 1.517, - 1.9, - 2.377, - 2.973, - 3.719 + 1.804, + 2.292, + 2.903, + 3.686, + 4.645, + 5.865, + 7.391, + 8.0, + 8.0, + 8.0 ], "resubmissions": 0 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-relative-location.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-relative-location.json index ca66cd6..c28f441 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-relative-location.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-relative-location.json @@ -175,7 +175,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" + "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" }, "json": { "schema_version": 1, @@ -249,7 +249,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T13:05:35Z", + "prepared_at": "2026-10-20T13:59:17Z", "coverage": { "rows": 4, "dimensions": [ @@ -395,7 +395,7 @@ "graph_revision": null, "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", + "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "graph_endpoint": "graph_release" }, @@ -405,8 +405,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -580,9 +580,9 @@ "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + "confirmed_at": "2026-10-23T18:37:10.942106+00:00" }, "warnings": [ { @@ -600,17 +600,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "artifact_digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9541, + "bytes": 9599, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", - "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -619,14 +620,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-20T13:59:18.050980+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -759,6 +760,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -818,13 +843,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [], @@ -846,10 +895,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:35.038284Z" + "held_until": "2026-11-19T13:59:18.051742Z" } } } @@ -857,13 +906,14 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170" }, "response": { "status": 302, "headers": { + "content-type": "text/html", "location": "bytes", - "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" + "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" } } }, @@ -875,8 +925,7 @@ "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" + "content-type": "application/vnd.apache.parquet" }, "body_file": "fetch-spec-known-sentence.parquet" } @@ -890,10 +939,10 @@ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "crsCooperationModality", "crsCooperationModality_label", "crsPurpose", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json index 010e041..c89f183 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json @@ -4,9 +4,9 @@ "description": "Fetching a spec with a facet the server does not know sends it in input.scope.facets; the build refuses 400 request_invalid, which raises InvalidRequestError.", "origin": { "kind": "recorded", - "base_url": "http://127.0.0.1:19493/api", - "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T13:05:50Z" + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "recorded_at": "2026-10-23T18:37:29Z" }, "call": [ { @@ -182,7 +182,7 @@ "status": 400, "headers": { "content-type": "application/problem+json", - "x-dfo-trace-id": "b847ea8e841a4560a8ffa3b7f337f361" + "x-dfo-trace-id": "060bc9edc00f4aeb8550070e8c9b2632" }, "json": { "type": "/codes/request_invalid", @@ -191,8 +191,8 @@ "detail": "Value error, unknown facet axis/axes: colour", "code": "request_invalid", "pointer": "/input/scope", - "trace_id": "b847ea8e841a4560a8ffa3b7f337f361", - "capability_version": "dset_88fecfec3c5b89d1", + "trace_id": "060bc9edc00f4aeb8550070e8c9b2632", + "capability_version": "dset_cc753cefa9199881", "retryable": false } } @@ -203,7 +203,7 @@ "error": { "class": "InvalidRequestError", "code": "request_invalid", - "trace_id": "b847ea8e841a4560a8ffa3b7f337f361" + "trace_id": "060bc9edc00f4aeb8550070e8c9b2632" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json index a604bd5..a4d3743 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json @@ -182,7 +182,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a72e52f677934a84bf84cdaee5c6c696" + "x-dfo-trace-id": "52642a89ff44404fb61540fe78b1ca94" }, "json": { "schema_version": 1, @@ -190,26 +190,12 @@ "schema_version": 1, "spec_id": "spec_cb5baa4161de718f18583060674dbca6", "identity": { - "entities": { - "destination": [ - "country/NGA" - ], - "origin": [ - "country/DEU" - ] - }, - "identity_version": "spec1", - "requested_window": { - "end_year": 2023, - "kind": "range", - "start_year": 2020 - }, "shape": { "kind": "statvar_schema", - "measured_property": "amount", - "measurement_qualifier": "Nominal", + "stat_type": "measuredValue", "population_type": "FinancialFlow", - "stat_type": "measuredValue" + "measured_property": "amount", + "measurement_qualifier": "Nominal" }, "slots": [ { @@ -252,11 +238,25 @@ }, "property": "nettingBasis" } - ] + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T13:05:35Z", + "prepared_at": "2026-10-20T13:59:17Z", "coverage": { "rows": 4, "dimensions": [ @@ -285,9 +285,9 @@ ], "window": { "kind": "range", - "start_year": 2020, + "origin": "query", "end_year": 2023, - "origin": "query" + "start_year": 2020 } }, "citation": { @@ -373,25 +373,47 @@ ] }, "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], "applied_window": { "kind": "range", - "start_year": 2020, + "origin": "query", "end_year": 2023, - "origin": "query" + "start_year": 2020 }, "graph_revision": null, + "normalisations": [], "code_index_stamp": { + "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", - "exported_at": "2026-10-20T19:50:14Z", "graph_endpoint": "graph_release" }, - "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", "revision": "2026-10-15" } ], + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -562,34 +584,12 @@ "observation_count": 0 } ], - "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "family_member_count": 21, - "facets": [ - { - "axis": "provenance", - "ref": "provenance/OECDCreditorReportingSystem", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868" - }, - { - "axis": "unit", - "ref": "CurrencyUSD", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868" - } - ], - "normalisations": [], + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "capability_version": "dset_88fecfec3c5b89d1", - "served_from": "materialise", - "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "served_from": "head", + "confirmed_at": "2026-10-23T18:37:10.942106+00:00" }, "warnings": [ { @@ -607,17 +607,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "artifact_digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9541, + "bytes": 9599, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", - "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -626,14 +627,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-20T13:59:18.050980+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -766,6 +767,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -825,13 +850,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [], @@ -853,10 +902,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:35.038284Z" + "held_until": "2026-11-19T13:59:18.051742Z" } } } @@ -874,26 +923,12 @@ "entry_kind": "identity", "variable_text": "dataset", "identity": { - "entities": { - "destination": [ - "country/NGA" - ], - "origin": [ - "country/DEU" - ] - }, - "identity_version": "spec1", - "requested_window": { - "end_year": 2023, - "kind": "range", - "start_year": 2020 - }, "shape": { "kind": "statvar_schema", - "measured_property": "amount", - "measurement_qualifier": "Nominal", + "stat_type": "measuredValue", "population_type": "FinancialFlow", - "stat_type": "measuredValue" + "measured_property": "amount", + "measurement_qualifier": "Nominal" }, "slots": [ { @@ -936,7 +971,21 @@ }, "property": "nettingBasis" } - ] + ], + "entities": { + "origin": [ + "country/DEU" + ], + "destination": [ + "country/NGA" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2023, + "start_year": 2020 + } } } ] @@ -947,7 +996,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e7b9afd7f94f41eb85716597d0432612" + "x-dfo-trace-id": "0d356c6a142c45b5a4e8ea173623cc40" }, "json": { "schema_version": 1, @@ -956,11 +1005,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "e7b9afd7f94f41eb85716597d0432612", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "0d356c6a142c45b5a4e8ea173623cc40", "warnings": [], "timing_ms": { - "total": 145, + "total": 341, "by_step": { "coverage": 0 } @@ -973,18 +1022,18 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 110, + "total": 269, "by_step": { - "validate": 3, - "walk": 81, - "reread_arcs": 2, + "validate": 4, + "walk": 217, + "reread_arcs": 1, "detect_edits": 0, "resolve_survivors": 0, - "shape": 3, + "shape": 4, "bind": 0, "where_places": 0, - "materialise": 5, - "answer": 15, + "materialise": 13, + "answer": 29, "options": 1 } }, @@ -1418,7 +1467,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "facets": { "provenance": { "basis": "fallback", @@ -1981,7 +2030,7 @@ "start_year": 2020, "end_year": 2023 }, - "capability_version": "cap_347a470e04c97eec" + "capability_version": "cap_94e25737d859392c" }, "confidence": "high", "available_at_place": true, @@ -4585,7 +4634,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "e7b9afd7f94f41eb85716597d0432612" + "trace_id": "0d356c6a142c45b5a4e8ea173623cc40" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-same-origin-artifact-url.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-same-origin-artifact-url.json index 9750a39..43923a4 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-same-origin-artifact-url.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-same-origin-artifact-url.json @@ -175,7 +175,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" + "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" }, "json": { "schema_version": 1, @@ -249,7 +249,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T13:05:35Z", + "prepared_at": "2026-10-20T13:59:17Z", "coverage": { "rows": 4, "dimensions": [ @@ -395,7 +395,7 @@ "graph_revision": null, "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", + "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "graph_endpoint": "graph_release" }, @@ -405,8 +405,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -580,9 +580,9 @@ "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + "confirmed_at": "2026-10-23T18:37:10.942106+00:00" }, "warnings": [ { @@ -600,17 +600,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "artifact_digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9541, + "bytes": 9599, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", - "url": "http://127.0.0.1:19493/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -619,14 +620,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-20T13:59:18.050980+00:00", "tier": "working", - "url": "http://127.0.0.1:19493/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" + "url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -759,6 +760,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -818,13 +843,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [], @@ -846,10 +895,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:35.038284Z" + "held_until": "2026-11-19T13:59:18.051742Z" } } } @@ -857,26 +906,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", - "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", + "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" + "content-type": "application/vnd.apache.parquet" }, "body_file": "fetch-spec-known-sentence.parquet" } @@ -890,10 +939,10 @@ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "crsCooperationModality", "crsCooperationModality_label", "crsPurpose", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-signed-fetch-partial.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-signed-fetch-partial.json index 0b27199..7ffadd3 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-signed-fetch-partial.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-signed-fetch-partial.json @@ -175,7 +175,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" + "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" }, "json": { "schema_version": 1, @@ -249,7 +249,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T13:05:35Z", + "prepared_at": "2026-10-20T13:59:17Z", "coverage": { "rows": 4, "dimensions": [ @@ -395,7 +395,7 @@ "graph_revision": null, "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", + "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "graph_endpoint": "graph_release" }, @@ -405,8 +405,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -580,9 +580,9 @@ "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + "confirmed_at": "2026-10-23T18:37:10.942106+00:00" }, "warnings": [ { @@ -600,17 +600,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "artifact_digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9541, + "bytes": 9599, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", - "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -619,14 +620,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-20T13:59:18.050980+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -759,6 +760,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -818,13 +843,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [], @@ -846,10 +895,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:35.038284Z" + "held_until": "2026-11-19T13:59:18.051742Z" } } } @@ -857,26 +906,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", - "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", + "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted" }, "response": { "status": 206, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" + "content-type": "application/vnd.apache.parquet" }, "body_file": "fetch-spec-known-sentence.parquet" } @@ -884,26 +933,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "origin_path": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted", - "x-dfo-trace-id": "0911c16fb4824a499926e24a34069b40" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", + "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "6a9d471b19b94292a956e2a09a1e1fa7" + "content-type": "application/vnd.apache.parquet" }, "body_file": "fetch-spec-known-sentence.parquet" } @@ -917,10 +966,10 @@ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "crsCooperationModality", "crsCooperationModality_label", "crsPurpose", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json index 7f0329e..cfc71b4 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json @@ -175,7 +175,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "72492035a830492dba11a29fa89ded8c" + "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" }, "json": { "schema_version": 1, @@ -249,7 +249,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T13:05:35Z", + "prepared_at": "2026-10-20T13:59:17Z", "coverage": { "rows": 4, "dimensions": [ @@ -395,7 +395,7 @@ "graph_revision": null, "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", + "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "graph_endpoint": "graph_release" }, @@ -405,8 +405,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -580,9 +580,9 @@ "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + "confirmed_at": "2026-10-23T18:37:10.942106+00:00" }, "warnings": [ { @@ -600,17 +600,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "artifact_digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9541, + "bytes": 9599, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", - "url": "https://storage.googleapis.com/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "url": "https://storage.googleapis.com/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -619,14 +620,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-20T13:59:18.050980+00:00", "tier": "working", "url": "https://storage.googleapis.com/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -759,6 +760,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -818,13 +843,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [], @@ -846,10 +895,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:35.038284Z" + "held_until": "2026-11-19T13:59:18.051742Z" } } } @@ -860,7 +909,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "72492035a830492dba11a29fa89ded8c" + "trace_id": "e1bfd7e1ab67428e9dc923e28d07d4f9" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json index d674e42..96dc34e 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json @@ -250,7 +250,7 @@ } }, "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", - "prepared_at": "2026-10-21T13:05:35Z", + "prepared_at": "2026-10-20T13:59:17Z", "coverage": { "rows": 4, "dimensions": [ @@ -396,7 +396,7 @@ "graph_revision": null, "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", + "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", "graph_endpoint": "graph_release" }, @@ -406,8 +406,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "8408f1f95c622223f8fa6e9ba55826ee8e22a852", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -581,9 +581,9 @@ "family_member_count": 21, "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-21T13:05:35.077517+00:00" + "confirmed_at": "2026-10-23T18:37:10.942106+00:00" }, "warnings": [ { @@ -601,17 +601,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70", + "artifact_digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9541, + "bytes": 9599, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", - "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:e9980972bce1cec82584a996b6e3f7f2e3b37ab1eb2e5226a40d37f7efe31c70" + "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -620,14 +621,14 @@ }, "bytes": 5741, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:35.038218+00:00", + "created_at": "2026-10-20T13:59:18.050980+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4" } ], "series_count": 1, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -760,6 +761,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -819,13 +844,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [], @@ -847,10 +896,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:05:35.038284Z" + "held_until": "2026-11-19T13:59:18.051742Z" } } } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-strict-info-notice.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-strict-info-notice.json index d552acf..34d3e52 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-strict-info-notice.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-strict-info-notice.json @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "d09ca5f0ae574410bf93b5d905ea8009" + "x-dfo-trace-id": "8ff5daac36fe403ab946f5b02785cb0d" }, "json": { "schema_version": 1, @@ -45,27 +45,28 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "d09ca5f0ae574410bf93b5d905ea8009", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "8ff5daac36fe403ab946f5b02785cb0d", "warnings": [], "timing_ms": { - "total": 5038, + "total": 4716, "by_step": { "coverage": 0, - "extract": 1141 + "extract": 1242, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 6116, - "output_tokens": 408, - "cached_tokens": 0 + "input_tokens": 6216, + "output_tokens": 423, + "cached_tokens": 841 }, "timed_out": false }, "kind": "resolution", "parts": [ { - "variable_text": "basic health care ODA disbursements", + "variable_text": "ODA disbursements for basic health care", "warnings": [ { "code": "retrieval_score_weak", @@ -74,24 +75,34 @@ } ], "timing_ms": { - "total": 3758, + "total": 3468, "by_step": { - "recall": 694, + "recall": 547, + "phase_resolve_places": 0, + "phase_check_entities": 0, "shape_arcs": 1, "shape_probe_coverage": 6, - "shape_probe": 489, - "shape_groups": 16, - "shape_labels": 0, - "shape_admission": 1, - "shape": 1365, - "bind": 1248, - "materialise": 11, - "answer": 423, - "options": 17 + "shape_probe": 136, + "shape_groups": 43, + "shape_labels": 1, + "shape_admission": 0, + "phase_derive_shapes": 0, + "shape": 1190, + "phase_prune_and_rank": 0, + "bind": 1278, + "phase_bind": 149, + "phase_settle": 50, + "phase_place_bindings": 19, + "phase_facet_requests": 0, + "materialise": 30, + "phase_materialise": 0, + "answer": 110, + "options": 38, + "phase_outcome": 57 } }, "restatement": { - "variable_text": "basic health care ODA disbursements", + "variable_text": "ODA disbursements for basic health care", "entities": [ { "text": "Germany", @@ -200,6 +211,14 @@ }, "measurement_denominator_unresolved": false, "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, { "axis": "how", "property": { @@ -240,14 +259,6 @@ }, "label": "netting basis" }, - { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, { "axis": "where", "label": "place" @@ -272,6 +283,20 @@ ] }, "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding": { + "kind": "unbound" + }, + "summable": true + }, { "key": { "axis": "how", @@ -370,20 +395,6 @@ }, "summable": false }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding": { - "kind": "unbound" - }, - "summable": true - }, { "key": { "axis": "where", @@ -520,7 +531,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "facets": { "provenance": { "basis": "fallback", @@ -545,102 +556,6 @@ } }, "slot_options": [ - { - "key": { - "axis": "how", - "property": { - "ref": "crsPurpose", - "label": "CRS purpose" - }, - "label": "sector" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSPurposeCode122", - "label": "basic health" - }, - "value_kind": "enum_value" - }, - "relation": "parent", - "parent": "CRSPurposeCode120", - "member_count": 4, - "served_rows": 88, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFinance", - "label": "CRS type of finance" - }, - "label": "instrument" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance100", - "label": "grant" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 0, - "served_rows": 30, - "served_rows_exact": true - }, - { - "value": { - "ref": { - "ref": "CRSTypeOfFinance110", - "label": "standard grant" - }, - "value_kind": "enum_value" - }, - "relation": "child", - "parent": "CRSTypeOfFinance100", - "member_count": 12672, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsTypeOfFlow", - "label": "CRS type of flow" - }, - "label": "flow" - }, - "options": [ - { - "value": { - "ref": { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" - }, - "value_kind": "enum_value" - }, - "relation": "root", - "member_count": 14098, - "served_rows": 30, - "served_rows_exact": true - } - ], - "truncated": false, - "source": "observed" - }, { "key": { "axis": "how", @@ -749,6 +664,102 @@ ], "truncated": false, "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsPurpose", + "label": "CRS purpose" + }, + "label": "sector" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSPurposeCode122", + "label": "basic health" + }, + "value_kind": "enum_value" + }, + "relation": "parent", + "parent": "CRSPurposeCode120", + "member_count": 4, + "served_rows": 88, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFinance", + "label": "CRS type of finance" + }, + "label": "instrument" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance100", + "label": "grant" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 0, + "served_rows": 30, + "served_rows_exact": true + }, + { + "value": { + "ref": { + "ref": "CRSTypeOfFinance110", + "label": "standard grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "CRSTypeOfFinance100", + "member_count": 12672, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "crsTypeOfFlow", + "label": "CRS type of flow" + }, + "label": "flow" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 14098, + "served_rows": 30, + "served_rows_exact": true + } + ], + "truncated": false, + "source": "observed" } ], "entity_options": [], @@ -1016,6 +1027,19 @@ } ], "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "crsCooperationModality", + "label": "CRS cooperation modality" + }, + "label": "modality" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "how", @@ -1101,19 +1125,6 @@ ], "provenance": "measure_elected" }, - { - "key": { - "axis": "how", - "property": { - "ref": "crsCooperationModality", - "label": "CRS cooperation modality" - }, - "label": "modality" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "where", @@ -1149,31 +1160,31 @@ ], "query_qualifiers": [ { - "text": "basic health care", + "text": "ODA", "named": [ { - "ref": "CRSPurposeCode12220", - "label": "basic health care" + "ref": "CRSTypeOfFlow10", + "label": "official development assistance" } ], - "slot": "crsPurpose", + "slot": "crsTypeOfFlow", "disposition": "bound", "selected": [] }, { - "text": "ODA", + "text": "basic health care", "named": [ { - "ref": "CRSTypeOfFlow10", - "label": "official development assistance" + "ref": "CRSPurposeCode12220", + "label": "basic health care" } ], - "slot": "crsTypeOfFlow", + "slot": "crsPurpose", "disposition": "bound", "selected": [] } ], - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3771,7 +3782,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "90ec74fce6534d0d8e4142b0e1355782" + "x-dfo-trace-id": "c1f0030e84b5418d89553827b503d006" }, "json": { "schema_version": 1, @@ -3843,7 +3854,7 @@ } }, "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", - "prepared_at": "2026-10-21T13:05:05Z", + "prepared_at": "2026-10-11T20:09:36Z", "coverage": { "rows": 30, "dimensions": [ @@ -3872,13 +3883,13 @@ ], "window": { "kind": "all", - "start_year": 1995, + "origin": "default", "end_year": 2024, - "origin": "default" + "start_year": 1995 } }, "citation": { - "text": "OECD Creditor Reporting System (CRS) (2026), via the Development Finance Observatory", + "text": "OECD Creditor Reporting System (CRS)", "sources": [ { "ref": "provenance/OECDCreditorReportingSystem", @@ -3899,9 +3910,9 @@ "publisher": "Organisation for Economic Co-operation and Development (OECD)", "description": "The Creditor Reporting System (CRS) is the OECD Development Assistance Committee's activity-level database of development finance. Each record is a project, programme or contribution reported by a bilateral provider, a multilateral organisation or a private foundation, with its recipient, sector and purpose, channel of delivery, aid type, and commitment and disbursement amounts. It covers ODA, other official flows, private sector instruments and private philanthropy, and is the source for any breakdown by sector, channel or project.", "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet", - "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-15)", + "attribution": "OECD (2026), Creditor Reporting System (CRS), OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_CRS/CRS.parquet (accessed on 2026-10-08)", "update_cadence": "Quarterly", - "last_update": "2026-10-15", + "last_update": "2026-10-08", "years_covered": "1973-2024", "granularity": "Annual, by provider and recipient", "currencies": [ @@ -3912,10 +3923,6 @@ "transformation": "Download the source data", "description": "The complete CRS file is downloaded from the OECD each time the pipeline runs, and replaces the previous copy, so the data reflects the OECD's latest release." }, - { - "transformation": "Exclude the partial preliminary year", - "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." - }, { "transformation": "Exclude donor core contributions to multilaterals", "description": "The OECD instructs that donor core contributions to multilateral organisations, reported as ordinary CRS rows flagged `bi_multi = 2`, are excluded to compute bilateral flows. These contributions are already reported in Members' Total Use of the Multilateral System, so keeping them would double count." @@ -3935,22 +3942,22 @@ ], "version_history": [ { - "date": "2026-10-15", - "title": "Partial preliminary year excluded", + "date": "2026-09-22", + "title": "Exclude donor core contributions", "changes": [ { "kind": "changed", - "note": "The partial preliminary year published ahead of the next full release is excluded." + "note": "Donor core contributions to multilateral organisations (`bi_multi = 2`) are excluded from bilateral flows, since they would otherwise double count." } ] }, { - "date": "2026-10-14", + "date": "2026-08-20", "title": "First release", "changes": [ { "kind": "added", - "note": "Commitments, gross and net disbursements, and grant equivalents by donor, recipient, flow type, finance type, modality and purpose, at current US dollar prices. Covers ODA, other official flows, private development finance and private sector instruments." + "note": "Dataset added to the graph." } ] } @@ -3960,25 +3967,47 @@ ] }, "trace": { + "facets": [ + { + "ref": "provenance/OECDCreditorReportingSystem", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "3734627990144800868", + "default_policy_version": "1" + } + ], "applied_window": { "kind": "all", - "start_year": 1995, + "origin": "default", "end_year": 2024, - "origin": "default" + "start_year": 1995 }, - "graph_revision": null, + "graph_revision": "dfo-dev-dc-datacommons-service-00228-ntw", + "normalisations": [], "code_index_stamp": { - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", - "exported_at": "2026-10-20T19:50:14Z", - "graph_endpoint": "graph_release" + "exported_at": "2026-10-10T10:52:17Z", + "content_hash": "6650f0e76fc1f91e6e056b29495dc17dc0182d091d67496926a1710ce1999c50", + "graph_endpoint": "https://dfo-dev-dc-datacommons-service-zms5lj4zhq-nn.a.run.app" }, - "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDCreditorReportingSystem", - "revision": "2026-10-15" + "revision": "2026-10-08" } ], + "capability_version": "dset_ac879dbf49857907", + "materialiser_build": "1f6ed6307bea979d38cc35c4e38e0da896c431ad", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_CRSTypeOfFlow10_CRSTypeOfFinance110_CRSCooperationModalityA02_CRSPurposeCode12220_Nominal", @@ -4149,36 +4178,20 @@ "observation_count": 0 } ], - "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "family_member_count": 21, - "facets": [ - { - "axis": "provenance", - "ref": "provenance/OECDCreditorReportingSystem", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868" - }, - { - "axis": "unit", - "ref": "CurrencyUSD", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "3734627990144800868" - } - ], - "normalisations": [], + "family_member_digest": "9fd3643bbde505d9542fd3d090ddd549349765d12b6bad95b17271cbf297ea8c", "frame_grammar_version": "1.1.0", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "capability_version": "dset_88fecfec3c5b89d1", - "served_from": "materialise", - "confirmed_at": "2026-10-21T13:05:06.336796+00:00" + "origin_catalogue_build_id": "20261011T194155Z-80081f08", + "served_from": "head", + "confirmed_at": "2026-10-23T18:36:51.837863+00:00" }, - "warnings": [], + "warnings": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], "diagnostics": [ { "code": "processing_level_undeclared", @@ -4188,17 +4201,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde", + "artifact_digest": "sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 9785, + "bytes": 9842, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:06.298931+00:00", + "created_at": "2026-10-23T16:56:32.058938+00:00", "tier": "working", - "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", @@ -4207,14 +4221,14 @@ }, "bytes": 5981, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:05:06.298931+00:00", + "created_at": "2026-10-08T08:43:31.704442+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff" } ], "series_count": 5, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -4347,6 +4361,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -4406,13 +4444,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [ @@ -4449,10 +4511,9 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { - "pinned": false, - "held_until": "2026-11-20T13:05:06.298810Z" + "pinned": true } } } @@ -4460,26 +4521,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde" + "origin_path": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted", - "x-dfo-trace-id": "d14640239a5a4ffa8f113140eb5b23a0" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db?X-Goog-Signature=redacted", + "x-dfo-trace-id": "b2396d674b5848e7b1828fca235d84a1" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3A598ce1c1e63d53ab7326cec266aa9a523d9cc2f1acfba280fd2cf2f01649fbde?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "58cc82a3079f4e4298eb45378fdf10db" + "content-type": "application/vnd.apache.parquet" }, "body_file": "answer-definite-fetch.parquet" } @@ -4505,10 +4566,10 @@ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "crsCooperationModality", "crsCooperationModality_label", "crsPurpose", @@ -4533,7 +4594,7 @@ "members": [ { "parts": [ - "basic health care ODA disbursements" + "ODA disbursements for basic health care" ], "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.json b/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.json index cf3c278..3d1995e 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.json @@ -4,18 +4,18 @@ "description": "Minting a spec whose estimate is just above the 100,000-row sync budget answers 202 with an operation the client reports as pending. Waiting polls the operation path built from operation_id, sleeping retry_after_ms when the response carries it and backing off from 1 to 8 seconds otherwise, until done; the done manifest's file is then downloaded.", "origin": { "kind": "recorded", - "base_url": "http://127.0.0.1:19493/api", - "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T13:05:50Z" + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "recorded_at": "2026-10-23T18:37:32Z" }, "call": [ { "op": "mint", "spec": { - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -54,21 +54,195 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } }, - "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a.", + "entity_groups": { + "destination": { + "label": "G77 countries", + "group_id": "groups/G77" + }, + "origin": { + "label": "DAC countries", + "group_id": "groups/OECD.DAC" + } + } } }, { @@ -84,10 +258,10 @@ "schema_version": 1, "input": { "kind": "spec_id", - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "identity_version": "spec1", "shape": { @@ -126,17 +300,181 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2018, + "start_year": 1963, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } } @@ -151,15 +489,15 @@ "status": 202, "headers": { "content-type": "application/json", - "location": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry-after": "2", - "x-dfo-trace-id": "bbf5965c737145669a9a88d04867b830" + "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "pending", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500 } } @@ -168,24 +506,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "621bdcc038e34f44bec226434f3f7378" + "x-dfo-trace-id": "043386d87ba247048aa921704d3ff030" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -194,24 +532,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "1df7b03572044eedaa412f6d2ad6b91f" + "x-dfo-trace-id": "c7ef77e57a864be6a4617b1aeae7c11d" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -220,24 +558,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "b5b2e2d98a4047be98aea852117381c7" + "x-dfo-trace-id": "cea2df9c98f94601a5e9976e76842f12" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -246,24 +584,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "686111d592f3451e8c55691d91a66663" + "x-dfo-trace-id": "7a800f2714b94a8482dc5fb553c669f5" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 1517, + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 1804, "progress": { "rows_written": 0, - "estimate_rows": 108798 + "estimate_rows": 109318 } } } @@ -272,24 +610,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2", - "x-dfo-trace-id": "9acc0caab7e143d38b3ecbfbcd225707" + "retry-after": "3", + "x-dfo-trace-id": "f911f5f7ca244733b2da3d5ce6913f6d" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 1900, + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 2292, "progress": { - "rows_written": 16734, - "estimate_rows": 108798 + "rows_written": 0, + "estimate_rows": 109318 } } } @@ -298,24 +636,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "3", - "x-dfo-trace-id": "22c08bbaa1384833bd92f8dd9cc6312d" + "x-dfo-trace-id": "07d32bbe980e419eb9f8461492ff4c62" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 2377, + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 2903, "progress": { - "rows_written": 64341, - "estimate_rows": 108798 + "rows_written": 0, + "estimate_rows": 109318 } } } @@ -324,24 +662,154 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "227de800033b4185ae9b958d3fa2cec7" + "retry-after": "4", + "x-dfo-trace-id": "dd33ade549434abf82b662ab5251b0c1" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 3686, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "5", + "x-dfo-trace-id": "51d3664ad3e84fed8da1d94ce250d5de" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 4645, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "6", + "x-dfo-trace-id": "6a3b79b90c29464ca15c35d8eafecb96" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 5865, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "8", + "x-dfo-trace-id": "d7de7e24059f4d75ae14bd1778b984de" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 7391, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "8", + "x-dfo-trace-id": "cd1a9f894cbe4b6a9c1a7ee78315aff0" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 8000, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "8", + "x-dfo-trace-id": "e1c46fecd652459380163afea4dc35b7" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 2973, + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 8000, "progress": { - "rows_written": 106324, - "estimate_rows": 108798 + "rows_written": 105253, + "estimate_rows": 109318 } } } @@ -350,24 +818,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "retry-after": "4", - "x-dfo-trace-id": "3197d4d8b5094857afb9bbd14c49fcb0" + "retry-after": "8", + "x-dfo-trace-id": "3b9df177b0a94b069b47c8b441c6f232" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "running", - "poll": "/api/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", - "retry_after_ms": 3719, + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 8000, "progress": { - "rows_written": 108798, - "estimate_rows": 108798 + "rows_written": 109318, + "estimate_rows": 109318 } } } @@ -376,24 +844,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173" + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "29f271852cc04f1a8b287274f53105b6" + "x-dfo-trace-id": "cd6f7d2857a44f9c947573b696793564" }, "json": { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "done" }, "manifest": { "schema_version": 1, "definition": { "schema_version": 1, - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", "identity": { "shape": { "kind": "statvar_schema", @@ -431,29 +899,193 @@ "property": "nettingBasis" } ], - "facets": { - "provenance": { - "ref": "provenance/OECDDAC2A", - "state": "value" - } + "entities": { + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ], + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] }, - "entities": {}, "identity_version": "spec1", "requested_window": { "kind": "range", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 } } }, - "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "prepared_at": "2026-10-21T13:06:08Z", + "content_version": "cv_3d58d26a874dc30b1bba7d5ad6dd90ee", + "prepared_at": "2026-10-23T18:38:28Z", "coverage": { - "rows": 108798, + "rows": 109318, "dimensions": [ { "label": "financingProvider", - "count": 172, + "count": 32, "axis": "origin", "noun": { "singular": "provider", @@ -462,7 +1094,7 @@ }, { "label": "financingRecipient", - "count": 238, + "count": 133, "axis": "destination", "noun": { "singular": "recipient", @@ -471,14 +1103,14 @@ }, { "label": "years", - "count": 7 + "count": 62 } ], "window": { "kind": "range", "origin": "query", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 } }, "citation": { @@ -568,11 +1200,11 @@ { "ref": "provenance/OECDDAC2A", "axis": "provenance", - "basis": "bound", - "default_policy": null, - "selection_reason": null, + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", "dispatch_facet_id": "1962969911839422253", - "default_policy_version": null + "default_policy_version": "1" }, { "ref": null, @@ -597,13 +1229,13 @@ "kind": "range", "origin": "query", "end_year": 2024, - "start_year": 2018 + "start_year": 1963 }, - "graph_revision": null, + "graph_revision": "dfo-dev-dc-datacommons-service-00264-2s9", "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-23T18:14:12Z", + "content_hash": "29eb81d7b6c88641b1d4e8eb5e850ca36de66b99d6e9e09680aac020507a6392", "graph_endpoint": "graph_release" }, "source_revisions": [ @@ -612,8 +1244,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_cc753cefa9199881", + "materialiser_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", @@ -621,15 +1253,15 @@ "financingProvider", "financingRecipient" ], - "observation_count": 108798 + "observation_count": 109318 } ], "family_member_count": 1, "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "materialise", - "confirmed_at": "2026-10-21T13:06:09.616741+00:00" + "confirmed_at": "2026-10-23T18:38:31.738121+00:00" }, "warnings": [], "diagnostics": [ @@ -641,33 +1273,34 @@ ], "artifacts": [ { - "artifact_digest": "sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad", + "artifact_digest": "sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 913395, + "bytes": 473679, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:06:09.573990+00:00", + "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", - "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { - "artifact_digest": "sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93", + "artifact_digest": "sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39", "rendering": { "statistics": "series" }, - "bytes": 967921, + "bytes": 144274, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:06:09.573990+00:00", + "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", - "url": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:172165ba17975b34fbcce2a7c4e322fac292151f004b58c817039ec41a45ca93" + "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39" } ], - "series_count": 21017, + "series_count": 3656, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -679,19 +1312,19 @@ "name": "financingProvider", "kind": "role", "droppable": false, - "distinct": 172 + "distinct": 32 }, { "name": "financingRecipient", "kind": "role", "droppable": false, - "distinct": 238 + "distinct": 133 }, { "name": "time_period", "kind": "grain", "droppable": false, - "distinct": 7 + "distinct": 62 }, { "name": "value", @@ -744,109 +1377,25 @@ "column": "financingProvider", "field": "iso3", "token": "financingProvider_iso3", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 172, - "covered": 50 + "entities": 32, + "covered": 32 }, - "missing": [ - { - "ref": "AdaptationFund", - "label": "Adaptation Fund" - }, - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentBankGroup", - "label": "African Development Bank Group" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AndrewCarnegieFoundation", - "label": "Andrew Carnegie Foundation" - }, - { - "ref": "ArabFundForEconomicAndSocialDevelopment", - "label": "Arab Fund for Economic and Social Development" - }, - { - "ref": "Arcadia", - "label": "Arcadia" - }, - { - "ref": "ArcusFoundation", - "label": "Arcus Foundation" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianInfrastructureInvestmentBank", - "label": "Asian Infrastructure Investment Bank" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingProvider", "field": "iso2", "token": "financingProvider_iso2", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 172, - "covered": 50 + "entities": 32, + "covered": 32 }, - "missing": [ - { - "ref": "AdaptationFund", - "label": "Adaptation Fund" - }, - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentBankGroup", - "label": "African Development Bank Group" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AndrewCarnegieFoundation", - "label": "Andrew Carnegie Foundation" - }, - { - "ref": "ArabFundForEconomicAndSocialDevelopment", - "label": "Arab Fund for Economic and Social Development" - }, - { - "ref": "Arcadia", - "label": "Arcadia" - }, - { - "ref": "ArcusFoundation", - "label": "Arcus Foundation" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianInfrastructureInvestmentBank", - "label": "Asian Infrastructure Investment Bank" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingProvider", @@ -854,8 +1403,8 @@ "token": "financingProvider_label", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -866,8 +1415,8 @@ "token": "financingProvider_type", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -878,8 +1427,32 @@ "token": "financingProvider_party_kind", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 }, "missing": [], "truncated": false @@ -888,55 +1461,13 @@ "column": "financingRecipient", "field": "iso3", "token": "financingRecipient_iso3", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 238, - "covered": 143 + "entities": 133, + "covered": 133 }, - "missing": [ - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianDevelopmentBankSpecialFunds", - "label": "Asian Development Bank Special Funds" - }, - { - "ref": "CaribbeanDevelopmentBank", - "label": "Caribbean Development Bank" - }, - { - "ref": "CentralAmericanBankForEconomicIntegration", - "label": "Central American Bank for Economic Integration" - }, - { - "ref": "DACACPCountries", - "label": "ACP countries (DAC)" - }, - { - "ref": "DACAfrica", - "label": "Africa (DAC)" - }, - { - "ref": "DACAfricaUnallocated", - "label": "Africa, unallocated by country (DAC)" - }, - { - "ref": "DACAllMultilateralRecipients", - "label": "all multilateral recipients (DAC)" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingRecipient", @@ -945,52 +1476,16 @@ "state": "partial", "reason": "enrichment_unavailable", "coverage": { - "entities": 238, - "covered": 141 + "entities": 133, + "covered": 132 }, "missing": [ { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianDevelopmentBankSpecialFunds", - "label": "Asian Development Bank Special Funds" - }, - { - "ref": "CaribbeanDevelopmentBank", - "label": "Caribbean Development Bank" - }, - { - "ref": "CentralAmericanBankForEconomicIntegration", - "label": "Central American Bank for Economic Integration" - }, - { - "ref": "DACACPCountries", - "label": "ACP countries (DAC)" - }, - { - "ref": "DACAfrica", - "label": "Africa (DAC)" - }, - { - "ref": "DACAfricaUnallocated", - "label": "Africa, unallocated by country (DAC)" - }, - { - "ref": "DACAllMultilateralRecipients", - "label": "all multilateral recipients (DAC)" + "ref": "country/SSD", + "label": "South Sudan" } ], - "truncated": true + "truncated": false }, { "column": "financingRecipient", @@ -998,8 +1493,8 @@ "token": "financingRecipient_label", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1010,8 +1505,8 @@ "token": "financingRecipient_type", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1022,8 +1517,32 @@ "token": "financingRecipient_party_kind", "state": "available", "coverage": { - "entities": 238, - "covered": 238 + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -1031,9 +1550,9 @@ ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [], "pivots": [ @@ -1045,7 +1564,7 @@ "varying": [ { "column": "time_period", - "distinct": 7 + "distinct": 62 } ] }, @@ -1057,7 +1576,7 @@ "varying": [ { "column": "financingRecipient", - "distinct": 238 + "distinct": 133 } ] }, @@ -1069,7 +1588,7 @@ "varying": [ { "column": "time_period", - "distinct": 7 + "distinct": 62 } ] }, @@ -1081,7 +1600,7 @@ "varying": [ { "column": "financingProvider", - "distinct": 172 + "distinct": 32 } ] }, @@ -1093,7 +1612,7 @@ "varying": [ { "column": "financingRecipient", - "distinct": 238 + "distinct": 133 } ] }, @@ -1105,7 +1624,7 @@ "varying": [ { "column": "financingProvider", - "distinct": 172 + "distinct": 32 } ] } @@ -1128,10 +1647,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:06:09.573841Z" + "held_until": "2026-11-22T18:38:31.579178Z" } } } @@ -1140,26 +1659,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_6c6a169745fa827d302436a068eaf569/cv_d0316e8762f5b852a55e328777d17b6b/files/sha256:e8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad" + "origin_path": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted", - "x-dfo-trace-id": "155fa981459c464482aea52657f99e8b" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted", + "x-dfo-trace-id": "b0cef6f918794d048a8a5056022de7cc" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Ae8f06f7ca71d7d941c11389e66c94e1db1675c4839ec602d4569b049bf4d4dad?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "228feaabf1f3473cad055088084dc378" + "content-type": "application/vnd.apache.parquet" }, "body_file": "mint-async-build.parquet" } @@ -1168,21 +1687,21 @@ "expect": [ { "operation": { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "status": "pending" } }, { "dataset": { - "rows": 108798, + "rows": 109318, "columns": [ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "dac2aAidType", "dac2aAidType_label", "time_period", @@ -1201,25 +1720,30 @@ "members": [ { "parts": [], - "spec_id": "spec_6c6a169745fa827d302436a068eaf569", - "content_version": "cv_d0316e8762f5b852a55e328777d17b6b", - "sentence": "Gross disbursements to 238 recipients from 172 providers for official development assistance, 2018 to 2024. Current US dollars · OECD DAC2a." + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "content_version": "cv_3d58d26a874dc30b1bba7d5ad6dd90ee", + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a." } ], "missing": [], "long_builds": [ { - "operation_id": "op_991e4d2ceba89db9a36fa573e3935572a030d57902d5077eb85f566e98cb5173", + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "poll_waits": [ 1.5, 1.5, 1.5, 1.5, - 1.517, - 1.9, - 2.377, - 2.973, - 3.719 + 1.804, + 2.292, + 2.903, + 3.686, + 4.645, + 5.865, + 7.391, + 8.0, + 8.0, + 8.0 ], "resubmissions": 0 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.parquet b/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.parquet index 05908d413e0f7e85e49eb687269e6cfecbd6895b..212b05da950a5f6112451446893fea1397c7d073 100644 GIT binary patch literal 473679 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

C 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


NyQ7LV9b%VpjIi7og{!2 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

w(QbBvDh;;L?Z|`ng+aXiwH^1yDW`9M98pC~$Ws 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


WqUP?-I=H1pCd-RA>*{lC*f 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%0D8*rg7ET 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
^kl3I(eHC`F1VjKvm4iCh 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%0D8R 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
tp15NvCpb>W)&v z34z3fy1B-qoA?aW-ek~1lJ|8Xzkq(WHk2W|DzOMl*fj@B()1ok!h zQ`kz9v}hR#t4Ms^U(bUYCa&CI8kVt5PH11!cPbbaokxFP@a4A1gRUvh1%5cS>3+@` zQNnr+m&??ii+A9S?|ZB}_XytxqW)ZzVuY+0PhjuYiT%G)@oL)NfBT|qTj)9eDV8Ah zoMpPpNxCdJCx<(@EaI=>t(o^$oK4XdAKH6PERBDvDy`pGUU~ho_QgtrP5#)`fJCgX zDd!F$Q~wcKLtaT*sc5bWAZ!kM7Vp_noSL7*G@ihs`2N{zDT&JZJZm3$92WDhKF9IF zU?~{Vj+QGnV9SAp#PsDV)K1;o(ZF~I*f>NZx@Hv$rgU^WR#rX4(`9-CR%;1iI^4XW zMnSe0TEA?RONH>XBIrS$7d0|&J5oO){~2@Khq|;c$59xR!!~Q;P_4vYQ=x46NO%?z z_9MZ5ZW&g>(|o;-uag4oHo7}D_f}14ipd{wv~U2u?AZC1AGS_U=|(|k+Z1Bb@KrZp zD3Tc}#E|XJAm6u_kh3YRBq7racK)JRwq%PRRtBnPM*Y{WCd;}=vIfd}MQ& zZMm`2$PDGZ^17eNsf1JX6Q=ZzuncB$XG$0&UmDf9wC*7latDrW$|vMU7e-G$0^tT> z;X9arIC!2GLuoS5g9)M7h5X}bioVdZmuk~NtlRi9<k)ft5i_sp4`H>qDK(kDV!#6 zly?6SlBXDvgO)Y0+0l)LAJ7W4Y&%x(?SC2A@TGwAg%Z0Ptwh(kTSvnAxwSUqVFlXyg6Ew-&q{ei#mq=D`- z)`?${FZ)U+S&$n^yut!{QX^*6VL#BRS#{^% zJUUB!VE+O-mHZTvPY&gKkdD5>TEmJWpPx!UQX`)*=+h>jRkC%?AL!l1yRria%}xkr zmxRbv72tj{6~~bQtTKzs1(DpLsH%LOe$K1NBgT)_FnW1W$!x0hekYQfNkR;N9$ChL zvSYbjgnXqDQ9B#E7XddmK6!@!BkG=1d+cLPLv*iYT&O39P5H#wEY+XPyB^yfA`4!j zD`~KeRcC#-c&uwk*Ev**{6o*GpR2<>mj?5Wbhze^-Cdo2#8=WVc=poLk1l;$*76wG z&`Y&rhr>OWat^vg%nBL%ws!39cN$+F+P)&==#c|jy5L;i!DFij4QI~XzJA2}{ihq( zeR^s0NMD_2#g*}+Km6nMI{T;J41RiP{rH~`jd~mY@vwc>#P{!X3}r+Xj0y65E%<1#bW0dbYBR$-J}j{R7oCAn=1;5O!~1xWwgWcl=P zq&$P^R@2>dmZ%iBSSpoSfs9pW*+wdwW+`U{@_oS1C5qiy6^gdXXB9HJ5-zG~DEW0i zWW#h}(M)427FjD{ErQI_4MtVGsNN+Rw!$E_g56-WkW|<`3;)rV>zDF<6GtMe;2@?E^oM9k%4I}m_)(uMx|Ocpc)EW6<@Q>O*_bu zq_1OpsZ1#bs6@P!^$Zu}RLc9nr3aOujxOX?mEB|Q`3K(}TnnMWNBLF&`zTE8U=XJ^ zcu`}aTLq^JhjO@7**TrI>Q(Z?jim`^{-(s<#%MzMb16H&*sjYIwaS$sgQMawcFHF*MI%KjUS}CBdX&Rx7rs z;w?yik_=WQb*anLPEI!RixV*+<0By%for6}oBe8zqyuYz@C{h0|H z`y;EttU7Hi8y=g1l19xt8lD?gImLNI5M<1^QHpu|-RcH2qG5GvD3$P%S?D1>{7Q}N zT#v79k5seKy=Mq@9w3Pu8@|UQ`&Qh1^j77E9X~G(-5AHAQV>dwqt#>9(#bB7#MnDM zu3RK+P+dUdP<)%A-CV$0ki#Bjm)Gl@#@f2OCw(_>X8bM6djsIV;l|BD-=zK6!xKHI zE=^cKl0!yRc2te`rCvapzka&#g}OWpf;ENziWvAf)MLixFj`wm9O36hOvv#7i1Y3G zamlMUhD>n4?S-vsboNYhxzS2_@Gq`{W%*VGx}uZLyzf}+Ma1N;{w=LwZLXg2#*$UL=rqGfC-O0@D`M$pi5 zx(~%rR9i+h9GpwmQdJBZa)M?=BfxFMGZ4t?KVUpN?|+Ku3ezPNA|}*Jy={-pg@%a+ zFwVt`W37NjAMj^2vJF$%l*(H6M~x^I=}jg*s@IUx1b@t>`GB*dQ%{3;K|vTFvleq* zt!ysfS4F#zn2H%@t1WpMjeSZg`2F3QKLEq9pRB=37vY5LkFB1R5lJJ~$NE2jvet=+ z1@FWjXGY6+Jj>Xpm`+n73X%Hn$Y{v%#0tv2GPoA=N6HFPcM{4f;MsN_j-}`+`yKF;7t++T%)sqN8v>GJ3+J8y$v|-F}g` zs$7Vh>*+{r4CX4{3L~PH@uJkm@;VQ*yyE*ekS~sc{-oPk3zRS zzo5xZsbv|@l2cDVwHmT|EKlE!WLvjN64tH4t4z<1lw@}7JZa!B2r^|6$G9v% zHj+HleIgUN%x#rKvJOHi9wP%d#&_rh;LA(3SwC>7O!Lg9GdXvk$ucQczqKBv?1yqudLJ&$p<9F7f7^5k$vZKIU5?hb>Ju@u zFp(*70_Ph#EkUTi9AWQN4R3>*lo?31>A2LU2JwR|&C}nBJt_fHDKDT(#ZKGEK-Ty| zX)ZGqTIDQ6H|a*C>YV)Cw3@(>QFkBiff=9YqS~D=y|TQ^a(Y9r=@fK&dRIWpt&%Q8 zFPL20?-NE##diNo9weT?C%D+z%#4QQ1rn!qn0N|R$ym5{ z<`T)5NHl~L$7hI*?Lu|WR;tIz)LNd6%qmhYnUO&_L6g}%sCIN_Abtu&C(AS5;ZAdx6dVUpSE{{9U zNfQ&C$`D2190eKZ$09wu#FP3&I5*Vs(OUVb06UXZQ5$UV1-Jt zc&O9Sv)?sGJ5{c0?A>?rteMp+Ju|~~O<4K;6u7CxDK0*%Ho+n{5 z6M74iic*={?u2*FN5p=H`8l;_Rz)kGYr;;yBs0pfxrr_g<7N^HuUG z$c_i@otCwm-^oOo6H;Q+Qti`-Q&};ULv5t9pJem!+r?ujb5uu!wImjxqLx4K=l9)IkU+3PD*r z!iVCj&wIH@@9a(u7OREWD95KUr4D_2#Mxk{Fw^NsHY=_b>}FcV_!FwqVc>??nJRnt zNR(Fjg}_`qn?GFzZ>@{ycvY>dfhabL`HaonQJ&=@D*pI<;C^WaFRWhe^>23>dCi8g z;Kz|7@@~Idyf9z3m>fBlU4CK4q}6$SLaTfxAZ@gEYwjy-y$KTRS!=6s0dJ}L+Mc!; zl&?+0GO{|;N~COJ6zgT|&RwtTrDSXxIy=iv%c?iJ*&I(-WaD2MF3E=ajaxza8ofY~?JcAonWRDd*82HCY{`5L+kI zMY5yn?fp4X{n^S<9@ElI1`Jv0&mGFQ20d9iZ(A^|8K;f5f~x zv{TtUbs~Xy23DbvU{4cGC)2m*`R!d71J0MDrLx-FdUdt7w8YgsH}PwI zY+2y<%9==Y{r=eS)~Up&9Qi*aU3q{D=lg$CZ}iRXY{b|dv92sa!XoZa)uBS-3{_o6 z2^F%arYOtTF;q0`3`N&fDVD4=jxXT``P z?W9!8N7K(Ek%I!64g=oV$-gJi=Q;e;3~q6_YEO0dj))s&wMO`9-mF`!cJ91Rhu<&` z#8ex~RY`64U3Ix)FLqJCt2k*-xjSvK2To5tbBfGl2L3*8j`utcyRm}R-L|CiJvu+U zeJPpVtRCCY>@PEvEXm4zl#Y3CUtDsP)KxctMc8WnnV;%3WNh88SHr51*EfdhmGCJy za{ymiOZ@Js>WXygME5WCFdVAdJ0s!RC#rJQSt`_bs<*M}+ajeCQGxoeP$7jA@QRLF zy{qV}3}^;(sxp|iOl_RT*5M@t=O4I)pY^Dm#%sQEF8*EF_9^>jSC`5+As+Y{&>9_% zsJdtQn+#QFEi+aJi0`QXRQci_3Gm;9O+P@nz}80+DfRNqP*zk zohx-ZY1GS5EIU+l0-ICDylw22fgA#zdO;YG(tHA3M{ST1R`ZxT_anY_{kzTnYH`8fFtwKzo9PLu^LTYMnyiP!&_8Ag4Jlc{oLPpY-D7%>QyKPWm2X zmWnayi{oko7k2(LS*>H?i=W_5pzF~8;iRj=%|-*KtcPzLe)sIBDjgRj_#QRmq+5k^ zaPk)Y2&0Q50lci6vG9*A@FN);GaV=WHt7qT67Nk|gwrX`z7$K&%|#H9*>ipHee!7!I|$&z=?Fs_*~8C_RrNWjp zQhNVBN~7ZPHkf|5;->f^<-RuB|ok9JKgqkTR?GzuGm7=G4Pz@jvU}=&9KqPc5^m3pmp4 z{pRQ=`$TJ8ksCrHH9l#~VWjOGjf;M>1{jimxN2m~;LFh%*!Di7R8}UnZiyMlOI4#4 zU_RRS5e9MHnloIPXgs18IWnb=15?>hLlb24Za2ig1Lv4U79HIlLvd0+4CNo7(X&UV zJLBF|n=t^`HyA@q{=I^_oRQSS8Vmh$tiwWUNJcLuVKWA8-py!b@?5*xz~b{iF#4G@ z_?FECbZvDTn6CCCTR9US>D_wf(wucW8CkX$)0Te{HF0V&+c3h9^KD+{>e&l(NE+Y6 z|592Zkm1_(ojc5tGz6n%PP%yTT?J)1-&%01pnf{0`a9=#Vs~Gwns{)ZzayZO5*;<= zEV1-W1^)O_vjWd#vmWVo+?##DVPX@*UDXEKrzyVieQ9NH09pFf7-M4f7v^HRrjkaa z`5uRt-fwO$VC^prP+M4~yp~GGKm6i|vfyK_O2^1Y7t}5$uYA)OWm4@1Hb0a9zF{LA zIlrmD+C;Z)(L`DQI&WhN(vy#E%B0t{Zh%SWOs|6Z*ejbErPI_wCOz+|PBN+U7B#>d z`uaUQ8=0ZDb7V)#K(&r|G;taF z9I-PnDjD3!j=rIwId_Vv_XS7-8g>Md(J%Z-`}eJsPVCQ|$cnGjZ-(I%Cx#7Ef=WmY7tbZHb?gZm!N%MOi#IrnYh< zwRj4aF#LBVWFAP;<+d}qtfAY*qzf*a%*3CDV{#3r*@~IeeM@cuZPZIsPG40thv>Jp z-4c_V-vF(}=e}Q<$Kt62jUFbNud1!g71$4w&?OrxqyCYLV}QSnyYh~%4kxYni=%)x z7zRk3KefRz{#ReX7BJ87*}**{HFi3(wlRTMzHh*TV!a_ndOGa@{*70>toE?@wrpT2 zuyRV7pOK=r>IfJA;?K{rbWD0()dm!8ZQ;g(l&^6F=;?mG9IR@2u9y0nx`FpD(-h)( z#$k%_-gg6}{k@p&e-fmtq%#z4*Z+vm%}O8rdz5?AL?bDE}r$%BpHE$#Cej0S(RS}DP@mL~cPBVv z7+tQ;qf-}Yu2o^@G=40Wc89eAN z`)5spk7R{3EaCPk-etTbXQ1kht&+kzZ%F0KJ-Hm6t zmKlj<8k0h11~n4 zb6E7HfLV!`jUcrbwajs}6y^HqxEx269yggIH2Vnd8qAJ3mA}n}2>7A4 z3d?N2Qw<0yUL@#JC>a657<<8?qof%+*_LI@gT{L8h|%s<%rd=XHG60{)t1Ag?;kpH zD4n9oVd6N8+C>Xy@OdDUu@B6Q)*tS+GU>ztWrgmJ!rn#ydmoGB9diL4|HPrEQg5tj zd0j00w5b@WVolg5#seBq&PVwPQRfb`j`r_icCw948!1Tk=Mx~g z`9h&Mjf(Syyi^*!k#Aw#>RMpO{w-`Glf?5SAts%IVZfvsIwP2|-5lWPpUx0o&prjg zEGWVo28w9~m7V2WISuuBTR(Ie=G$2{(r9PJZWE5uocX*TGySd&pM*G4|1B^L)91Vc z74GWuJ=B7{asZ#eolh32Cz$`|9gQSYlIZt%Lg zU#gsJ!N60-C>M&w{20>p=S|+FVZl8U1Z2Zh#&(8?B7&))_5KY9c|5aF5Jks{d8dQkgbKl0NH> zr6TFyR#t(@LSC$a>+rik*5KtcAgv6me+S5xAI9JquQJ^hV20;Qa1_aT-lKv2_6Vzx zJr9D%{B@C^E^ZAqH#=M7rFnNsBlJoiEa9JK%xL52BAMot`2fS)E1>43k}!(==_ElD zr2`s*?4F#?576V&H9EQ;Qk~xa9hq?*bcodd{v9X%cX?@o4lXcz>B?oG;yFDXL3(9+ zzJXo@M=;VM_Dzf>J3WThOt8y5h{A-C9$va*r8%D! z71J91a?9y_BSc>Ld5xcj2RR~it%PCcX2x{nc%}u?5c48MN?+CS&;VF-h| zCHPnVcpQ$dy_0a^f2ZAc*w8KD0I-YS0c}qPjRuhE*Vf<|&h_J{n^Xjp8%{pwBdJW9 zb)YDZC5Qc+MVM^5%X@fgn1_!+Q}qGp2C^rZPiVzUz5pY96-cIj9ni6~Us2)Gh4!$2 zMR7sCm;N;XtTJmb?4Zw|0MGp2I6TjW(0yJDBEV|kqZ*D#pZ%%|a70YMjk{+aDlB&C z0r*7sNMR=uzGGlyz%>ia40~_jDC+)1WA8ej9bHwt1*u5J?8EhF zn<9ap6VS8&vcuW^i@xv#YA_)?K9ql#e8m)CIMc&*bSNP-`S;NNhpKaQkNp>q6X zw=W0*mQ=eF)Vr)yqVA0lp#2^?{ES>bsd6#W{*j`tf+rFfPgnB=#uuC4iP2G)%n90h zTd9>^*#pWoG$=}fL#WzA1NQ`(V{+^}h3b?~tQ^1=wFCb^WcNsse*oa8x7l>E}Tn6B6ltfpVZ3Pw+$ks-xlpuxvN0AStx z3u{+i$4sa{CImoQ-LK(-{3E96{j1Q+$l#+;f4%mg!NUzjVLEZGkknAaK@F7Wgd&m7 ztCb(5awRiXVfq=^j;`n*7$JDn5o09yH)i4Nk9X^n=G%Zh&sJsxLg)N|%hDoqIb5ON zKrXhk%JfHX!gJwJT7(3k#-4N3RYp6FtN@3` zUgkQf;T$xGbQBUT_(%ghHP{R5%GHQZq%yMiA^7tA4KRwggT_vG6)75mw7e{YGAP*y z6E3{Gh)_v@!i|3qbxtNZLX>Fn*~N#j9$gh-lNp$!oQlBp#7;D zkcqFSg)H&qWShyg!Y#u?lc6H}hw!r8TI>y$X6QJue@^_$9Wn*4ZG8Lk>kN17`kszvV|R#`cD z;6jbc!;xJx@2Wibo`kB(A(fMBI^@iL*j0|2CwJqt#WLYXoIV&+;Ur{X8uKZEEOvgc z%42ej>?EVlc>ROhlwJ%wONC-aZ|h2N=TpxhJec zPsx58_<}TU%|u&JmBS55kSH#0sd)!+wC!}#300Ik&22jiYj4tGt|8dD`DuE*-h{=>9L5fY1BsVNBrY!O`%d9j^Gd=>0?@BMVbaJ=6EQIEvFB1?&@6FDE2iYTFS>W*~rh5HZR-K^sbGu+uRR0F1M9-1T;@0S77tC_^gG|!|}1``7DWT zZFATN0pz~}o|t-pFW{NzkMSlgbL}qVlLCCswY*%7$@Qy4sLJ2J;Qe|Qr(ffTG*9Gp z)fic16>>DRNfkBBnkL(Ae$H=Put$|-mB-vO>bb7Q?MH!^!|ivf4Xph&qtVa)ymL9L zoFlsnBgPzV#4x%KNNBt6z3%|_8)FM#e-PbQWiVP2LvF#YxjQIIrRZX5F*v zTaZM_Llg^yu3>!{<%A$g5Tr;}FvrY}{Q*rF;2U|PL%r<+a3ZK)yt1On>-TN<5@ zJ(G`DQAx80RL4{fuw1pDdH<$119$S+Pv5HwSj!s^RAEk<^kgJ(CGTFBk55pN!WO+i zjisYTxMfcJ&Knn0Ic&?r-&6@soZPv?Fnl!F)4=&N7}-~@P|f%X3qdu~nxP#qKl$HB zLtwWLSKq~WAD&-2EX0wD4~}9C^3}>7%4trxsWHx`4A!eaW3S(T_ZWKr<3t9K>$hAm zdf9CRB_o`)Wth{L$ECz49mFqkZzW>CEO@yA@5Dz69OZmY3X^va=9AS}ywxvmKa=|& zc}3f>6-?)W07n_$SdW~u@#FklMr!6!A(ZH1*7oSNW+)tIxro|p8@qJ98_&oyEh zZ>Yw^WCpL}IQjdni&Y{QuRYg?`HJnT@R3aB+WIf=s?LJF()h5B1-EonE(RTc@v%xQ zoD8a+O!{p&Z|9le8@+NOHH>^v$E3&~yuTK6*{|@iOcvkqT%E_{7Y}$H==9XDJj-NK zxf>4`RI0{Dv@Gd&L1pXu!OPFt-BRtRuGc~$i;0ah0a;Xg8>|v)Qsge@!Y@8rh~Ti? zO_h&1dMDp80_J2t#bln9K&$wKCvZl{)`U^dl0TPW9mTEvePM3&*-;x+B0JdPxDWU) zSPRbHQRNAav3EFih%@YWe+^PRJ*j#jOp`OCeR>4?Tkw$#CSRTIPBL-o=e&hy@ivmN zm`RVu3;4kK>ODLIprz|Ho%#B#;YFAAwE)xi3e*NbMW+Y zh%4QMrfL})Rftw)q(HU>7}++8H|Q8yx?S*BqR(PLRk*Aa1f<*0axTOi`L?dw%Vfh4 zbC70?2Cb24-#WsS|5%8m(a&r8Fr(UO>L|cUg$A1O7L1ZfE0q;*l4>(C5gVaG?8#@d z;gPo=+|}r0FUzK3vQ4_pEi8u#be?5zBqac~e4tIuMH?AMKN7-0G~+EbWd z+2fw_aus&!-kdT!OW0lmZ7$XU^i$*YES^+i$xrPdI=S}B>8b>C+3dVjoyFTOx4|&? zOvFS23w}WN((N#=Bp>i@_$8loFR?SZ!U6P7#-x`xnQQR?ET3ZKx}f?$giqo+FdIIU zZ#}Q8%*56TW0E6Xlm%^f&IcWlJCjcW{V!X)6U@;5M_z=zy8c~^W;pq08QKN}V}PTJ z4{QdxL=Jwv3FN|l?#@RmF_Qm_Ey+TrhDH<99XI=XvY0kT%Z=jScdab|eG1z^mcl#O8m`}56ydTEK``}umRBMA9^?lUp@ z@i%}YbcjN%%9h_?8~2k1ePw2p?AuHZpZp zzD#>Z3JD7$ik!#9;%Y{qd8!7%py2u{pln^cJYJu{0#xxuqp5Eh!L!z*#t=)cYz9GcBZg_S@vNzODbOfa&N3QUaNzA+9o@fG9b?Xd z#lZ3DDYLYChK%fy`feQy6m>**;jMm57*$~IJf`E#?qU|-dr1wPwE6|Z%XiOWp)7yK z;oygl!PQ^&FCVSV$c7^Tz%V}39bwTWBAOVE=>cSL^$$Q{;N@A&Hre!Op%*S(QvfNw z-`beu<;iD@LqN;b&TJDj4$fuh3dn`!VkgZ-Lh}lJEH1VE#0XCHm^~BthmzMx!a(RCV7XFJL-5w^D>TE7}g3Vx~4&TLF zK)y?M6{5}ZWxNYQ@0~A812lOH7zwsWhscPxH~D~xPkYz^cjoalE8Y*`sm5F_AM#U%dtXhLQ7IPG3yr{pNF?*%<7>n#@)v9XMA}Y`}BwFd|1n7 zmrvmHQrYh7>5A%89sHkG<~Z@@)Mwgg8W&$OGFvNYb;0US%WrDqX{^~82^NvKY}6mH z#>KMSpJ1rq+qBR4sFv-zSct_uJY*do(z1m!M*;(N8~vj#PveNGuY#?VML%eZQ#tAB zdv$m*m36dqP)z!< z`%H{)^Gq88`Hgn`3`>gKsN+UZRFdax;Nx1>+5fI$nb>CKXyaN=8Z+`oZ2)8LT-sE* z>slCte5(1Rl$X=kggRel**Uqv8*gaC97jgh+?i!S(sW&^VvE&#S{K4U)pyfqXVG_m z1zG>I{GK|-J$-bkxTBxVYcigXS9mFnd8c;bgIX4E_y$NjYJHP0*0LG@lX#ZG zZnmugIal7Yw$ea5$PdZ2clk6pI1P_X-l9U9V|Y&^6x?b*p5z)yx(Q1G0vKA=+#l= z#NdjdxF#2#pQymnt8uB;lE%rEX|dLo#z}YI*@roiS7BR-k;DJGL1MwlrNy*X+k6+5 zDi`{hv=G5C*7@LCUYEu;d@{*sV5^hoLA8gh8~q!Rx#pc z(^lKOY<;_b07Va1H+%~K#%j~W-~wW)!jm-CYvv6Yq2dp#pTL%uZ<;nL^fUSNYQ(ob zUfv}usw395KSZ>lH1^fzB5>}qD_wDG!<%hEe4Ml=^U#0iWPX3_V;9(*PBdR{`7|_XEJAD1C7G}Z+zHRCN zyIjQwzd&mHp@ny8*;7{!#b{p^t_Jz_WIuLnu*_rgI>tFMyloYhA%Eys@C!+^2kkn7 z;O4X_0=s^(qq|~@-*~eaj3GHkD)!2gTa}e*%*ua)AKvqyDV@s0GZbUIf8DpTK=iBE zcN79zx-G%m>p9#}h3zxHEAS3P3`x{sZ|uhJ?jOyg|cs=h6$2Wj*gK zi7~_Jmk`U=D=iSb(7&?9Sn%y?ZfM!AD96H2N0O3rz0WtHi^KZ^XdA$&}v< zg9v|}Ds(dMqY8ydcI}I~B?h*p-YZ_0%F^%nN?feKnhVM)Uj9J|tYkw$3G9qt8}Q+} zv`2Fxz_At0y0{ByC5_p1`H2#Qyro=XJziqCaQC;BeB8C35|}Sp z)#jF&<)hJ9ank%3-jd2PuP))ksch`XOe}UFH?t&wTqA=#C%3)@{UxGN-lAdcYj=iX z)Xg*-0oWAcL-xJdpU?xIY_%ij5JhaD38dsf)SzH#3LN3Noo>m;Y2sbea*i#Jg*GG++{N8?^WpGxH%!Jfq=VKKd8Is~OhR4vuTEI6&7veZ=emzC4>!9pU1Nqbv^^6g_Q0A*rsMp=@%=6(VArPP1H zua@Iiu^fqpWe{VQ?;b*rgtd#&lH6IS5J>g}vv?<8nRr(LKC(j#4X69RkFei2L>+AR~diZrbpPzN7H z059pnDTL8Lhd8_8B5y*;92uS9oqFosDuim1L4scklchDRKls2wW7U}#IED4!^9gP|t;EPcU7@Uht zf;>1Q%g#vNCO(?MNN2ZTNTn|YAz7cUpDC0hCcR!TRYUF*atiYj{FziXC|AOp1b=;M zSy1Gq@qYz-WhzeQ%h3bcL~8;NAyJ!3a|Edx;;BMGH5%oG@+^uM;se&vOvylZC<6mY zy#;vZ)-~A(O@ue`GQzre3K9L_Q6Zj*t`SH?8*~tQ#D{?!sW*=ZaOi;IeeP|-N9r-M zF%QwzXjcfByYKT(1Q9%DL_T;=Pqo$J0Y&qS0@JWOZaVUv=~#gJAO|k(r5rN5uta`J5_@tnJMs zEg?Pl*?~0m=UCWb`+QL*-e`nStvFdopd887z$nu4KLjf<`WwQ~<%`TF8mps-x&^yY z2<5s}Uu_{dnQ|Q(ObP`xfLc8eN&50~7EJe^V7!fw#wt>P`@9hkjyPtz2K&;TpPFU@-4&DydJcZc|8~q()XJ_cAM^fHwzR#5ml$icw~V)I zSe<>p^MpepunbT27_g5wrLy~vzfl;S>)y!cXB%H=AW7`2)?)g}kh8Fu)fjLV-u=e^ zsVy9-_QlF99jyIPz7Tsh&%?V?Ij?2!5|y6w&c8BW1rhY{JIsI+=Nk!&3~Gz6#J_k* z3qz+;Uop#xr(#&=jdjKtf|m!&;NqNW!85qWdFi~fHj97w6fVNkd!u+$3cLMeewoY; zHyokFrt0tP#^*3BN@H~ayWN?Cketyt4~lM4yAhDEwOjTDN3NiccvlK*)Z{=`4o8N( zO4Y_-@O7?#28E%m{=T&jnmInUAwtn?bD!mk$QbvnP+W=D9i+&@j}}5I$cuUd)`i8$ zAe=36L*`Gs4oKtcoA}CEpH}A}2F@S%WAfW0_xS|J?5DC|J@%PX060C{AN_~!ftkvD zGv3~(h|q2!B}rcX2GS(Db-5C4-&t_hqRdfL%ogpms)~`Stc65{=_>E3#Ytb?wS$1B z`Q1?_zeS7*WJ`HoN@3Gqg_%KWj%6N0N}j6KbJt$)cOl^>%4o6&B+Y z5N(x`U%({kmv0zE&j}%EraC3}+WBM)Agk{jjV;P@{+xq3rT3_fILNXdr8~1=7+vrh zp??qWQ!rP5_6nd^Zn?9}#bn>$LJP8@A1jKn^K~WF<;>53iF!JJgc=o6Ws;KNF)TQv z82!Qfe?in-8wC0m|87&}VadHu+{G+${Q<7DUz^S6!Cn1l2%PMfqn58$6|fTrJ_feK z2gXB+=?ADVPfNGI`EUvpXgz#7j5*Vq`*e)_I8Win=-c^xJcWrTF7t6nEHY5=W>Nd_ zqBt%7N71?9_%{5wBV8uB#gsOFoLqZ)vuAh=oysi!t)h9}0^z+8%2vxsUSYh>` zJ2K7RfeffjbpLqhaVb5_Po=!JKcoDa&KLS;dzMm=bEV%!;4J0zJoejy! z&8IYRT5~n;0fxr+=aIGa4;=(^ME|UlqIe9A95y{lsY-!i!{B;~K9o**m8nD@sh}i? zn7o4w;$&!=^l^gBXpg<1Wb$`6AdYaeAp*!yK@kMyUzPzKy{tkEWl@E^9)Xo8Ux=oz zTk05YR1+lBiR?c&%z}!hU7#|uDdB*w-Y?i2(q7ddKlpagB2a;hy2c|b*Ux7T&`al( zwEFig@Gvd=5RD9zg>WS*-xH!5+CTui%E$J&qo}1hsYb2N=pPiAywx>sNYF2z`jECk z%{$<$e-5UQ#r6U?lty`hkq&->+PPoYCTxavH5Dm?7wR1@KX;{pgs4mxfr@J zmK8)|uR$5o;N{KX)LN$GdT4w+C_=nFps<{})(eRYmK@+jl?SurHU+IdAU;63k3)yi zTQQJ1X?;NuQ|Rb2A!ed09T2Fo5@U!-llBXVRQiU!q?}3hh8pt_I}DU0IWp0&n-v7> z^bisa6dS1^3(QquPSPEPwgf`Hjf_r4-uo6w{OnW(xo^JWqpB&fm8$t2 z20D#btfGP@2!O@U!iLLPshIM8R;xpd^xo>Tpx61igw|@$duvfCD>K=O`ajd?=x0_6oRQVuUClyB5GZ}la4qD;G8ps;#9hn$I6o(ureCZ&W+umuWqBUB5RJrh&s>% z`SCYW1szAfwebd&LcE-87U|Psh)Su(bA;pN4uYuxl?yUWsYHZl5Btml5cSnyu51&K zgzwZF>{_cTXg;)0&}Y-&HBAA%Q3#)o$ZH%)Dx5a!sr@R*b>0xnH?I}a{9-+7ET+2k z2-BUemK&$88Mt_MRznmYNQZ?)eM+ig`qJ6LFfjXr5Qb3{z+AZV81LU%2%oq6E+511 z!_T$fpkG+oeZDR~YikaDZpTu7NrfP|C27zb%5RrUzp6k6*$ zM~L=Wj>D$ia1Z3Nfi_H4=r6b$)0b_58rNtC*5<0&LNnVbwX*jrs)9`X;Gho+)b5}{ z<7IAe9NE6m2OB*-d`Cy;HNyOpGi>Ed7W(FU>7X@5IdsByvx`nR?hbNN*9jd}n9Sx9 zcYu-i6@Re@}D}YTj-G!9KkK_PAPzW?4QX#`tEkkgP=Cdg4wp zGRO+dB|lY1QFOdoh&QD6&lO2=emejXo0@ghaJQ$6{bQDse%75`Ebn;1x2At6xDPSBQK$Pdsb zw{j!&W`DDlR{t4jt-mARM03&=#Eq77!!$I|4617dPA{GWVtOOb5vRK5D7&E71zj3_ ze~Ar*B33C$z~T`g8>I6M${-NTz148^zV$%x8(eK5-bidDq+xa&P@Ys{Gz5?-!!0pl z-wQn@_2Dt{s*l||PHJ_wy9$8)k>vFP>W;R7&Ac}O9w{E~z;=pVxrAKI)VHF0DHeOu zwIUP!vNEt2IphRj^aXC*>b(^=U zJxuIB1szJ?eTk#k;d1~?x(-q#oBa4r9(A=VwBX-+e7S{5BVU6#NY{T9iMLaeo1jY+ zD~n9)3q*c7Ug5(}uNniWB-Nr9Y0>jS50lPSgpOB;C*GDxMSTl#qjpu;N95Dq0Ql=A zSi9$Klre7Y)OcwN6>dqME^5$;Y9p+C>6HS{zXvdmRJXd?&g5Gw&3ROMC9tND146I~ zDOgenn9j2~%xhTbHjUZ=unGkPI<0V3 ziX`NEDQu#NkdnbO2}Cvu=Am3iOyTvg+QMn5So$q3NcMpJ?B589bZXg+o}Rp^q}ojq z)^A#_4LFo)gUXM!$VUh@Gp`-(5El}aXv50rIq$eJ#H4@o%W@Ecs$q`Pl%+PTMd?+r zAbFi>eTRm=$GYcD5d0eIDuGrVQ7zX=TQwIV>GXD2Xp@}J78a1#g4~pPH{S76_^h55 zL{mzr(~i6T8u@ut%oJkH7@2*{h{7_9IYy;HX^gJD2+1MIjf+WsQH;hvhut9kD2Oen zw@ncg!^%<}EZ5%<5@3PS0G+m9&e+v8Z5+Ia6g zjE~=pptUA16-Ma)HOQYEq+BlcVuFWP0|TA|4#0U>lcWV7ltyWe-XT(PAq2iSREV^s zE{EXK(8NHclI#9F+)Ez{A`4g5IB8rBu^n8jiPP{`W@zbb5UIG_tfLdp-T^KKg0vEs zAu2_?5N}CyCZUaPt{D}42?U$GzbQ&sEx=pxT7_V1>e`+bA~Vb(YFdc_WGkd{>?9gW zjdJZY`Y<0oUT|2crB!K&Nuk8`IycNA!4PZhccF&&*(M1 z!$oxya~U1m7$U?QGCL`^!V#cry5*wKZw>|^SIwZvZ6O=jXg-Dx{{qf*?ge(lLz)1U zBe}rIG6$p5yiyA#$8xRIRSM87OR;pWY#gKyOPw^Cj%SlkgfK?~E7PLnr(8niEkbb% za93_ji7d(Zca;!sNyAOhFY%jE#^^Uv(} zq|$t}vn(@DwO55y)P1V6dDnhS_*_OlU**}PNWSj`Q~RCdI3;`8b< z>zg0(uG(zfu0_ycuu$)XSU zC$*lI+(Os)ceKHltl`u#N=l`ZdZ5anlfT~Wy@wD?pULK%TB#aa^=y#V-i(tM@8@ur zJn&^d!rj$VuP3z5I_$I1AOxMpe{%YFZKx%CU_1el?iU8YP%?eChL7V7U}-D)L}li^ zTgd06v*bK4Z>Yj7FN^p{6}GWmKIF4A^WFcdzCu~N74F*vvl8f)|Bmw(sLW}KHWA0( z{`@{5lKNGkN}_z{BS)*$piQw`pV>Yx=j_+%9noE+x;)hJ)c$LexY$DU)g za$QdJ$a>yY*R=bK=C_ry!ba61Mk`C{(MKDv$BE^k`Mka!_vxaeu`DZh$v_t5?)rpH%yn(} z@~YI6Kw5{bpK^=03fNP3jn7MG%l5C~UHCPB2E^4%=T_c}{PCn_yp+z!^hOHQWW*68 zVU{&EH1Mu`rA7|jHdpcC%Q;B($zv+)!|)u{#+bsr<~)Y8;cqrf?Rc+d5`Yqz3FV*^0BsJ1opfY+kU01X4$Q?vQQlgWX--b!J(+Cxs}F(aX4SIQGCO$kLv@s!np1zfN@A9UWyTo0 z@ZltF(8w7&nK}=1abmHw4&f*9$#Qo`D<^h1QVQ~xf2yY%R?N9xrfkD6LiY7na=&8Z zFz-ToYe!bDo=&OChd3twu|-J&#;0vJLVL}e%)4M^_0sZkRhC`7r`Cy2d7hfJ1hZkc z>cf*9cc=r5zrBCA2L-eoaRStzbM_&Q*Nl^KoV{TuFVrTIv5!klZu2eDmXat#m#L5>rcam6?IOpK6CO4vx(db7>MDoj7XN6l=K zeS+50fRh}l?_@gJTiSc}JN-7aP@O!5`8=kK4v)X9;7BCw+Qv;`lo&T3&35uoeTrxNf! zVvDN~Qs(!|&@gHPA4C!Cp*SWb_1Me@QSf-LJ#P|N@WX~~JBxQuUqD&wbJriP0LB^hR~xOx%#qNaEqnzCLo@|b)|*?Q44BMS z_No-e>Xx`z5P4Z~+_t4Dmg1p$LS72xpTi4|w%l4+fQ>1wl@#K&fv53M zzYRh#jTZZa5Tl-u5?Pa4_wj|8)MuIX|(@4P^Jk{ zuxhAOQD8isg2H6vkec-W05T;wxUUh;-u;q%FWsjz+TjB#0f@}0WmeQK*9E4?xU)iD zCSAWxk($!2>AVRp=+{E18@BZg#SeJL)df+YgMWtA(AjUxL1o~dC8%(kxDZjD$l;sD z1T`EI3|Xwn*vCFUOR+TLBQ=@Vdxy_yz@7Sf=U1Th84c!PnJj%b`C{zKCsWiGwy5Qb z5}9>g)(uy(XSXSdu;IJ?a1M`o=lYPYxYd#uQO@kAuq{ez@>ZlSYTiMJbZC1xjq<{8 zN}NnykB{rZ^p{^K>FeloJ;s+AY)cr}k9`A#y@pVa@eerAc8{o3ZJC>DsnEY%N zAF7XB*GwCN>aE;1D|5cgRu?e2%3O_su88nCC<|YCzbuY=uzP~FI(_&7OqbOs1gAib z3x*mjY-xxYk+dMZS}_t*+Y!>#@Zk*Rs@c(vQm*v}`GkhK+8%^d^dIDnUKYBS$vc~1 zAMCr35pis52EpO;XD;TdUI#G}C#m8FA&yb=@tUmQ*9}Hg4|a;Uqs+ePHw8muYe4HU zc7)HtI!luTu@fzjg(ye&-mt~k&vVviK?etZy;)YkJ{>p9m|*d=Ra%zCk)7Q-fYlxc zbiBd9T7A`rkJn)fvo7$~rg&k(XCQu3neYLHBDe6NDon1caqAfwKHY6%@spjD|LtS= zyh=y$y6_mbyXSTaHCUg z;F_#&-KaoLKkBx!=pVCyO3M|mPi9g^8t;K6=J1zDOnkA)SIk0d1|kqHO*y8p`9E_2 zi)?rZ`c59auEgR=ycAAe@C_wEBK;)j(`k=gf~g8kHZdky_Qf!d7Ft3f(CC?)?nLR{ z3wI5I8AyyUb_Bko*hq%Qr;XsU<~sqkcUe9p9ifkn9tgm;O8W9pw-PV7{|y@hFU{edNPFK; z0T0Vh-{%v6Fy2;(>FDf*cs(^E*9L)Hh`U=U_MEN~EH&t$j@PFm4McB4_cN8RnxU&s!0JRPh^hWHK5@3C3yv)FC3XSGXw4sP5zapH$F=361?i&a7>niI7sVn}daA&yT zFdN{X6ow{O5@R9@b!voYM~MUTlG;uMU6Zl<-3Xkh1%DkDN)F=7Ip(Up9Bne@`XolY zD+^srcjLT*srq)_4uQ~4dHse|a~N+(VL3l+D^&1yOQ~@r!6bl^w{=pao@R4lkh=VL za+vOyfe4&RWj(>&$wDV1C%$(05vETJW71FGL+CWC%jcj<0-#w9*lEzlhc;uzxe0T9 zd`Cga%yY{0pZ%z8#+KTTgwJj{tk7c58MYwoquUA@1;Q0zc)elrxs*98IaKkTO}->5 z(Zk?R@@gxOZR*mqK0~tN%(b5f3q-xTGW9nl zn9%osWg+&*)mmB+dHZKeTKRJ5kUs^vHS#M<^W(Jh#Ue(lpNDE83tB08SgCsRvH&Yr zS&Nc1cw2DRp)Yfw$)f8_#xNyPW_dR%))L~?Y5Z$Jr=eYT^Y&C~*e+NcEH-408&K6* zb;nBUu5|+mhHGV@!)|{7t0U^yx9Qo}f~1bHV;`#cU<%W2o2yQ;n?LpA3m8jYo9MQ% zQ_l|bi3V)QQfyPha`-h7lF0NM>FyKy8`Sat03wWpz=NRv4(<)-L6CITSn0gcC3fanuR=WN#IN}VHt@H}st_`s zPu1m&1lkFC96j$+Hs(mS`3S>EgLp$#W^wm{X<=$;^LEd;7`6lHGI5E0n>kUbfKD~;;kG$Ttf)$FH(_wsg#&JWf>3M3XsartyFFq5P| zfiUNsOF*``xFsgL5o78aIF$>$%7i5Xklg5Uru5nGl-4 z9W<83Sm)m+;Qw9~dMWi|<6rM|NL1HUDSurM+f)X~ZdP(2h_ucKfw22a5JYIw5{ zI`5pa+m6g#?Teu%CHbHEEB^$z@2`izjB8sfYZV`z8>gpMm-yj3b~A!-igN{1ChfW1 zh==l-11SfA^@G~@%NE0i?(#xAGnmFeybwznA3%)lmFP%PZc<~Jloa}*NGHO$lkAfa z4|CbwVVLN3AoeQUhX+tT2{V@_OoBp_D#c*1O6P1E11+9~5aRX2c$kFiJM=V~1Z{d( z8aijZ27Im;aB z2&psf4C5(6YD}DqJC2f?`Nmw`91Bz8n8h8(h@+M|cB{5scbr53%sCm?gk|GpVEihQA6yC(Rvj#=7Pz4^(D+p3g))OEJw>GN) zJE+@Lu)|rFv87N?veqz)Go@-hRB|UPj9B7aiyZ{@3o?A^lZ)qBE0^u}9RaE-Qw1A6 zK^YlzxWhCA`NLp~hMws-5`>_y`Q8$y(fSh@9&={~Ss?s#7UKsCIiJ=I>|)TbP;gXB?QtWk8;Af{P`*<|qwu_%dj8>)y9 zd6?+?6sqRfLMM@a5Zy2grd<`>HHq_}#e>g%pkA(d5#km@SA*xtj-y~7{t{+IyDm32 zli#1jfyp?F8BN?+k*O!&#vJ&w?|LjXEd0%s4*6nkl(;6xBVZC@>h9p~IA>M&|I*at zwo*t(D#PmD!!(or##LfThh#Tr~fTZ0jmDA%wjj*~=^%Z7tj$`x?T zuPR{859i=*msx2hQsWH^>MJJ;VelO9B+;EnemsSLs=mf|SN9d2RiKsPec&Qq{7IrJ zmDrYnYPs>EPEEoe@M&}nzUo;ZN?O7V7Q=OkXUNCz3Px~A+cM;gahzz!GQ%GPzY2W& z|G&?YhB$6;JOWf&1oku$F})VCS1-_&(7XK&2@ZfjPwW#G2%L_rC zzPL0)uqzSgu42&ho(JO&!^gG1R_Q^dxeJ|ox1v&=tdhT|T0I!2rY|4A5^a@<@1_Dy zA!XMBCn@|9tqPpND`sNUd9+&TtjtTfcOELu$p`~n^a+v9)YqQ%^3WqopHkzxB{(bn zsi|=~UVdtSrKB}^dD|mda3f8)bs5&Sz%vVaS^xH1+0u5ld=%$F3GbD^mHuix*REp< zbFpjULxMMn1}lp&{NEi82)-oxWR_kTOhNm=mcN6&O3lSsCeaKOU9BirF0a^&=5zg+ zfz736C)?w>PqYxwE8aPf9oGK~!IebEjX0##x8=FBdstsLBdMr0A{Su-Q|8VOugwa4 z!{ukOWc<-Tj$(;O#-UwUrX6qTtF_X#_tpX9vv!SjxTxpZYKxyrd7nZj;7|@*o789p z)55f*M~K@ba?R-Thf=B=-kFnN*0%y0!H-47mVjfKUJBrHI&GN}8%l<&GVbM3^n+bv zf4D)=C(&6`vS4RGOHC;8Q>%Wd5UEJ@Ek9#^#V?;KglGb-rZ}m!)1!_56+Bhwn7o~U zqo(2?S`E;xl7pkF?M+#2RBYXD1vWR}jwMLzFDg>Nq-kbiiLLUzze=2>Z8y=}m3CQJ zAB#CTv`&T^g?49=EY9019sOTigxVX;1Jo-Pt`MZkH27V%!bRWoss%=QZ{{jMVb-`7 zkb2&A?+n;cl|A^oXuVgUaOQjx1ak_%-yDyYOiu+*WoWZk5F${?KdQ_5<7{NaZ-O16 zm6pbSxPRZL4_M{wUw8i$)aVSfXS~4+VKeKrj+|sQc<%Y=eu)IM&jk@bX#jw*;Rxa zv%5kMZ;VG<1gGr;7DiuF15#4bq_Jc`DVT(1arf_)hRN?UkgH7O)-X*`aw#y)+dn=n zQ%5e>j@NKIMOe4;q}y6A+CgOjB(BluZb`W2 zNrT}+43F7W5uzYE`LW;&(VGLNR-!^f!<)=n6-8yV7Ru(&!@v{AH@~Nd zQr8SGYk}2ZYd36OKeeVq&C6d@*_K*FHR**+Hr`k<0xR*)F4RiQ28?%csIM7LrJ)Z? zz2xY17DLmlo&r^ALTk~99K?yZspn{S<|RGeoQdO2IEV!L$iD;6MC&$)p;@y%84}OU z+MJOWKqI`;7~pemU4slg8Uv18SitdC-Q!>4yySIN(U(dCwL1tQfyQJL)}iqqaHx1$ zy?sF(3N|J$Rm5n_vQ*)v;keIPQ4P1x5$`6KolHQ;w2I(_!P$K&_HUljN1IMvWjEnj z;f1XJTkbj8;Y20L1<>K)R43d5o=y(b77h8wfO?f+1)yh$I}A|~wLWFVlw6so2s6r! zhkh65p;=$G0JVoTUIp}*XA@xR$+VxsiiSogs796M&W;93IIE~@2LS96+z8J+s15Yv z22L~hkd3>;5rm$!STHuB{>Dp?lOXL712u_^w5K-2|6GjLKwGVM20L0|To8&>AFXfL za*7-aqK2afunn2sT7W0&VzH<)eKmee9I#>ye9G}O8r=s-$vMfWOOmgO2#)z{t1TMh z8!86I6YeNDI^|ZMXT8l#Pq%=yxL1X&r9j|RO#_s!N)H7I%wp#}P^SDOqd<)Y2aB~Z z%(vHK>ACM;g&8K)Oa;UEtlv>XkZw`k!}B^Oy){^A?8*$h=GVJZz)^Mgk7-)YWN%f{ z;rU0YbxUQDQNho=mr|8UYz3NUPB1F}-^+^w)LrrfbjZa;fkIq9Ggal^S>qz#nD*KT zLLf(&14Q%LXNn-z?@;5_G-HfKL#34efl8#42k?n>=oDV9oBLakiZ$yZBj{Ty!B&y( zn=}yVUsP!HNr9U#yRx~&M~e%RkQG!=ebV1yTatb@|^IbYi_Kyc&O~W@{w7$ z`wM#sr?DMr9v3<^)K{edMnkxzq5wEMqo*N2!plWh2AZgh1X0SN#@Z;=^r!^UCSN^K z3@6i^`MENQ?qxDeGpl;BOrzab8*nI%YO=CCuCC>k~D^ zE#pY!zxD!A<#q9b3gN66!o(B_ISs`yCDU4n;Y4z~nIk}@*Hsm6XtM7OGUZB~Am3HL zAcPRSCkFb%Waj)82_E~7W9oOB=>mgPtyS9 zxIqs9H@Snzf%QaL7=&xIT;ZeA)g+KIr+x>HrK#S`;H8rP9xKy}{*sDxl*6B=QL^)_ z!wW%k4qe}=y5doXiAvf$U=9~uSFC|2X(iz2>4%s4CiwP3-y>&)YnSZnN_M|ZLvy>c zTBsbWy23%daCt$1$Vnn|qfD9Xz_CrAcUnVceh|X2CX%Ya<%-5(R!)-wF&R-hLR4P8 z7ZOcg!<@|0{l!RP8KH;Oex@=!406!H)Z&XcIIjOmi;i-nwV(zv&8g0czd5%Irq0#+ z4Mc+?HGDOjDxgEHpDaWGbKfi=R`|r91~2g+>)|Bb%782QzrMy04LdTC*Z`>UZ`Wo9 zxT&Qkz$`g^I!W?^NaPBvtvDAhQP@y^^)+7Q4_+wQPirfpu>5m<)a7XmX333coogl= z9tw!Ma(6O8ZxvY!)lvH)P4@SL?n+pf(%=XJ_tTIga3qcBhr5it2YL%1pDqMob9V2I zeRG2wiuy`qaZ_wmp7f`~NP}DIp_hwXRy1}Z++ET0DTMte4m`1Fp*BpVi`D}CD%wn| zVyBj7B?n#>hY)p05_HfCK@HhR^>aAD7I${W_qoV8kya(%o;bm*4}y$N1yg3j4|aVW zBfZ^MwNA>-Y=x!D{SU*Q@zg=Sv;>8HAmzqAEC3CkYL=-Z<3@-!fl$``Ew2fFozzf> zsVRB_I%Mh(e+xb?dpaqwjPX|-5yH*u5hK$l2s)(PBxG2uME(q(3+~7dpdSCE0*EcL z`wSlM|25*U!wImRnc#BQBF3{N(?pu- z#iEX6Mu7oZ%(g$V3~A(6tqvz%PH-VBWWgQSb$v?!3R|t`f-#Y1FVbp5lx`aj&Y&t4 zT?VRK`6)m-c1b-UQWYgp8x$Ja_f>tSFQrE`1`cU3V+}fLt*jCBJi3Y&h;}78oG7Y! z;yougtJ3uQH6f3pL%J0P8Lbr2-aii%Jn{6v^>u82Zqx6QaL(6*#r8*%O1A+J1i~NNPIe@XU{Wce(Cjwv~80GfVT`9BhUg%+e@T z|6Br_Fg}XIZAT2hEJPA$yB%S{sigag&f@=96UqxdLn zTcW>{ZzLU%yatX^?zF*&h-(_w>rDKT8CsIv1F;#NIL83(vfoBSl+vnwp{@AsXF(64 zM=Jnd6l#iG67jbZ?MU!0BWR$MmkGnncCUipCT;YI6BQ2^2Yu zP7aX;XN4j>Zs!Hj2+`an6AlMGtMc^>FxcQy8o&}H2h_%j%)hkOny6>WcdQvj`ldBt z2hs*-sfs)Y!cw26x}xYK^mHN#2Y{Ap%^|EQG`)sHqH@6ii<8>EJ!V0KDYKY0)(Zd9 z!eT{B8Jjjn^}&OHiY_mnvG8z3Aq0)O$1lZJ*vz89L3W%g1|Km_Jj3Fkvu@R3ra}sL z$WTOW?u!;5o!|CHRM%b3eY`uPh+6wv1uKaC>JkOA>}!c$pyaN3SP*xnjw41?`^9h{ z>fRKO^?Riz3KtF5NiGJK|H1m~hs!i82~%$K=h%||$u79e`aMQ>QZlPsK@|G^O#{9% zZ?yuV|8ROKQaD3}IAtmP);OO=0e9)WeB?eH?=-U*no2GZ)izA6lZ)dPmRhxd; zpYPx;Z8mka<8c$Szoh~KqUr$vihfoEQc-<70K4+7xuun&=)b@#?$!n@KU(8g@L1gik?T&a zm%ha(lIf*rRFPRX1s_V&_Qyk<$ZviTG!)rSm-4-&^@n1x?D-pVC34$j!O4$K6=2wM zQ!eL9T)rq7k#aB;pL@brSjXew^E-_6f0~F#n$G$Gbx-?>cnzL{#3+EyyMAb3lgsE(b8wTsw$Fa9fsW>j4vKndk;3?{1#qr<`uFm|l%E zpCCk0FTQBMh!Q17d^>oLuI3xC7}VWUHEPoog1H)vKAQpoEd90v&u|wuDsa)r*-Zwt z*KqU&1LK{ zpTs-SmtC~iAd&ro3taT~jsy|>G9u1%Ag}}zbzhU+Hy`pC!<>YURjWj$OeU_EP zoFl?%Ca<|sswaB%XM;JI&I^&6ltZa^3`c;A2il{wN_2N%B?+!%qFV}nwfQ^_ntR(8 zV7xIPEuFrc&=?ivz73+>hluzL8O555%P*FlM(_TCO#E^sb>gkWHj^F7u0Clt^5qT#&MTW{8cCjH03VW@ ziA9ZxM~R)P{+Agh3n21SNP3$z4b}!(z_Z@zP1=I7a+N#~MsoQyFV_fd5|DU23Ng>| zck ziCG=*9UjQa!zIu}dx_DusFD3GUm_zjaND9h*4RN_-2!KzKW0I?#DnB$11eYMA&C7N za1YYFD|F8TrvSw=C3tavE>IXW|Naj_7p`V*h+5xP1-FnQIQEDGQH$B%;J&ssqOle^ zIT?X-G|G+YxNx%5NRpO`v;tWiOjF^#sV8Z)Qwx}G6uFi_vCCRBP?~;#QE9MGPa{^d%K2Iq``8_^ zCwWU|i0sb9|NO?ZC>~i@1UzP$q+DFxVw{v*`83Bm^}0}$Aw)pAvLC1VZO>d(R-i74 z_!|M^xT?7^LPw@~Q4f)*=H`m(+JyV|G)%lk5EZtWF#Z82eHRkBlMCL|HeQDT5uh*i zyR;B7#{mmW1wy(OJ^n5tqD))}r}l=q-ho;0((pFSs5LI_1!PtI(~ha3@()^Qd&D*8W}#hsZ%#QG{ms7cG8x3Op7# zWQ9u#H&P>d0+jx}U$eNe=bTg$fZ;I35~G@%dPtvLx7Y&yxLyK^4%GqY@=rhyR&+vK zRtM@$AbA}`u6)pmpky5~8+Ql# zg51Q5S8iY50uNaGY}NzFb!{(eKBAicjY3Z~V@F|K&X+?Vc%;1qW_I9ZZv(o#8M=X; ztIvPT$8Y=w|26N<1_O)UE-S<+nxSrIAt3p?(FQyE7M2%m6{xYtXM(Fb4U8`kYzT53 zIj*(S+nV!+2;H~(I7FPvbBKwI4Yw3FYWmO=kKHz*A+thK_Pj9oX*e@g5$3q8@9S)=H(EO9e&5e@Qg= z2S+^5wEtfpe4QU8|2$+)F-_SuSe5F=7c7J= z|Mz8aj7sU38RviN!~hf-$`G*m$-z<&nI}Lhd@={@$Ma)>38~o~fM-3@a6sX1&qTyQ zjE7hNMAL6F)FIE;>$Ta$_ivh=aAQOhbou)Yg(wWA-8WgdK6~0-M-dH|?JDXL$fa7q z8BT61sE`(S=M%unJi-g{p0yqAl#CWJJdl__5v>r1KYeAv%2ppf9pzppdzO%T^-8^D z?Sg#px*+?t{9A2C{@j!|#o1IIg2)lLo^DM^gm^Tf8%DQWKOO>c7IQXfTAj0i8-_Mm zWQwk6g0U;edOAC(7dr)6ptkH67C%|3K+jTY^W=kP=nL&Q75V8_M--Lr6SNYQ?|`VF zG5_(oMTdw@WpMcsn`aw9@nXj5VJVoFtqpRw0=!RT}fti#9Ym_1?I6`!H z!{{2(A5U)mQKF}_PT`A5ba1Vkzz(_QBZrEfjHDHSpw8D*fRb~pxkj?|E3J*k3AfcSP$a zM81q-Y53G@S=@A=VXkP?kmhDBC@(I>088ii62XU1Sl$hXp85|y1PhkBzrmIe$A^E0 z+&>~jQ)rExGvM%nrqFLZ$tt)~e1DZ#Tr`@r#S*5@l8u0`EwDidq|nw{wP1&a_(dhH zjRs;GsLhSqe9xe{Uzt`!&Wy8UBM5c@AD9#W#^!a4%cQBvs-X~`(O_qXoj!b6+o7R{ z8{YvbW}o4TIjY%sL*b#Oo}C1_Hl1Ja6X>9CnF#*vZ_Q@2om+7iKygK@TFg}K`?NrV ze4AJ?;6HK_?(hHMwZlWZD{FyPT#N1kht&%Y2~I85bZ@9Iqq*{Q76~*@t^w;O>3W#0 z=*cvNlfF(li%;rSDTBe=RMYKiEv2T0Yz&%z`=b&M41(_XYJzngbII+#y+jc~$G2Z` zfD;Do7m(<$tKV4>q|WSZj5RHNT>!K6-Y7gTJ3XerDUTUl05m#Pz92;JHP8W`uS@p= z=H`19wLoVLf}8R5$*BJ^mz?S_Q=t7QglhzvBFujBce_#&0YI~mG(l8lM4+4$tO~7I zwZVZ1*s19jaJ}pGEFiCHdvE}px4IC6Ci;0wNer51F=JwqeI;ajqsDBO&(IQVRsQ8X zvi&fZK@6*?v^-OhO=ES}0FLsrVfkL-i5K0J%y@zGkgxPFM2vDaOWu~VvH>jl+k2$} z^0X1Q%q_0OqF0SXJ6w>nCg7AfJ#2VTXWz+yp})$_0-*DW*;pvoKZ$v#-ZxjokRyH* z2P7Scun@D{Y*Dcqek9gU*Yg)wh>FkU1$av0N&v)vVSv_z(y1#7Jy56}BaSl&oFbWF z`Foawtna8z2PfPBbmrWhgBg>4=miaz_n0oU0#8VJHQod||-E)A$IFZrziNgvIVbt{N86MUKD z*0XU8mw$(HN;qVttfv0QgMqoyq-|iv=tGZ9J(&m8=cZINK+L{-$(Ax=ILpk@zZP{$ za(^H`09?Mxyd8(y`Ceg9KCROQ!ifdT0c zKZh8t_(6~;+5#L*ixA;?noJH&1(>&PwjkcICRtueD)md#6Wg3*eaL1>`QiW1}nNq^RS^WCqb!gy76P1%ySM4&Me_~ znDPh47>YopZ$!&|#BuBY65K%JTC=nfY8=!<>jXDNcR5O)ToPjfDL)jqJCh5S zBWF7a((`Y)Y{-VIf4XQ@(S(v-sp*IxB-``3mdTpV#C;7+&cF4)G*~5~R)=8OV+Bwu zLsCSk^vi18C0wR;ZaP_0%5LJ{>fnG)RMb}_s|mw<=XTLYiR)LG6n{Iwj<~Q=FrzMI zNGbICC$k+fwm1j8EG-jQQ%Tp~eTu`BJO2u6_kVvPKSrl*92f_XMf!&e=mENsFmB;;<}p;O6ks^Aw{D;)4i&VM4PL6G0N@P;$1h4ePC2=2yf;kV0& z9rfuM_W9t3A4^|<{EPu~c=KEjKlsI}F;Ad{zwA;L^qP=4jgCfP+f@dXH$WfXvLIaXj~= zU1dcPHzwJPf`u30i<&m|9004PwHQqzPyPTS3r`vX$4mGt(P|~!V^O~vp`#Z0QPRl3 zOpNRYHCYQO#E5{B@^Cg`mE}Taw;&-2z65c80jQ!wLb01j--_9tscl?GR<|1*wgvPl zStpkmslV-I(4+oW3rFPJqE$!3b84_gS=`O->`>hG#jrqbC~`ScH!;&l?zPP|lF4cT zwv@j#uFy=HG%W_szBUOQQgD`@F2D{)4E^Xa-gnZXf-|Z+qJ#q%YC)LChG>IS(_#|q zI4}R#A>T~YJq+N7J4cp;>1Fqi%LowK34`p0Lg zNK3U~Ye`KBNC-j5&6{j-(s1K_*owKbNdYnN$7x`6`p63c5)I{}@fswZct2KxkGp8G zQ}c>L7CX;PI?xnB0XeJ)Q9APsv%>U~^uRykFhT359y_adjAm9>*n##9U@b4&dfG@@ z{o()_*qyb(RX%4DeXYrgpV(9d zuHGi>o%;hX;cKDXjbo~A5dYm4u zhdLs+==BAy5ndW?W{9&Ts|FJLa3J;Jn~){a1_WY362S#=5-{k0f@v6y?$v3-=r2 z+%5N#OFYaVM($=Ly#VMoMTCMF&K0F3lKnXdb@5FMKeLGHYQ+4|hcQzN$M~ciU?-m$TC4$iJ{F5oN$OB0b0=MLa8wQtVTjUu9zy(oZ!GZ=shOxo zkhjud(Mn0p{@4ijMNgI!EFW$akLgYC3xeoP`aR%Kyf5BHYh14vhvn>0GOw$SD$=Rc zs-?nBrGeG8QS^yZTW~7%@+>mS35I?&Fn65+D>Anq#dh(_?*=U4_ft?GJ(*#Hk7|~` zfCSN~PdT7aMrSB|th%rO3ylAn&8ARY>xH>IMA{-6lSsIu7=rF|w+u@Rkv=P@&`^!{ zRXkjF8r(zj>|hOq{e496h|_!Ht>m}KnSQcY1^yb&InIPwz4Z{7^0=?HDm0dVk!B{F z*u%N7D>p!-dKN2mqeL;gDv?V?%@Be6nZzWx#rFhCuXDl9~StxRY2xbQsEhg3-$hjK7g$>Tq zJj#q=;wxI-n(K?2YJ~eVIix0S_MjE&u4MaCQe!8uWnWjE6S6YH*(9RZ+f?wU5%tOuOw|$s3E&5!=bYMk?5;Hy0(GUqdvwI6ID1DuD)BzIy2W< zlt!`2nHU7V|49K(MLzBTbd05iz~pW5>D=*TJx@MC6WMsuyX|QYnbN652bos@FWtUg zY3W20#g=9J=n^#w>oOb~D)&Lu6*^^$F(tr(lxUF)tCHCuAwv|KD^_aw27 zr#TXMnHePM{{mZOpSjRSrXPj)ln;LFDtO>Uu94{8p7s*=B~Yn#V<{Xe#mOd~TOhi( zkPhY30z}2wr|Wwx!M_bpmvy-^QC$Kv=RBf}zIPjNw3?2qSn{VT7c3mp%4X2Ks|W4aE>=8&HBDPuHK^z_LBoU-z>fVb%|C1zi=C z5=o5OuUVMJ>#Wxg_ExM9YcFei5E8Ph&=Xn{^FOF+NP@Wrb&cHhQKN#k0aP(R2fy?a zUoil*S&Si-dPn)CgZ@6G-2RnO<@YJ==LA*8)1yV0T|JfZA+9 zF~oZFIa&az?$FatxW-GugqxKdG7@7;Z3Jc59e|m2M~GG!TU9fW)wa7BmgS2SIAwU* z_MmGVj-%#6Asgk{f4@O=$#+)FhSzNSYbep_4by@|Cn>x{o*<@=hv|2v#7#X#%S(z- zWcvyz=Ks4fz{I(-9d^KPZ@!6yf6B#L0)+*X^!kBiA8>E8Ki1aWY!8kt1+PGA_*e90 zMG*cbp;8|?&{Om%Nu(p3${5cza-0GomQbOU3!o~NdRp?V^hA@!O6{bZ29^&lSNWDT zYoT49u}W6&%Fe8bvF!&3o20THf9g7pCS*--4F^R^aaJPDl4_aW&` z%7Dtm`V^u=p^Wcs{HoN=^%bcI|HDWF4)vazy^afh%wU`y671NJ{6oHuc!r8{Crmvr zbdd+gz=3TuvCD8phs+Xx^WBI?8H_X*iUNeveUbK}+b*nxbk+6j2+A_P_zAC`QH&jM zySFpkm@cp$J9rN0_Q&OX&yoNV8jvEXDkn)4(gu;W`!<_4d5&!0-0#W`zOV zt{%A>YP!)ZH5>NevO+yc?86T6lY7{==UHEao_Zct1}KPm=0}p)Sj2L^%sZB+d5Ni} z)!9(Q?B50D3y*e7JR83xv`-Mx_z?DT>X&vcw%Ip$$ zF5$ut1}AlW-9%7VgGWYCz{HqW#KNSmyied_3192&KmepsMV2LO&-)$!_k=$I3Cd+l z;5&rb;q6CN4KNIz>f1inN;LeN6&%R@<4%i;j?kC|^mEeua9^-u;?*(P0Z4H*Ex^|n z&I0W3Vgc?ERET;67AhXn>QSz>OR!^BTK9=s0NB4DR1^-0l8H((YcVU2Yyp`mMM|&% z^K2y)p!7g7SVwxn6{wui`>4oGq-GsbIau`Zw2`Q*31+m+IlUC;=xHDp&7qz(7G^9g ze~ zT2RP!sIG(?l5DR<9-PiKk>A^XZ2QvWpv45$a)iN2E6Uq11~2 zS+XyIb0(^|NyUJsw2nC(TF!wr8NC1|uI~vsRBl(X9)73xOmGGED?(J>n35SKTiPqE z)F0mu(23NPjswS_`>n+;Xuc5IFh z5?AGTR8zp(q?}r#ErRjbu{eZ8_TR-w0@raPw(Ff1mT4o5V%BQ(V@-Oi+F%B$=Lc#hb-bq?6gmMTLkKn7^ zP>kZWmHzM(n z58No0DA(|Gnu$DQLV59^G#$4-**}%E`5Sa84<5`;5z4QUu3|s2>D({S;t{%2ZOQA@hF1@!mt4 zNj&jr z?Fep+Qn+EZV*Dl!fcp!09sW-Ap;K^Blqmd*xya&a2tY``z6FV8H_;TsYC1Ew#7U+s zWMfw3P#@5e#><%KuFVhGXh^Fx6mMQCrU>TR^slq~gpiJwzi>$?>Ow0m94FX2(dRW2 z1y38~B-n*O8~R~tMWua|N;(@`i;+ILG-7I|j11@fkB+oax<{a$+qOpRz5G*iJ6dB& zKOLT+(9pls56~@&%l?3_PtB?RX`I1Jt+{OlKgxuL9~Qz8#^1~mFo}g89BuGZo%=Vz z)sk*3N@P8z77V{6SPe9BZI;q%;AQ`#n}R)!wk$q{b&sx!`KK9l>6*4eAcH659n0Br zdtW1dw)m15sz<^nMcqE?`EOE*ooKEJ9x2Q9s7A5aiQ{(tlONCY|FpH$aedOD&k8lJmtD)QC*x}MW-Mf%Z%h7XVoID&M=rcg!CU9*^huZjY?^RF zor-&y@FlMEkp9?YpziKBXcuQ%-rxf3^Hb}`)q?#qKEe9m zkqj@LpL9VP>CDUJO(T@qmPYd4rWY>YzWz$(t|?<#D!ED3AAjGhr+@zMpfZr9`dL`u z)TGLE(%3e*@zuF=GjOS$y3Chq;~Vr^GbYu_2QL@?g{N)oTIYYbtlzqaEkQcpr@Jz{ zhl-n?_wU&_nbzTaO237d`u}QX^Uf}Bny-{c@lwLCT?KUyI(U*zn1SWDYE5yf{z}=rlC!F$Md>>p zDK+Eh;cdBioWFx}6>8DAfgc6|%%1woMnBHTrdOL)ilZv|)!dg)QYG5^b)hmF-q_l! zy9xRpbjEkr9NAPe{}437x~)}c0858vIVrU+N=5fIa*05LUz485Y5-CFY}IKugz(YlUzFOqMW%p^qQTTDat&&CpW%V`Uo@ z^pZN~g;+P*Jo6|_y31StP?-5A)61<%Rny*!d2sP_y%o57nOzkzn~alU!}g1O4iT3c|Rw}Hy{4p!wd}fs4|?<+H=>mRG%umf$RA+HAu^Etc)|#Y%6mU z3c*Ix_&C~V_@EwF+T)DdAFg;4dwgSQJ2{T(8;v|$z9Z;oX{$evN_lR&WveI0uj-um z@NAbHKV5aKCw^(Vb1Ra7Ult`!1rJbZmM;7x9(P}T?Tf@5pRvXaMMeBmv-e^Ok8Ado z8aw0ED*v7?-IO^2dO7vKVl^G?AEAxW(DD&lHT|#2L_<1l{~`@6aQD)eAOv~l!(|y( z-e0$s9-H=b=+_n(Y3A5qhLbmCmIY3moV~Akl5qD%6|%cm!F5U>8WG}bbX`hQhlW1> zB9^D-xs>~-gkV!TU_^TddM(W!rldW2e{HiZN5}ie49jMR{#x3j^p1z@diDPe3ZMlT zRS1*aVXkv&vKeP0&3#@H!9>`UkJ%=f>kvC6Qe{D7XcVnfaP2?PdZqIK&`_>h6Zv4ReFK{PF`IT;+!k>rII z73EuZ0wl&{PtxjXn@h#1pqEC|UkS1LbbIbyOqshFw{_v>Fu$d9WIAqm`^i2DmxMFM zd7C5rqHFNRv zVDMaXNaLZ6e#21m^FOqB9GA|U!pA4#U)=OPk}_=J<%i}Sd2U|5Uy0EIS6$OJ)y(@Z zZF-}OPT=Lwk7RCkVTgiarZPH~=jif%d0xQt_*^!T;2#)(@kGCj1(Od|7bEe+z6Www zx*QdPHEHu;q7djn_tZg$m`pmU`xjb?s@h+KSZsEuw*%w!x*P+^?zq@3L*`}m%3bKV z#&Ob2QL08J$$|;4EZ!bEM$uY}%wPF)_(NrOA9_PqUl|$8OYMe!mE%}2~*Nd}6sQ1oJ0oF%A^Ar38 zDn#GZm1%V2Kgwu)BX7C19D-wwTuEyTT5zxLzojhRdK16K2zTCB$$1n&($^ZZGec_R z{7s&(z&~y4x`x0T<)4OKP@3X-?u$kDER-Kf+8@m@Q&sk2r4-N0B}*2ua)op47g+SP z>z+s8+;Rg&OGP>z+_jV7Z@|kdD#>x_G`#F3%U$F2r^TR1Qj^(WMRQS?*_*Ar=gTFR zlrrVRC8wL=t)@-Qk*O+PzJ4kbYtr;5z8sJ0*4giKD(ArntUM0uNa5L)Ab)N!^KO{b!+hmdCivtaPey| zwm6o}d&;*w7#Bpp(fzNKu>@YTX|zWXp)S41WKQGFY@+4u+-es1di~$!IN|)e^h)8P zS!3h1GHtT1NTDM~E{MSdGT^=Fsz8iAlhHDIP!*-QBJZE2?3!WY{qphW$8gkdkFAKa zp+oGH4D3BDEdP&jo5boh;#|DPw!c2)EjPTykc=Q7oN)MyJXsYLzWMIGQZ14?W0qRO#bV; zdb|WTQN16&_7$#r-AeAY(n{$(%a5sH-Zkut9&EYXrl{6Sb^nZH=~N!q0c5Ak9g}tA zS?t4Jn~VqxUJd>$Ky&q!TL(5p0Vt|dy({)4fjRGa&i)=gK>Vq_M*)Cv#hc0bP+ zf<4fX;H^lj5OYN2z9Q4^iCjhE-J1to8r#ajPHO6>ISf(e{5vf}#Y@%n!3;0&`eJld zFluwj?Z=8J{q^?y47Dn{XtDn0ZS)S_)*`$&)E{>^i*GqpKdFZa6*Y`S70R9^8GP*wg_h5f!A61@}?pks0u8(*B z*Xtnm;Qef75(8w1iF`y49}K&fZma%9pb#ayzb@dyJjkV zprU^gl@@3|_L`npBG4+-I_ka=H~tJ_nsD?doa%?;oDE`1Ep-LlPiGg+W@d_;zJns7^K9CD| z-B2N2O?3|~LQF}s-xNV@u|7*NgsG$&1Vv_71HUr8B7dUeu<%_MxK58FSm~3T1+#GR zEO=c-DJN#NtNTY$Lu@O5+SXWeT)%35avqMPG&1IDGbNlI16Dmj21%pW$ND8!!oTI8 zUc6x0z>CvozSwNz*XxHeVP$-_?MqzrT-boi>wlKd+w4|Fhc5o+pNt~9Twf0;=9{Tz z8m4M_>(l?{VV3-i%E}PsxnI@|12CgKI*!k?@xHU&;_!RUcyAU<7izJd2sRa+FuEC7 z5tn@9U%?qq_kQ^fdgqao2f*V!rZpMN9EjbRJpk07uB?{~T_v~d6`N8xYC`#r$1@q&hYW`lTt@9`IF@P{R>2)ZvYLo0xVpluq}A0^4A-Ml>V1WVGb2z-58oMD5Tr>H#tShW zO&$6udO(WeQNdn%@RM~IhCn) zW0!y55*PoH^38FHOfM~?G*;jjzp2ker&KiJ1k*oqzHMC-xS8JT!vFFx$nehZeQ>+% z)z_clJ8t#FPjTU#FY5@A%5+MX&lO=hdiW=JT|ManVEbeiQ^z_S=ncd?_Klj&ADDD) zJkztPetxQ0qOCsL78geHnHxbXI<`Ya)_Y}CjVo;0_2`kl%@70*en?4_3@azNSM&1h z&fTD{%(>AEw@bbM8h=+hCn%#T0AAA$EJ#*XTmZ2%z}X>A;^mbUepcAY>-J*s3+mj0 zkX!;)$S;JVe(ughj? zqtFGW!)g9XV#NYm!*}4$eN;_lkm&g(J#k>O?k*P8l-l_%CFyk0q5q&^7X3RD9QpZ4 zJN`azPQXn&PihnAzM`6c?;HGldDah&m2QFO*7mFfN$1;lA4(E8wC*wkM|Hz;StFrmiypxajLd(- zvKEj3;Kqi^PUr!VNwVHHg60yNGk800ziV1}Wt^M0*Sc^l&xe&y?Tin*+%5NsGLp!* zociNAyiMT8e^7eyv=gSQkZJkH)LIj5Hn1vC;YhDCc>U$7p6NOA`Tsto0*^O(ztR@b zhh<-;8hP_Osli<{Z?4kq&0QO0e*Y4sE}oY%A9$6~1YWjo>dD^A6{O#B(*AN~?%WOV z-1wG@OYHQPK3_0ZqLFelSkI)DH3|eHrA6Jl+%;n4`_FAyX2GPp z)zdPco(8tqO&wTdlI}-=Vk))IOu!NM{qCYd&0k()@Z`zp^ji~OlN#wupj^E=hSjJz z$@6w=oCX}w2qjEkw)46;70oIOt4*N2m*})Ay8CSzg`I9MJKy4=+*h;Mtl2H~MO8Jj z^%U#QpL8m}z)8;?i3i;_n(;{iVxl9yb%f~Qt)mrD@?@E4UP}ibH)+8&mwj8TCn;S- zkjBM7PvLNMRjwE`x$eKX^> z!biMi#iBuU(Cf7p6?KkPz|A}JMmSH03FFOe*m1kmd$>h)7gJ}r-Sz**>ByD0egm&a z@%R^~l<-7ptM)y zJufa`m}~{!lk|I`Qm(*&?3=cwP>74jT<$B8(nB_4=!<&87Qu=OvgTM26U^@ zu)M)WHOHT75k^`+o*mjJXrWsNS)4!&%n3X-Lky_M?66?2OT$aL3W#h!+Rs zhpV$^TLIEiW_|;+Pu_P(z=~gfdO6j}bE{|_CQsyJK6^=keED6Wk95u#G&wvc_ef<~ zyQbPdvk5HLma_o_^Uftgqy{zTFB2fq0vk69o>XGKlpH7|g*!i*cD`r^B)Scaf*?^J z=@BlZQx@%4AYXlIM4L@-9jk_u-By1N79LslfsJo`CUaUpT|51$BS?QAF%7iKNz?TP zH#L6I2{-ZXaRN|HnkE@MG^OPSZG`GC|{2EB4c#Z*>4q+v3@HM$*8%WBBQJ z^ZtvoqKW#ItL*aInrF(Oz{@>`J=EH1gKy>mc^Cb8pYiXjcXs1fD@IMhak|P>#oy;M z6Y)Ad`cY~v?qx{zs-zFM=3UOw(=ijaDqWCT^Amn7;AnWvKGqe*S-%WZ@~^cS#M1C7~<*VdVuv`)0G zr*P34iyRI#N&00Ja4Y)i58OZSiv_r4THg;R5nk93)jK0Lh@P&P@Ea`#Z@SnMNk~!5 z;QEoq{8)!4={4lDH! z_{-s>{)Y7hM0L;ow*yF-Ubh#PV-yAy+vp!1+{IqnJ9lP55uI6g7=G|{Dn?u<&}~C^ z0uB#qT+#yDbkmF7^kO&#pl#4~D%L>%zKXk&6`$hoxd*!ANFF73FE&$OtehoElSlL~ zaM9)Weq+34#JWC~0QF^7#kMQG8I30o7#F9EL4&N(jo>F&y1YLo@m#(B?O=QG{;T1{ z98M)~{=$AfE=FfqYCuA9U#9P7msW=>z=Gn&)eb4stMi=c>(vET5{?stlX&=o9{T^^F80Qk0y?HAN?y)f@5G@k^*&o#H!*TeDm)( zqqg$mMDuk}S4d-7m6!!5y_p%mnJ+ib^zr7xhtEUvpt2TOEa(J2*y34yMl$a%QT90_ z)Qvza&1r0Xx2Lyi$jRVY4$l zU{II+#&dg`oQbT-$?<4v_%;IEv=du^emGaZ0!PTLm0M+2+SJ|0(n_}bQHG^6^F4H0 zw3If=>fn$(c?*y&YuE~-T^jdV>8e3FGhTSC6mxu>#!XYwALoXsYI8?Y7SC0?utjE- zUfid2^3qP5l-4~|t%7I(DQNxoShTTu)Z&zQ@D93?Ng>dg(snTAT+2`0veY(etvQjA z1%`O3GDXXaM_;tW`_4v9z=JvK-N)5BX}-})iGP=uWzoV4KQvk@AFD9Bs8eSrlTB=@ zCW<`V8{f?glIh0^2hiQ|wm!#o0}j@&V+^^MNf)yV+fl1(o8F>Iz#G_^y{xWNS#T zozFs3{USo9HPWfuEPiZ<##jb_Wu?`CXhpkH6(v33R%)wD8~0Zt(dfm73YP}SzLv0> ztLq!X3_UJgnOt5PGfb(IOGkz~RAe7CF;`Cm|0u8o`L07V4gos-R;H@mJeOiD&Ww)R z&W_Rqsb2Y2Se?!5S&BY$$sNp(M0N0r!c>tWKQ|1~0pn#}xQqP|yWKMpXrMp+6lcqV~V?f5n{bf#R$+608HMRQtoXkx(A}0d+ zC#H=w#?S)OMx&g1-1ys~qb-{`hmY!a|Hq-D9y%{Z@<@!5U;(R_>Xz%Jjqk=}xM3X` z_(_Q8dHwc^t|Tq53VbpO<}kUc!KS|-3&~1KADfzx%?CR~PGiTG+cqqOukHnzse-!< z^bgIgf-90Yclv!p&@JQr-}c=XTw(G+jsA{Lg1kJHt;bY1-d+dC(+;UtXz^Nj!kCsypT9}`@lVKz$r=e2D?pkvw`W!W#{niU1Ad81Zk zx+tP~QMBzYXUL6_#z!gT?J4KnQ)nPnQA$@d?VMRh6326Y=01~v`&_?IB{q_oY$QB^$u{0RQfwc5K~#L$g4#<*)}X_!Jwts z9dW@gSXTL|$&O^H6){kCpokkaNGJf!8B=Z!Ly!;cC3)l@oU2T$MqfY1K~c!-t95^! z65{=vHYaCt)GfUbBX{k7&ISrrc^HpFBCT$9T;)Zdd32Qgt15P+saYKm-&Vuh!h~OQ z83ra!>i3VsPdP6S!d%CFLnDgGo&8PBz?>u|vr=rFDYty*h15~~bmZ)zYkmzb!86 zP|ajf(W5wxC5|p%jKjpU^8d9!aOD#4eAutKKp)XR@%MjXhx%VNi%`G&hH1z2x8|J@ z{1{>B-%a7X!24g0-i*JWx)H{3X3+JwfYhGE(Xu$|I`^FnR<#2$5CY2DWfmWGyC<~- zsJ*fb*oj^zIx)pie*awtKhM?dp_Ro@-X{3g6{C-9s(bv>hI(bPKxr9LV*#bfpL_h2 zcKm{cqjU2U)FN2NlSampiO0PilVadU+)!yNA$?ZNqespR6AKVf4Vvn3llzi~Wx!E2 zV(xl9|73w=|9p7_>T=`OML(_lFnqCIdfW>Qr^-@N221nyM_^EVgEwg6q?`0gd4LAi z>Va5pc)+5-DJ?Lb&ds9Kk&%FHLo2IDm(y+)uKf33kCS<^|HQtGTdaH`im|=+IbRsO z#)&5Ag~aT@aOiKv(v?Ga=%4KJ;1zu^{d!Uw&jr#-uwb4;5qpeYDtI9^rjhF#L%C(Y zMNJ%ivQ-k`9m+jAd0!C0W8E4cGO6y}(ApXoBEmn&vT10i&l)fFDb`OGB3YZN1})FU z9D0ZrTASA5TKCKij|fk)ni@0Y0o%nalwMTmqp09{M`M~aI9QpzkU|j;6?urCk81%; z4umQz(v+m>-}1jGqxaJiOuYCh^*Q!8_w;|?67;-SqkVU@tlq~9aae{9OIl+eaNoXv zv|t4;)&?T_4>%lY($EbhH=CkAL@TlhkwZTL-n`Kj*#aGETul*FQk$6)pviFVBV>d8 zLdv{dlvBGs^FicKZefgFa@=u1IId_auGZSkSW@!DNflDuyjTTZjmgxF>&lSz;}{u+ zQ)lu^nU5y4yukFx-s^QhX1HOsR>NuDUq|UZLu=X+l(+t>?N158646}m4(skf@9%%u zC|%H%fTiZ(V27T%9lC9V9QgMjiH_%d!#*g2VPuo<)R;(|@&qN$q^eI!=T1JYO7o-y zIasIS4iniAc2vmgNwss7wvp7L(|nd&zF+iKwO!8bUT57W(NRZ98zV;zhZSP!E^Iqe zED+ZEY|Bj}Mbt*4jzW8yCq(cf(}wzZ{}$UpLl*DnG89P>yuNin0=lAq{?-T-@{bz3 zlu@<%8m%##UKw(MPh8^si(m?^SNmv^DLmc;u!K_g!>dI)u%c3bn@ld2$@Ao-uG2uK9o5OR(|c<$?7Kz@SSl|3VAFF$o%ubWb%Foiy)`GH)pr z`1&JQl)fqRnov+Y0pyg=UWJeqC&JC@(-K*_1!k<8ehrETopE4ep9iO~jCPlpuYu^* zGSLCKeyRte>cz%N?|J%l{V=%N%9J6Pi^KXldX*#%5wyh}z?1u_GmQcIHt!0kJlE$= zM<3<1eF_8;S3dvuv7Pt-+4&yZ&oer9hH6QibYlw$p1;qjS&v=3K6_ImLpHBJ5p|ud z#`V-KNdeT~sjdu`BmSpL=9UhZE6uw}RktNeh;#|3wG|<8_uhgW<|~-)A?x^KO98n* zCU~+bu>GLIj5L?|Lljw2$cXnhQ`@<;pA~W7csoZZvP+P@N?(PkDFp+}-%k2<1eg$M z|0QZ4^tw`)+RJlSr^Kn{yg2gP9Z4R~tqDfry=H5&7}&cfH3l-6J583wBc630HXpYt z#^R(NZl^q02FXmg- z3E1}GQ;E^!#45?`(E2s@E{L0GayCecM=tH$y$TV|cenO~A%fF$-bl*&$Btf~kvRiU z_!ZwG7fQE(VsZS`dLIQ8ydUb1opR&JV?hN8llxi;1gz|E zw_bf_#6jQsg9fZd^_L!0cCi@18OM!%s#fuw_uN3773NF7JV8X)Cuopt`E6mA(EY^9 zR%#c|t(x7F!TG(iE#OpPpbuB=kg5WXB<}OBt+D{gx*fx&6?3bU1JMn(Sfoiq3cv-K zZd7fofR{yKwnC*NcPS)VflX)!lR_}6AI(y<#Fflq=@vpybRcGv{~(8t5~r5Vw32oc z!cU;{xKx5w*?jm%0hk^e#=MRGN$vI4Vnvq{$VI!J@}sWPhqz1mY;0yN*;^^qaS zi@$fbRinY$*>xCxFDpMJm!slaok@8l8m}Qerg~9vMl4Th6wt-{*ICms+nkj9>LAic zPe%nv-oNnujuiC1|7jzM75=*2j9`?0-rXjN=fw|AHwh@;Bi1Q~;E!fM6rpgQ8+qb3 zU}&CxkfE>c5wg{RnHkD*-udgf9YIQ~Ciifp9X}XL>QamYzWA31Kt|)PC4)?L(r?GF zZT`57WqZD$FsOMo?RUU{JNIEJqs(*uJOrAZ!!H3-*+-$&htZBbqu80movVhKY13zT zR5W^hWA?5*YLO<3oUt!uda`ynFEdl@`WO$)qm$+6+f-;M7?(A>aiWD$n5@3VOb0#^ zc9y?a2k=0Xk6u&Ta0K}(2wDvNcGs5$H0o1CZVYMHb%CCnD^XR>MB|A^ehBg4)C<3u z2-@zC?b;(Hj^|b^`0X)K`jz>>ny`ZfjO#tP^&^m{z_lht5Uw6JW!ek!XP#GN5xEkj9v=#CE@if@TT_o&pgoCtn(HEW z$}22Ruj3OkRdnl43Z}McS(jp3>DyOm-MZs=t{vlXC<0Mbm{SYcC3*7~-)VLaE?+uK z@Cm%T!PhFF!+Ob_Ji#mQ`jO@^A-*iHy3@NFAT-3#J2Q(Sd!%ZDwBq0zV9Dz4n{cq5 z{jT&aroE?2QCy`4s5YfN+KjSMtFrAdF0t|k zuy?xE4?N&#KfW@;+@4i(e2R|r%_l2NC=XeFj)JQ|!PX1$vZ~bVTtDgS^=4s8`h=pG zomlcLnibo}Vom)!k<$sK>2^;;WeMIKb|OI%kARcGcx~XFIhJgiG449(e4TF_L3XQ) z7g^ea<0Ic&vgk}2gfMdUFURsMRmm%ZCIjQ`3K98JUJg~5BBUm_(mS1!BUllHxb$ZV zyPWbf4Mr=a6;5T57?Y!RGPKjT9LVNfabx0RfTzP+4TMK=n97!v$BPY5hEi}lq^+3( z0#UEeEB1#~t~M!FUTik7k0GA-8_Lf}5Q&?Zp-ihUU7i6aZ&vyBu@GMlg*Z)DEOvM$ zR=_qbXFA9%QvRI-6<%n2#&*c`N`p~K)fK5|SBmc_u&V}6J$)wQqVqoe18#}@rhL{> z`s!&o)x`eAHYDWn`h;^c9X2YzVTcTw^$)gW*p_8KpOFUNwLcYEHgFcM4^DV8V)zBA_ML*RDu0sOT1N;}=dFs_KEYg-=OR7~SLPL$&RJ~$dECX_ zGX}}y*RgYHr`RwfSgKX$ev0@X+Q_fu+{ zN`Ed@=oQ!pmM^-AAiO6@rua+1BwB=9?2Vp$Di*3#BT;jNf+2Q@m{wd^0% z^qVnEshUpw!YB*eW?FT`#>w{g#5?cm@|GZ_PGG5Xq9^@iRM(xVQ)_vyoAe>r6VZF@ zU(jIxpgHA*f^c4cM)(LIa374nfFxyyw>PFy&stjqD^#qP&!jN;ESY-N;wHY(G>w_6 z*E=oIk_fFL2Pc$GrP0aGE=QmO5uZ79?CdW{K4r8~y7n>ac$Yffq2fOUnw~X?H1$Y= zgpiKmFsuG?uk9)cU|#WZZ^4P3qn%S0LtoZ+u+d9v_9F#XF{)pQ$&7y}cVcEA_YcA6 zQFZo9tURae#A&qB*h9*+C}~`4rFkZ*IV3WPci)avnRa?Lz9o+7UX9)xozjWXObb@< zY8Y@PBbEU3@vj#{LnGFx_MgBqtMyt<1WkNyXB1MBv=>MEiYEQkTH?Gnm8xSDaO*NT zQptXK(hzfQK%i^rfFcW3DMG@ic!bZoTOsDA39I7aHI(r{_d0C`PQIMxmB0g}miz(o z=^m!kAEB7}to%;I+O8fXrh5|dB$N43ydp+VVsmeKQ%ml%GT1`e@ub4r5`neKkVPu? zDDR#?Mb>mwyGXP#K$u4bWnM@GYjMzveV!|v*neA6T46D`EnNhAYhIkSXP6Lx66)EA z1RQq(>p<2=UdfX4@)1rHKv#7w;ttO#&}qr)C5h3uwOqrzt)zBZp+Ol=gb)%if~sT9Ffn_qEwQV_56S)ChH5}exT zK{F~{V6N;pe|A|SSflwGHTNx$$aP02cWTi9k4MWp*K8z&n#Rrwer|&Atx7DP6@zZ?f$WH+y_YGs`Y1>M}_U@|0c32UhREP z$gV2amlBV?S37CmRU^yUQGHl-V>UG&tX8-cv?4+YWHDS^sDLVT@!ke3r{Ah>t#I7d zZCFzfi}CVPOK+>;GjyfVYPC~t&mHliun=md^$+`46ywTza{L5((n|fk1bZ}Z+cYm1 z6k4ZwRGe*;&)cV@czG_J{~vH+!`~;ElBCHyRT zsOae`f;XDaYAfUk?%KSo_?G4BJU%DS*0eEer6>r=41rmh&10*P&QtCcvC^iAgekm)GiD`i62tPM{+UXnhm zrZCItSv9yQh0(&^?_^FgT{N+Za5)SAllsfv&ooKx4OsS6PFp_k7WohEDv&(aR8-J6 z1m_s5R|XqNr}bAtSEq2fwoHLh?i*GX#ZuPe?BjXieA{hZfxmoPGZVBn zS@n|D+O?)5r&B93)f=r*A*EhYE|FjA3ZDQxa=i2w61C4kC? z)I8Kpocppm!_SNMa#w}8QoO%V+~WT{Qujan$y9Y>(ypWE?NJ}II*X62|Hn-s(2^Is zExdzeX>4HF;X(;j z1X0DuUwWUK5l`G7^E1tSa?Frv0Jk}*!!V(sL9{&fOz9F>9qrRWOYqn}e^jdskuQ)h zEevHs@V&0EkX;WOFXKu^Hm|CZvkLEsbVQR8!OEoNlF7|+Id?=RT3ey(F02ft$v!*h_4V7?i#G^EbkAwEMn~gVhQ8 zt=4THTX}9H7x0=&fC&jAl6}Tuc zhxxZN3n=iT1aK&<9kZ4--4%<|zFN4_A4RwBH*qA>-U01$byV53KYH zJua!gD60(;olpy~i)kTEiKpxGmVymk-`_b;joUv1M?r(0B0OMfq}IMJYB}#7{{${# zjj4BbVF=5rvq8*QbgV29vht-JJaK*9@XX~*>NydnS#X}H}@s3VcqXL(rD-zLppEJkvz(wrwzIe{F6dFj?oOHLz~2R|a%__EqYcgxnpf{1?@?Z`3=!(_i>>ImLE^lN=VUyR&K zdMI>td9$VIBk2D89_a$Loi}eNpKbsM1{d83fSB!nFG+IBIle_krX-#!ytFdC#=aW! zu$J70&!9`mIRS;U4DD`m&giCrC%)&mUnvzsxZ>Rd8!8@M)bb@#DLxYyf8 zXGr8!V%IhqMfdN1>livhsZHrsy!ztROJ;xUvR?idUMa^z3gKgSEIkMC*$RYvAZU^1 z-%li}=vkx8|KNXaSx%Q{61ez0i-9>-^}5Z`=lD@fetsW6s)k4=K9=a|*5NBMH$U`1 z*EEdj$DAsg(b1Rn(Tst4HQVFCtyi7mZrmD{?Yk9o&_2B^(aQa?67ev9;@-po2{0(F9UhuDTqt#l|^uBXAP*+{8RW%sntp7eb8DX-N{c!{1kVEm! zrx5O0)ly{$lPwsZx|~J+m=%+1vSn`DI{YFAuCI5=e;sPYYwf-<-_aI6{S7toV;)Ix z_(C*oE>rRC&P}~0(UNpqD|JxL&96P+AYR>$pedkrVjYi^Te%0HGe~Zm?Wd%;#r@{*`5^36>g;?Mm zpV1(TF?`XRwtrCI?mo2YjwHghcGc{iEOxkE{JQHb3OK*}CW8w1%bm6VaEp7RB+8DzRc4xc?I$ADA8@1HGH38K`N%?}8;JEw;?ykXHj_uug z1h*T1tYi+hy`~n~k6ZlPI{PG~opJHN9`qB@wxt3JVQO~lU;HM2S8x`$xVAmZfJBCp zHa=Dd60I+~jV_LXCfn>c*pZp%>-33*9R%kX^$-L(+tOLEX2tbAItYI?&%5)VYN*f0 zlZFCbKf3Z;7##J%Pty|Y&_UmMtjXh#Za~yZ9*z6{P_2y)7{a#v!Z_ra5h00_kN3I` zBXm!M84KON-OHp9kgT^4cV-eR9s0dTJW@0k8kp94u6PY^KA;i&u&o@dxq4 zl=k=o=PsxZA~dycN4((gQC|j2=3lY6<`mOvRJ5{f5UQ+KdDF0uPKGH!mBK5Rf@QHq zN8qvh-Gc^6alGsO%>7WC2QRnPt9>{LgtcflIHg1n-1L7|Ed|OE*dChCf{lVDj^qJ^ z9M^iQ%t?EdgB=AR3zPRsl1XU`U>rB*&XC#o+`03;SW(xF4Jl|NtXCS~M1{*u1w>T$ zKCi>*osy%w@zdzc4e9tvvAGlYrL~(RAU52dxZVsK{0*6UB4S+I1RY;}dEf%xUbbrG z8T{1w_xMw2!dN-+U*N=oxO|C;7avHwIMVpoA^kt9ee|SxeMvy>AA7XdXFzX4m)c(q z?&$T_LSHb2(D!_4ev+Qn>>A1d?JNFT9pXc;uOzGeeDH8@7WxzSM^pj)!s5SepDBel zXw>HzbZ0IJBNd?Z#$FV!aKja`o_Jm?GcXl%KVCJBVaFkLPiSJEmzQZwq+Dyr)RXCQ zlE=#j?6-DEbi8@Y<^N%_?~07n1W@Z|mL^E|ma#m(x5re`SjkyTqOntvgnuR7W~MAgB+eO$O*{oR5+8DnP`8lS{B6XE|0-l+1B0UH>;1 zs}a4Yo+h4`8n|S($ZZzSH^}+ofjb5Gsp}{*U|mO?r~vrc7T+zAl*QA?ll6h;-UkQe zKMX{l6c=&!cuVJw#+wBLmL}kvy+iH2_(S%~=#CyO{W<6a8;yGf&MZDuU#-MX;;<{F zakKXRRV2v?_OZ%r<{W2TIuRU7q^mOf;_Ng(*G-Y>wb_?IP7%!Xeyu7-IUT4n86zyH z)J!3<^72VNe}D+PJK6p*#Pi-jg9S_l8oO1W;f)q+JzDu+*s{UI(jC}#7u(3ha4xb& zZE&-$s*zYz|HorkyR5p9v!#P&>1H~$C|7{(j2o-FbrfW8Y|W^QG@iRwYfWY{#nyiF z7`u4je51wA|0(}|R&D0%Z|exF2JO>sg9ysc|260|4$ppnt~P@2dbKz=i?@Ba4pK>R z-={f%v{7HD1In?rYO@WiZ|z-y|K=Z_iphn~yQqnw=$9GLx_fO;7E4rQx>1wuT>arv zGB5qlw0mJ&Y0LdgX&hXz~Ij)QPT-sJaJ#!{A%y zVC#C_%7}=B$k>`rY1{ydh~?P#LkJ-BR6LHf(U4y9D+7$;fvHJsKoGFJbgpqDO*R$O zN;W3*{!H&G3@CouZ(ysh{Sq`5N}MReK#uGJ88~SiAcF)Pc-fJpO+6Sa|6<@4z@ebA zRpz3Bry6YU~64*tV}Q#!z6@pLlL7!)hmQN*xMV zgxsYyP6`aX#+;`He)ci?s7)*+vGZK0Up@#(naP<&Qk3xDl!W# z0ek=8IzCAZ^(%J<0-*R<-p^v?b06PE#4kO3F%>kb`6+{-<0NHueB*7xs5oNLIjeKVG&06*)I$iP0^sbE6~toqPX@<&QMn#OiF=$%;Q_FYO8} z^Upr4Av#w!U*jk5*Xe4PT%3G;*WZ#j3R53qE)?Rv7K2%uoe6FY`kEP0HA#eB@%C4A ziLzN!1yuntSAND5_bEo;H_g9Q4poHd ziR>x6Wd&q@vjR9>P;lOfM`^k;mTd5WU&mpg#XG}Tx;<{*SEff0T<0ATP!2t{18+|s z?}+}_emSH84XB)n2|s&wH#3j!oJT=a9yQDtNpv)Pu*#vOxV5dIg>-jk+dFM^cNX&J zE`e3>YF7)# z5f^)&*&fOtVbLwFepPW@TeTdn*@Y?ruYD(r!7y@5OBoEkIP^cQ7jRDAm+OQQ-u zmNCf$9bYWZW05zcTqFVyq^MAgD_**0`Oikyi^?2L^Y?j#dUKgC6 z+`NZbDLR-8>u(dZyj;|_opuR}6SVY@S*dzdDodx)u@?(r+P`|D!wPr5>)fq6nm~QtFiIFRm-V)O8QN>i!ylv@P(iaXSIAJpDTnaWN&VRTlAiKa8 zfh#xf5HO|T_Y8*DRkwS0???2eZyT5#ESX91?c`Wi1zjYHU{gTDNOj#cS!6HeB19~Y3sR& za7_r|8Mj%Tte~`=MI`s=Gc4pq{;iNgt3XzUVyu*}epD)YhLIea%$>yB7o1=qv|bT3YL zE7=(B+G77h|NMemnmo$iJQAPV)j`TZ*c7vsIB2;yWfsR#Y(N9tKclFI_VhV8ous>e zD#g;$H$#j*;%?k_xGArBNk@?6%cFoYdF`_ucGBJGVzii&?akRjX)b7P;^DmboZ?zYEyqyY+G& zXoRlCl-v;Q4tt`AA-Y-%*#f{?4qF)w9GF!2Wd`=*AHlcy((v;k7P`_{y2=qpwNu~V zkxNqr` zF?1dXW73zzReza)p>Lj9{ABW#wy5aP$jKO#{qk$Tx1jhfFbO%cR$H>k*ZK^Gyi9Q$ z35c65!15Z4Y+!-Z<8Lm|Ab9BMzZxyQ7_-9wD!Tj2W(-Dr{9ynS)Uy}P$q2x|t@aJ< z8n1DSOr&1_E`_A$-B|$iIl1qF#YN_aTaDS2e|;E!rKgM`h}iUq*&4azObtiR>P?aP zsamL=%uBWo_bu4F)ujn;kksk7@NTGWU;M1yTpbI|bvm!iBB}Y{;-EA}k2Jm$Iv4{m z?he;!bkfHv29jUBVlWkxrildDp_gm2$-Fkq0Y~FES?J!GKRC01v=_QN^dxV=_Okg` zKO8Tvu!BbY`P#wOY^zVX3=Spt3#K7XoAuHuog!ZxqQV}8#Yw-me2HZ9+l3JP$@}z} z1J#9C=+0x1^QOnuEI*8YZu#aylT3rnbRi7xk}QQ>{Z4@JYzQc`gfxAi}#z4_nKXa|lI{PQT7d ze3)lc&h=7gLl{OI$noGx8-`~>L2#srCYgM@IF_bUe0|r0dRdoafMh6*$z)8Ocn8$hw%v=pm^2qe`Lav#tI-N0(eoWp5xTFnRuW%tAwCS2$(EQ_% zfmYg%yDV9xu3S?FG%Wub$Ug9OS)g9M_FM7!f7kP1x1-uAB9LPGKkUps1h+`YPlaz; z;wV~n%?KyFxRrQfK5zxeW*HpQDp;Ad0l5_Y}6&tQxw`1Py>o;@G`b;MKR{4KH&1*Wq2ormer#z<3@qlg-! z%m!CX8ZkcIM+^F&!k@&FIjpLo{2{823l#WEG=e)_DFbQHx9BmJ(Tfe}VaoiZE(|Ecjo{ZNpE-f9roDv{AZxWx88>bp^_z;aK8dK)>6jAYtuHWjjn=T4hydYm-2eN!;A;%UG4zjQqPF9{iDUhMRB36^Wjxm5ti zfdTveD}HtuZW+bs_>v*$$lQ1!5cU3oj_CSF?gn5-gO8k1PbXrSBlRuydItoXtq(wf z6pf0@;Fq_3mJtQIXE-!jq&1e4#n6lj<8qU!nK%Z|Kh6r^cvJqlgiRq~Ewn=Q$G6Fl z6ws|j7c2ql8G~C8NJ+oo^6_&!=D1da_<}rXGro_jKj;e8-`r)7R$b)Pjlb? zMnC1%E`~+n=3i9k%i=uT+)JHI{ub$@^wQ0jn3uQs{jkM`u-pWXU8<_86w&V0X-Hlz zZMvB0CAq78Sh{J?F;;SxYju>>@;F#enOsu3vo?zb3@-0CDoq--Q)wzL&CSO&+SVQ+ z_{;GA>EmQfqH3~rC<{dO4{CjpF|PfWZxpgvKxTu=tbXZ?KcexMZ?6(9R?2QCvat0L zz4m1K$z8#P*;MN>g+)0uepZMT7^;7_l|@U;f&7{t@}fpyTgW1^I9Y-x?2 zkUJ54LP2JEY%KG^Y3L#7S(J;gj|O>YLB97nRCWfj!|&2xD-lPc*8&@TBpmUiN!OmC|hAjN71a4={D(&6DU^2 z)lep@Nle_1CIVxNO_kWmW?PM+g?4n7IVo=VTb2{aKW0A~n=@9HMuECTnV|3P_XIC- zy*3K2;!yqt%jP1;=+f>DjWp+!$Dw ze=`o@jEf_?@YEMhHhvlTC%C^x6(j> zlts^RE&9A18rb%8nL|zwGV&cn4>#WcMul2`!?nWDst!Lz2Ak$)(~7vB4l`9v8HvHx zno|Sq_iMQs%iO8wX)OHJV~;g)^oMID{&k|BEhCF}X){{D;acbK^tk#{s9wxtx17qA zWWgvDZnTl!7hkhLx}yAliFS;aSsit2jVP?D+2=Ec=zN|HOoFZ2ON*H%6`ibh0x5zc zl}?btp)WOBq7uc~lK4xo9F$!ARn!lGH1zmiOg&T%>l@t0^5$w?yRdVem6v&f6c^D5 zIAxx4gq5|nPa6&@pzm-S8#k-)Vt`F-^AVp{-ObR*X-bi|pjqw4L>aWO`!+b}2~ZVh zn3@pOcxNtPHcfdH)a-fBRX}gCBN2{wo-7N~i@bzRoy)@z=>Kd{d3zX_R}+fD zk)JT7xZ*~U0(+*h4G{BVAe+JNYkM*3P^{Mh14U|UfaFcO4kzq6)D$XDEnYRps`g6# zjV7no7=$}qgpB)v zrLM2EpsF#Oz6||rw9?ic^Z zFi*Fqgi$Z;{~|pN1;Ntobh+y>KrEQw5lfqV(7~k1ye22Gj4kvFVeSd0){HEBls z$9QXazkSt(G%bJmfrI(aUq1Y`5{Rwd*3coAUAS?IYgvFZXF8`fvZ&O-y=>&nA} zIn?&Dp$p4|w&~$vPbBVF2Yr531^3jn$jU6C;?A6sO&Z}|z2fNxjd2$bKRebC_udLi zka++6ycG}{mVJUYFdc-IHmKc(GuJxFehBQ7N#C~~&NC42d|o>ojk|swzAU(F$$bM(99J6R zY1N=ndJMRDc>9$WLC1)Jfw){snY1&Oc=Lw#-SCi?$4W& zWEk#0lmjCoetlFODBEk|Rp>eNz51OpfX&+D=!qADQ46*iWB6TDy$=Lk1f|sS8q7Sm zy6;Ls9s!4_Loj1agw6?aVF8;GFFx8 zq-$#_v*1p#C&`gT<_pbO#7&;Qp`rjsZ_Ql_Um0>0I2gUt+umQ)OYg3C;220)gns-h z4lfn*z)DS+JqrY{ZOs*etvK&L+<7ycx_E!Nyq~~nvBnklF1M_gS>V7=WM-C91mSl# zcD^k|OWLcco&s_Y`7McuOueCzCqzXacfm2eAT5FUl^$)<4pRK;ozF6Tq%Ho@Xrsv= z-!TQrKK1KiiQY4(!& z&llE|NnpFD)Ry3lCPFZpp0zzHglZxWZXdYhkSkuV2-TA7f9xIhT_Vz)(tEMe`hoon zf?UhXm%U^vZtuADBNXvkC<2dbO!O>#wI`dG#kvlu?NslpQlp}r_=mvJxD)GQ1YI;A z{3C)F%vx|H$_+`N3WMK17vgI1@icLrkX?h1)OI?U5F?kTNt;wia?!I{mj!=q1h2M! zX21@}&i4yxN}zpJSc>?jk>W+ck7S=+kpa3GDX!Loymq2wv;nH$q6x1-g+<@Hmrfe- zytBkjV*f-`cZ0=os6awgk#o! zpytM;03TdpMxBbn?o(0z$NpW)`clDd`gFxgNX3&lJCSK@d|gj~Di z^6!!<2+)YSrMB`551CseIr*XG*Pp>F++-xhDS+}N>L*UVUN@e~pkyEU$_Olvz7Gve za?#2%75VD_&B|M-BCA_MJU8P-O9)tcUo_)K{BmSADkkmRk?C=R>OA-rEb(ZZDBYf+ z$U>pY>oH2JKu6nIBzn}pQU;+CT09Esvz~2)g0iS);GOfBLvnb>?F2dRo_O5s2-2rp zX>7Y1PB&15>Ql=fF>FH?9P5kWils*ifH4H{TP$?Ie!h(?K=f9vw!?R1@i9nd&ezS= ze%=;Q>6O9Dt4?SEBYDsyep7UngD5jHeWfCc}i>dz&H>z(d|`m5I}SgyEGXj#kIl$qdlgc`*P@!?H8jSP2e90I`vLMoGv!tbAkn>2Ue^$(AWniadL(eg8P)Y@l= zpe<+38Wl}F&>l>!zHmP3qf4c~l)*4+SpO6XxbdzBrCkyf63*`Ero>7}`vs4z#HEr5 zlrOC;xRFrkW82(ZsLhuD^%#f6+Maa<6&&m1OU%V$=<60c0HPpva<)ja0z?;AGYnld zI+4lO-#6Kki1$a+Qy^;FE&K7s9E|>=#@x3wc4K#oh3Z{M((~?r%SI-F|C+Zz12X#S zuT`*Q`u}>;^|7D#AGy*L$8gZs?2;xxkteR9dH){1D6yVG+KjjY5x5V^>#=m7biDXC_myOK&tO)@b}f2w?_uhkQwi;l(yPMhg)& zczu;`MI|m?G{z@C25L?@)6rw2&*T0A&OMTEAQ4sRhAUMy~4Uwf`N5; zel`VUs^*PG7@2uz!yLg}pI6muQW`j~&uM3X$pDoJ78{A^ZWV%?CUkoYb+a}8QZ zB$FIk67xnTMZi;`S5HMqAnlU|o&ZwJ4)o+vpwBpkyE2(q{Of?P%<4C+3c6}6B8!mD z%ZGlWt-njOE{4;_q+iuQupIE(EZS3o7jFe>#tSH2Vp&a&Pr8a^toVu7RQbpb6|KcN$W?p0Y z$n{T}E0U}8!9k-&s6iAe?HrHuFyNEr#z9%!MFZiz_8h=DzLl@1-~zJ$xlx0usP=7L zgah2QqOh$y*Z=6)oUGH zZwtvKcyHZ5I^x7}Kd>CZMzI#JH(B6#FqB)Ou%7zJA|=>YG1giDmOE}&;Xo2l^S%xa zJiKk4aUP&z+xT(60SG!^dxqfT5r*w-YS8j#eW$ZHJvgsweJ)3ulCzCYT7PCH3;R-5 zyY7MU=}jeUw<2>wxQ0)Y3nl@|o%EkT*0`}HtE2g#z1wd=EAZyxr_TTtbK>wo438{&3M;62SP$}J>E5{$~30SlJ6GH_@}AI?+=2mnB3j8&W1BxHTN|0 z_IA0eUSwy)(4YMkq2jdj{1K0t-aQ}TvD5GgOF_?05Ah)!Y@^Z}LHaK-4kxry%@wwi zq^d8enanwa4+o$*52riuyZ?ckRvA+H|j&4gC$9y1`jE5@Sxd|xZ^ z^6uKnSr~*_sPqK{cEp&m7>a6RL1!#tT1*?2+Qb+9GnS1n{zxhlCju{)^uxNGoKbve zf{E8RZL|lT3VGqH|H2>6mA-rrP~_H1duF<*#Zp(Mmi!M_3T}93`7=K$@_1>BIZTHp zmhj4a)bK(-@SrF2r%3|5{-}wC&gPf>)f>k`Xo|HI+yL4QxbX;?*!jG~L2b~rz6NI% zY$f?32`dK*1ts`SJ11l@EEnfivnOQnV$}YdmSie<^`_uM-YsL(Zz*QE_}7l4+d^JR zD7A(Gl6{9X&a}}tVUj{u3K_p!VS1ddO;_MP7u`pf8HDa32r#tMwFULe$*rnE!NK$c z5NY?eRO0W?{u+q0)4!((4l-S*LCX`er2chq522HGlZVJu&1A%0`ZNg?JnqS4=FGJ) zf_WBfuypezlkL0%UVHR9n1-|Q^aU@P3Yj7;F*Le@8!z3w+#i_BZMm-0R+Y9#KGv#I zv4SG27Kqs^146HzWtG1A6mj#s%uTOSjzPq6-$0H&_%>8-3^dO=I8l}+4JAVscZHSL zq|yCS3lwn`C@eh%2@GgK9FMJXd_fzTiS|CMnSqISHSIyS(vSPq*~seSN9qCi5uKg{ z#=d@P7bt?7b-n}kN&5U3ODQy@>p_c3dTE?8yBL-EHG?U}XI(q3@Rg*QVF@W_o||4P zTA?jXg-*_dp;)}QaGt_jlENDPgITUeY8oA7{mgg7OXKG#b;W2$k2iQ8eteL}OM$jO zJUDbqG)cjcQ1qJ)>g!L>6xmU{cx~}3R^M^v))tJ2Juz=%hQ;@RFh?>?Qr8AUD{kz5 z0rF#q3(vtqrT99^>=gaBFn|#o-bNEos-?XxD%zFVAG~~-c@w}=ESs*3XhplfRW#z) zqRkx~lFeQJKS@^}*i!nnZ@A%<>q>9ys&!JNf+8qlPZ44-W2rqgV!~Kr?-#{FcW)h^*yiepM*5I_rC9Y_Vb)`@NCvf^(B7`!1&HS zPURO%g{h?E&&GB9dmp1LiXz)nll5e}SWQA5s**cvAk3M$#a2P7PWtO8_G`@8t$6+M zmqEIG`r2IHJs>9gL;ms=him75#b<>XTdYzon`OMkh9u z-K|N!vRY@LE(H&vY!A(Jt01Sj>U*RN%yt^KQ3_Rov3GSMM3rH4;rEc>teJTZWXRHsBW?5-0NHHIm3>Aob%*%G-Kj!1RO3pDU)RO$IirA)V`45=nH+DaM zK5F+2GX_On?x^!%s_#Ik{87t)!y2A;FQvoir+w+>44R+>*`$~4l|Ji`|7x($rlA+r zch0s5{sBMaz;5AMB&dGc(CQ}zB8kC|B21) zpwmLo?59s-cd`m4*VZn{Fgup#e2O;+%Dgjr@TFq;%yNd`O}Jpr;N4MCdK#VF3dB2Y zb%xqRa@*P1$BRdI;VVz~JcG>OwlAy1a!sA>Zy1ubL1}HNr$&cZ`*27@uKTG2Di@r3cUz~AXhtrU8A<#Oj~n;QgV@E+1`M;* z{d)`s&HKMDqYj|?;{d$2ygwDhV2s|$e8SX$ z&%9Z5pm|+}BhaQS0)vEh=BZPO+Y*JfP3Y7Iksr5nW|W7^khMliBBY-L!~3m@DxDf$ zP4sH$ee<&30L3mDU1%iE(G*LL4JJbPIJTpql7~ zHao5V?J{msqiCSb%@3aseB{ibf9Ik@>pz5ZeZsxNWA5(P5`0p7L_NG7ST)y{MP~;! za%S_NTSPf1LE7%MQ$V-XmQMqc-h$w)p*48mzQ*;CG)<0gP^FO4X3Iz`ZFtwpjMrU- z4A`i=D>Yek!K|K>wx3N(QTj(ZgON>VLd-Abt{)jEX;9VpDoUp(PZLk3Jxr{r-I5dIvq)XYcV5M7EY^gN%BT0@J`g0)jlet!F`r{yW zHHTGoz75uPbd5iLy}91-DE~1oRzz65mJ_xw|OYNL>kCT8`uCENfD1i%DC55 zcIrtpeToi=&+jWb6*4qxf`#di{cHnfEQ%RUcFzSHFpZ1v`rhkl}Rb|d7(OM27e%)&f)1B~AibG<&=F~!1IWgnuhGm^b6W2Pv*JCAr3%L4&K`*s#h=*I}I~KlhCC^L1I$j~f}m zRfntwF)H=b3WMZHFU_I_D|TVdbu_KNmV-mcN?`DlNZ)0Up-+eIhm6qd-2*Z8s?vHj z3F|v;Tc!%qvbopQE}9o@(dAKG4=t{}rC(bd(Oqe?E=+?KbwQh$jDO|SuZWx9nA!Pz znh#3zp)uPZ1+3LOw=eB4oRXr{7&6-c)Wg(!c$hXj$|mO_s4#dEB1cN`tMDhm3nkTq zL<=_bzdSX{FqNosPno}-OnWAO18REz=`EXZ#1%N6+g#`qcEFj6W>n8|9b`B^2wK;) zzPRLp30L18}O!zGM7xL*)0oAQ2Vn$prJM_of{cdfLB9} z#kpb9KivVdF*k(RGur5u+QclaTgOU^gw2!6)P^m`nKpL>M_4wgVY4U&@lBbud31pJ z`Y5;EZVOS%+Lz6#Wa%_l(!#}G+=RMEi^x&NxbSM}x_H8Ab>TacvVsnZqOY zIo;Ii_v219saW=x7{;|~p>qsm!{8~Bz6=>wJ+-A!bbE}(6}Wyo+X2!1Iew&(FS*#J zN5w}FsJzY}!OZ^R7DVNyt0g0#GXFl(xoFS;9UF_7^pl(_Q{ZDWTY$6|Z>aq=>1;G4 zNJ{(fZK+hT-vhNmqZ=Pr=Tlre6PTy-ik{$`vdx|#=*4aN`V-SwzmyuqOyl*P{=iz5 z|HX6$0%KBdDTH+7gH_KUdIRS7Y#Eu?O@oB?~HID#hcY2XEi$ z95jAj3msJ0ij!$>bcS#4#{v8`ahT0dvhN-HsA4h$KO7tW5Wkob6$9ZHbjhJ+WE#DO zHDOT7yq57cpi%4iRN|g+QE{|l2n+ry&t}NkI)46o3Gv{T>fK;BPbdmkf2wNkbnxke zWj#RH?y+hgy7KM;>ji!;$!3D(9oi$=5i~ya0@%v0i>GNoHO9MG6W6E_8zh!D;{da! zv}y~)SIXdgIbX;BU6F;3=4JF11BhFnzfpNMf-?OrKZrgO{DsMr8M z!_Rc@NJY_9S}A1tGr5dkhVbA^yM-^g7&d`}`*avsoR36_ z`~2tC_^_Z1-?^JT){r?5&4@IYx#~3$Dm9^n^OOEI=hLr>i$$fEbXteRVv{Sfs~(w# zA2;WbvUa~@sEje*3365fzvrA}NTgtgoG%^tQahY?^CyN&dML#~LCMhws%$y)BwC~| zGTUiU>n`lzuCFwwfeg+V8>>B}TeAs%GFLEg3qxSVnYytsLwWZ&aIa!oHxm6cE zl{~}9UTM0-hUI@d4=2EFsKOZUY%$5$oQlfK@Y-qLrFyu_foeH0DbEDws>9S`&0)kJ zsduG3{4S|`Dvm#;?Jtt66ivQeALhRD%Y#8G?E3Fbk0E5DJo;`pU|Gt+K^2P4u=Ikh3W z9hNsoC~IbpGeZ0B{{+k2ULsuz0q1dY6-Xwp)m^Wi@*Vl$zjeQy!aYy)_ygQFv(yNL zf0cc@&N`yf6UWpdzT+C5o&pn5O)PLZE5C%z4TCDHGf3a9lP;Z7T{@hCed`Nw(IW2+ zJX7Et@3c_8o>92ZA6qv&@jGSj|HOP0tURcdNB(QEx)3RKy0Nxo%E!uP97XA-Qiezo z@MTsM9eenP(?{t~X62?+!sK?4DB3>F(X5X@uucvdXy*^P-c-7?d9N;xhVOZTN1%zv zv878Im9uHdkd0v=H0oVDosa(NH3)zGdDx2kFL37fC4VfOF%{qYFXZyK}n%l*cO)e1H5^py*~;I^(^j# zE$h8+B7V`mbx-IPWxEL+{`=acg<5K{*Xs>Z(b}iX;cmEshjyLyWScIV7Ui;1#UUqu zU{2(!6U)tE`tSiDF+{|+&9|lV8=p!3hM2I~dJ)8%a{42Cpq4kwvHjmy@`03Hnq5qTVZZsRQ(CqDB{_xVAYAakS+x(d?jzY8!6m?(`4Pe;k)nTvdYi zD6**mU_a$iXs5hqUC^{cB&tP&cC`kP*K69%Y{9s%D!H)GyE3$8#gkn@9|;A$%qYc} z{Ea!4pJ$ZA;Pya{Y}E4}zwD{YPpK|vBvW2yIN2d^fq$b^=~VQz61Jz=fYo@uo9lR| zmRh&ta6N5#h79_4P&)L@DBVc4o~pDLa5#QjaVeC-D;aWJV*o>^NGa$LJnIk(w{bfX z&4g(0tK1a9w02s5T-|S;pKGD2kD?2WbaZuVT(R@q`gr}*)E8nh$+RE$Hda^)GH7s& za99bw7^V4EhoFQy94_m0@dp}?%%_PbcBy^TZd(JWaedwbvz@ z-6tJ~&Tow{^NH{HkCfd;u=1_Osw`+@*A^Hu-kSEBcKuRe^^k$tijP%8HF%^+D#~5NI zUn_e!SjX=Rd?GUlE|qTf1^5@Yb_$~nKA{<|?wYxTIXt0?&BYMJ{KYA)aL#*|SI4}9 zITaQ_JfzI=hG@iRtIkdqE^M>%BTC5rj@08`UmI#uqg(4TsQSslYJ>1^`Gecz(eTqK z2RiV9;Un!d!&*X@MWa5uK#)p{33#1(W_oUb3RXRU$XRLml<7g@<9j(ALtCPkq=kty zw^=|`&@5ucv^_3LvX%#dq33d41oRKHVyTpr=V=`Ir`<;?G}`u)Q%}9?Z1ZMOR@Dd)K71uP-9lZ*O;AG&Ef@fP zNU1LC!sK}U78b$!*Rma}F(N4`D36zNIQfvLb|xn%huUmKs6km-&n^b4pv!BCN@74j z4(i$mT?!o-IzK)|P=-An&%!E2+Re!j3%_g|FS*b=`RoX_h1TCNG3Kw`NH$x9n>8~p z#v5t=JOD}Q9T#Ttla8rh%w5yVRA%Be+7MxRkVx6BX4Kf{F(CWonI*6rL-LzDt@Ovp zC1x$TuPu{3W%vPGnJH5w!`8^VQ7P9>!H(1Mnz47C4Rs-YW1)szrcpMIxa=)9pI}vO zAFjf|wK;%Y3O2kTg#g(venWDX7u@An%~xs3)OjjPA^8)ZYaRy-l7qHNazvTlspZ;NEc0pmFsc+0&HZat*=E_G# z#w%0$V>Rphuaq3|G$pw{BEyPzF)CgWt!r-;BZ%?1s;;uZeBbw^S^a~E835)i!FFsJm7T`e}pARl)Zg& zP2@?sBUz&%>xymD^WWE#jM(nnxlgQmxa6;&@ZC zZr~!^OfRt9pXREwDClEub=J2k26T5%Y$$19wdTG-X*QW2E|K#k{(Ml%N+M9@a(U|48mxOBj1T81Y7phix&M_wENH=5L0UirV|aGF%kL4Jxr~wF8KF! z?uQ2)Ivy<-0r#ps;j$Qs7fernJk6`=JbgM{+3TTc!k=m_#q4g11*LBGI{5La zGN2ZR+cW`VlyA@)Jbrhmq^+V+Dr~5iqq6g@FbSa!t;57EJyn0&7q8D-xYQ}M=20SZ zZ|hf%%gvzkJ^up*`tPd>RAGTD(IJ{8w2W`Ay%U393HEFMEJ1%rjm4egh!r)xi0e|W zP$A8)8zEd$s&zB_Xm_YguA7c6?f}=vw{5dcOLKqILc(UPi5D%{x&LaLaDrU#F0B07 z-@3Jw4fFZd*DSll*@KW&+>61oL8Pu*V^sOX{hB4)qj>wD64#VW(T}0iS1eb98+-%w ztn;`yY#B3!dk6KI*#fua$HH6`nRFvt3cux{Oexg%On)6Fp-c#|fau|2VWi*&$WUz0t(sb}vr$X{;f8t72}^xifLf`Pes@|4c=C4X58{yK@(w3=S_ z0~o&K1usnRvu(khTXybLqqcA8QgHv%dBbwudrxJt|+s-adhUu6y`d2-EcP^>zX!zp%uBqkDnvTrnJ%>&haC6 z@k9SyD6n(elT%R6Ke7lZP_EsI-nvx!ZQ24H`i4fuApa9aI6$=vt1JZHAHF0f`$)-b z#1g%}E|&@%f}-y^8a*?twHbWYt~}R;D5<{@hk3yi@LGxcc@D_;P8kf6Dnr4lYrFw^ z;n5copFT@YiKoAYi1_pSr#;Miy0E9X+9>=|&g_lX^R08_JR=EzwZ_?8%dd}zuRMC@ zv@}lmcx~{=G>xFI@l}GDt`m~}i;fX7_^E5#x=qA%gW#FpgaPeZe(KRn%%~=`f0enA zeQo`~==&-|*A?n_&N!rwdmnyYvl8Cje|KCidUS&Hp~Og)MMyZCIRMJ$?!CezNP!Q^ z_}|tVqNfJE=#?nuM-%r`MI^ff?(gk7F`WdD=bLn=pNeixV^Na*llNw7-~wr@ih2o& z)k|4yzh~&*>4>)cGz1ozeG$th{8I6W&Or7blWqBAJ$n*ool@NFA!S{i97-H=rM$K_ z9!p+4008a8wR`&yt%LtQEV1~usIRZtS^RXf1|kijF2zhDnz#M+NAv)OT{&_4pS`%7 zw)utYVzwTrhEHbp-!7@c#gJZb>|XIe)F(i*oHmGoT0*eyqj*u1D7Zg&KgL|RZc}TB zky`LIZ(r9%sMk_p^5L)@{6!a_wy$SMdEiIeWph6Dx>?`7}Ki3xRHG~v*qgnC!8lQUK9!X4TNXIX~MZYrlefdmRP`rO{MVdhfKCiz+g&1+W zS>KALL^Scc_)v@h)|Yn?ZL$RaS^XYlfK#URxFQDY3tZ2Yr9?e?#GbGM249nAELq7) zAS;J1vQ+ELt(QQE{MEZmn1||jW0;+-*^4m_8Qu7Qsh?~>ujakwZEi~ZoSzdA{O6{P z%7l@Z=0*xi2!2&^j+lz9=yx$M#Ekkv@I?RZDz{)N*|tw1QO_TKD!}U2XK!Rf=($c6 z3ZecVR76953jc3MCnI0`ETj>45G#u!|A9Qw&#>i%MP3c1-%Mk0ipZ#iYQ&Ge{($ln zeo?#(9qdaj$GY>|XADQxGH;zP>wEH{Q3%+f4^Yc95GD81-!h!d(aLY(+j2uU&qtL2 z+=yI117m9I7&?mfL4cTUY9zWF30#G0Z9s}#?-qp_T z;3P2a8JA8!vOZPGdAt8{wby+aaLI60Vv#huiFo*IL+`Gx;L0@*@Px< z5D~h)kkP&|-d4X`eF<;>`{PJcyshlUx53+?qP*T|S+Fek!qW5X`_w_y0?Y9*c0I1f z{jC03bk(Aai@j||A#&nadKx?yc}RH{K23i*WJ;P0&QN>l*XXgQ^IW(t5%)pIi4uv-SPWbMPuo@o%VRs8y#41s%FZjjB$kBzWl zHEo8g*n{+KlbCCzm!m64EQ0+BDYPp5-7QFw^Ixx&-Oc%|#cbS#XGq&Gz|4=QWv&cA zYK&<43KzYTmxjfAkCqUP*!TT!27vjMJ~N>J0uebL=xejh$ z%Zn#OF|L*-{p`cnRmBV=nV(ukE>Wl$rY1R7VMXb)=kQC@=bPtqQWD?a=F25OS{S{S zVza|SV8DNm7_%qs*;@^Spt&BIlanQ+Ug2INCe^$4CbKG4Na>T<9KrQ{o0P(VT7hmZ>-GBLmEX zjG{SC9}Ukt4h~v>mStYK(WPW-DgNzGa)!iDDl2Ll3jXCMOz|F!b17LC&^v9)m6@=$ z!VfL$l3ju)HL6OcA2W|`y=IL&-EXUWz_z=8UT{#Qg;hM}JbP|y>soNG5wW~GP?b&A zg;_Q*^r}^&9g~dTWYS&2E$#m7KmKCEv0v+A_Ut{EW*Xy18I)R zE@%%P<5lS}coY}wM~G@f(P>ewF&QUq%_rmB=dbh=-n7^*4+=Qp|uTg}=Po##S= zr`}g)SPjPi-m0wRA2>9<1D zSYo!>Nm)EEH`Rk*T9Y8vpB@+gqR$J2>!dxj;eL;aq z;5Of_q{2?Vxcd=2m+_>$*-mjHkG<0R$1}#bRMKHiq4rC=Am^KZNRG55cjJE%cMGUO zOXDMySo@wiOxGW;P^Z$bPp-`dM-QBSRh@x;8Ej_vA8pICiT2#xI#w|quJfb!*PQwHHN|mU1kfddb1pNh`U$=v#xo^ zZP}usCKDZ!sT3t1FXqjsGYvkDwDNu1L5P|HOXQ4bGFMuY%mH8gdK1Vicsu5Fd{D6N zzm}c}fe~!qHaS(WW+$LDS@82#r&&Y4-|Q#mp+Ml-+F4>=G{6a+_DcC>>8kS=HZ6t= zGh46|T+>#kr)v9uRwGTm zubJc#>C&;~%!0XA^%Q7idWXNoEX=Pyu|1)H6S5oJkH(uNvw|u|Npz3ep(2QwtkGw4 zR4Dr#)LaVJ*W{0lbCnR0vat3m&zuqE_BNeDN_9K)QaN9)oZptORV1Zj{`T9$*hTGr z20QV;uFsO_N}db5PsOZAAq}YNg#vAbGhXNAEHnz0UHR8AH|vw}(w4 z>|J;M1Z2j5^iv?mW;>^;h!p(AKU7dczwU*|;PRJVE%2bxORj-MC=@`Ap~sa+KS=>C zaoUDbL?lzq>4h#q89HHt3P7d_R>=hTc5YqKQdQ7A7B-5;(i%sC;vWA`M z{!Z=1ph0j?-M0b%&G*H86AxL?ikm9x8^8~LAnJk?ec>d;W1{K#>&C2WXz;Jug32Uh z{F2x{8NzGB_v}KRS$$?hz-R2Vpt-DIT|jrBoJ_mswZNOlTWd4EqOE@)00|-W&9YI+ zdciet(k%Qfec0M~VEXhwSU2IrxF#+8i&hvz=~HhyLlnNfmyI$s{I3yoSVGp2!Z2xX zk9J1r;aEQdmbcVSo-1Yug7L|zrlKQCm^XOwZrteA|7Hv=$Px~87-$vU%>_@btoiu# z>FA$de`&w5dwz6$NN}`yH%yfw< zfuP?`G-Wpoz8?GaPL$hW$r{1!XMQ0GcyOmUrl_6}x z@FL!SPtLH@xZW+1dQxs(+hsP=qAT^C8MJ8FrJRTmKDMtNw3M}0Z1=Qm!E>z3FrX%4 zmu#)C$`%X_hKB*7jPy#s1;-#V_5qq-q7&`(HTYj%X5mFJbL{JROal!+tY`U`$~UT5 zU=3Zm=>16@qJ#PsX%@lp;g%CJJofsP$4t|iP7k)_Q^uY=TOLZP=So}!N*RYi0#(Sw z_md*A zgjdzZB*tf>*T4aZOBU9*+&u>gYvt8QF(*&(pPBiaEkHfB+r>Ch@E47(l?l?ile`yE zli!QUijK-|ki=|o_3^k}xf!(ftKCw*NXImy7va(ibK!{_ugcjiVKSN7NX(>Yp5dMz ze4JdUr|##Q!>)IHN@uphaHYIjOBIbkRFx%%VUQG&DSYt=v-17kYiw4=t9BX)mPlH0 zWTW{@QF6*4%A2W%#5w+1E4cwL{u$b!1l-BBO;#xFw zBIR)R6jRZDj*~)hq&ZoO346=pY_%QZbC$!Nv3xAaim~k_hv9bFw^LcSP-WL9$%PRH zN9N5)M#q4)b;MK+W}kig6~tE!VVk58=}1SLm!moN3P4wFUNvR&XSwtHVE`LLj8yPf^D_>I5z#cr*7qsO2coS-aJGfqLq=$oWo>7!0 z*F;qP{_=kK^W5_blN|zgXvdgLD5}BT+a|*xI+pPUXK>LM#^ah^EN9KR?7q^VI>(-s zxY&?C4l^&c@9=LSx*9Ia&>4V*zNbs24E$^>m`Z-BNIJ=M9${MCWk4ndJmS+G6a zkB`rZL4ep^-kywA(5Z7yG`gwtgBXey{2xzei*cY{?I}wdsQif`67La|f16mbQdg^A z(qP>zoirGyzTrpK=j~&a?vTC8cUzW0#Q8VB{w7l+C?oea7xnPCZ`HdjhDh*VT>6ig zT}Log960<77JP5lm7=zSpp71VBTX+Ty>ezq0Pcq#BKD0QrwweZbTh8m4PBVdY)=GV z*Z14m_pGDqRkIkXxb}o6ugyORITg|Ctc%3ArG@vu_ zmoXfZ*AAEc{Yh!?&g|pu&*c1xl)rkcI*%;9%Xl-;YV#hR)3<*R$li0VGK)lH>u2Ig zUp0$CxV*?A`^(XjZx^skZ~LtQNVq?|4e@J#t9$rT##uA?*WudkG+?r4Ynzqa22n~8 zC{}YC&Ahf$k+ZC%HID*gr*A%{c4MB52|w^$J}DVRK+e37SP^Lx_{+78K@L*;gw-B2 zur3B7+*rE}80E~u(=efT4obi`<2uz=V>hQf!krJq7|d46GY(T*DYbDY#uVGHgDX?V zGSku3vpVF$A;){5!>iTmWTXdw|Ahs{7Vn5n&Ztt+Yo}796tkVeFK2p96z#5GXs4;i zVAqwVlH>o#HPPG=Wzr0w@qX2rLg@Nw4n)_vHPmqEdE^>J_i z!S5wb=G_hDbXabd5zY+C|7cPNXi&Y;YPehtSE*pwogDHBGBNnLX+<#uJQDYyg~}ml z&DcRH=^NfojIe+2ON34PXjvnXcQV;sq%M{aXKf4Q>b z9Bfc!MS%cWJ?&y+(SuCIKTDR25m51~wO!a;d1aM2F5ZuVycyqSrf9S~w8r}?D_{L< zS!qPZ9^ILA-P*8Ajut`pb_?*7E7qa3k0KjCf;#Fwh*!IXe}#Um-~SDPThl{uv$ z8`fVvhkG0tvl9DZFg#HM?^C)$u0qO=O;WfHnHm*ie)^@OV{D+rKa&_h(^LLiHWE~+ zfr<4%YZY~nGO7UCRZq$T?0?tiajF3M5;j0Q8Ri8UjH&(J@63pK9dhG2G^*NWBhjrb zkih;s=a~L;Kj6%0_a1DYvNeaNhwKCK=ocZ1}aulfXZt^EOD9XtIY} z*^p64Zl|_TjmC4G7IHK>W6r0_rS|DUlzr)fIe=Ki0ml9#I^jF&sbkCrdi`LeEkJJ? zPGFLFR@0th82~75As89hW|`TwnO#5_}Q%Gr@iXr=C?PKsT&o$8_#HUSpUDl z%pca)fiHh&cE}vZo7$meuV6ZPsyowAt?F%n2&>;)vUUTo*z_H2Qd8F8sIbVi?j2_O)ZiqoNCp zI_8E3p|Lj`$BV6gC>I_{vvtTW#gzk@Z?gxm#O@E;p-3 zLlL+AO$}!KYMc{vUP@BTS@fw>eTZ0>{~w%7!1xDFvO|M1ko(KpN%kaQ!PmQSRGpgt z3kCAj!<6#VtA9fmsOv1niWQlgCHi5gR81O%Oik5CA;^;pCGJ8sbRL$;(AHxoX0UzQ z9diL<_ve z@(~PMVe+m(Ufg#xn-uHlL8}Whme5 zVd;Zg&sjY1dDKwo&pQ>GVwv@Bm(T@h*}a2c{Pmri=iq$o53fLQDjf$3pr25?vf!uT z6S&q&98qU`6r?TDrTU>p}EHW54u!ZD5)Sl zmhbQN1?2PI*_7>8W^$St*@qWato%-7gI7aqg|Bg|TN_#5@=J1gvqqR^3mi#vQ`Px5 zpwN|=F3F6_9{-J-J<6O1s!=}1Jy)e@xQt(39#3X`>ToDG^@7w61FzfB4MHpFyy+9^0~ffHK){t|HJgl_#{cZi>FU^n=~ zEp+IxId_X0&2ih8Wd#&35_3U+-Mg^Sd+YyQ&)SbopZ$`#!dzL^InfU``X@A*F_(FM zU0psupqOm!#1DFiIzvIZq5d)6Lfp{tvZo29y!snDtCP8Dd^)=BadOZ|LwCD$3N2i; zP3NJ74eJ-0D0@k7wTt+T9k4wQ{G}yqPp@VxbOyTiwFEB#Bnx!l)EfBK zwHXJ&4t)>YS4Zg8gJ%%FT>~8oSazR*TAZHg5?(-ckzAFr6;DFoKPm6H*~ zA?|%Vhd7yjF}QEkOYQ7@Om>|)T;vdT+*C60lybQs{Qt| z{OnXXmh-b<4;QTIlZG|@8rvy@|Lr^3*nyVpO?A3yLyybP1vSQJ}shwm(_=&rGQ{?I)aQ*Nv6@33v(F{Cf*!7KB3w%JM zFCflZyTE9{2Xn9iDaqGi3Z>-s0TFP|P9eIgwA&|qkqRUJt`whzmS77`h*q4?o+-QI zL5evyw@<%^0A8OnDX*zcAzyFQE!ET&C z2|*as?s+*#0hp$LcaD*oJG8VQm6XRA7TOmL4~DE{g%182EBA`}s)BX?(CcC#MhJRN zd?os0p#4YixLoYfZ*xs_Eb+e0N-_5b>4Nm8c(r(wV6rw?4F)(e_!5NX%7cAuMzjRJ zAUkUDpKW3u0{+~3ptej1jmL|yJTWix>sn4N6`o6iEF8UCf|lm?-4ugO1?A?reoSBd zHsg^EwS+G_I`iqTezItd24H$Dv8{hOrZjjsbbCH_A)t=@0edb%1j?)}m zEoS49wQrkAdO(#v6vH|2-295}dVIYalDiT4g;#8nq|&p&T~QCgZ_+o3x0BLoh^(zF zoO^Z|O-K09#CW|%aSWJSAjWm3MZcaBQ5|5NVe1$VlC_ja?@dUc{L8G}Pu|I$Ql5rJ z-#O;gP=4vs=6vE_wKMyvrGw4znY3n%4FKC)G0q4jy}X(02U7T&IgX5@ntKEEadaF= z0jn^FDWyW7 z%KU|oVHSk8eh&tU`+id{+y|7S#bKl(;28lRSayA@%0kPaGP!orWPI;U;je9zQhtP| z`Y1}$m!lC?szP#wdpf{$kyd3SzlMxyEpm-y@13c$)6zSe%@(@2vK%z&$Mr8jvs}Jv zsMExsjYz2-1x54vDpMt6uO1PtRZ*MXdUR$AdO79fGDGt2x_N1FC=adw1urrot1~3F zZ}8zXtZS%#Ts(f~(;i3;3QBNRFLQvpy*sZnQojaIb3?Sb%+GkB&mI+syjh#?*hEdP z>Am%~EUK`3Ix8odyu4iwxUoagMr_6M3YD0`44kf~!nNNR%E4t+Mo%?@9oFwQLq7Un zGzuX~&3#ki08}wjp^~LO`I{e*!hk5fcqK)uQTm%UP9z(`I>$p;vMR)QWn6Y(5 zVP}B4j*XIhB7HP4N!_yQS$yeg$CaRig(Kuhb^26#CRjXk$+_8BePo1-X_sE_zROLa zijS}37aalW`X)8-)U`tl3lnB z4U(O_Ms1<$+eSkl?5lT#35~xSkHix-PME995@PQ!$rU*?fE#j}1qhYBPs`878C9E6 z0K4pmP*`W8X3=p_SC76PkLMV39bMr<{5|ufA-mM2^wh7=e~Osmm994L(gyGg9!==-dE#!ri=j z(u^&RLl0m7m>UulVc~ZwJXY*IFrH?8O`U_%`_I6E>hmh$OZHM{bQzSfUBNQLmu>?_ zEf^N>o2df({FKB}IrsFr@h)^?={ZFgp%l-ws4!o*l{uSU4h%4T*SIclK5&&~kR_&2S_Hv4z6 zPXDH2OU>zI%ARP3sae~nj-W?Sf2WnKEef#x#t!eCe!AtT=?qh-vjeZC7Hz_TC_jH^ zgZ-U8wXE8~@9rb{A=$UJHz41@*&6jS>oL==>Kl=nt%eko=5j+dDnD@!G)ZqtToCg& z@%B+GQ%#=pOV)>3ks=xhu&mnLzgXi z#!LrO%bl;$UqmpOqDp%6>8ATMRN$ZTNM_#nZ(h@BN&D+DFp49qC0J0Cwe@iv|1bu} z;jVbs7Kg^F5}qg!4kQ}{f7YVQpv{MuPG_bgxX>0@cMKxEF+)@kRw(C*`jSfN`^^+F zqqGoQRak;WRJ6ykNz4MDR`2a|X3*?5j42;KZJh)4UA0D!FH@U$kK4#%u=^fqaP?xn z_Tywt75bC})p8@kUULc>lKzZ3hgg-Ijux2bIoRmj)s3to%-y$QEzzVEOqHs47qwbV zdf7LBMl+C~f7yR#3~7}P+O#x7v&5Dv#D60lO?J`BzP6lH#Dh;hj(3qVrZw6rkoBhq zEHld87|t`oH?8{x0?7S58Z46EY%wGckH(4lfN=vSWFZO)nXC<%ujDz_Nju!Gl@q>p z=Og%@|K2;Zg|AUZ&YMOpTUc-v*U^%oc#p2KO`)B}u#~MKP0wApi)r9^7fd;SUfezg zSWtSonioU_lQ*^rTXt>Ltjvg@Bz@a59vf3Dax~e5k}_2q3u0(L2ILH(qSA>%S1;JY z6g=ee66Ig}KG_FbEqzNNIH}byOkyCUHi@4|~%vLd-e}}XMg5#SK z<5P$`x?NK05m)z$#60X2chPK)!n?=e`@Z3`z{rN8WE`DvPi7#u@XSZx-q5I@bQiZeuai&w^S z4NpyYO{yzolE8^&4tPC$+wF389BID~I&o6Zhp037GEq{V8{)okmKRyA{cI9SjSk6$ zF1oJ%9S>2k=PF~HAI?r?N@39Gn|K&*uU%yhks+kTx@)FwpN)qQ$L__qho)Zv0O^%q z;(7vH76p5R{~nNDh28`PVzaqzgJgYap1&lAHGHT8K2hquVKaxhp@QV8PIC3`ac^`{seHqcl0K2R3H|X* zrrOa=pRbCOVO@S71W;Y{*|~p`@tk+(H;d0Eu74%~JCW>8DSXmgj6NA!z(kHeze1FQ z_qCSYW%%w{*a+^`YJ@@fMKKUQ+_EBbDh6v!RR<`l%aPd%H2UWt%XIiZ#O)Csux2mM zk@XF!p0gMH4(0NZF)A%eoIXq0=uM!neq6L-V0mY``RqKw-=s%|2nSMYY_>cz10lCc zKf+w{nf~}*3^Wvi`}XV-1Hf~B`r%0?jFd6cFYElo)jloxEuAI_Ax&HxL)#5=#`RJc4QS^61$af3k_z8KaC^YVTxD^UWC{%b75)Ml?O zU0&2A2%}fKI0zT(gW|75O-&)J|E?6)!0q|;f9V?Or#ZbXHa*x|4mE z6$~fkU-1Ig^K2)Z6z*yI>lapgd_tX1!GAk>O>j2yIw8#0KsHS04}D_2C%7wf0O-(j z3!67bY&tMczc({qNPnn267v%T$IlJUuz9<^C)FtiAVB)-nTN3wO>m4u^yr1i-0TCQ zLofKQq%{)_XtU>;a}U<$l*s_dmO)SZT7@1A*|;cbu-i&{Z8k|Mm=Ns^B5s^w19cAi zQ`A=?zwTrqCn%@-TrEte0p`=9TN0GgYj+@t?k_ivb?q|UUD}UP*Y$yXJOtFtdaSov zovaOzJO|4^$#u|*O|3!gv;Vp8)R23!){D%7MQ2*ve$mV=9@pFUFH({M?nTV$kJ(0+N`m-4c8@68tU?0+*dmCw7I zoC1ASyhLGyJjbeg^C=;d7qak~W62 zN~~C5;E$tsSvhjd$MmbTaU7Yv~~W|JfC#;j7JDpy7*`T7X`# zJKM)=$Y19#DL;n%nLkTD1G;sL!FF|>_|WV_?}jSg05w!9c-{15q$bx+S8KDb?p?dI zhFP&XYe>8suKx;kj$ZJ`D>KscLTJ*m)nDN1iOI*)QUw2w{%_HkSO^Sj^&!oUXh^*l zII@%-Q%8y^Ny7SK94sB+j2{_!OT?J-mWS( zBKUjbLIVxy)EGPack*sg3#~tL`)IY6-i*7$@}9@c-`E1Q;>2f3iKc3Oy4vzc8!o}% zUD^^~Ge1E&BotXz?ii%@Q0LK`bZ)vkN|b^zG~)Jt<{wSj`=~IV4)Hf^`NYQqJ6DG8iY(c| z-Ti>>xVE{lJ2>re$v%&iKHa6fmc)rM3+#NOKIbhcYznE|Ai9W{M?z@Bto@>)F8N~K zOO7-la%wu-IwuOos!B5Sw&PB>-)4hz+E-2#(}xPKu5WKU)9FyRiK4GIu-!$oMSr}& z-S2xuv>*;}ZS_E~&*P@8pkxf2Pmjtm2!`#bek8#T_V&k4~hZZ#`xm#Fff@Aw&Fz6zFvBUO$@=RoW-L5&q<4*@9%V zeuOuRZoitPwo`nCBaDuB*G!POQnV(fx;mXsA71U$QcbERX5chNuWAvG6zjoP#{77W zn)_Odse~aIm5>(%bg#8ONi+=;@>VQI(O-3%K5+zA+WW_QowE6gPcd;W`(G)<+OIUe z6CZ@{F_LLD!&KHQA?s3cm6ftq;whg4%~b-^$1sq=57KH2eT-$KOABpBMs&%C>JfRE%}@ z(O2)GfKtx;zL=kDCoUE>O$5)Oap|lDVX#&6qoSrcTHDREI9>Fl^lQA<{(6Hqi@(S7+2=eP%&kE9z%NStT1`p3sXVb`;XF>nrNkgR|Ea!#k z5Mkj3ze&~@iW`y6;_TTN?O^}{G+Ne7CdWCS6w>hSn=-Q7+*7_2pi`67ZX8=1+1j7C zJV2n?zfg+63k>#@vnKPwBQlCWat?z$mCS>!%@NwxR1tj$(q9)6L?2v(WlVxM~c_j;O zv1en@X5zW$wH*96r69UFhgr7I#9dzqWTFKZg5=f&Zy=I>Y@Xgru+kqNHXJpg{e{3)L^K*|+C4o30o z_sel*_=4_iB9)R@U9#6C)8Iu>4$|x^sZQtpm*E(j?j9VBK$m~o(odob2;?h?U1nzk znpT7Lg4ve)NOTC81iuoELn;cUul);DVL^FcYnP}^1X`Kf0}X46yY!6Z2S0RguQH(l zoqi-sQLLD)fCTpcaVeez|KVM=;b{9euAM3RB%}rI&#~$0%7o4g(!ET#0o!T%dcN61 zR{dMALN`TI0lYU*FtDzdM=3pOMyUS|Jq8iU@LguA5DwOOH9!ZV2rSb>foDb0STIEsL7-B-nVW@h{;)!vbIV1N z56*k*MSWFzTBRNO#Z`a5Ek; z@#&zW-m+&XDLXx#LVRqG1txy?nOqK~QcqY_Be!48`f77KPk(72nACoopZB?>jNWLy zvRQ%+WmQpP6&tz)em0d~FAmjP{#@rP0 ze^>&?o^xX`TX~R^4mN{_^T;7RpK~ZGz_)AT%pmIvL1!gb_y2EmaBUMv$=__94s?9b z{@B3Z`BT)i#F?%=CTW(Cscb{mALh0418e%*bZo+G4hXo;CB+De-Co!iN*3gvkFA^? zKvpf@#LS_`AMqb)~8oZ;u-I+0AxFIK@%!tmsWL=juMOzE~y| z#Do<5xqEYnWNnWLY9u|@bi`%d8XLt1QzrROEhx_T8mcbJ?(pkE(@s{0JTvszT>Twg*%kkQa1yJNFbG8wE+5yTXk7B zY54a)pvNbF59lKN{MtRqpGMr;WOE9p(H&R&kk^~9&O?QMlsZVJ<1Jx~4}J+Y;6BKj zWTfddkmsg}W8(EfU`2z`qN|j~+E3j!O0FfqGL^(dZJ8QM%@LrLah@! zD3>C{j$MAnTZC9AcC3@4#5iKdI8v0BBIeajQCB;5Imhqw+&_JrcRu60r#!o&i|Rp1 zJE~%>8ud1$tH`1XHolN>hN|t)gMfI4+$Hp1FQC&B+d)E8Wyd8E2ByK$foR9PdRE z&T6+p!^zEB-lMWT6FC9GTA zi419j!kdJ19h$lXw%-OdsGGKWFJAB=HRST7^g@!PP6aQ>P0Vy6I;U(m>Wg6-EJ_a& zCgBB4gInAp1pe9EYbneCo7*&$h4FW@g<+oPtTYhszJoMU+Sj~7I!JoKDe9r}Hvb2t z(J*zc5I{*X|CZqf_VH8NL`!N;BS(YX+%_vj0IMk%I9m$~@oU0?=or8}LNZz>?UhXYCgSNXR#Ka5oQ zRQdJtGz$hI(F#g14FKHATP+pchGhr;b8#; z6%+ZrAjqYNyX9=GRCxA79Wcdp3nK{jp=lmZHa)`v>-Qa_{C(6TF)IP#b6?R=aiUEu ztV`^Q8OlOpY}HY4RYZyXEqFq1AHepRSBaj1?2sfeVkN$|A2U-(P#z-qDnLHAItxib z_bH&An(7;{MnRXKw$qXoAtfa3zFGMY8`qrAE@YdR1p$zYmW$FeNups8k@HC6Q;(z|x=3(UnVt6&{ zRf~Q?!g@YlBJ%1VQFeBO75mH_{FOEbksBD40G-a&ga8P{jUPg8FIMjMM=|va(~V!Crs=dUk|;AwlQ%oIoFI z|Fvj^2TD(mC06E%Xh4?JF%g6ya#A$Q?9N|AV;NS3>SmSMU?b7Tu~ro9pUwKe1HqV; z4RnB=A9ZTM|2Yr;S{pG!urh*1eUL4WP+AjgPpc*|gXbZjcIF;u3hV6#HiqW8j>m$k zI)J<*i0awDrU_oe8)uXWH|n}NtDJL-ZYGNJ;uz`Ff4{z{J0N+9^sm6=%59dB$Hpv_`qK)#FP zf2m%kNl#>PC?%+`dejQB-px7#k;abE0WBupp^0O+{s3n-d=#V=fSqUg5@E)z(gldD zJZo|hxv+`}C^+X|kTm8&nfw6D6jpGoWw$hVR>1b(?NpOs$F)EuMwc!`5+KY4lrGM2 zW8?&Fh)6>d1XTlKuF+`+!*1G7F{WN=w7;laLYYD$HM=;y=(+XD2A+C3T_bejyAHEL&lQRZ`;dm#0)L}a+1(gvZpRWi`Bg;2CgjsIOjxhUSgjl$S zO}Z;&l}C2mek%589`1;+51N74NKw;tc9t1A98*hKNxRp!xG2IiSD`Nrtu4|bN{~3R z=ytqd<;aPjPS8Y+E;A`yhQFTL;bEtLPzH#7;qFWyaXew2xeyS>V~_kVH^7?uz86eQ z#DD!$rUr>+FR^0gcb{mEhvwIQCI?|+Ihu8|x+^bJ9WV$rJ(@jH!-h#MJS7GR>xmf- zhhQELpBXH>Z-uO~glSO}szJE4;GF|rSo{qftF7HijJ?6Hl)xI^Dz!3Uelt;prne(o zX77Fgd`avDu(#DoP9Hjs=xk=}vR6PEyVz#WAagze zzEsW9;eGZwQC`-QLse1D9!N(|-UtSPTi$4AKp~MIma+d8;@dejidRE)3FuGqhLS4x zs`2YS@J1imRDU{k{`oGfP7k8vZ9_o?e1Jy}gPsv*OW~A1*Y<-e$VWTcEQFDwX~rkh zVWJ7kP_A2kA#pETL2C#XoGj%eWYnHoU`>t_Q}SWg=tGUm3)!Ekd|;Jo2zHPa^&(Ri zw5Gpopvr;SB^6la&;=W|{1{)0u&U;wuMCpd?&{oZn~)MyE747tg4L~a5HyJ?b{`un zH_4{_^%v1xo^^EYkj2V}MOtqu{wu1ktjq?@Pe~N5gcL015Y0G{!~d-6Zym9#1}OPJ5g^8={$qy`uqYLRXv(v0s;50QN{oj|!3GwG(7H&C+QI@P2m(xs(3SSXJ^ z%Qmooy#gWeR{D#=pQfSCrY7E1i*znhSo07#isrT-G}ur_ksm=j`|dUkiP+Vks;X-x zF#~J0<~r!_e=wkxa(T{aB>F=aDR$P$z)L078Yg^piDRi3L1jD$_O2NmGyy0|97Deo zR^BWYV5Ke%%J#EPrKsjuRh1nmvwckr^Gs8*U=`6c?Xw_@tZv#^hs?(P&s-$f{hBU? zEr_dSr%!tYHs=*IMTbU6K?^QNC%|fM-QjjN=kMV%D@XD{Xi`q#q~*{vBfIIbm{Nh= z(0Dl7O#~W1G4my&ksX`$jtXzbMlA5NPd3ykM9W1~)bloq%4LtOOV@+H&&dbSMn9y& zNidfW(}s$O6H^A+#Pa~topGXGU>9;U$^Cz7rH{z>&SV1CH2MXJY?2EweSK6d1A8$V zT@1R^F|yg~QSsRPMhui?gC9UM<#Q{XY9tL$aT?(NwJktd&z0#u0Fzx*7O>m_N?RNy zp^EC_oFE^0?`;7X7>}6jBq;c3Yixgo?I5e6yBpFaBK4V)o`5FHrx z;0_Sfs^mkyNZKM~RUnOq#PD_%LQC455?msiGe*>`MP0%#LT(J3{+p2U6FQ0Z8cF@` z7ykF}ABq4wX1HKCa!h1$BMd*~<8%-rl{x^Do$_f9b%gjmdjO@5B@3_`lA&QbHskIr ziX#tybwcO$^~6I3ND;&t`1y{wK_vX#@9;i-e;uM4?QRj0J0Uej<%+7>z3sboGRVMP%WC|0a! z9YYMW-r0;Wyr_q1BdlCm)If|)d!dtAX|HJ64WaZvHmXDQ2Jr~3T!**HFU#ok#FzHK z1W4GJgrG$Twm&ieUW~W}bS&<7(8a!a5F#iBas35D0ER8*pi6@f==N4dLax4Pc(eRu?hwC)t~@qV`KOsL?<( zpr5i3wYj%}xLfnYfQCrb?>ZTx>M_+6M#XTnTS9>BRuw3u)aEM26W*FjF_QV469}4W z?xN0R=3MIzes*Mg!GlUgzr3>nht*4-so0h=CLggPHmDG_8ow&7#Bn9hhMjx45g6L` zQCCb%DtE+$t-f^Ggp8(wi@HLxvi~)R2d9cS$vWCHj=WY$Y`(tY{B^lh_Yo?iB^Fvf8K=4;i_V&3S6;!!H}+B ze`aNO9qYg_@uCXVC;qhP)bK`}#a0E!Jaa>hnWQrk#y3SsDNAJkI?7#Ty#)i6?ggC= zB5(A7a`^6ycZNCd_j42D%_tjdQTmBA(P+zMB_k?266=EkP=N4@-8Px{H(tv`)>QVd zpnJim?UiQ2Xtkgk!3HIxB5e2&bq>i-k6{$j#}@bu^B`6XmSnxzw4pr{dMGBAVuwZp zwwcr0Xtl^Hc~L4hl!#T7?^Xg^^v@Uob4vD79YdJ<*PS4)o7aK+$thvc8wD0oi(x}G zZD4Ymmzi$jz5dz;6J+=4CZOo=!$Ek%^BF*_oDq{B20;u8c9;;F6rmKQO#(Kc`m_VM zRnu-aK!U6*m9HT)OFl4Z*x(gWzY^83+tD7uOq)(hP(0(*;fbs?PK5Vo;(WZ$di5g^ zUv;NZEe*>|rCGX~jFnhD4LgG7+F951c1kGZds$~CDZCF`7*-%Ex-=`FpwZCQMkRDU z5^m8(86wP2&vY_OwYPuKVj;ec>0n{MA2+$#;0RFzA@$#O02s-;7l;_#avwvHR>Cm@ zm3f65%&MeKr$IT9BRdM%X02&)S;PQ~`Vwq+#{vs$D3`5f!yzh4Ui?7C%f$8=p>^9Z zklEn1NuW#C+CIAaXOl1v@6Tre#7y6i4g&4{UZxbn%;xF9cl-%CTeJB)z*jEXUYA8A z_ZNUTvtthSB~mU^34VW4l#o|tG&-^9*C&8DNxG*tBMGj*n^{1@mv2S6*a>|E4Gf>m z`y88_m8TE)v*t#kyE5zlhZcX9UjGg-VeyKN~%?p;C&L8sR$orOqE zb`3WWgZCYzQtKd54b$Wln&=&@MtfO*v(>V&2-V6Jh*;KUg7Ng+Wa?OKRd$Y2MUuuJ zM~)i_m;7HoL+mB91aB;PZ2iuYa$NY!&sn^^5=O@S_tJq|Xlml9Lmk|#?{9Eq=6Mm2 zow&-`E;eNo;B#d%_00z>&WQ@J)^u84m>GYDrXET){sutatB6L!awacuw|=31993E^ z7#);H?iE=o_^NVAEf*b2_7UUSV}hn4=`{@1 zL&}i9JSL@@RK8VKu+$;ej(r6~MbdBWt$a6;7PrPrtygC{Aq{nMnhJ@b@O^risMw!=El?BmEPpt6p1^Z0V$LVME_m{Bp0W>*bN(|D}jh( z?XYM;gd9-|PR=5tx*A1wiHCCbL}z8aUBz%o)-h8Im0_7v(8K1gr9r5{@3);mfCDK*CL4kQTAT*1LlF~bzrJ7G3glA=~7f>lWvFxfz7=nx=XV;7BNf9k|NldtT!Mj zGIv8XitLa1@OJsjK0L{*VmU*nyHoi{b0+Mf zi0ZE@^r!bs!{ay-Dfur@r6;I-^eL2vhI(9 z-i|Plz5Sj!*h(VpY7i_{afgv~tvxhef~-H%^7O)=yftRNkQrI3Mc-G z+bA7kPSnKoQ>s66u|49Ppbjmc&X_L6iiRs8ExPWk&rME>vj)2%3EZin;+buXI2l z7gO*F9ukgBk6o(tq3q!C1zHFB07pYE>JPoILJgqI{uq-Pp}lp$hNQ05X?nkeI$Wq` z5$<#dBp`hKqs_whzbnF&^sSee<%JA%Gl+Ca`G@Gmr!As8jg`)c9u+%kDP_EjUk1?1 z8U{j2@cAJf1U1M1Ob+6G9RzI%ZrBdJA>=irC$h{BQPr8qtNzx3ulYXHn{Vkty2c2LxRW{3Xz5Ra0B9; z6xw4$e%h6qPAu5HsaW_d@tO`BEsdnp){I^a054Sh0`{u8y&r=yKJ0{7RC<}1ZzkrM zpJ+U9N)>&+gM`Kl_%yRHo0b5SIR#k6ygt-DBv<+sezHr^qEvz{m%G5hu0d6EBHf+$ zERh}YM${0NT?is_Z&kjJm@n0)yI5F^(r)y}7F`wDL`Dd~uWP4awC0m@((Rn8(#56m zur18CW_pQvS)>O}93%_<-=Z~&4LX1b zviiCS?h;?Nh0PVSLu`1aSU7=|S_mpMHDGFGhgnTC%2lKzLZ~T`V@AW91BQEZzao)% z6P_tuB>XH7t0%ih=w!e~d(lvuT|9!u$Od!fViCh#y(T{)rL`FhC;hv$Z-#@jep_|Y zS;#FZXnIqDWVm%=;W%P@)cL=T;-@ZOqd_Lp`zhaqU=7kMWd;q$XFA)d3sF`r70fCk zXH8n*VV4}GHgJ`b3wJvytVA9a4H_Fh(ip%KR2y}`(!Wr|g0=oY-w7hE z-J^s8>5j_}5Y407@W_{$ZF9q{nUZa09Tw3M#m?qUSb2U1$l=hrp!<8fBqdeMbEp-2=CHM;ym22^@w0jond1%&JXv+gs9M8?qd{rzRJC zXj%_nl5}HJeO^M$Ue=oqS`8-+I@5$!J(X)5Oaas!>^c*Fmv(uF4;5qwKtpc)XduWC zUe<~BqwMYjq6M|Ty3es`Na4qy1yYvWxx*;E-0E?)cV*Z)jV|wuHj(^U0_Yn>#>W!8 zX7Q7&w8>B4)C(FGw0Kr4`fFQk8Nu3$)R=HWP}d;g8}8IXZrWdmzw+V1T%%!qbNH;m zqaMsXxvM5zWCv_D$srz^ZFh5$tx(TOzSE!dK>1<|kIi zi<>=9xQ*Cx{{9XvUi^AWV?>2;sZnDI!{l~=y6kp8KRE&tmQg)9Yk|NEfZr( z(n_m70;76SC#dzd3yuSvhcN+PiesA_FJ%t@~F0Xl@#C# z*SiQZ0!VZ@nP`VfDjjBcH*ynP32k}Q)nUGF{0TLRqf-R*440bhcjCuc%xxt1%aGbL z5Lgl1y|f~4T*ocndTTyj+V;nsmWcND7vEvT=tqqGy)~9)f4w%TxK?ZIw8l6o{oU2X zr&L!3lQx~Y97wniiB;JAYChuzkC)d>9Po0=@#iCPa5An{2 zlH;@zH!!nfeFce5u~i6FOWquQA*#6 z(TCere!=_ep^IxOinDQ!j_a@$l{j~Io}X|WT+dO%ZCte z)PGDopB2S1hsIntg-PMzXu%yz4mNB`ZA+>(sOybu_Y$*gVKT8K^~$t+eGLEG^V`w9 zxCNKm+CoJ78V9mo_^vjvq)4v<+;s4J3H(*vIW0uWu&xcFmG)R zSmu}+f(5$ayXoNRoppWIUmNl2CmW)AzlBzFBJa7Hu_hL9Ab-15Y-z=*14Y%!~%QiXi;q^GxulU4I|b! z5meD+#QtSU!uh&>+@VNe4bYJfbDHs)*AUd=c(!6WqGLjvs;uLE&{eMfgXn2h-S_Im3?8 zm9a0)PFHd&tlW@G<>#d(a!+^uGA~&|{_F!jPtQrmKhc7-^0dcScwcGM9eL|RhMqjW zM=5&PdA|$=gJ6rg1CnuX$$_-|G9xv(ny*6s1m(NZhu%;`t$Suu6N#aFJdG_0U6g2H zF6O5@u*tKUG{IY!D|q?(k;2Q#lS{IxVJua0V+6)gjiaqr; z)ytjk+3^9EmjCXmuQ0=mx6zUsK{4`Sqtd|2{&#>y7Fv+-ZPLK(7q_pT>OwimKgweh zq+8#f>D(a9G;^FeRhbH&%Cs0!ozO06(V;~?r?z_93{5noc@K7v$%#NK}awQPiU zZoY%PwNWHKGWqJBd^aglN-q>tBB)=>yCENBURVH@zpU7Apsbke7ttTfF6}I;OS9)@ z^X3|yVeRH(7@)WJkQ+3}DU>vLA|I;FxgUL*nWpBX1B1C_kmSYrv6yxuS9dgmCB5w% zO`voP^;nmJC9CJ_HzEQNnN!n?(6!w+Eg`n zuI8>o@kUPlq|b)L%$~ zAl!eZ0Vk%tPziy$WZ9ppJc;vG8#W={MHtmNA)JFu#x12Yu(ACYre|2WpzF&C48~Du zMzQu81! zR7a7U7S{y9U%gM?g_tlxnz>0qYhiDr!`Fz>i$US76jS_v$$fc~$kXD!>Q;R5biSWcqQw7%gATr|u)QUy4yie7b} zYOqX1%*`VD_4}Z&NV8tsG_1T#)Kp>JgGEC__QiZLlu0@-yPj_)6($T2j7UxEnPAH$ zg-Lbk+Vy?M0zl>XX+1L%fl=IiF(9zB{^9kdxX97bu?iRGeb%IZa)@IVY%0XB@Sp!~ zjkj`+F};pzv6r2ed*V~L@N~~uZ3-7@dabz5PX2Cl5{iFhsP!3^%JHg2BL&vKvLzav zxF17+pm*!$bsfZ3yCV?yU2lJ?a3LRnL^IXcc@rx zPkqdL5w6v+-(3^DwdY|iuSzt_e=}tff7=6~*=){A(L0E=E!WoOAoCVqq4|TGU#=7+ z6pOT8$Ov-Y%J*bm!*Skn<5XDS*Y2C3%Hz4&QLFNJS4r;LrPgctERNf@tJ+{5WnMd8 z+{n_ZjMkTje&rdsO6RS6_=Gp2p|Sc9A4I|Rz`}XFY~X?ezOJU*Hn`n*K&4FJ=Twt- zid{-Q8MF2g1)ydp7(UXNlRljqOgpIul_ktD;}vp4Y2QoDs2WF7Rh%{N?Z;F-7aSH_ zA9(F;RV;`n89iEZ8_ICzIvSV4Mf9;2TI(s7b?a0lXLbz0J$GTCb@XN02mu%tWDv{d?aQwSF1om z!e!ZVZ}EWy&V23KONE@c6&MuWvQzfJ{_@?VF~UQ6ue%Ys@U zmX5G;3&cOc4!eyT(G{IJRd2Q{kID=NPpiu|7dcmBj?F`+R{k%E?uxrKxD(d9<@qe0liSIUAq= zCisz-ut`#&&?MB-Wntcr5X;Yd1^;L?8?inGy_Ppm?8M7WIjP>6GPE#YpR(V12^BW_ zm+8n`qYx(?CqzbZ=B6(mBh}68Y&SClg&qF+S8(_^>xteyQ-hqUq-|lIohy72-9-x! z?%!+!l`k0AeF2$>)fbL;s>uDcc?t(I^_QAxvQiOeH5v$!BHzp;Y7SH)8loWg$5@sR1v;_mX20Q&LG;(+Y?c<=-kYfi%C58b~|1IuDM!$HQNkR6k5R zEy$GyDAR&a}b>Pm0#?yaJ_CnJZjv5Uc* zsWTnJ5D(-YK2I?}fpPVN~sVIme}cgHUC@oVS02P5Jcu0iy8y$){t zxnqzlSFOnb370BY8`>HKs7cb1Q}ua!7b5g(pBW^b1rO#hYj0-^?>zeV64Ex{6v8U< zWko%+d#|Jt8psqbYRswCRoW!*j zRW{q=W$xm6*AhhvCob$U61*cpiu*TcrS@=_S6LXl?3~pt4S+w6KgYX~V7Bp>HE9q~W-rL*Rg*dE zvg=dx^w7Vz&dy^{$n5ITc#w)goBBiZd^B*ot$?)J`?J$P{+ZuNQ9zjAZ`ERmQTmXF z|BG)GL!HQl9V@VTmMIY`9=yA{UTH=yeqSNC49Su{12nGp`x`d<>5VJEKKF9f-gGrd zPJIJW=WHMvKqyDIpkI2iPlXr`_F7djaUI*bqZm3zM!cw^Q?wN}C~>m;UY(zGyto?D!rlI@b-84W;v3Sz*)1Xi`<)ybyvEpXMw z1!2UsUq1w4L$1@h7F73C!&@4x-nQ5gibSFPRFh>opZF9Hgdw~C#uC5mSl$+7r|^Pz z80rX|YnUA5g4rX};|qygXOG~6;Cl7>9&9dBLP`ogGy1f=9>gaiQ}t73428ttYIZPh zh1$8@a0b8^oU)gsf!$=?*~jN1N}ya3X!fm1v$V$lm7d*g+eL3`-84#D$OY3(CBXa< zl=iEjM-1Vz=0d>4`9lL9(yg^l5h~DQq+0nvx`)iV>ZDWHKmS#7fH3jzY01}i7q=-u z(Bco)LkQHqg`#UA>AmnC6%=~@HqL1#!;@%nGimwT|3VedKD7w$DoB_pYqGFc^Mt~2 zP)x&TX%JsRju-G(cjo8?!_tzOlk5st1>=ctn`!AEHE$C5-JdP+}J`J zLfmpGG51%p?q)ZWkCZyw56~&I)7W89- z=6=D`ihWX2gfnjLN*dmjyY3NhRw3)W^+%AP7SB6S7543gPsx}u66j5E`oHgRQeH8oFHayIo?P}2s(<*at|=cui;`cJefa`4 zz7hW$Ey4Sh?ZTVU=b+$Bn`9&GX_?b_GvxEOs%9oP`DJQ3lb;kDAE3hHjotB?C=l1< zC=|vE=Ce908S`&`ssW*8rDr+qBr+>OU}Dj>_AIZ4k6$&$fQ|%2?psVK#CWecmw>zk zLv3oL0z(!oT1J~ISSKHyoaW`i-{O-f=DMHF&;p?Mj28S4!2VK1RTZ*ZucloT&UVq6 z2y)^F!Y+%#v;{-S>26m51Y1vRrO7n2i@q_r$oFltl(|IJstw3Kb8FfhlT6HYXvms0 zuonKl7JDcq^83z>04ix34gSkbYz0#!msA`7tK%Lak(tbFJsU(T`e_zO;u$FvZ%4cD zPXFLbxqaV(8#*sGPS=p(abX2Plf2JjVPA6Pz?Jv_Iz%>_0G(~b2hlTvjHvff86>}N z5J011y<6~f!h!-piXlsg>*8p#cHNU3H#74$dQ`JF`TR$}gb71Y-I)00d+ zF$n(xG}+dpoEA1`m#8_*=DeiY1u3gX2_X%U3`=Qfgj}($5U4^Hekzw)NCpMJD}6+m zGgFz%bt!WC7!Sl=T}?>b#4$x}$Ph&F(6oMl^j-V*X9ijIJ25h!onAt;JY;tpM0I`E z)IxNrSzEqnK?H2K?ci0UOjGd43fK1vlA7%JrZQQ{l=<}`v&xqbHn9cB>%(PeKuN96 z4QUm-=c8^=`R-l2t*Jo>ApQZ^S!u($UKe$g}2;`f0F^OmYyqlM|sY5cl}h} zC2-#4Di$8rtl+Cx+rU}Fb6(t|K>}v7Mi(JD*Pl8)#FTY5KbLqmm(dxBYv2vRTAB2m zF%Szox5u7z6*+P4c|75)AAkNr4J_t8&)5tv7p!oY=R>79LuQPX(sH@Q`HPShB13+e zfrG)-yBjSTXDFC5nP*_!dU{PXxJaWbnsh6)MQ@?UsG%MzY6p4smFjL&Z#mtowqPGL~q@9D+e!F1F#L zDMY4qML0A0rQtkVA~CnHL&0Kpmu@CVWyr)%J1DSl0bI}7AYhul-`|?-tY{alN68J?9F z{QN8}g$sT?B&C8aPMo<6EiO3h173oa}5hZfpx-5MK!(@&RsG75o(8Fno7npr#u zanU6u((tACYY>e^R>YT#2ewan`ztI5a{F#O6n^wBEZfuOAa{h9CJz}hYX{=E*q12Z zw1OCaU1{=>k!g)GA(bBX>s+Mc=J7C$g)8jh5ueXAN)`FWb!I&Uzz+ zmD69oAOh(|@F@W7!uvJAh;Ygc|3UQpE~ za+fWFssj0CMIoXZ*@6VoGKbvT_MPHQL#GnhP^ZUPossC4-G^k#oU>BFvE;&2wAkD3 znm27~V)(iRddm&XKCBL7&Ma=ykln31;Z$uCgBdmGF&BCxb6J!sliR~irs>gPpymag zn{2rCOz9w5_uLscHSVv@`603;W;XSFmzsYTRH)eg#k`+z@`JpJlt^A*`4wOO{pC-P zGnoUvZoC^-##P(m0F<(S-WV$BA7p3eSvc9TZ+^U&CVz=G|pD>%qa_6?$Z=UHq16;jH?q8hlB0qu4J{!N5RAH@D@I*$2>JCWZ^` zdiu&1Awdp@C(tuf`Z~s?fIU-N{%u77yJ^9o^d3bDg25t)0Z>j==X)>rW-N~xnK@fT( zua(&Ahb`K~yHNwRYILd|vAbQwf*#~k)ja}2@wToI;nM!CGwVzt@8!Yq*!AXB&Vss0 zGn&`u8JJ$TCpSlH8^pjQ3+}@heqt>?#G!;{tF3r*wMQ%;jzPr4Wx@IY`*x?6t&kx7 zSg>LqKP3ve71-*hMEzl+8pZ2;oMX`YHF+M^d{87a$gFUVBEZQTuNYwFkQEO*z*s7O zzVK^0Awsq0ltdnQ-!DBvPOsNvC1mG>r*uISj5l2-^S&*N$9l}sp_Ww%GWl|Sz<|_b z^al{KBDn%Hf(vR!&xuduf=gGKz)1gHFr6;_g2o>~D}Ks4jFF%F@)|oNA6G9_y2$X( zV}W3khWvm-1Ww#Hu;t+#bp*+slO{$sU;Jo)!^~pfaP0wK`!V-?J zdI9%!^}GYg)WlbXROKC-ou3TweKa~85A?q=U=7M(ppwD>(W+uo-io0=$sgAi(9TBk z{)T2P)~ztTrPhUW?F zeVty#hd8-MD{4-Y&iKw@N&0^Ij33OmB`q=;BK-D`(@27r2{v@vn$7D1Bw_ejotm7R zw>4iyZj~tyCNq6Mm#JcV4;9^G$~o~MD>d1$`q2cehxm{s9#m3mjs^N2L+R_ zpKGhIBd_YJ4dBs_E2;(lWHlK;YspM`&1(Tn2lqS_TqVe>$y&7fBxhkRE+mT&(1vhLaN}BW2bNM7LiO;*28wqtgtWH z&IMm4H%PW{%cjOch-VMN((a4F16pS&5Eell|? z&3)i+7SA-331v#tdce8w7vak9^&gmIvOip1X&})r?q(*EE)UhF0@5}n2WsK)hGK3> z(mG2UuR_PMHqEdl^9Q!U)`f0d)~Zneb#i_(rnGj-4=Tcx4~~P8=f_Wic`8h%%R0sf ziER5rU}_+e!|)073%dG7(p;Qui1MfVNmj}pJ`u*GJO3<7wxUq8@qRiw_f-9_N6WCJ z=ZItV>=otyq>ZN%U7OAAj#5}iY;XYV!cy)tvLr}oT1Tu*?t_!m-&$C?5UeA#t+wEZ zBf-MiH0ax!QpaQ6mMLrZ;Nt=tz{=Y=SWDrouiF`G%HeQdumZ_c7jGV08 zHw1Xr`TEK9T=FF5Q>vRVTTxRPwYDal1DxEbF6FC;CF%x5u$MDNJGq8{WSW+$wJ6EZb|u0+2RZmqJCDtM|piG_v<=JzfRs zGv|_#W_lkj`A?>SY@K#49vd2HHb*O=SlEndPJ;aCzfBCM*-&?s)4rbjP}RV`(lJTMupLIOfvAt^juF<@GOGh70zI z@E{G++_=Lw^sY8rz@USpTK+}B;oi(@_=WUfw~$hmIOgY@Qowi${wu%itwjBT5@Vok z;|o820t^HbVoh!?Qm)E8-co^FDtZGn)62YBix3ndwS6o|zi`Z&YEQI@s6h8t46GnS zw|q{UHF0ovu8ZOUucVdI4ADn&o@YarYj#0>f!PsU3vjE8W*YP}?2tNpoO3UAr*J z*#{=@FonwZUJGO;9O~a|K+2aMb#_s#yYhG?^bhZcxBW7Lke`}U8?WYgJ2Y@%za7-s zA!DzN)%i$LjNTL>{-a;3|Fi}amDxdVYHSFuaSwLmRj}kjJ;N#W1+`U8{qmN=-(lL!=14U0W27 z2lM`SK<6cMUoiL~_cd3dE!i@=qUtrvRS{fBD(F3bnZm6K=2S|17w==A!VXjpB%#zF z&^0Q4d8P2e6!BV3jgJqf3x)GJX85c&X`pmlPB#SH$jinaRXWIkvXemJF2a zyYx*?AL-qxfkHxK@uf+4!K0-e0gY0)z^TPcXV1E%g&Vlopbe>nL(9mQI506QN@}fK zxLMgP7=-ui=7c=R5u=tV(p)O$OE>9OYA#vUx-8&5vuuMjyyU6aosM>xOF^gL9J5r5 z^}Ty)E;h{CE2lH&y_0{Slu5=Sj*7N50tfHJ4{Dy&@au_YFeAO#8*(e;fj|Ai6; z{o+LeGEc+9M1Mo#(Q-5muk*Z5nW#Od_$|{*wpwU-_U@M&z-XxAdYhRThX1gcIm6{T z6BMZN{_~`CHE|Sdv*mJ{=Obq-)NEpZF=!^!>)87%B&WWBS4;_++^Je%`GqY4ZALJ$M7q_wpkHcNiI zGfHV7?hbpEW-_YUY+Bji;>S&BT&iLoAG~r5vWP~AUf1>&gC%cN&h=7`~g#53oFEgmgRUjsAsd^7ZboPBnRu(8H->&8ebl4LQiZ`Y#O8 zg68b7d<`5aGJX;r8^qF8opu^hGLxIO00n>TMa0BvdiiPKI^2WuDaVC$D^VYl09WfO zWMEH&YhE+~VF=#${FMxm>G%7kaZ)bk`ji}iAfX!ut%`UjzsQepntL0k@VVtt7`0Oq zTLDpA>5>=Wf_r191G>Yz?%ty>tKxcQgYI~D9Ula?g%`}HWpN7HqIMb~j@pN5Z8h~3 z3#Q17Js=e7*q0e1Gm6aJq=Aiu^JXtS0?fX6`U^O&bl`iDGz@5YGfyhG(28!2co`-$ z^OXy9d|eNRQ@ybK?D?B2u)%T-^6@ix@+$Su%iaF`8^VyLR*e@_V>6d_02$@)iF@!? z`Ton1R8nr0)Q@6l&b<%GppEmgk7oEe>DrQMS~C}1sZ#ukjV*Mv)fc4%L%@c@q zZc`{_?xdO^x|U`wOm5O*OQvAu+0GNiNEUg_z0cH;zgD}!%BB~i1#7OT8beNDvM1%( z+@#&X9$E_&s?E2-pS&-WI~9ds-8*Y(2^U^#{m(|4X}<@87>v0~%Ny?NbtBKrF{_O= z5c)&Dcc(Nc@k2EJdY(Q?*OSSO*3mx2zLwVjuxHb!gE_2TFQPin!Rkkq*!C`~0kF)C z!6tl0Uv)#WkCitd@7~u5#0Hl4-}+P8{qx(#8vS=5<~=LVm2pDY?l!4hMM@lI`N56f(N}x&gG<6Rkd0>7pz^W zSiF&wdbRrkx+C=&(mokX;^FZR3Ii7$vXA=MnGsWW=gTB9whX0ATldXWT1f8Kf$4>0 z-_!PaiH)Q_=MFxih}rqx$;@~Q{yCHR^gK>5SAYDGO)rE-Y`%nN9|kL3#``jQFj=6$ zr?v-`dixyfhzqzSxc}Ll2#(?Wp?6;57}=(cQK&{q&u)@;_^H~~<{^#73XLvN|09mx zvB$ULP14VGp5tJCojo3GNt1VEio&Q0j&JzmE$}0u=I{>y-8)rheZrxAnVX*x$zEmP zph7(Fo;!8`Jfa=3Bw6_z4s!3fr8tEBJAX&4r@GmK zxp-b8kT|!>DjZy@oyT#gv~0`)jDALqZ8{a#bJL|i z@%FU*gcCS-yjV=UQ6*>E6M`7V@KXJCgc~(w*m~UYZQM2*fH${JnYB19?r)|M)Q>t> zqh7W~&q7{2UC^Z|zUa0?gJIBL<8hE(+uGv5Je-XXCzx1nb)~%^5M$}p$D=Uk0x zoi%k^j*&_3KTTdT&2Ll|l8EglHm^q}+J|en>i<63fVVKa^FTrL-rWG_|-s7ogI`dPWE{mIXZP2My12Hvk01rpD?G}}*ijCZS~VS5fB?vXR4*d8W_;qiSH?@?*w?}s0QRSk*ke1gZ+ z)A!Ptu}EC4e5H#NR8U}L77u~2&oE!V^Z~K;57Sw>gITxIFeD2s?kaA>A}5t(yKj55 zgRW+yCc81e$!l6;{@27oDZ3!cd0tbScim1k``?5w^u9aLiifTIQ3kotHHAh zGvT{+0?0F}sHV;k=Lme7hwnKuRyjkYk>!L9+V8a2COtf4KNet)?38Kg*s${n4bvRt z{_w0c3uk_(tw0Z*mmI?(JW#O!2Wdso>NseMZ_&`htx6PAyw&RrOar&-?P;cUKnH%6 ziN%vw3H7yDqmHiGe`|f*l%EowX+7lU{T;EE()!oy3bcN1VE>vg6mHHHKiGx!N$Ipv z=_SSo<~(-08&hR=ooj+eg8R-vuhHmzHXo;P zwU`0iuqt!M;)>La)A?XtkD}eYm>cQsaPGI(Bwj}N^poed2q|~69W_DrF5%SK$?`!| z_taia0#A|8-(HddhT)ighf+3%8UH5PLipbd&P1Z#nQoF0X*<9vle$-znGn(bPvbun z=vy+dsm(*`yEvzVWGKI2piGG_V=z#^r5lt{GVan$3_x$02jh*Q^QjEzHLmAlWsEna zbSEb+F$cOrI%fWCzdht6$>lPA6p2$>z=o zS?j)J%H?Lf@*lT z?s?7k(uHZd#IH1xvj+!)bb^OSQPd>(c`v3H{9MoE;})wgt-&C3EHRrg$hlQV>Lj9{ zwm!XpOl&Bn2RZBPXY25VMylUB1li6_Y(a#GRU3jQ7;fBfJfShrwu9DNsrd}*;MU1@ zvsKpV3L(>7?nZ%gU%!dC$*LddEJRJ-=FUPWhRW%XFw!38n>okk0n>m|a>f~xnH2on zM3(|D1!6tb#QXPLEUMq8spTT`$1TB`;Myn9vwXF4bx;8lU(Lc0iT(8}YcZJ?+E)2SQbz66dC0I+m-7weySuC|KyKXsNoRyBZ(1fp z%!}%nQn-$L=N`X6$!psrqjS9 zSQqfZl)IK$z%kX2XmLS$?^0?AGqaN-OBF2AA{?Rtxv&1YO<}Fs$aPmB?LR2J4H3vB zqh}wS48EWL{02`-kdBX+V<{Wz7US!T{LdcLp2_bB=}&rGG}DdfuBPON&2bFZ@lB!oFnmG`1?QD@6=E76v5nN-;TXS_0B5iR}w}I-Xq9#!4H8*T7PIax= z1VsvZLhS?W2V1630(42!I*!CV5}FjTK`C2O8jIe&<7-ohi*`QoVNAx?G#|Ei%b89C z`9DWj9^k^+#wRu5+1-d3jCE%bvMl0Wsx^y{)kTW3?l?l+QAgKR;|Os!6pf?A5wgy- zt~fi6u!;&*md_DK*hL9Nx2k-<*FVW_l9_pr=X#&x_dMRRnH5c|>vcBZF~RLTBM;Np z#c+*cPQsLx35^G_MM?bMOz>#CuM=YE`TfmCEJ?@h9oa{%REhYR^mlC@Vn=>G_RM+E z@`um$yDVu*!xSW!&S?Rg@KRo3y z4B2GT-s^;`j!eG}&ip>oA768&lVD_Mq%m`xT3ez{E*LA_z^wZfzo3#dif3T{T?K5^ z{kyV^{Q5=P;Bs3HR|t~3xPGR}sga7##PFZo=F|xG;ii6OkPwvZ*gtSu z;--FHoO%0}JsZVN*ix}C@Ec|FyWPiqQ0|8Z9S`c1pB@~3oMEGvy8h}Me){)j2=Y^| zinz1fWYJP~%lcbR;SHUS{xPQmwsjfEI`7JzS*m>Eu3dHIkUM!sSRvcx60RWSOw`2! z8r!ue4wZv4fw_WR+){NpyplL@-EWSgUi9BCukohTsn<*uBAY7!$t0CtSU<%GtkM;A zQ;fRk+fSzb3F^ICgPB#no5Rvo5l!^q-Ek=<9DNt2sROioiUC7%YM-oP>)-y#c($$R z+lXT`H>we%_W!1d(L_4cwt*@e z%UikELVXw8Hu&bZW+M&Fc${I>NhefuuBs#&;9Ck^D=*Bcm0{9x7W?Z3kTEyMIw464 zN<`2s+?mSS%S1m(Wbk&*xi|4NQ^^7l3iaO_wvsJ=!tWv9xsCo1neqp~{b{PD2CYU% zbjMLmK^F`rTUzc5%R(76LDmNic=x|U+SLbvjvr{;8VLi$Wd7Vy0^v53L%=x^0y zxo6R$^$@4lYyaTDY&$$VrX#wa#!BI&fA*>^bUqRA%L(M{FQ^@;qQ8YzA;(HQ*!$0X zA%X_&tqTnbt!?!-93rF2={IQ}UTU%(Y%;0&Acn-Upz8k^4E&o@Sy1NhcK;6(?|5Km zA;2a76ckM5x4|sPGpOP0aGY)*oyur*%JS+MtEoqa+z@}k1)-)a4Pdn?sWoI$-nFh+ zuc!_^Q31n{lz{5`OHG)=Gn%{;GeGjRK_<>R8LzVaSB7gK_d5Z#8(-WF6OfX$7^koE zP6J4w-H!?B{G;FPHjT6-->QPwdzMbHfRqzI`vx>D4ZSxSH2U`xvxy|@0!B@dd|-qp z(x}1nK?BY?f4LldQGY;qMDuE4kM;0T6NQ>5n%x@fg!PkP>FHaftGyKbvK_WSa;K|( zl-H9t=b^!J9hZ;vJ(n1YNEuKTzln$QSV)iib2Mv|_dc+VsJ={w?%`AFLG zwLwR|I@dmej2$#$-`2bUS)S7q6aq||7I*+zd}1{*!S%Mk`$7YvqA zM=1ZB7Jduax;8dANZ(_p86qggOMJb379>AO_~_ap}@G3 z_}02`m)c12_M7l~_uqej64Fr_nTLLkZF7X2Buf6_ow8vL$XWT1HwE3!PcF5aD64(YZlT-L63h{L(B(fyA$iq&c8>C9oMhd3Cye63lJeMg zVWM}fp9)2#DF5C`Y!2<+_lS|;k>`RgiIxujmsNtjRJCPz6AezEVt(5>|I}u&MAMid zfczP|l3~vNH)n-lNu-~%_F$Q~T_$rj`G%hbHA%0^;+3gxIB1bkJ(9%VxwIJ6t~u6 z53(x^qj*c@HxM%N7X@}J`9i6nrs%SH!=3!)?RE)38{gSs%(OU)l~pVsEwYx+%ogO( zmTHv(LjEp?VcE-v>*gxtvUR{{R&>dNoK*TRH3#8Ld(Q0HM*Rnw&wL)_0Or&xm{r2}3s&w9G6rGsD^=HE+{yWwIR_=AcZlhp%mO;yv z$2}?D@;zR;p;HYY{%h%K$cE1^*nMQY;W9XZy~Y+&`THIg&sOLH9?X^7W;aE4?FKPg ze|v7QX}DJl4Jr=;v6UfrGhAjc<=l-z zJYMS1JTsmDd?732<&-f(0hsDpRa~q;ThXN_=`pVkK;HH=SjqUmY1o-)t7qU9X?QvI z0QGAKL%mR6osOjDo!}(*Y!tI35z#@`d}3&|gJB)LO74SAEB4?t2D}oDer%*U)5dNg zdEE=#HPWCJh(gNR2pJ>wW3`O7eV6eB-Gn5A8<@-OFn_s9H&6pNW&;Fiv-1POZt^ai zX)hw%YJiB-h)PSC*HHV*N!HKEQn?=%{_w@Jc$!TLnN1pL&Fi5+S~|9c3A`l^bpfEl z(h`dJ-3<%@=$K}2QbOoY^ocp7;r3HgbvoZt%Mjn?FB+TUP!%}~R7SW{PclrCD_>w~ z`1G$3fxv-usUBzMPpSxBggun?fc(&Kci%UG(O=qY#zRta3=xvnA2BDBa@gUIlYVs> z2pHMmw!3**76IZE{VamLsk$Pp!1~NJrPDu>!`sV@543=ZN9JR!tfNWCEOq2WEmd_48x6e|$jz$1rZx zyvneYIQd}M%<)c@3!ak|XX5~aE6#KbxA&|WR?4Q|)G&>19mVvd>C>>vN>`3eujVg? zh(><1sk1tp|FpJQ2ejVpnGW7E^dkg&dKi_7$W|Kh8N3u*cjtQfx?kZwwu5#vfXj}h zrsL1bP>ss$v0y4Wa|T8p`6>-`fyB90Q5Q z;%2P*fgY^xmg{g1U%whx5!2?E{uR@cw`R4NOo7pdV<8Ie{os=5Otgf{NSDu7wdc|1 z3Kv{fy87!CY{u%mr7QeI0YTN|vx-?l-2x!gD`wu!+YsQMMFPxfi<8hq&ZamI{vFeYOtSr4sMP?yVwT+4sXR- za}MdB4a94FuFVA!FZT{BZ__tZ=abT-iVK8Zh9RUmUr8UqWNP#>K>VtDnW5Z!wZ&^u z_t|VHo>?qi!gRks2!IPb|JX5w(Dg2zg5$X^hsS991@(j!nf4D*(+{D{S{e zLM`d<%Aw$sx}YDcR*%sKHF0$jVCKZ(*m}o$T*h62Uz-mKf)`4{Q446UKTSI8t^71bp`0GC+l%xXh|cmlBs8BT&OR_$X-(I@w<_hmx6CSedehH6lh-tpPL%3 zQAa2${0M0h-Oubj%K#p!hrSc35*cUD#yU9q=HWK(eoOH4-m^M_<6m(_n3Qllid~9o zi`xsRY*s_op?>I*sV)f3HuEuscE@M3_@LCKiohWweQCC#08o@ohkJO_U|2h=yV~(( zuPk66&c0;_sn*$TPbS-tVS+A!HrrKZH>G!WVAZ6KC&F>c-jjhoEJY0qiG~;|fbdO2 zX4t)&=nZjLik0`B5rNmBjA{)ONAk@3*Bm6hSPE1a?Apn$qpDXoV3M|PR%7hS!gYpp z;u>@@U|VXCC?)YPPcTC#xvvYVu<{t}KiBCWbspI)R&@>vLegreWQusv84w4J4jaNI zfMzYmT5#Fj7#yrr>m@rQ%RjCYtmR4hPz}I~#Hl`Dj+gr~^H-kUTMeQ9#?N?7`edu$ z1{ipaK}YY(G{UgnT^i+&)8ZY%a%#*0RH)@4!(rE;!ZB04sFK z30Ht3@f^Ps4L|l7awvcKQnRda?jP$01Mly>qWDJY-!{1w>0p* zIRfaf%di}zlOsXZ`iBOlRHZ{c1HNc>-vGXxQy*b+l1HTD5zW4xi7o7L{A|oZp@N2j zREmC085riM;z9=m3(V3K_+j+E^#+D&3Evte>Mk*n{iP{ z$Brj|fW+fUx*@KlR^<#Ha$Y&&3IZqpM^`@i<}WrEkyO;g4#hcb0=B?&thdWUy04#N zDEih7@%yavjm;KvBu_T$C~f>>vy*ZztOX^8ns+iwFlhcVXVaxLwiA_e-xCW>VEdL=(7Zji|a(O zbkcWa{$lH`)NmBdNcQ=Sq#t_;PcW6W*kM{M=!R1crzw#P%I1!>Vns=uew6@>`ao)i z;I2a1Tr0bi@?*ozK{|hIhM6d<;&I$DbgDM?($caSc*V2fq2R?SqqEE~61cU0vsEl` zi5BGPW{Xyllo2IWIdoNf)Ni7PyL+L>FV#w~V~A_kcOvF${>i-oxBS_9%pBAx-Ol_3 zF+A+fj}SqM@Kzls8E70v&}r|Eu4G`UA9lsj*m^NMy7JXwk}4f;)qfFrMiKVEEmc@+ zLmn$LP9K(Snp|v_0x$}=OFjJNDVI$H#p27=dF^-v~lF02-40>|!sf68e zy5|`nYWA_%lJCqGgN066KXJjQO(vI{OiP!k^~l*BO)3i(Dhk@?PPJyL+m{?PC=|WF zly$4o{aRD)BwN3vFvj6GW1#|D=frZTXb`7%lQE-?!OctE#5f!P=c4{n7m?$9n)U64ZG%yl`0wMQ zdb+FKL~|=Iw;Rb)9NmlPe9w~M0Hp;QVJ^mE_XKYlG-B+fw$Rs}gUsbo8LcoSs`#8- z5#opajn{y4668&*KAl|_G(MRI0<#6L7~szNk3}HTuS~Kl)cvzo5M$H6ZiTxp*q)8i znLZnhzvUq>@EfUBcbAQnxtSlGR|9#M2j&m}Od*Z7HWQu6{INxbWHgU9VQ;0`-ONN! z@9!`pr?Y)ayF_`rpBkcMbPN&z+poJNT2jb!VHnmeF!KOR#At`-VH~DLbuttH37W9O zitR@%h8%c{Z*vB6urikG>!u>~FdB*|@b)A8VzWS?7__tUur z=d7OTLb1iYs`K4^wIA7C?=Ft%$o8a<89FVM`AOyPqaax)8k*oR-1s?zU(Gu(-VPbE z^bmR`^PdkCY-LHR@dzdZr@V*-(Ux)u)=T%tdTapKZXY|BeELRU>oBJKcE5ujoVyy! zBiXhL%&}bm4$L2DeK8i&6t$?dHzS{_(Ivh6)odEy}&)GLid_ve->yq23RU z>UC6zCy}PG2x5qv2Jdbv>3RXji>&RXSd^rBt+Cv`55Ky6Wa?et4zJJjpTaU7IWrfO zy1L#k*loGbq*yw<6F z@0FQ#r#JTf5B5gmk#8}Gf%Ps4zC?OZpA{?l&?^8rv}F$CwelBR@X4rOia?5OZr(FX zbS3x~OF?W_c@bg-{O!sjRij2H*Qt%PBecVuP0r~Pgk)f=+?cC&@~w)*XlEQVoh+@(G^mRCVD5JoiNMSgpQ>MwVspcn!K3exc2&u5mt11Rg_m zjr8IVMGFLUZe#dsh|u26#XuTe>04XK(P}D{_%Adtjy(9TLP(>jd&&7LOsHCXYatE* zgEnQb@{V!2*s#i9?iJ!1O03&eD;rT1jglH2t!h$JD;adM^`}|KRaR_1f%Ug#BTLl8#aEAcgKLh3T>!?F1=Fs#cKRP*V@!lQI>9Msmu~c%nE%! zxH;e%Iqq+ZV929d7n|bIx#99cr~8D4j9~YkhdnXoL8^MwZ?UgT>$AEK4m?UiM^>P*Xe~80`bwoH zYIO#U=fvx++Vq+lQ{jf@T1%Qn-?=->aPTy)=g;6YN`?L*RXPd}`yY)-@VMWxyD9js z+65`zs15XLvu*xtikAP?9)jHP#;hby^Tr&s`JWl~WXijoX_sk2yOMT2T}_>Cx6-y? zTWs3Uk?RD#4u#+u_>pB2>ITVsXtEv5m4-t22@tZ*sxZuC$nrD??j1~1iI?J?v~ z=<)ni54RlcgBw+Nhrud|FH{AH0`Kdi^)}Wyzg(C3@4&e6jkYt(Jxm|a`+KdmvBo*6 z(PnLWV@<({@>-<*MYnb;UmTR}EH<#@z!0+fw>F1NTIF^Nc}D6oV(83tjq=H1bi4;v za*p-#K%+)FRH8j>9Hl~Fgy;<Tj~x=Z{w()Y9=KjCNa9Vr5X5$e zUJLo?6yEnZbEup;ve0j(&Wn)Zo6Ju{3p3QIt20;&rrG}9;Sd9;&8*mj0R{IXLke7BAWN%&E$ZVwKyc_laou2T(T%hS5ny^ZhP3<1^ z0wXUUz7Hg-oV=k968ByO8EM^F+n!IHWs+!3<$tcAmZ5F;vEX&q*qP8(i;m0?U>|N? z&%-Hh8!2L^!r&rSbfp(_ACM(Jy*^gp#}41 zXq}|t?p63DX5_i*qEwZ1+an+}ec~L57v8pB%&CpgGpoRK&Uvi%@Ya!MeegsFv7XVS zG`|mxqbuT2dHJOsAGi2}VX~PCBz)E+<_D^PvHAJ6N&&- zPrqp~E&JT)dL~b^pq6uRMo|eO^+J5PSK}r983U6G^ zvSt{!BfOAxo62jnu!yA*S@{Us{|aI9?BP?ZaiIwEW!!&I z048U$ABj50C;L6*Y4a5P9^5leosLSD@`44XXz(Wf@jTsU4kGFGr;q*LS{`yaKy+8^ zak8B^nBmIaH3BRtm2AF6t8bu_k5mlZROOMuePL!)qi<8Jl2)#-vFWS|F#0snouMil zOhEAa3xyd;Km*Iz!XPMRccGItFDgilX^Q~VpqiYlwU{*WceOGyj2e0RlcgIh$U?Mt z#hNu(JVnqU>+1eEgID9JTxWR(4tj6XTvpn#=t4}vv1>HrgdO@Z2AQm*&0*97I>(^L z61}fcfR!o=-@;x=rkc#%%e^@Tf$Y2Jgm+!uAm&%5V2dS?bCS9Y09i4TMXzVGchkyD zWHxGSH2z1e+z=V&P3tmDOWS|_TWPbKA$x928GNl1yPH(lxs#m?DyWbyWd}l+E_`Dh zh#krA`kU67q?5ZYcz;F}p_Mc`1N2Eg-Ek{&{)VVnce1a#JYm>0x#waqw^OPDcR{0( z=L~$w@|)gPAEHXv$lIqTn~i+kgNVFx^VY0VIf#=TXwO6Xn@eLR_%z=#y=;A)4dQd= z)nUnKwlROi3W%`Aun7WtX()HiW{Zp$rq3TXC?Asb+0YMk$s!YmhCrT1ZYJ||3_pU>BrtPNmQAFny8R;WSMLJW0W zuWKm|By%6StqN-7VLjJktb$L0`p$ZDTIEL5!_K@aq*11(jerEU=k#GaDC=$uDbW21 zpOqMx4it#gVp@qb(zm`aI}putT>A(_u;O;RfmpSR$CeqQl)Ak??#A_7XvLWGx(LWD zkiYAzLDHx6*jI(+gXO+C2R1%-F9V{P-Y)10M%H%!g`r-KUB-|4bcd|vJjH|}%mKKI za&`XIe)O&RDWuLPsowl>06m}0EDj{cn~Apae1o6E&{Ib*#VjO$TRqdl|1?=3w8v`C z0xSA~ld)g%JeI1$8B=3kat>upv-NLN;cW?CU+VYpW!qFNsL#JxFMxClDqVtOlJ^#g zUKC|_duQ-adgICvtU4F+NDZ>ZKqe%R2ua0VD%gO~{D9abepx)BXHW0Y78mqq@ zFwp*ib!vv!kcBR+mm3>ta+Ls2jC7tv>2%hzAR z+S|94Gvi!M(botan}1;KhPfsGh*AQtYnqVHfAxkr0l5L?OPaWbsSbX4RmfOwNeNM( z#9!eP9Q?Y?F(-V_1;dT}xMiRk>F$2Ez{=HM&6vrQGjMc-{%Ed-9n-A~1EZWHt5}QE z<^KCIj-O-`0Z`kd)6E$A^7aJ+L3ut{O^nwg)5PCdv`n|WY%GtQdpIZ>98P_)Jt}l14xvKBX%6KLn8FN@5eFt_G4JU%I=mR zTDc$*dnC1S3jrps+gB@a@AiAZN%`%EkV+R_kMCJ9t@5CMD*g%+O^(wTK2 zf^FrvUC@JQUf0Kd$;(=pO%#t8$G*r_8j6ub{?wI^c?ahw8Dw&ndtkPZ^~e|oH|qRS z#T;{S{w_l(kO;6}ytR|4t3qiLb{ia&KJ|q<2m>~7&|H9eULTlC-Yar-sry+m0}Gnx zMx204V$V>Hi+M)A-Bz~c4_cv8kB_IiLg?Js65PWLoWt5;erhliLg5wBJGa)x1S=n{ zf$dXvUpF|xt{#CPHS0IRMO^A5tQR*o3p+aRi}^)-et&y_E-wC5xhXa zLxaU^4Oi4RRju%^j`%_8Xz~Q|&94NJ#uas)Pkdnbd@EmPosg}^Jl6kgApTRo+M2tdB*pMS!aBNgNpkhP`;zvPZ2c=@A~7z``dWSrU!}IaWklCHBfjOH6k*FGG(>igJhcRy z+Jk8z4laHOx`AuO;#Sh1SFkx}Zz1Nsx0j&^bA9y-Sn(-JqnBQe`K~VjObMW% zna!BI(Y%8c>TnijtZ7lI%tsS46}s|uMWoKyx$a?#g{gEa&=ZEYXAe`BkCB z*Lm)@V8B)3iQ#!+l8_{#Yxx5!zX8R31I2oo%;V9!GU?@Phjnv$;^ z2}j7+k%t*)Tyxj%roOMOt|&d7JXO$@qmDh9E!c6}Xc!{K>94~a$>S%XFW8PNEKyc^ z+Y>{QdJV@;E5CVJ&`6s53#d#vbJmqia{GS6b^Oy}VxT^6y^T(CHLqmGdEG&LSgW7Q zfi8hYw7Oe65BHA#IZZHChYZeDTS*$T*o<#q{=s5x^1*u`Sh;U6WW}7>h81}bNyy=k zwSlxk?2LPop~HqOzl9x&X3dv4%kTnh-hMUYLs}6t`K3osh8OTlR8VdMNgGXaC1M4&QH++_+5gJzxf9UlMB9NyxO6& z0sPpq9H>g+=HW*2Nc(6j_dn2ATt66m{IqR?;1J3C=X03Sl4Fel=E1wRqA!sjQY(f! zxZFzq0Cksa=5+d@LnA?7lHMb~L@7(=dEEqON$R}1x?Q5jv212fbK;CHf~O?4`g=93 zEBUdqPm6kYj{CWcs88hMSLZwUz;blwcHGn(to+_J$ovf4h6cAbQ-h_KZUV7p@#A7?t7%#WDDgdLYyXSklfz86W3u^vcn%KE~n zf*m*MEe@g4?LV1iG(%jbcA|5a+lL%cMs0+0;uy6Dpp7n_mk;kR#u_*cdyyEr6q9uVT_CQ?NY6)t^q zkpTh8+%f zAj$kYxS+|pLND(fjhV`2Divn)$LGzr@CUBB99Z48VGM8294MA6f5V#gq`8uLrJopV zg3w86v8W7RmOIPw!P@h6yylX>> zFaM-NYLq)xFCJLA1ePjZRVf)_1|JKcqY;MxP04I}k?n_9&G*AOgZ8j-~EPPnuOnJ@%u zJ}_kS)jQ6|Gutaruz|y3o`$!UfUV4@mxioQ?pBuN?4)-cD#(ZeWaJ1IJ((`9WkCpQ z7*d03{&<3beyHe#?eb2j62wZk*pbzyJ=Oa|*g&S_=R`k%FK3 zSbCQAa|5Q}v;Hke(66`7vqPJH`Ew>3m0?Lj5IxjH7pABDXR^mh-|akBGP+}x%Z<*d zUyGh3zMh6r*oU|sv>&fwz=CS7fsuL@7RGsBIeUa;cjeq7K5_&CTi$mG;l4e?)FIgI z`a4J<@OW~Q`8T&=u+ACa%7*ZKqP9Tze-cA-%1>p~dB~RB3Z{1M-|*3W^kS%>F9o7p z1FA~??GQ^HcAk67Mj1+Ch}qnpO>BlW>VPy-|4wl7@8>~LO{f@C0HV=QgyGGXf(qH6 zYDSEAfRzzGH|LtcOLEO?Y8zRLcZSqWKhRY$l_SrqreJr+)-)kdiYz`KzOmlR3VX)4rPY;9p7U4r0t*D zjW9F=%u?Ah*^Yf0&?9UlY1>+iD)!C}1M0AdcBcAX!y#l$k9jbf^jir-5$UO=8RV6< zi)9?^W_^ii%AHsbZRgPa2C&4&+5Q5$p*R_3RUeWjL~2sq?|6Sc^>^Qe%KLeFO@XUG z_fEGE(DLzJgN_Vzg$o))eJQ@r+(P2B$D1*-%V%IoaX02?TKQT>=bQNUzd`lRNBI&e zD|&`;+WGxmrjOsY%rBG8J;sl~a6w-|hv?lkn~2MyINFeHURpR##h)$`qNS+gOFam5 z(a*1icuk6AG{QeGOMS(h!qq=}DCCu=w+r9mGsmMQ45W(N2Ia-q)QicL_^Y=HoxJ$P z@Bp7X5{oXkSZ}ss6Q`fm@!Jj>d=x) zCQmYNKpJ~K8I3Jg${#c9U^D4m5qMbVrAB#W3j4{9a+tI4XDuV_v_!~-=$D1exKMI& z#;myCt{`%`i*?5>`37f_X$&Azr_5p?iU0hU zRCq*oyl_WBjXa~+ z0Id%W*%KnQp?FmZHj$KGiK)*I9n7HJx&la4-=e;lqvQW83(25AwhIs9oMR0E(r;ZdkCbJ7T}EE6C5EgZIfmuOJv;&Pq<2%bo17iXyTAv> z*O{?ZT~|TO9(kXTO^+MZRw-y0x4pOu{BhvNTqi$#8wmTT4Lj(*J3o&vJ{H?3$$cQC zb5^=Q8&gr+4o6{KrW}522$tmg*VQg6sAvCyOIxyFRd@RVkOSa~fuqn~J zwfIKwOaY~H(WNmRFJG*P&dcAGW$;d1|BBfX|4&us=av8d03oMr-xM>E+~9NUA2&Kn za3EJ==^mJQ@=k{#oh*5~7`rw8?X1M#>!!x;9x4S1A9X(hh$8}MU;JxVcp3Ft8F1G< z6n#nD`HEaseyc>EGV3CS{&JJw}F z!E*1jQ$u|IHl{^Cf33zwuQ-U5ZeIEX9mPp@H9{bkn=(IuKvh*2_TY(Gv}W*}9k#5z z-@?Z1{tWD+&!}e3=cSQ_gj|MnjQNzYtDrAS&!+mrIyB%YSe2pBj(W?$jOSN|SR&vM zcSj)|PO~}Du$~|FP&75C&DU1Cd^F)vX(s%$8ZmDS9TZ){X^iq?{ot-H^odXM&Ee z@Rb>1j?DGU#cGL+WF94@fyeCQt$W1eHpG>cMFLvQK#?oWAA2`En?JM#FOjx_RG#E3 z`(nuu2LaKP#PdVMbb*&2h*32B&K7l_^5?blef$Y6DEqJ9!6DTj!3w=oAJ07g6GWq2 zfBx_QUD1A-Vj<1Gm?20t`>n&PEu_H1W!VN#)V2zup@6!Mw8iqt^fwYUQ8N}>1W_Hl zG{+y}Ex>+mg)BgAEI{ertt@jt@^eMj&pH2(%diifCpY+W$T;vnSR2mv%^0&K1-S?P`4Y0Y7rAy7ly1NYam1XH&syKpTo=Yd7;F+`i%17h0)1+UYfHt2Lps=#_4t z!B;EapEF3CTur0QA`Q6PbgZG)TSp^}i<-4mStB?2ZYT4(LMtg;+L?P*2q6gV;*k z_Te$7*Id^s2^!DZr${-dqf-W7c>P+d>rF$hoz(^aHr{5+5^V_KTCZu1Hm?@CAx%qU zU43=-S1+^$Kn3kvHHD3R{};=&1(i|%d~%o8Qx~V7&(vBDF1b#d>%jkv67E(=39%J_ z=!TnEB6}uW_0otjUu$($@Y@H4Af$-5e#}drL)RI7diolm2)!rTVT9IAl?6A73r|ml zPuI5bWnWd1CYt+4AO&;igoAacE^SBS0&g{q?NRCeLLikYCACK^(>HJFIBkwzqffql z8T>>8-h&x~rPlcM^zPn#HQ~W|^IZ|jGPcc-q5E{uFLGkc0FJ1%F-%ZIGgw~-jyuU( z+D)4K)`hl(i>9z+$HTFo3CY#z{3aWt>&VM=$oxE6)TL@%XNDeC*=S1gRJD;Vu1CID z6r9saUjZn~+zQA_D2s<>j3)A0=gWi+P- zxS1P&(ORn_jBunOc8KGGzY4x`NJFYQT*ve8?4a5z8mJ>BVP?39EENa1^7#qBiJopW z{`!7akRee$sAI}9+r2bpcs)PTxlT5N7s=A7KCiRf6P*KXiT#dlZIQ{WT-y`_u~Y69(BJt#$}@9NHw#Cl-RD1 zN#REiv5t&3-RCh3j)MZxQOaZ$_-F6pEUhg?BOkedZpMO6e!lq2^D3E|?DD60G;;I@ z5&PTsK`qARZ@aQsf}C*uUu^_QLC;nfWjH`CtI&W$Czqdl^p#4YRNLPfUX8C-2Zn?b zZCVl?+0r!1z3&@l_%yb&%jJOuNWD2z{IfrA(j_Z|KnpTJV4O3)zcg_zD=aKa6c37ckW&%rz^nE#*sjnB4p}v%r zYCE3T>;OB0E=srO)876IVi8nL{Sb@NsLtO&|I7c)KI`E(S3+0qkxM^DfD3;VhBUhoktPW7=9wRcW8tzF0wK|U~Twy)E zZ~SQh8>PxmT)?ycc8(AbHB>oqOG>il>gY}fU@dii@dAtK{pZIFOu_i(Pmq+Y(p`fE z=2eea5w-L06pYm=;ZA%egd{z_I51D+`*LQ>3>(tYR>&DfQq+%xNN-Ja#FP5Rtr}bH zlY1Heaq%XCvn(2~d_-DLowo~nFFjxQjn;znvp^2}SGg2Q-H?wS-*?7uhy$fGQLA!l zlvQ}kGX5P&oZmtf~$W!51~Qf_r+qJg8#B&#}~rmy`6Tr9h~ zeQhw(FZ-sr@@d@7J7%cOc4-DQ6=+j?V3CGfldc&UL~DglOWuuZgNjERTo#+GWt;Bo{AEg!M*1gqK%3JT81p0gsRHOpa1Ah-X;R?t zRCyZfg-u)#JWNVxB|AJIk-mAu)0oQBCgi z7bzJ=q(@e+Xb#b=WAWqIq#LCTtf=|)k9Wg9I#!Hz5eP4Ca@VBcvImX88F$K%x_)%# z`c44TNT((X1yCUk>ocDW_tOxU1NBouAs_yLQk#WPIkNp!#16iZ>!%<~K<0MRymuLTG?32%fU!{5L9C zkm5ajrrJcF@hs6h>iG?8?=989kdMmx1p)^@P2N*OoP4kMs684_XYmIJDPNTzS^Oth zG=i02S-<>5t)Ok`43~$R+q&ZZ4?2H7Fj*r%{3pY1r4PXxh8!B3`$!Gs+TtH856nmX z0o13r71N2o2`?QOZP@n^cu`w)Cdgmjz7WDd`F1>O(8_sgwpB+ckaOrG(89m%P_N97 zdXHnAykVa|NGsoUbm>U*Oji47Pqd=JN2c#}OrmG&fAMFNczYutVYu-d)u60ti^~fR z#CPGY(o=Np!MhPWtm07|@}!RahDZ6|`ifBC|88pRKVfm*uWNr}7HNG&w zubX8zp&l?~R$$SzFhiw`1Dproh>DF(F_F@lookhwO~fJ{|G2+8O7e|t$Z_t-KR6}H9S(>;Z3fGxCZ%bZhkkDFLr?(GET ze}6EPWlZtSMNcK()B z!GmgSkzOvw=S9ElwxevyQw`*AZT&_l(vnm#o4E${Lv`i|iuZPirjmT0QMisPehVuv z{dKycKc%DMd^m2$qf z8YI4Dz8Lz7DwTTz9rf!Vtu`5%IIc}SPo?BjhyT?BtHkH~U~_M-n`FWsYWrGfkSFhoPuX^|D}J$7q2YD%3RGK3Ix=hR|!!JJRD$;Pp*VR*biMw9{p>h6Kn?1rSS%?P$nrM(6eDrRw zJph-%tT;B4H?DGF$!%Lila>z+1*J-#UVspm>NPQ7X*!>Q>rAdG<^UaiRe`8W;)RBy zu`GY}sTf54!cbO8$k7_nT9vQfn0a!1RqScnys0? zQ-1RYc6eINUt?~POFk298b15Eh+MaVe=7?5nzSRYJVS(tpW4p&G;5#VNy{rU^Q?I1 zyK0H@C-Ye3Igd~IlWA_RAK-4*`1TCmk&;eB&Kwf*k|^+oB|g;YI?dog601%KBIbT! zlsb+?5g&6-a|Q#Ph#p(TP&FPif8FSNWo~o<>3gKLXTV_a)%Ea z+(;U)Y1g4R)`_Dpw2tFxR6|mZdQ1Ju}4#e zx@7Wg=&mk8Uf>+8oV!U7`dl@yTnyqr_&ZoV?bs_9RPVPvT||S*KFJ7Zq%OnYnN6e$ zT6Ee?qIdJcE_9JBxfyKqtnXq7($VwgdoY}kr5W)qMq>o;V_&bNx1vIVd6qXh!Zys34@efzJKn26Dn{5cX{V6I5{F${e zNaICFok}LT)Gau529(FrNRw`Y*13)?5@denNtO#6v}z5A%Ab3SCDZSyEZ8uJ34eh> z^{Zy838^FvhKKmQn?Uq(@nhKMNN*eD3mt_wtqJK@{Al)4D19}%%rZ|8?oNN4izmbf zZZ9ddFloPMK6LeT~oCOSm z!_ajBPzmd<;IZDGwE&+!LJVb*zRe@GgQVwM1z6RRafuzv+ib@YYdmTnUyV89#1n#giP#9e2J1&Lfy43_z6;hHn zLyGMx^$gl>j|~LpYb3d>WIFjPxPTk~RceHPVg-4~6aVM(kksQbi&6Qy7KCLK+IMFP zwp-VaRmaWS3VMMYgNLeRDlo6atLgO>P@S`A^Kb{>G7l^+_YE_jo^;2PVC7RYF)=RT zD>VWW-%M9~NLOYew#B--6DTBF^#>L|i_H4q_wthwZx{INzJ3SQ+_FcARG{;@+thA4 ze`r(KNbN6u9}CcXEyW_5V+}9w$SA^5w1?n@6&k;dFlnnBXQTXi2~iU`xu0S{+@eUB z$(RT1`NDi`2j>-qXi4(Mt7GQ6MsHZYRNnR+jDwS&3GUJe)`9XW(B{rTR`3<6e;$L* z={^mw5B}R=hg(l7;kVEb-5Gm`(i&Ye=hG-B%X7{;xe|;+83kZ_c~LLBg~ogu(K3`3 z=bNU?8`M3kwkw^=ez=Go<&JF2weW9B;J4hOjY1qxZx<1j6#mcBu(*U5Vsb_PQopbd z)f)9!p`!ApiQk99#=8dCJ&&u~@%y>+L`!AfSBsJEg^J9WD;Swz<17^&6?x|?(E_}R z(qfSK$UXshJMw`Z5RcJWEzcJ4(gDOXYp!FFe(CC8f-!}x8$Z~SNe>Sim89&No7lm3 z=DjSzt)peOJjb_D z>hLWK_B`l;E@=2so5|hb_^^HdG!5eJ?NUL;1!o8M)w=Pn*>)Qj%C*N$$Az5HdjY}S zW--C7rC(Rq^T&}T^nKWYB726_-}e)Og*fZ&W|nU^rS!ysZjHPrtFqPyZ1Gc_?`s|D zz-Le2jzf~K+P~l7ezsM0Rtnw*VO(0rvWr~vR0PiK}DIj&0#Oj+*C zZC8-K8C#Aq-`j8Qf*`*8wz4)KSwP9DGs0+S()>Awki2rPKgus}Bhr%^kG znVsk<_?6j11q~|!D8oBkv{a!c=MuI0Dgf;6`4}!cC2!AGbZ1+bqwcrD zI34LvH2+Se=b!q-Pf&4${X zvcPV%{)Qb5#qgubtP07=6j-*?$IHfOTl5tf3at5$ng!PegmfUOi@@@8sHUW;I4Xkv) zHr3z)$rnm2D1x%YY@~F^8xa%LcNaaW{L>3eu}b$uxdtriX|N$FT56wQMbKqgd4W=R zE>#TFgX47_5=f>D7V@AW{*alY>sSghu}*N|ru zTC@CC=Zrnr#!*e4Fh45S^)rO>^U!Uj7IDk{FvY)Y^f3XZ@G(Q_;BIttfme4HhO>F4 zgy{W(`nP|wljiO(KDxJ_?}f?9 z<&(%I^2gtcd8PQ3Mv+V6|9Y0-<}$@lb=p#Q3FMHbOxM%TAoY`58&tA#Q*KnIukU~@;x6tR;l?5w2rbGrQXgu zLUK7e{^LblvF+|JxFu(vD(cHYHilq+_2AAH(9g#|Q_0W|B?M0b=}NfRTGqMi&*4qC zMXQ$2D=%^akb?ft(Uk|daJKPT-qgE{h{1?;Wf8K@xZ|ExA?r+0)}2++EK15E?pcJT zj?@`<_9H|osjKVkP|>(kwBl^2C62bCj-`(8_xfkDNj5X@@m%k7{GPF)0vfBe$n2nX zDXZb`XuShvoVRx(l?vuymYXfXX}wSAM-7zzGP@2wZ@J#Igw4C(Owv&8AAF&Ow$Ap2qV#sjdV&ek zxOQ3GW9NucAy{XhtPnFRkRGK}I)43vpSP#t5%u1)@Qcm7(TxFR&tmqo(VVL)K$cfK z=Bu`4hXh>;P26~haVz8c;2N(xR7i+)>YEI;4gHc=CF}E8(VmT0B&E1I*p82dE^Su3#_`;f8{_o>v=ywJtKsF|<;E~}m{?%PdQ`uMl;n!E zU%0H>Moz~C^god1ei$nRtD+eT@MJ(lf3}6haZF*}ySxo7t$@2%42c*-UM{+Z(D=xi zEG8Nlc=2OGA-y2VS^%XSO|_zpsy*98nw&MqAs%yJ!2HS=;?E^}88s^Io1#}Bm5$(s z%8nM$LtiF8@)yxR=6>Uk(d{d4!Y*vKIW=8fRFUUCUD7ZW zy6Yh#R}b}S#J^| zBJrk(AdZ6MPaxrJjV7mA$(c&f78uVU#F(!96AVV%G##~Gt6A?Zypcw zT*6e-uH#*g?`}$$>46{b`H`dfWhYEO<~v?kKpmpWouH)Kx6r?ycyY~L}xg|--U)D2{U;m5%>+^)(H<=nqdvHh|0PhmqUKQFr}Dv4O4HL=1@5~kf)nAC_xId!`pI`+;Gu6mbW_<#!9X!miZoj(I(t%D zv6earN_jN&0c3prf0;+aIU*ZU|K6+=T>rPPp~^zNeSaKzu3mcApiQ>Dfp_8uO^Dobb6xJUCd-{ZC0<$1%{ty2gEX8>%la)--t3# z6tfw}#EqrJ0-gj)A?@BJ20o*~#TF(e5|3=Gg^IOOk`RUbUJft?7_arFsT3M)^9x(u zT!Y#I=U}9xlrQu0KfTJS1Ig&UHLVu9qVm$v&G~9WDfB^Jeh81(mFQ(-#ZroWxQnUv zEk$J*{%Mn9H{smn$fBK0Urczd0*ur73GO(OuHa`OayL<_PJQox1Y1Z_M4zBips6`P zP5B19ryJ4~yuWOD_m$$ziK!-nnsj|_V9p+<6Y=@hNaL`Tv1#(pprXkHK7>Cf7 z4>iNK%l*3eLD!RB-vLK%e)&S}!`SYutfLN=N@2+^qR*?1qV()Ul2{_u0}9YB)i;*57@t)>Z~8$|qegh~~ZG`C8QM zwmyg#x#5LUAKU&8yf7jkQMI#mt{=}u6RICdm?^#Y-lF!18u@Oq%fG0Vva}}}ooCWJ zMSrPHh@DtgX<-y{8&?(Krqa1edJ}S%MvIOrBs2{)Bpsj0Di3T2mg}R`mOMDs!ApT( z*CALeS1!IAKN&Z>I2`A?B{etT&HIAe_=a1VkEQ}ZvOa*W4ZLk;k2Q=;>cmaVQGd5# z*Zd+B8As_Ij+a_rKx0_aGer!}qCM$@J4Py-whG2id1cwThFAneSQXYg=%PCZ(=!o< z&zfX5QtM?m9(C(T_jD_jDs>k!OQU7e`uBL0>>9*DSK5C3llh3b$(!8@jl3%Bj#15) zWl*J_tZn8ZYF*7>MPuhiK&JaXZJZwG<#iiIrpmCeSLNRc^OECsZpcH&e?L#LtE0f5(AMMQTd^bjA<&y+K{(J%ri#&3+Xzz zF7Gk>Xx+LO?9FCDG{3+-fQQ0yReFQ1DxVc@Ta`phE0ube<$l*lV;wP1Z zO1{SKOcV$|halm)eg>JO5&A>sDW)$9Wtc$~p_=xs{l)F0i>{4?_$!!PqcBV&Q$(8$ z5VR98T<)!?d`UHHRFDe3u|YwC^|ZYY79sHVITU2eGj@(f>bN1Iib^-~XOcjD(J>Ak zPex<%i;BO3jJXo)6jCS|Q&S(KbM-CtVG=zoTKZG|_9_rlFuvNXrKHhZjBRkA1%-G@ zqY4nDf%fy*8XpM#UMKA7tvJ}eMW>bc7s8c$At`s#+ElV zHxK)?e2+dzV+|_m<3Qp(;}4)n1a-);>VJW=lSo&@qPB#4Ek@v&Et6twPWD}3Ch>^7 zV!SjNvk5LiT91K`%i(|0;@o!8fIlCdWO;(}v_d%dR<8vd7dLx@ISVR!Ywtn>^~ooo zePYYXegw-|D6ooj?!)nqfVP+KVM4kpv(1@+0)1qTP+zzH*z&17K9;_lh}GBCU7$)( zg)f2KR|X&l5xc+cv0$hQM2k&OKT5Q%*-Dk+LB^%(36NE>j+tPt*uYur?@MFYUe{=a zPq=O>k$P>vg;`=;t9xam3)?K}H{{hq-9BuvMLEWeM~a zu9g|$veh*~3y#&_6*?*R-#+H$_MSWeDPl5o!HpcdQ_Tuey7N)YMVtpkpjwIiO9`+n($2IHjeGF&7G-wJWPQ1-%70|dE ztyFnQA}HcUww232qWb-C*{+41AHq}V*WH*6?d&xSwwKdcLWPo(NuuLRs^om5iqhDp zB~%Gw{9X*qps3Xcd%yW9S12e;HA`T7m!u1)R$z&ji+XPsbUb-pP7HreS0w~|MW*i& z3r13F%L2hyp4$3N0+u6@JBr4VRH?mGPpK~Cx5Lx+`AstxaqF=RI5jf#G3c2KrBefx ztED@wA$|7>QU$6bnPv-3yl-w#(C`P=GFnm3!3J@KH?U$Jbu%}Z`^)nz>Dqbfr5>i} zjrJf4?&&*-7^%cGy9|J+8u)?F|Hd4oK5ZHnUCG{V#=iC$1#02Gy`GUt&Xi!Lo3fT6 zE6LnT*cHmso**dKelVAAh6qR+#dHGUr1S@N7rL=5VO4kBA3OaPz-#pW2sXdefpu3R z0DLA~VTKnL#H_)o8Y*k2u;H#sX1-Xdf5;!BQs)wG1C<|K5qveNF6AnyOInkr0vzPy z4SGnMT+z`5H2V@17&|;cAE3J3A2XW5~ zDmbW{MV*#Be=2IKk(9+u3!M1_-qiNHMOuTb-~BK`HrHpzi9u5#ex#j??H(ioHnsZz zmjwqRQA(vy2e~gHi#CkN8kOAJR59XPD29hodAL@uq0-u7D)8GF1~2T{d7d7J*h{^$)3vi0?lZ0p#|Id8omEehqU^jP^s9 zaphy8r8OBk6du@;?Zj|0>1+AuQEgwBWh!$Uww?w|7=VFs=9%#a9xuNYQKBxt&c^9M zUe+42UbgMW7@j1u9o(rN9V2VFlel%Lgnav(*`=4H40I>25J81K>0;cu` zi;12{GhPNd%{GHrjQQ8xAo@R11BA=jVME?bHklUJv-k+P!{ZN;CE8vl`lZo+Sx1p1wfk^0v?U~_n1vor<-B-BAQVK zV%d}4N(HZPlip@1tDFQFDYm;QuGS4Zp-U=v!tO|ml9;!|+I4~1KqE`1vdMQ6k)P_R zuo^qB{MZ8uO7^niQMr722pj)jL;QBe0tho@wFe|3{dUd|hR+xU&f?w~F-+y!Wn}R- zexlN-vqt5Dd+X25pmdv~1=gdm$@n_>RV%#(#SyEqvd%;Uvz8jNyJD@qx<^=F?VfjLz-IPEzjJg)H=ZhV zQRS8~IY#u&uy#`S@hYrW$Y6IMx%BH~C;96M6XiMtiDc@_d8^0r54px%wk}me73Gg5 zZseyr$j)b?wg>z^&scoO)NnnEZ8Y0bh@C+}taS$E&dt-CsInMmcLXecnyG@Ut8?FO z1tx1AW-4zU3G$FF?c7?bwERS+rOt-J(I9}OIIOV-ggZ5R7Q$=D2Gu_+y|;_(GuN=%PL=v7kNIj1gqqwoxC!R*|k~SXZ#tz>U9iOH@v- znoY^{yKLEeHZbd`F4$icr&8{2%u3qTYk`+r@Gy^Bez}YW3Di}33KE0Jq7q`jNj-N< z>x+12y9UcKGHJD2C@PQ64#+qo1-->!FRH7ve*s5c48Sm@-F`;bJw?N8s{5Mthqui; zjs1?KR5H78YP~u#3DUpcc96RBzi%1gw9e7v3F2f}AGVR@1W8N7qknOGsWPzyhHBWO z28aN6CPgcfctnW9cUG)8@+U@&7L^pT{*q7t87tR?w^X`-&{~b+>He>97y|WFhXoqG>xvD~njiWNS-`c~;07s&an=b)dl%J2fzFI#UR*6m_u4eD!r*c?WUz%x8v{#Ogq(T%+g$E<6DT}L(Z%Y#}tgI_SV z2Y7}mCit|dl002RyoW_+6|yr70^-`2gi#fQ{e`&)_h15%G2v{9*fUh1%mGHXgT~?; zApkvxmbl@K*|#SIB6dx|aw@5>Kt&4RVSI$!A;SLjG_9)#bFW^bcM{!RF)#`t!*zZe z$mP5WtobxxhIZ+Bf*nWYPpyz4J{M|M@mmSjXT`IO{$EvxV$qEdi|{Z1>|t;_(vm|V z=#F3Z;YP{>1`cK0YGifP9Z#c-tI9O+ZC^mkAXVvajNbQj3l=T*z1goL-Th*;E4{g} zi64wozOvm!9a;Cm)!K>GK6bwEFc!NacUdCFOOi*c@DSy|QbB_xm8JDilD0C(9;8av zTSo5F19oW5N6)ZZN@hh|r9qAKFtwh?AvdMuzwJfHA8Z-> zNEa%guAE{_OtnAi2Ynr^57b&JP4MVtBCQwca-qTv-i|w2e7vkI{nTV?f2$4?uq` zORbas2dNTUHW({-#g~E~cn-7|;$`WG;l)5=k<%BUOCt69VVR91Rc?5*v!Zse{x(Pq znrL=uft9S8&fMGd>s8w&!gUorpYqa%B1v7Q1>rV{hCXy$PJ3AY*PVXs@2+v72u$51 z754FGPsjm`AQftNhWBKGxrNb;Wl=V$Y*aVpAAbQ||7xZkF4xzWF|#V8`+(I}jD%35 zN4~e=r=HRSa2u)DAgsUc=$9Ce>}Ku?-=k-C7s!88VFFIP>kOFIwjrB+y?mf554ls9 zPbbLB6>Rq}wJ|4Mw|qEDdfh`7>dsX=;c;m{-YvVV@N8H|`YsWCV6j zYFof0iN_=&G89?%N*^VL+S}tK_K6s)PPFYsr8|*Fp~Mf_K)-@XNqD>vRa0%tsd|uD z)36c%zqTci&v@c6`1E6?N!!uJC29>(Hny*K8m%48A|lOChT+D=Vl3{aYC?CDzzJDHW8_Vs7nEY3)*-nhF@UmN{>HDHj=vg zLtdhFi<)n!^_OvlI=cSqGkpM&;U$Q4IQEJ0FKB$`b3g3z>y2@p+sO+wA+Au=KueAL z5@L+ol#Vq9pg~?gD&0G;!h!RwD9xf$TG{X$-@D`x3Ca50l*T+z* z+S%=-x-;)WQR=xEciVue_{<$ZOd%?8XvZa7htAG_X3m6}#d;x1{+cRm#J@ilLP3;x z21{R7i3wm2dVWx40;%*fzk=RrHO)TiTU+FhA+YkE!OQtpmIUKJ$-sbZVVrtBEN+Hxa&Lh?Ol>85sW1lr2Rv8F*#|Yiz5YpzsY$k1 zgmbOf15v9ZM|z1tfuJ+6hRT1%R6fAn&1#t%pxkH&!a77b-6PB`6%o?a4eRK4Lemb_ zTY$xsz&&GEH)CbEr)|v8z*qjmHd*Jk$M}_~%;3ay6P1tL4q!x_e>Sj#t}nF+u1#y? z#Uz!?br7wsK-$Aj7m#4yLl{W61z#u7(?$_4GOIgVM{6BQf#oQl6eT?|WvdMIEkD$3 zp*L@oa+~P$;>FEykY^rpE7WLNV)jz*@|6%rO;e77RPuV>g21`Aw=ZMR#K0l=NLlm? zmgeLM38KW8afC4h!Y)ntg1T2%B|&S~T8<~kWh|;FlD6-o^xC;h47jPy5j8uA)g*cr zP(#^0%+4N|iBIH*B3zep?_6k?*yzzLVO%$)yvl^84Sm_b_zQTZX3}m|1hKYpg)VAa z!kGiqSe!ZAIjch~aC6}lS65;^!|-db42GX+!0%$PJjrV>X4WSKAu%cf7Xxxeemlbr zMbM@;SQD`P2qR0K%VC3^k2`~uBhDtUHF1u6jCIx(Ut~vjnkPe{MIz^0hvHQCZ_kho z1qEkWl6V2SwbX!7JQSm{RvZK752D-wzOt{5Cj02JKkB7IZ*TK3uxgG=y9^P_JztVh zKuR)vW;s?0XDF`j1i=aCLU)^xiR9sf-4RAu7Wac}2Q`P>l1}k{FpzErmY;LaV{9?y zI_th5{SP_ky!`e@OOgyv!x(d%N-NypuU}L!!#HDFwnAR5X8-?ctX-ke&sX~`v~7*9 zX4s=;d*ks>eoGhRlJv>&a%QBOEnmqrw6y$T$U<`t)dOk9hBbCa09$bmYBZK&GGnL$ z@CxCl9_#i{&#v((9lx~+76vy^#Bv&KTw#D}wG_8D{d(UVqn^XQYB@_`Eu=zrfqP(=TF4CZqA_xpfRn+t{f0S+%+-hk82>!nfz- z8*-8a3acqb<^u?HJ|s=BRZqJX43LppWHjY|TdyR37Onbnb?GEe_c{Y~W%0IXQc;QW zcn$XbZ%DZ$P4~$)-c`U`<<(J7MZCrbY_?TOa+1!=MBgx4YRWmm+K^^<>V?G{S!D|g zh03Ox#f7Mz7mB2P>1bNk-}@1+>bDeiqz>=def@ws-k1;Ge1=@9b=06i3tx?7@)!G0 zt?NYNeR`{-jd|ZUmsqu#ZsqiCsT$tey4`RD|2Qsbu0WA#UUHQm`7ufzobN9zIx1Mz zbmNuvW>ihj5S6z4?xV-|C*|?lv|s>1LcUtPT}j9xC{YIkJhN|Lp~Bats+~z%IctVqAY&+9%k5>dFL<)xfgC4^udI)2fAYE464n!ov|x(Kyot^Qji zglp3gJzl7TW)1h-uEVjU0D1RV(Dc+uU3!OZt38wG=^tjO^BSUNWCgI~8}gCb@=LYU zmG`aBYMdJ7V}l)k<3*~_H>56_T;DeR!}brT>~iq=FVul;uyKLtSB`oX1D2Jbt5{+c za>k=>R3mk`C-3{Ua>*4z$=fBY>sYYIR zear(EhrU(4MXrkvS84e%yOZwg=JwGu2Z^AoMECW`_d5^+H<}%EYuO)guHN{A;3$h6 z;v&dE@9AQ@Qz3u9ItlS?u`fFv`83hK}f6UU_Lc=^dHyIM-)05svZx0k7qlYQ-Fl9!jav}L7;+~mdk&1es* z@k2__>TwDRyi+;R;UPuyM0qQnl2cFRqwS}^6=*xu2UkM8jP6+iAbOzj)#}RfVt$Ae z8c`+IpP^ZEBYPDVP?`Quj2p?EoeN@Im6U*@c@1bo39{aV%EPxT z;NTJBkn)LkRs0$ntP~9esHWCioDkL?Ukv~@`8UfuRf3+L^n*J_vx>FGWG1&sF~?}d zSAEsiG@g6==_a)e3w!I|`l$uTy_&d!9sSFhfKjJ#WPnaJjs454@j;Q9k_nL#`H8{1toW z8jxa<+tjV4<8t@1gcPo4Os_>H!4MpbAN?YDpy0mxhovn!=Pp!ROYz3SC$EoNc*msy zWA8|Ou;itFSuUQ7ubNeeWWVu8SYp2AtIt^3-T&G`E^zX-zo1aLO>LP~R{mFZtl|cy zWk*QkK`iq+mg-E3Ak_G>z8)s|@pR^a$y;$x4_yi$rH&+eh(&H{TG`8 zuEhxFW_--!*VWqU$5CS6KG-63JPMM^(!9Uyf>Ms&z10M!7+2WB9i;JT=deT47v(|R zmx3JfujQ@B>*%BCv23!V8~Zn-%>nwYqQHWyQ$D74nc(?J>8=j9;uBRrACLSOXHdNW z4Cfnrr6|>*iG_!Bc&(OaP-D6mIV7>JF6$i+a+lPX%!t=4(zEDg@R~)CkgB$zfeKbq zMgqRO{gLBgK0!KLpdyWrGY_VEcyGs2TT?w6&-Uzu-oIY=bjs5iuc9cH)_uQa4pf}{IQ>GthnKH4t(2dq znO=HR6^%Mhi2`I0HE&dYo|9`qYrxNi7+f6_hYE2VId|nV$A^^TH*3+zw>b9C8i=W_ zK#YD-I0}_3+%VUoe1+%AKXT<4@R19~z2Hsbg&-iZc@%uLW* zK10F|H}v;TVD=?FeiXET(6{)J@hev=R#zQPM!(x(FWhk|T~wJhRNmIV&_gW^yWsDl zf&*Y8PuJ>paQB?6Sw650@NnbsK>u%pAfZNUXM4suzTVC3INObw#A?5!5f|(Tq-^}e z9wXdA(ZeGQeOU-n%8{ScK8jl$me63Em^zB#HaMfg#6^OlO@>Ywd^*$aqRvujEO4pa z@l*v?IcdisPHI@6WpD2s{7|sM5mTcEB*}_KzxWe4P-bHL&+IA{a?*^UgYkKeUd`Mi zE!rFpIq0d`@9_0Pd0rOi)={DW3UPd4SHaPW_UhOaPaMA{#Bxm=6reb=6dm==Z+PUc z7aKxh+U4yI?1Oxx;&Xi-Z8*}Z57L93jtT`vx~uMewE`_rtiw-9AkI4_Q^Av;7xSvU z_;7xuubFhQ9cYv0qHpd`PFH|-wG?Ae^0%{c$;mcB2W#W-_hyC24@Act61yZu%hPD6 zL1BU>x?F%~q0%UQ9G&VHs4P^jbY1Y3p}`wL9O*3k$1npaxM!Uor_2SLu`9k7+rjG2 z%ZeMzvhN-1Od)^fM4ckKdu#PY)b!6VKSxiJmds7CKBGG1@ICbuRI_tozZny&H5;ui zOVR1Adok32CWF7#duho5zd}mv+i@JD&WI<}GOv*j>QupDy zAV~=ENA1iUo%iJce6?n2RV>E7pGv8me1j^Lg0PNjSraS-YUE>uQKDHXYCok#`Ycv- zKDW|UeS~)Ws^AWosPj}c)_(9QM?Uo1vWeeg*L!5GvpYz+c|u|$R`l1y41sxEL%W0q z_apR1YU!b2@g(i+%6bdRj`9S#0`V*aGBs^h;&Ybft$b4wXL)6OscZu|vs3U?h1dQ7 zhN@ex`WPi|^$fF>4t~y%sw{cVkQaRvsSwnoh6}hS8tVG>3=E#Y@Opw#AnO5)*_moi zx>Pve^je9z#;%NFtExNKMhL>*SUXLXN35&SxsGIB644qc=-TQ|m8ho2aleH+8(hK; zMpq}{Dtlg_<`L!n6Fy5a(AdZaZVuUJt0C;UKRfCkfZ<6lWGDP7 zcqRiaV9+53X;_Wi$l_4OJm|gJ0@bY?*E;~A-%f%h#Z|YjP&-QUv2GnE3#K;IGj|4S zXK%_|W=2@N_CFvL&YA3X&{*)0-T~0Pt8NdKTbkJ%e4jU9J`|!Q0J+6?nFimOIT&S7b7V)=}Nv&BM3ph{+PZf~_REqi(OH(> zRqX-ArW|7x7bAvUf*BOuZn4Ys+~o5tG+TbjeYb)VrU`nu3!51;=dwY$Oxwc`^Du^}W{Nh-6!L52{}?`o6h{DuK0n z4^1@v6A1(J7MlNzSjoHr8e`c&?BzL(Qcc)0h_5a5CYf_kQ)7??) zpqW$mSHaL?HNVm$nm$F8+tBEcf9*kPUBym-u8uA7t;zBkD4c$4grDHa+{#Hs$hG`K z&|7KnsH~T%?#4JXV8&nLY{paX9=$3?pL@FaZS>Nb>E6ml}-7enG+QPS??rCoo1o@7I2Uu|_9 zbZZ1T&fVE7SmC^S&LS|a4i&<= zu_4DCpw?U&>?aMaRp>-3#ZeGT(Uvi+#>nLtSq~1&^%Ef-$yvnG>>CynBMaz-qQ43) zsEm>P7E*46nAlHGX3oSdlsd;)@>fEPLerjDfl7D{>V!SiQ8Wu{Xi0jCJ-41Mv#Hs6J1rrllUIqG>sWG1_6>5iDZCA{&^_8<>u> zQ~eb`GO&&Cvo(yG*S=0u6;bQDuE4>vrf&zX6M$Y}hN!0Pf#xR#+eL3b%H=&!dFb3q zyY&_-{m9{OxxdTopmQ7Az~r@P1vBLMjtw{t8z+mJ!^pW4Wg~s0KdiFR#*HS~fmI`2 z!sPPJN7Sa0!2TLHR)|X|=Dx&wL;pPbe_2tUQ%(4XA!B=6PX&hHHoOM5y((C96S07N?w;R64=xWljxR&^8Gs6~krVUh~ zm-Npa(k0+<^;qjSQT6U2>YxU`v1>Q-ZM-tPvPO*pF*$oo4~F6M{uO^$ZD~vY>pO*I z;rqS}5w#Z`W}e)*0(y87%4IZAW$$QA%ask}iIP-1_=-D1=e+PDA?*8X4@KEN> zvZ+B{ZrZ$el7*L&YV}c@+Vaxrx0~`oc(TNRNt9+|OA474=$Ng8Sq8q6`6)!pn>Rp^ z5RoplrI4e}Dr5B#dd|I5rNAfL8!-;g7SYmz2KLraVYtNu4DoXM0HZlfvbu`~4IOc4 zAQZuLM>eY_+|!(yE;mPihVuk>=j^xSvvb^B*(T+W$l{hwqmpE zS7H#>##GqDpGOiv^=d#Pwj?`zznij|N4sdUHiQIS!KISv^uc%R4n)mcr0QU-_ZuJt zAY^uChT_zBqC+T5J>^P5t|gAvNdkdN=Le}XHF(XV`Z$SfMa+XfdHlP|#zz}o*pO+plK2N%Da{FlCpQ?fnt^JCFVhrD%2NVBqsx2LN@qB%l6(D7f@WY2eOTj$_+u&yi zE6c9&Dn!Q?sww~0n? zE>NK&J$IryuRPCP+SbF3$btPdi!{lTu8LA6(*HLz2Oa!c2vkRg89}n@)kh&6l2w*s z+2aYb4qjHnmq`w4`*{YdwzHiZ;?JbIs?DLngDqG2ZNyegv}OX=+rx5kf{j|}GbvZL z?`a)T)X-<#t!^O;wH?{0&m+pT6x~{qTSJ9~{Arlrgpm<@4D0*fEr)PGl}B}bh@%F# zLp=){)xUIWyOGX%-vNIoZgl~u=-Pc~tP1zrypuw-40Sblr-xxuv!5AKZ1x8=1v{Vb z|BXLLZ&iviAMPXlY?Xz+EOpB6rQKeYb~|XT?{?%yc=?M;QK3krzt^h{H8*j~HPF<_ zQ;V7TbD_p%xF9|(6C+1y;fZo84NSzrf(69~uBhOwNezF=5X;`9-Q7jBe!&wxqBd=( z19hJ$5m9PMb>F=JsmR-u=4u<9(;W=A-BJ4OB9A>mE7YmR4(b2!r`ZhcEk~%FR6F-; zdz^OJ+7`x6;)qCfRQX)z4k9+c9n`1!a36%s`I2`tCfIaPUqE$^varbFWrku|oyn&J zO*J$P8GzG7@PnuwL~X%Gel6iziv=<@UV8|J(X}pMJy3k@Lm5Vre3o@iwhj6Zz#~LH zD<(S8qV@N&#@Ziut4vT~1F-F}Aj@1g?u4xkmx->gK0*Jv^Q$UCD-EmQHj%bXL;%ru z%eh@hX^xZ#MQM6&MLh<7=4Bz}$BdR&r7P6g@tPanIQv~eTZ^99lw6oe%KJnsPw(yg zjR}#z=MC^nbYk2HGSK|=xjW9sdaoOmWI@;H3q|k2zgalilng-DIOFHs*pS$SpnQjF*+7`q!#e) zh~wSe5qf2f2Q;zon;ve7kbRptikJr4_MtN0s4 zv~GE>9#-KmXctfA6X!*njzq3N3vdVj#O*li1JP9vtuPn`a-5kFnz8eD?l{ehQ~~kF zyA1Tls4?jb2tC;CPKZ)v#3MmhjwV|DgPX+8Fw6w*@5MqKVC8+aDEKAq-v~~0B#B&R zx1SpT+w!ufzBM(BCO;hOzMQ!BU2-NV{(`MoPP1GFZ#MUc0DB&={j4dDxYvzITf&^V z09mOI#6T;u^GDJ0DY>~EGM1CRU`>dX;9)VMA$jFt#k0^Pw-2rI?g-urC^0%Jc+t1% zV7i_nc~!+E!pvTR0+huA&CM;u_44cFl^41325gf?K95_e}R3n~dY;1XT#iCk7+f9WhWSRuDkJEiK0og?; zi1FY|+v6N6Uz&db4wr}ghqdJ19~BKesWbq>%eMGgvW6yp)h7jj{r|h@t4H&Qb^2n`NRnK##^8tsE5vR|;sD>cvqdus|r?_OfeN_bl#hGO~>izUBV#R%|C25!hX#YjVvGlcc# zkVowh69V~g`Xk`V`0XN1rIGO^^+qly1?f25{b?qWnJGrCq=^SJU9kpALif9n=|uYY zf5}!Ne?VceMFj{YQnH+==*a&nXP`ODC!rXXf6^u!=(HdbEy(Q??CH77!6Mx7p~#@W zw=qM*eIh8;p=qB_X6|RM{2xd%)znuN5FaXpTLShh1**c=p_n;FmFA1|5gId2^E+9? z!!#|qb|}q5$}aiXwoe(0Un=KSGWxD(n1fWAaTDAw&v4>5()#i+Jv_s&`0?oPw7A;l zb;T*T+9fkaRBNbc$s)EN1p=3DbGL)k8x)44E4 z11CPXaag}!2+?eMRxBjbyvB+;fznppv<=4-pl|&fP@6I>)lQMORS^@{K8ipo%Uxf< z_vL#pdR7wICu*w!JbViL28n-Qj&OyYkselhq*#Y;18;`zBxg2J&8-Dy zE9HjxK~aax`V%MstfJQkZV_bt#m(EcF(Uj1x&5-X0-Y+ZLF}!p=y`pc{cBi4l3;;!vA- zCF)E>K^a;-!c7t!Iq-wc1=l=g=w-^x$=eO&S9ILg!|uBHv6Xt)eaIA5N{gOm$PT-~ zQaEHmG9le;Wrl%p6-DnPB7L7B5#Wwm1_Hqj#sXPuTM!{!dA7q!QW{5mYPfFX^+L26 zu&7qs@*zzAz2?rNihtSmFmYu;>qzbYaAVfiBT!Assw}p5HQ%1Lke|O7f^hCiOGT|j z%ZOoTp5azf{>RoZL(jlQvGhiWs9$EtOF4P2sBKCDe}d0#XCFc$&&FS- zdbk)N`WlcTmFTEXBs-IK^D=ul$(^TJ`)qQ$ahbWJQJ{BgO{uTF}TVk+lXux;(#~iB+)q;%OE;i zpc}s;G3N;ny<+ z53mD@y<#9kx@|f?_J587X(RXXK~gKlBlb)xw!Ux zinO3@K4_wE(G2$I_zYhu#qHv66QLUup7Wf*4puZ+8A4tBmemu7oN;r$17&JlUdy zZ83wBQ>J6Qx|64vAD0Ur5nXM_t8%OuMkyucH6n5shIh%e9xNgivd=cQFmjuTpo|4& zSc^Zoen&ru>sUYV1(&r1w~`u;!)`e4FwIf_A;XouH%s)CCL@}%NO#+hPHE3NXaf0l zLw%5Poohpq{!-sLNln+pgv#mGKHYmx>b{d zB&Nn0Rf>uf$Is)@kcn{P#3(Abb-h6nk%8bx%X%bX5&2YF1bx7FrC_`EW;=;C{a=V%(7jeOq0L~_TQ4B>gf8DMjj&HWd$cS0n6%xAzPpoX|kCU%d zT%_%hNPH1F4p++Sv2Xf1ETy(>F>HY3Pz90x^)NY(nsm&pGBR~)lHpOk23_CBs*s_U zyP4I^YNkAAD=zh_E&9rl#v=-i)Yc^g<;q10^tjCgG5jg@-Q5@BNGwm({6x9H6(L%O za{cF;y+kf9%4tXy*r0OJpnVo#o5|f-3oPW$d~B(vMs3LTaJ74O8y(!uB*GFC_*jX*m+yB$wN) z=XiPan9M8-%H)n=antLow9pTiN`VcfVKwkiu`?~9C9TfCMQ1X}9;nYm)@Z4a7wzHd zL->9P$PDb1_Ml#-(%F-GNVmaF1rt!2j8p7B922@Qh#{$KJr%x>{|1GC3dit5qB$)_ zK!A>IEXb|fkz}_5Nh83-6|pbFFi z$S@&-l*2QS$n;SAnyChyOus-?LB;dz+fADx?>atE#ZfS8aAP*vHrPDQQ(`=sTgNE8U<%GgSR+A@?kmM?Qt9jgcQ{IqK7L?arM8Vio0yzb{6+tu<= z4L4Jn@lcJNoQuU*Cg~7FFV!Dz2aTo8XKH6%K9PH>vl>kkq&b@ud>l@WcTyLm@dZ7v z`&du<$jX)7kmW;-hnooKgb{4hx{yV3TUK|e3sO*Wg`mw;o*UQyrP={d`%v8~>V!@s zli$2bs*R4SZ~@21Gq;MV^F&@wdiese2g8EUPij{qzWWTtuh!M)M>PKZikhoi-!*BJ zM?{|Ax&2*%>e7Aiiz*YU;BDq&)xH{deY9(L0}M~OkkUhKN!2Ke=cN3WFp7k?0*1GbP@p zZSYN!m4>-nLa+>VoL$Nqx%-Z*g$NL$Z+aOBYvoEE5e%1S9^ROm$LmTJu7cMh_I2xQ zwOp5%mJO;8DZBd6m?T4e>CN}$|3+$>^~M1koVT2@?ErX-NKt_(x24K=Wd$6i2G38C zr;{bS1ug~sT=xJ_nKaxldXG@onNey5i?sRWOtlTbc1g!NsAWCR@qhoO&NJ}79#=1_ z3#y=s9)(!-dE3=4`AK=at>E#gB$?M;Nz*aA1X_s(U*8mr zppe_kpsVFS-@6g)cAbF-oG5Qaxi@v3D+jCBpr0gI%F^KW>&fWo*#W%g8zy?r(xS15 z;Av@+sh(i1O!uy@t> zw_&N7#*_8g5!NvIbC`j#WhIcgM-)^Ql%!X7+&4?KMunOxE6uxHgvs0-bJ%RpwLTPU!%yJdRhip6Rf-iy-@6Pl8T1@ zd}eCiq9hZo;#y;lQK`ZPAy}PWdAre0>00q`wQm5gWYvQ!rWSRPggU0x$j$Gp45)LQEFCY8*m6s4ti(5a5F4Ep;E(j|Y{kpT4?ASMv`t^t7l|g`XK7Awf#+?larjVM zIA?p7k51>>*aN(D<;K=@FE3^KN2UjPx$f9RE_l6>uP%5_sXPfy1e?%D!}~x0a4D~; zS~BqR;3}nHwl4~u6=HfCZo0(oL56NXAEz6$KQZUg>z1(I!%rGk=b1Y3CG9+RDKyy4 zYt!v6+PPLmq}EW|;ITrq1+Sgd(9IGzJ6)c&7X;!R+n}!6*%Hm*pWaW8AUx3UO?m+@ z$KL1QVejh~=7Kd0lb1s^Hueq$2{heVo<$74DWzkHfL#CR_8>X9V|#$)^u?FTOghRxqJI+pRXcXxH1F5Lw|KH?9WTdT#I{oR-{; zDYfz~7|PUYW)v?q=nu8U>l%%5q~Z+T&H&1=_N;1`sP$?cp&$+THt3+5OyqAw=Qbt-}DwA za^dm@6dAJTva=vPc;x+(j{vi4u>EVpKzZ8!Fh)o$B2a z?D~PVUL@Lb?K=%f=XiP2o(XCTJcW1O#+d&+IKMdLzWiI^r)Eljezk<1?ye4Gwv%sC zGeJg)T<{b#4>h+`aHwpUgx;iNnM25%!z*X1pHMq%0PXMYkSyG3;v=-@;JL0{%A^f= zq|dd0$Wf3DISEi9pNPI>@^dTZx&VwTi!5^hJn$iH`np>PYG~)}pR0{&aK=wu$5vSX zEqu1LVpqR9(uB9&efajcgAe?9y^9*q^|8vjB(!U@y)$-6JPUIyGOZBI@Q!d6{X4_X}KO=R?pw7mTGA@0CQIB$-NS;h6=iONJ;bb6!TN=I}q#@fINd#7Q>TmLco z!&KXIwqUD4o3wZUt|@P>Bji=2o<%i6Mu06^LB!I$RRULq8kfDr;yd|FvyVD%oDbOm zIPkzoVFMa>C1djG$;K0UQONryVy9ir@~4=YbqSxDw{F=C|NWmdh32IgJ~1&FIi zOw^!Nwsj2^QRClhFazCnpWaF}$G>8+T}74G>$sNZcDKs|0VsVJKFrebu^Z*SPj~W4 zxoTC9LspKdM$=6i>Dtbf(R2g-qrxRdrgE>w_Barp;DY-DfdJcFGp_AiXl@9n< zOGTwT5t@F4B2C$hdFocaE_9IKNKuFSwQ5&|NNMUrhyxt=t5-m(maQ;F+n)s6tEJMs zr_@)uYDY3}tj}rvMtZLRfUzz4p!duXJX#vPqs(z1uS@SfJm18}$`1SMI0*3hk7F1G z=Wcw2cnUw$^!52H9bKEf6**4wqLCBTRxoK_+NbjMT?D42 z`C{fEBCQbf1_3EOo@?TLd&q*U0zQ(tX(Hg#BHa@GlcKz`?NxoOsBdJ>l{-#8*m9;$ z?LhcC@c#I5N;MU)3eNU??3BIj|2ewy02i)5KFbR)WLFHv+AgvPi8ENl*`Y$>40WWg zh6;%~LLFO_X$e_Jg*xIWp`uwuQ&-a#9qekh7O5)h4nNDTGjz*h>F@LU&m@`5yyJVl z@B6;*aa>fzzTfZ+f<=DVc5?=&a^KsqAMUZ5s%^i498GvD~LEBs-0lhJ-|j z-X8yTiri2o{#tYr4tsLl<&(DSRASwR%ex!Y(hu1^|NPuWzbV~=RYsb%{VyJ#u5U}z z(F(^MYr&E@$(1gGevK2xnnF}Pb*Ljo#r>UOEToMbqu9soUAK=Hs$w4wPsc%SptXKf zO7X|=0hm$`DA7zll!q-;S3Z1jJe$I{k-d4%WZH2_#}v+}lE2Cx zwVhK1rhHj1#h`*;W-hslIz42b2Y=2P4F%b|sz;JjWfeR0V2iL2llxPNKG4E!>sjsR-yKTY`zPjdRtmw?STKH(!?Dg{QEs4B5rT`R>+RRNW* zC59TvW6A7Q;?A}oph&(xpg%Ay@o|Pu6+V4yHiM+*oeqp?xkedcO1MLF`}VntRO|>wWsNz>++XZnes*}N zFln~KP8YS#1x1eb*M$sPR3^gUFTsd=`vT=d4=T6qDE!!F-NzCxyU! zG;ztMFwnJokFxAh(#LPKF=GEAO`c84^dKzr@zX^{;!_LpW8j}DdBt?dIS;PfgZm6Q zjnYbaXFcj)eGm!(m+??=tGO9zvD#$XdPN9%YD1Xk#}`(m+N$t_WkKuZoaq~UE%mB2;Z6IKVz<3pC&;+y{)TOl%Pvj z9bt^TB+wjyIWMbBX1cIoXt0oko(dtE28xVYJ6-&;E{r`hUfL91D!*S_8=#4CdS>$% zbM|TBo7IS=9*`#$ISOe!|7#ZZAupK%v`XXWd8&sx+Z z`Sz*FN2TR6c{42eeXB4Fru23yEDXCIv!IypMzzI9pZ670bYS<6$3doCZVAo^xyJ%G znR1#7rZSc0*_N>i9d{Fp5mDb0>$i}ZoiGaZh3U>tU zbj@*(LZ-g@EEklxZV}8Y55KBnveSLTI-4|fNXtHsEK<5rFd{>2>dUW_vgrJiO`sFb z_>u?Ll;$SDH7hLR6(W+!?FO}Ox%ob>VqGuHL-9j(@Nd7>1&S<^9uzd)=&q3gg_#AO%l%p`4G8a5MnFo2;$4 zEK$G+*L9HTmc0eqC|&Yl4?yEc%Fhmt77v`RfMBb(aZ(aMQ%Oh+#6i;*6Zn290r|nB|0szj2@1wtX!E$W^m1}wkJ^^u2#?NWsXa_}73Qn+~#L_1RC<#d`jSP^F&(qC!*7NpM-6Nsa637-Ym)EaG>oTyPt0W!|j zuyAwhqOPE3E_K>}HMg2y0&vB{Q+T9(6n6`DMCheuFzL0s7A%Ch16TzgvBz(Ms3C>z zgKm^f9mNV^g@?Dtz{QUSX`wT0Mr`G5X)Ae+*4 zt6)ndXJ&h#=ucdl=cMW~EBIZ`7JQ(=3f}@S^8J6cGExIq;iD~JAfAYrCGuh`7=Yty z@nSt#8JlJ0EArrzUpbXA$fhc=wEw0~kwDb(NLt}xV%wsCDRR(853GHA z)S#lojnf$LwdWt2APdi|W0BtC;ayq~N~fcMocV9T4_Ay_!MlPE?lIkwO47@P;x5!& zB*QVD&>w{8O&YuK4$=aYc?GF0@(~PB1Zd{P;lT*qKJ)mkGL@7)a5c^zRHx7V@p}r) z6N4iQQ$jd#DrxSP?f3fg;m@Kdqo2iii^N2&{ui>|{=c1mCH zWpLp7eJgMw?f5KcguXfx48>K~m_Uph$FizN+?%V6U}_v@G}3hzecKLd-nIew zL$N~%vL2`H4dfiA$MJp58Whq@p^rW`aT!3h=3Qo)Xsx~L7HO#an~(Bh%p~GTr9IbeU_)!wvIt3szMH}X&gO@} zuhE=TUi|?yT zI0m>f(t{&{IfC~rRkvPl!Wr&DAvP8MuD1bo&G)xF2I}j2)}e;)>okl-z3G%fgVO5E zwyWZ3CAAhO{4F#f=`Dj9>t?RvohXp$t6x!(O1k8+d@vlhS%_=7;xvDVTw2N};Je$e zo=})ZzCXZxrnzBz1!FzJT@wr+5ZyyK*Ldp*;WVNFRl$91&RF!IiB5*E807IvSa%m* z()y{9JD~MZ!{|A%0jCXu3^wQfXG!|w-JlJ5P434-tgClT0aS#7IaP|R{zEmr->mO z6+Sxor*-g`IF(W)Q~%Qr9&EH9ZU?HwES5Ifc<-eNh`Iis^eMjwVzqyhfzwaBQm|T) z5Rf@Er)T$-A~AxMh)NH)y8lpU+^E3c1iLW>4ek?MK;=b<*%k< zIyrjK6Q&04F3ShpqX%1YRxFyrs-;P$PrxVgyL*w$#lBl`o~7=JS3z&#wk&eVTG|1^ zN?v^#=m~u9%hS;XvfG2CU6w)6YJ3O2W99s=eA)@^ZT+nuCYV}jw<$sI%zdfV(F^lf z+H~T6Eu_MwzQRSgeal0H05TN(a-W^@jpbz|H+wN!OOcNPTa}tL{?*$ek)D0q3u|Hd znn8*}+UM&c3>>yl?3^MwX+bAFZ`}&~l&&&rQ|a_$W(XAf^om7T5W02Cv696L^1b93 zVctnOa9*!VoGqCNM|zRzf!tqsh!?BSBP-j28GKS(rYK!IG#?Ure2a@reY<$NhoYE9 zw(e1s(X@p>qiwJ78bln=9Iv(0gl!0rZmzL64@%s`PFe#+;$^4_+-MUZ@}b|Mrs0NT zwb1sKEHPPW<}E-oRv)}($Uz@RXp$)9HI6^sdYhRPYCv| z)h2Anl~WZ6d+2b_0Y{AI)4^>Q|1Hpm$?h&7dzI}dAFn}wo*jaYdTOA6xVQUbE@LgI zmbM`nr|Dl`<84}!S}e%(Y4Q4N3M;iHEm1gWWIa-N(rBWbx1t)<$gTiIVAmCvD9Zk= zPHUvzlX*Bxc0Lj!XK2mEosqy)l_mbQJVQfuot}UJ)zu9iO1++0kZifL{sp^>jRai- zD#7z86}WlI{LZjXvy>>9Nto*E28yL&hOsPqMwlDuJp1d|?K$=OVubss_E~vl=2uyCEpYFl`OM zC67PAiY~-I%gh7mbiFmU7_QVePz0zJBA5<*pW*|}{j(=0#hRv)`(A07!XaL2(i}IE z>#GvaxMPq5Z(n}Tm(?QUeiV%T>5z&m!N!Zn?I|+T-?tjTipJpq2hzONzxbcK{>-aD z>AC+Y6(}=ZyMY4Bz`I&VR4I5uBH4=$H54H-2!J;1)^EbAmOKmhN85T&alQjMtZHLz!Ho<-cyl9FCph%#7qa+_9`NjOkJn2(=7|zpm+kwT_*VZ z(dPHAYD1*vPePfK9QjKKjH9*-y8*PxEzMe)W}ZFZpj7HK#{<3f+b57r;dUcI`&~M- z1Bh{T{$ye(@EJfYeT_usRp_qww_<=X($3?gnWdLlCCTQ0FV#kiItL|d@`&h*21Y9!LC4o1yNuB7l&e%Da&;izdX6kxPJ1*9nFK26i; z2v;VAQ@K%T#g~Zx2CHGydS(!-$l@hDGe(XZ#qteu8-8GpT!DF=v{@vq6^xH);0O!d zvkymgIj~TrJ`gAI*Mj&Hl|He7&P$u+nX+h?qD2^S+1MRLh}&G(7x$ZEg< zui?#)kV#E~b~@R(8#tF1sK6q{wI)NZ65FhzLa5WKv_uu|N5~QP;}}Tpe#Z`Z5vq=U z2V!f`g{_{}{8GrrJKDX9C@p9;3&#l2^-Q43%jdFe2I1CEK#_s!_W&nJV}xg{=6gYO z!*{4N=#I1ZW{!kL_@lI>5C6Um`Y-?c6e~z-fB5jf$o(ga9XKnwKiC9G<-41QM%Fdc z##Q3ItrNRPQBfATC8(`JLaRY>0SCaWzUTmIi!Iw7(A1s70SxPl2SC5^w zmUPn`Z4&l1JTdVFm9q_hS*^19p-aD~J=RVN60BrLmqSxJYnI(tHC* zCmTi>AKA)*(d?|q)9P?-?1crM3)cS6cX{}>94EOkmU%UE)(S#lYogu^FKrs1{4zER(nqxAjT zemuWoYahtR-R-XgVR<}ws`obhwPJSi4t(egJDHuV`M(pt#>a)PzgdTmEPXTwAI0r+ z0{A%cj)2M>w9%L+3Y{v}LcJ1=#E148hra?lQ`rXgSqNjG{fC|l@Q%D~ z)na^z2g}&;Wop>J2rVQgtyE}Kl4|o5v>^VrPvKPgGERSjA!%;Ro{HxTTW`-|Z{4W< zJsuy>nr-_^OCum7^PN2G>c9JL4GS+i_NPq?13<#3HL4=cmb+o>-TmADj^fQ7nt8eS zu-1Mjf(HJ2%1i-sd`3A*t(&s0@d+SAI_ZYdUS(T8h1Hz*`$K#1;LQD*S}@?PA&P{G zeE4`X{waPne+yc=^Wmbk!2huMS}%=ObORIO+mA=%f9`BLtK28<*)H{UVyu6a zuzm45NgGndbhW2rV%$195*j7YE!| z7~rk(=TNjCfA0E%HN0)#Bzy#DI*KaMexxkXx$(tGDkc;Spn8&e&2ByUF&#`un&U$M@&e(P{j z+Zl!_JDu-vt29H0&IgWS!Apu5jW3(WB!p|8Nk;VWc;>_;2R};EAxSI;#*KgTn^uj@ zt51t<(4Damg53JE`VcKXKP<^W)qUe8A8P0x#n1x(>n{N+qUB*0dR0%EWzwh$XV+Z< z5ZgRwR^i^Y&J9fl5b(u*4D8cVZ46%ZUk<T0F20x5-r~4@ zpJ)>Zk6k?%tq0T};H-t(-~UY!Q-wE-{uE@&)!Pd_gZp0-i%8#nF^yrSZD2f};%?Pf zzzBGFJm$>RQ+2~U3)hlgg>!O89>PL=Vo_#6JRhU$OUJr(X*c{ozGj~qMVf4I4+&Xj9ORM+Nj-(MhN z@xAC~B(svHZ29#j{!F{$|C6=SK*w&@UYvO$$%+Hq(JWKtl~z4)U3Cx!T57meo)lI| zOB!{@prpIZk;Pl9BCaccYm4`D>%TNfv{R+92^*2yV}b!{J@%y|OiwjlU~z_!Co%9x?U`LO*J>%>zDZeso(B>;f;o zfD&_g^%1NmwTh-|jWn;MJj1M(j@3O{n3QmD=-BQ&CYBgG^J+zy`qkf6Ygz-JTTUeZ zRJ})cN=J=vjXA}?x;p~{wH{t*f?^>gW9Wf4SJ5!H`O9D#T*(&)oyZq>694+9Ew<=r ztw3*dF3qiK@e(EDdv3+MTHugd@rb4A3SVbQQ=ASxu9_1BO-t2_Jx*$f6+tc1bn1|Y z+E8C#!@u@5R~!0RSuR*xMaf}90OrCBFbKD8d z;Xp8%6cfzod_4C7qvA$en2F*}b7dJ-XY!y;sm)OgldI9n5undEf2xhsrl0<#P0+x- zohGWf`;hEI8`jh--(qN`?#KA&;h3Pwj%e>6aP>By2fV#a10YnA=Ryb^cQ)%425Vi^ z2c6C(=ks79-Mk=Zqz8viG+Al6ayz;!JQ%>grNt^x|MSBMg-=BXRQ((ax?JNl1oh0x z1DPuI-EO^+jxEfF=qW5+ycEMv?bUAsJ|Z7CS%KjMPL>1_IM;u-B244^ItC@WU{k3g zL^U(LlHuW3-=f1|^l$u-%7H!<#;ADozA1uXRsulO-|locsq}DdQ8CqQ zK89%}`s~h2P|b>5=z4O6w!DGjJmeA!dX-9_C_r&BRJ4=G&uxJ+j_Z(4z$39`hSe(#0J+*0L+6< zctCp8PfG#rZOQEa(O3Gj|K}}7FoJI{!g*AZ<>V;Fu`PY?;vf0(*IGBk@hVS3l{lI@ z4;&U~n(TpT#50Tm?YdB8fQNJ)lNY5zgJxqA_*NTiBR2xs=%mJkfODzq-S6E!!vCs0rYnBMhEns z{BPkSdTuI$JSyDEfzR*;R%t~#Bf^t?P2XT##r@mAV-jfL@9hY5nf{e23nxmC9U$Aw zPOXNjH~1KaDs%@Was^Mc=(J${98|TW|Z{XE6|Np|Cs{E47=B|@0Hkar8O6|sZ^xRwSGi*H3oFK zR+k_*xJJhvR@mehYD3iCdW{x98P^AN313#kNwicm!uR|HFJ|{}_#Nj=wP?te3UHZE z%hTGZY^(s2TjnXSwDHStia07ROaej!eTSN2sH}2XZze0qP)ly>T1u$UwS1t|?=pHA^sBLq}q;vzOWY1~_AaQOdW~%va8=KPFud!>8 zXVmxL->&Z{yr`;jGl*$;|L_#U+_T7p3A~&X1ndqs&*lKDYzo4xfjc@T7r)RFx#f(3Z55mHd!Dd#uGVXE&Gxu>Xu|4OEm{0Uq3u&yXX& z5%f0{P`zO<-K) z49{N!U&mT|+&C;xQQGM6_L&MhF}@N~kuvSCzahMIIjn5hL&4sLKJS?$J&0+|^7_t-JnAN0iESW-$bAuIWk;dJl1n&ul=0^kx|(y|lR* zh?R?(1$#0%^$laJH{&rDscj0jm>(5;A}XoDtKl%E`ljh4q`_3+M046=L>Mm&u`B98 z{3Ti}WRcbZ)O)H*ee2VhGyj`@EWMUH`U~(*!e<2lN>ka1cCELN-$F@`%w5dVFppog znx$^EN*)O|e|WVN;#iwVy%zy6sBK0!cUYcU;d3Rlj8K*(>;8wnrhI_Z-0cCinOWE7bes5Q*Hkpcok2= zK8reZekcWxPYyYjq@(S6vCJ0!qyO-}YSgc+0J88+Z4UvV-qDV=?yHdR(V)n}CN0b( zPj|5-aq4ExFxZ5rJ$Od*0SivCHeJQMk?g~2c#K$;)}s^7=hRwZ-I~FiKCR2mCS=!m zeO_Utws%h}u;eYA3mz`ax`~zyn-?>4gi~;Vyh}q(SS+OPou=rJ)64`HXEm+{F&#Qs zgB^fKli&AvY2rc!tef$ngV2-iN?Rxo=CXr;^w~~FnI-f*e~~w+=!uzMKq>5}{&;VO zj^>VpKVUUAH|s>jFtqCBn)yE@!5bo5i}6dfPn!Y=O%$MRNJCyDOs~g%SCkB$jTv$W zTQJ8BiLZp}&Sd0U%uvqlAA}ejVfH}6y{_c|v*dPllu@bpUY-nLv=E~b)w}Yr92ic! z3}i+uFNAup@(%Qk%~SwA1|iHi$yS9VPS-Ahx_fO2)4VU7?Ml+&I< z9J1yB5x%*Xag5iO<$HVJR;A@XwCN-5(o;xJU)jg?&Q5FO%8wxUWaa~?RgN9pS0CG$sbn% zqu-wL2>IuJZjm4d7YJTT>Rd0v_)(F#Rb~-eO$ShPxHC9gTs#BN=T3+wi3WD8!`k#fCBOme#A&QK z-1b$xw+7ONR{>VI4*$h)R=i~j!>_hESfK1TfrI=hOwp=IXHF>*g#tXmjnP1+i|4oV zMp%$fZNlm=-BW16cI(z^0jk)w>@X>RPYZg^S_hhvUMv7-a)VJp6$8%vgf9lBIl7Uy3}OX1&Dg*E6~%~ULe0se?alsdDa3aWqX69Fq(asokboWh5BVvDPtt- zi9SJR-a_#w5*>u~;nW@s+unG&BS7UHE|>{4D{Fg11d#_kRw_3djUm`SYzvJ@KD z3+OBYQlc7G8bMR@1`Dw_>|jL#10C8j1zT+Lt^%r6y+1MdMD9>X0j|1i0+QEmQwGSp z5sR6A=;)sWWN0TB0fO^pXk)0LxyxcBYd`!iTzP9YW_cqG5<<5E@soQ#4N7#mVjf>s zhk6%1X8o2gy2poW(OoC212$cHCJ%^afK=GD`d;;Bnc}XZ!k+dgTK<(oDuv|&$ zUui=ifHxoj`H#OnSPVWmqtuc9uN)Y}qHMj6oK3=W@`Jrv5h`{8CLw;#>aqq#Zea|x zX-rO(%s*|(B6nU0?rOx=$AZJBJYKF1%fOhRncDX~;N8hIQLMrb?(G!3WQfc{Gw~;9 zfid?G7JMd7XcqKSd-52jHtlMS14>OVq*$QwKZoPV@KZbB&keqVC)Equ0Nn1Mwm~_d z;qlB;82IxutxUxq^!V=kOTsl)u`?t8JxyIkvUra^L?%Bh36szPmW(9u659#+21G}5 zA9GVnwAlgT`?>&xF2+UZGg6OPS|<&B(-pK3|KU@H^Znr>XiQ&E!txnw6jYSq)a`7Z zge>Jl^ZYa%{LAE{;p5%%a0>OqadgjVHnTufv(FQtoP1h{!l&-r``e+WezzIyqu$#W zQbRn}4_JuTIIjqy`0XHc6CS%jf&I@{xwykoj>StBZcxU_%wGB^$z1Hw0DKQD@UpuB zM&bTGlH`V~tLp{ywYY$7=CxyjlajKNf~+LtuUJxvGzH7h{-sJY(R5K7;mcC05UI3; z8EP~mD&Y7s-VIO)9~Wo}i6!NsQ%!ZjrzE-age)bAA?E_31WQ@n`N;=@B7&-o$_SYs zQO1y-O@@AIzEi@H;xz1G(7u}_=JPTHfK-l%zA;28lTbP?#*cFhgjkhUBIO8@ny5pt zN))s(0ZQpMC8Ek_3L!Pw(gdsTT`O{)O-@E9StUw4X~eYUo%cbE#(DV3^&IDZ95 z5&L;OS$0TS$i*Ltw8!>VIF#sBk5$m{{SE*PIpdH}#i&Y&pG>mm8_B6!`8c##uJ@AI zaaWWWx(Gg$uw@-Z#_GdVyi|p0+fzX6k#;2!5?du?r4Z`_Si=IR1SAcOfAs_hzkz!Y z6IOjmjBvxDqjSbP*k?$u5%O3zFi8O^F$zbtM6Ry%k}Pww#DxVPPr`Qmj5idF)k#_o zR#JBlOkX;KIn4L!?Idy!tC{+V-j7mAm(hlp8UuE?E_*{TH_i**h`plewdy5P8VG^4P*atqt8%C2pix?^cg7Noo zu^$9LFI>;Zx|j{}D2!)gmO3{@m-3QmVFk z4SCqW;v|I`Sa$mL&_m&|D2=4vAtjJJLur8XvL8-AM-Js^h-y5hZeEAWkiYTwwYk|M z(HRA)I$64>4gwUHk~cdAk|JoBkCbAwLA{u1y56vR>o$f(8tBr&)Bk zvVk;^b#0FVQR)ytRqgQP8MJaXpugNQ!Kkv|p{vLN=GHfXQWqc5~HPnj!z) zsty~8mJ4PT@r^{Mu_y@n2!|z5&cd|J{n6Fg-N2vmD$E*Xi||eC&u1~^VHyx1H)5k$ zk|PuMVxTNq47kQ7<@kww$r2~UI>Atl#BMOK|6>u!fF{7+gbA38`#X!5xET?}I$~Oh z&(O7ZCEC(`3s97$SPaB{MV}y9i@+19F};&m`{;dyegxe5l_2|T9>CGw1Vd=_n*}x6 z-vg+JG!{Z|DEtd>ZGIRe;;v-z6Tc?kO*^T3$H5%WeRqUZbNh{P8KW6D2cjNuOW zX+DYJ74`z29zMWm!(Zn3NUV;l-Wcnzh9s)7I%sbaxM z`U%E#BEOHJln((w9?r~hlM8P!QSUMrm|_#=X!sU5NNjOMh`H3F;|h{7o&gp&*ii2! zh41PO#2B=MNqC#m&w10Ll+-K*J%^5VZ!I27AzDM71+loJix6 zDVgxn72<{}B~+BW4dEc#ORzH7z4*#`vjNr%Kx~!an8RUKt3B`zy2~By63LL`Y*q43 zR@%6p{lmofQZOUUN3bM766eqr*R-UNBnXR(kJIE-^bjTSlRy^TXo-=~EC6-I9KD;w zB-}gvEXPcCHU}(I+h#jS%U+g3a=#+mz0dz6KTehmv&6Zzj|^n;Ga*1pY>5&uYKe>W z3R(@%0T_1P0z_||!fZ87U4Ei!0N(C-8BO>5LSIaDcY$=Sjy_HZ6EKB8X6wk7MQ9+s zF{r7mu1iO(89=V|5QNm+k480qyb*1cV+_Nte0#%6l0E6ob7pQYtj)4sM1Ks&5 zfP&?LEIa_IoixO$1&H0l(1hU=V7jms2*`a{Pfyqn~F;^K$tiaPc17N6gfXBQwlm?<{pA#W94ax*pkVfm04^pzR`nT$B(D&VT1DDV7r3WVDtnB$Qo0WUJ|x}J>q&y%C{2t+&3+dI^W_obuT?u zi#^yul-*a_YbB8_n_%LPFDZd@$=Ga;gf-~i>d{AuxJ@wDAO^QmhaKfV*hH6gb;*P# z`itB!ydGNs6mY*OHDvr`Jl*^arZmF`x;pZn64uI-0ObxVz+t!y!04vpTl5tA?_$$K zr=Jbds976Ov^K^p%Fg9r0T>Q4P(KB}pkDZid6i(SO77Uv;5ZjJ(=99AoHvg;6-jtC zNW;Dfr0D-;iiUfxHxl=#WFyxbRIB+3o%_zCbei=21%;WUN-juchF8(5k5H*$K9mO# zT?lb=7D&eb>7AS=4g47Df}uXdx=Z&guML|w(R^SLN%~6wesVh()~#be(2A`XqOCWG z#(mZW>9ICjB;I@sc1vwRqTplbW0fEQ~mxjoz z1Zy%e-v`XY-7KlZpXVwjRy&3ciS8p#HbL*ZE{>F1ECwQd0t(;xE{3~ci84xl?gnXk z8FSsF&?mUvEes^|MYfJ~S`S?Q-X0*OO#nG}AB@0UVlk4LZ!BTXnPx;yx`E&`vP(~i zxCS+Ai9KPVWPCHcvLcRGjDlVw(tb;vgx9)2^huaa@gPWs@`uVo(rX@2efC3)QM~I4 z(YScaM5z?|4H}cEDG9K|D2dv{{6a5s75YH}<0pr!mFS47i{4M}v9E67>&y_Y+=8pQ^KQAD6>f!%bMS-hA=qV*7YhFMR;4%vo;D=L!s3O+0KumE@ zmzqmYwvmDlFuT!}0nfrpxYXDW^amawgoW!9V7mnEO-wA&0;7ILfrG8%^36o#@lbIX z(2mv5t7csVp%>nI^sjfj;5H6;f>b-{-6K1elG z%>}*i99rtP8N5vY1^)N!130evFs-wr^-hv#3aWEX(i=$nO<-*1=Pp07JXe+xu{n4;9*;qD@G=t#Ps*H0X5xzfJ<(D zOChms#Po-3!`Ql?%l48hXDtEZZj0W$-{77?2V@r91dqjfvlKtJ9YCr7wJS^>pHm{0 zml?a2c$zu!Dlg!%sRH7QC zhc*!es0uy@{q)qM`^AsZR+nV>??|oN+Yo4w$g>zp+{R#6{8kS+a*k;h*8X7da4twU z>k1lA4PiDT4ujA+ZjGKJg^K`3b;~JE?j`8s+BS^Y+(B=}*1ZMCO#<2_U5<}6+W8RiZIZX@nl(6dYQVGa*kE%r>_Yr91pdW)8-xC*a9rRwl7f@S!2N({t#ypBw z=IDq|nU~S@0^6Jx-5(#1_ca{YQY(_zmDWHWFYeM50b&p9?gURd?aN z?iMxCsL-#i6IdfuK^f(WAB9NSBNsHyK_z(XBxa_bj+w=exHt%s112vVfY(4OxPMg2 zWJmveCmD7fV^}f-({=X7Kq@WD4io=;;0JOlM!d}|UXqv#8n-hWV7NEvMwe_UB+)H7 z*lQ1i7%#^lQ@@2Q&sxMvqPitKoY)C6<^IuoiRcCGm({k!NcrD*S3L*grGHpBQY8*P zjW@;0S-u;+i92v$MWU53Sg}qCwq^eV0NkZ|AIZ$gmWXihmE;1Z{!tbiac@;7RNV7iIR(>6WC8(`C%fXrI>rLM@&OFe-1SR1JQIhz zG$gQFA0^j5(I<%brBXu-pXov0jUX4yE|79SZ_$w<%d!n5HW)3a(*S?IAN3f)sB2+$GmABS~XRn2~*QK## zUkeA42RNu`WVT{Yzn0Gg&PUPA%cA=RqPvSAD!y8D5 z?oC_uV@!}nF@-k<6DaXH0+KRu zAm2=C_Eh-bEs+hCz?g=FDw8HdQumyNzt>*`sqeW4FvS3d(j1oWP zTS>_Rmf=%UA}buigX4dBV&qjf-q;XE9-GIG=<)s825!3GMfPa-5)WMQ;(d6(26o;U zU)Gcw@(yWX%FW5p8_82YGa*~o?FfjM=FJqDb83Sk!2Wi@=g1squyhSK$Oa}kXdmB@En#d;rit1f(z(?hE z=NY}7`=3WmxoJZ^n8VZRdf1X?VjU^c30zas1etCrfpa+^QRT7AO_v%6CP`F2ja?Ku zbQNB0TxqOJ5}YtJX@NFm=~OH<>c>-bsN|kdlAd)T-d+s_%4RSlv^_81#_7_W8WQiw zCfBqCvN3j<_k-7KJ!V7MIm=OqYFF(YkjAzIx>)=V^ojVn@>xkfMEcz^84+dskI768 zpS91kt88OiFU5SlrR8`zdak<`N8F#x0>g9RTFAgooL^!oe|iGz>N}&g1{&YhjWyrO z$tEv8W+?-tP8sS?v9V{vw-B$*@{im)O*W``mehA{aB-!%hjoBYVn zT@Ip_I==`;Q31LPBZ|+vmZzikyy@Vh_-{LLm3IU%Ebb2uLlG1I#h2CYu885pvky)t zxO1{ejogq27|I(C9+qK)ql%IDHldl;fqbM3E&Vf%k9MS)m;TN}0+WNEqLoIQ2Vn&3 zSO39_om4$Zon1*Hz0wlluAS(eG4+dLv~-*UgNO}zkcR@!%ctQLGIC0uftFQx1~?TC zYY6%@tV`unyTbW%HY3vw$Ug<4TIsA7*y6_Hq|!Zl7>>9N3wk)pX#D6?aFQGgXBU&5 zhd|I1C%WL^wTzdWz#+5T1bJxv-GQkF)L8T+Rw0Yay^2G=03D$f0dy9QBA)$I3zwhv zhxNsze!7FBQnLZ<_K0G3*1f3*#8>U@?4(UBWZ|*W$#)=xL~Ui00U@lj6gny|Jy!(G z-dC~a>(ujbR8#Ka-HnO;Sz6Rc=E^4U&iF5}g2$T#0~FcCg#bbzZwmIRWZ%9LC!z1a z%MsJt1mQak=k9c6<=z<~ob@Vzbm?swmh+^a*m2F`A;6o|EW_iZTr*^4070fi9ZnS9 z9&L)E=JXj;2oCgL;=6kIO`K~w+fQ?Vi7WmPlo8oJn;m(t-9drZz)#0b94-5F8gtT! z-;TiXg03_AAruczug3lvf~6jwrE7WvN1P-G5$xp;2+ftX< z#-WW+ScMEJVyP1~YuEvdJXfGdd>-1B=cZi$AFv1dNGPjLxGx274dT1Vtk{8vLaaG- zsbDdUFRtsssoL_YAZhvcEr3^`|9(>{jqiT|fgF!M2W0IlmYQHgoPn%z5V>yzcWuHA z65Po|hk^vK5a$a<$l^(nBoIW8IOZsSIvZLXP2v4IsyS&kfyoXr7bIyiJBXLJ{RMT0 z%V`d@a5Dt47QsPNKCSHzx_DGD5uPp4A*v+X zrsms8_*IFT+(}bfiM$P=ljK4`87GG`1RIdFfY%@-D06H!JTp`t7-p6TX55IgtOi`4 zR~{?8K8OSKeDRfDLv%YKf!F^Cak_UUE)^fULd0b7sNv$i&5XRx^7o)ej%#KqBTE{y z(u?+G2a0gU=FP_8^_%q&w_>%sAl&%pi99>12oGWj*>C2HH1I33t5SQr3LXiI&i^3# z?2THPz;$OF3Nww5aOA;86BX25;ZfK=2+UO2mE$MY8LSLy;vKz{?UE8?_D;Q<6g+JH2_C4{PwgUhkdaH)FC+ulux zRv~+mOhzh~7lKOLus{QiIadqntx=+nkv?lY2`V`vT004BOye>MSAfm8eQ0D=Iw^Fn0$#$_GLRsj2KkTzAa(bE>e zS&LXrg0(8)Yywgi7*JNV4%xaCoXZs#SPgMS}YE6=!o=wTV9&A-QP(!a{$J}xX2`>Pg74@#69Sdwif!^h{i$=ox7trj`o1B+(7BN$BDL>ZyJnvv}#|J;Wm z;m8`6kc+FI!jkEp9nJZ0m*W$`s6v7O{Lhq!n`U}Rkv}|ZISAuguK{k&y ziEy9Eg(#O=_h;2=1E=(!IJGyMh;B3wyFg?}n{MN~IO-oqh;m#TL2il4dH#1;dFO^C zYq85mhFGBraFyQXdr9#Ig%9qr9({<^=$s!VRR;)S3d!85)R0Z{v>*%JM=V8bElngv zvLM@JQX0?or``hQJ%8r?T`Ua8_Po}q6rV*^RAF%xfdt7Fh0_Rsh}nZNeDsU{R*(`f z)3#nk*Xl5Ix$5-o5-N$=iI{M_V4_r=jtY=1-GSsblOdWaJe)+*tMucLOhK zk1xfiW=37ao2fYW7x}zdO}*p-%X1`-d{tzCJ6{qjnHfvE&AclEVsi}6uzIe-K;4%= z;6)_RkUtT!C{azp`jdMlM@I(Ng1ox!`u2&pLV4J9vfc?x&f%v zyo2{4&Fs^UkpURHh|@)38vFMncwixie;LAvlPd9XUS&O#`)-n#KR* z$=DVC0wKiJW(sZiOVnN#DCaO*%D88&$dIOT0dxTIUIeyzSR983= zI`V>X)QMTlbS-SiR+G;@fgpI8%YsPc>Mdb)D&7snQ8KdP3Y@QVo|DpVa(M#^>2hE3 zNMVpTkjkr*Y5JrKJh~$tp7Bl#jb%Vjqwc)-aaDJmnc}Uc4!j!Dsib?DrkqFUq*~I~ zJAWU)`ij=>F?H;ndesu$3u&@<1aKB#_X$BlSaEgJs*G;t{4Vq6nsmtg1AIcD?`?=< zAaf?1kY2YzYo#ca47Tj&#F;C%CoPUD z3l>2_U_n)giw9|b9;xHAklg81&<+nKJ_s=4a2|%N0r{z<)XDo(p)W3m)=r(pjrkBtZqA;| z+?6Fyykj>rvF=etW7O#YScWxdz{`^ zd4e3hd1yEMi#c_(?a~>*l*j1@dYkR>4_VUXh zL~#I1v=pdUV1htQsF_!A&I*sHQfnH_fLHJ|B>f>=SHakg25R(lxT*T+4M&)Y8<#PY z^zv^U*cYBW3o#(R+tmRbYb7i7&b?>l)zwi7T8lrV=Kq2+aa?DeSS!Oc$dH6*zSM}%_bkKp7E$HFA^ zFL^R}Ka|-nLI@>bxShZz7g)kngYn2&p~fEb1giwHVk>hjOZk;)2Hdf#f|Zh5AD~nj z`HQ*nFP{lzOq#S0OZw)f**L7}nq5Yott;`uOzTpU=nR2NC%%2qUT1c)a8$KQpTQ=A zRP5-pU68r)N#i^@X5u@<$D!QS3wwMj(br=T;MQxCz}4h9A+;ajas_h>Dn%hwAxY%D zP>{H@9e55&uKt&-1=KH6Y^Ask>mgC{PC+S1?xnEN_{@nxta(fOVmlwms--Q&oIhnj zBg+MUC#vc3BcpBcVh%)urcIv5N~K2ZcyZl7ytNCJ2D20u+?zRQUesg(NwVF;%h0px zRA(DD?wi#tf77MlR!@kAXI0|egH`!W9~?M9U5>HzkmeH4+R^-=o#6?1g=BdlM#*b`a9dK5|4-1X+a_#vNs}OMxBaF=N-?NCHZTCTX=YUMzQJ@}y9A4Bc=BUD{!?>nvTE#03eews74nJq=^6EV!SP{HZf8NlA))*k;^$Bm?Nuc;si{^ra)#nu~@seErKV$_Xg$G#aT=|!| zV8jBcf+s<{B#*;)>FwP-Gg3-4=ChDvW!2iOBqyD7$#*NP61P|;pv^yCMQ%mZ0c)gQ z(X9jmbr6rMlAmV8V65o)^_F`Wg6mKbLeRVbr%8?i&Za< zM^xOXtxmpdAT55gl8-9sc+tv-hSKz$%Y3LVO>r*QQdO>DX*fxwnY+^SLbPO9V?I!q z_Uq-P)mW>emnIzMoxSLjT?l3+H$PJ9ROfsRkD}}7 zozG1=vi&VoD`*dQF9zN8+29+zu^w$ap`F4@Lk|e9?!`%pELuLc05h$<@j8&3`tqjM zOP_6D1yTvzV*yULFPjv8_`g3W66u9e3V3Ns%U96uSt{w~7xft-tbW-ODwsPq`nVP1 z=JA4TKaL@7?MT^WA(l+`jNwH!m2!Ljr*aMrxKfGcw#Q9p^HdS0Kd+Xw23qsiM;O5G z3zuR>OIozmLSt*tx2TYo?X9c`&`l?Y+={8B%l-$*-z=@%wE`I&rN!4DbuUEP>W9ph z{kzY0TvAE%TUxspt2zBpdaiqdHa>s2dtAlEPi-*SREGE7Tc2S^4%MqBp7H?-1#0(JDKi< zKnd4>vM^6Wf`48V2<9qPunDq;*~wjBlx4{$O5*4TY%3_WFefPi7#8VYDxxQ-Z zd&z-j$g$OsEwbPj?N#Z{z2FmnoASm|mQ%icVGavE-G=2T_5Q+!7tVr+)3*2c=I{BIC66kg}_vgnPQ=6#%Z!uh% z_D076(daGjP%+(YMHDPcZJ}*efif>wRU^ZGoDbq4$(0TiK@H6I)3}2x*3iF>Fe5+z zh^8ND9}IqV7p{lz%s{N_l-}8sN-aeBZSFM(FfOB?+LlL|3M)hPZj#pf7f!RbqZ%IZ z0#R3mS-nl5Nk`;kV-m@A(y!0KJ1$+13)-PpCD@%A?FB8L*iJirs%oKFhS)<`q zA;-o(ewy!MHJ)6{2PjhMl#(n>Ug@5E^ixPz;Jbz=ih(rRya=&{16$Q0YS@o(hVz7& zl}-aHJe=$m2{8RiPG{)g=(H4AB}NPw_EZ6bKK*>mm{f9x|Iek}Y0JTsV}TQhJ4Mhz zq0ejMLzxmt(h20P3cQZ*`EJA`ww1?otIfkkZm0SZuyEI8m(og=9Vis2RglNRWuK)4 zV9_4TMNtMdd+Fm^oT%&lR^X&BmvYNbyA7eGyhU)M$Qm({Mo9;KKu7)(U6qO9Jv)7! ztM<^nKNw|3YGBqFCT31T5J#M8j?#||MIIWcj+a$vgN;;;WrVY9!iYYdT=dTT=(_F?fd#@$q7C=*28SN4YgtcWV-5T|W(?j3h;LgznhDj>{WRk@9=8#*%erl&ugBC1|Wu|Y6y-N=Zzuy zS|~7}MjaG0YmJ%Eu5LJ=?f&HndFMOsJSGq54fRh7_d(1)Sd<;4(hSjBla3e&Dlp6w zbrmTYB{#ZdZ|$3_B~))SW6Y@X&YT013linBs zO^TUbe8dWwX$FV((p$RHtMA|s>|r5UiGy%^Ovw8sK}Hr2hptPqvKhr__1d4SrKKH3 zi<&k$>I+f%y|XzqbB_bHy?W8AqprHysPvcsZJ4Zp7iULM>nA4=u_KwHK~2lAyk{Xf zdXE*G`_pEizkbAJt>vC0f#FY>j)%FFlS`@hPHvc9U5{Xkc2ag0m0E##Eky$=D;7b1v@9b=)U@vo z(NdmXUdY8@MFMldkdaa1g_Jy3K;_>zYdxW*FN6)j(1|(F)nSeJRAP zTx&h#ygcHXpg?}N!8}*sC^Reyp!cg%Hq_5@1h>4cVd(D?;XP22)Q1`)nA(apaC;Lkc{G3+`V``34L_k#fl6IPU0W*e!3c4B@_s>_&b^UqqG?xn_OecS1mvFn zU7*0pDs4q|zro{>Doa8{i?%-wdlozaSai5j*M5X9365F`>zHh-EZR{+G};KKBjs!C z>SeEdOn`XZL%M?}HVy9#l4q}5W5R{z$b#u1w?ro-@rM49FCP!T^R`)H+tm#r zD57^^epqG{MNl-(yGfKN7Xi@$b_j~&zxq5((M~T&(u`x!k7UgcP;y5^(-3&vs|7!z zxUV~vSXk`wBY`mH%H(h*+w;x{0H=&aVgAz#K~d{w#}A)XMOaoAhqsvIDZ$Sqx(9r> zsBck{Du=ijxICyJLMKo6MJai%&uc|%+{Yys|KY&QTAdmf{lu(Loq|gumGgs?oGvgi zrR5?1q*+4>B-(C1Xi`4jQnXZ|_rA-GQ_WBaayh3UKr;3AzO5ZWRS~tiVy*HCu&WN7!R4ONiYtd*J+(7zof(ARV$LD3z zy*$|F@n>c?B!qAXr{uy2dBB;p&4sjb+Gp{MR-2FUb6gn4Eh4!y7Ef~SdFY@Eys4X% zJF0Rq(&2V~812x1sA7z?EstxJjn5!mc8>Gq0F-m4+DcFUBU)79*c6RD^7 zbfA`^k{~0_$AVN9*?74qL9;5@aCpoAG)9pFIVS`Gziu20>8EU4<%4~+r>W7-$eXe5 z0N8T{2#!?zK?V9Qxdsg>C;q1j&|n|YH32g>7OE9`wRU!h?jDE64RT2z8%9?Yx|57p zW~d`1sF!=vz)XClv;94V?k_6A!<0oh@?+IFxV^03iVAPJrrxWkJx99zOnSY@Y@(g~ zqNfsl&9Ef$`4Lz!S(P0!EoTsrOd-bS9L`lq-h-i`G~i9u6xLqZEO1F=nK%t6>R82b=RyNTPk0w0xMP!FdeaCaToMCzMBGSfui4eO3!Hk3ZA3U$kdX=Rh9J`F@=`gsa+EsHIk|AYs^h{jjLj zQK2fg4E>)R5VSm;)kiQ@W$|0jh0=;FA*|*h5K;@4B+^xHMAScp5}O56DvLSORfs(< zXkUov?ei+wx%FTtPzuWwU9jMLWI=|8k2Mu!eB32swh%L1ngM!}{^5O@@&!c*V}`V< z0S54`3OfC} zw{UxzcJUm%%8fQbHcOl4L;58qug5@K=0Ev1H`Ar=cX(i-H2paom%!VP-3pT?^9z^m zo4`cz1)B>YL7;#oX1P2BOOuv(-K9)v8|AWd?x4abmVER-L;CfP?g*wFhXol|*l>Xn zw#Sq2d~o_dcxPftgekqR;6$X{NkXI=3x1TTf_q!;Z=Zq@(ge>n{FSbFc0;>!x*=fWnkDuYgfi>Nm9iXSbhuDs+z+qGfPDu5qX~>Ub7IJLro*hKN zo5nJd8w5{vw%xW$h@`Pz?HZ;A(=>`{Us|d*TO${pJ(rqg(2$O`7ONySpw*HdwVSHDb^xwq=NgXoGzR9lDbdz}joTuJ}-I#3@|8laE8b zRZs$<5xoc@AJktFvJiHxyG4j;m?iyy(ZG7dHm6D=W*B~a`uh}_9oY4Z|5vW@viS*& zFKMv(@HbdO=JqK zZpS&?h$<6hF%JizaKqAfc=$BjAG(W-OP5ibz_)DcFUdH|iyYram z<_yrp_1`|>5jku7QbDTBG^w8p3eo~V!vf@5?*oD%mBm-g7lP@`GozDWuf{HKe<3(^ ztWV2J#sHgne~U4P6=~K(l%D#gW@?UJBd>6@5sLA5xi|l-4>pzZHh!{2j8~*xq2nQ5 zo{NUIRQW^95@=)w#J~0t%;w>@fs4!h4_o-a)urM5EX?LwAb3XraD4*S;(Aq`$C0Hr z_wkP5@S*$wD{iw=unb~f7G6mWSJRNbd8ruxrA*ygnMZ4S_W3r|Fj*sgl+~ycj`Z{- zV3cX(7vFsVZgZ?o?G)7z)z@VmcG^}@m9o8+mvqu;hI81co=z=iq#}Q8r2hKo9uN~{~Q1Y#wH6d?+ zF95;yQz6)gO?!?5mkWs*Oe^+L9bU-5hnjPsNPb=EErG?(c=wQ&dqOTC+UP) zg)x>hVlh7DUsexyLUbkhG4RK)Vlj%H0Z)tyk9C3zIdSZ9-!_7V| z>)N}k&Cb$v|MSJ!?@w2xda7&Wwg(saLaa%!4@Cc%eg_3Z4R&(V&w^iI_bX2Z0+{^! z=$l((h#k*5)d}B48tLP(XuV>VmfqaPt4pGFO9&$q|1R>=dkwG^QuA9O1n2yMKA$i- zr#gCZ+lv@%=oEhvaxkuY!b+?^zQJRZnIwNLcwn1QW@@wSxho%V8TI{n$*~bzZGWx!HRH;TTnQ>}VF#r-bZ-iF4eeWN4h&A|ohboKB zsx&0S0`%1j9C18zh0W+;8RJ&tZ{?=*J3|PP8pF=xo$~?XE&SR05}q zlS^BjID{qRj7iqzPE&ARt(CwsLq_(IDDc3iV|X-p)(wu`GsFKV1rM!IrvU3)(rzWE(lVRCKk?lieT>C^ z?e`znM%fjdD&xjSg(0|UYix+1*|peYB0UZb>q>nIlQcf=yZkVV|J+%yU`+V=s@XYo z#9I7b>-|!2Rc97^R(?bi@(fyrJ5(+_<-v7wwi35pT}}H6UNx285fhD=lvz}eMZZ?@ zEfdu)EQnO<=7!|Zpm?M*)gBO?jcE?bc*twLr6IFy7g9X1cdo!R%laDjeFG-uRiS-3 zNEX>4gt{}i!8u-*kbErgxR0`KmyscJ%OEL(l|~q~n)tyh9$f3)+Wnxqf|dFTap;mi z&IuAjRYIN*9^$c<*s4-i1;1PRMDMIar}hDD8YYE(E)>$v5W@nk#}nS<=hNV1>pYLq zLY4huNY9)XE~q>}*~^21wM-gnbTRAE!$yP?3;PKyg8^Cy|G8B0wV)H(qzN?zPr4>S zV=Gd^Z0<@kG*k5XZ+Naf+LrTgnvLT~3@eu#qr)cR#aUNORHCg{z&O&#g3N@^~2NyvWA)UexAw8W$dVJq?Chtx=Qr%$U+mdyu1hTmmG1_2LUwY51Yc2R}BOg?$F8+ z3YDSJd&UJv^-JZDhp$y**gRCzVi zmt;Ej0e%i%u7l4yy%7#emA7qaNe&x*#4FgXEIilEDZ@1`vn0Uset9GW1vWS1oL~W+ z(DFbd(GaVt1B)1hLXot8M zuS#!zf`j_0iYQm3Egs; zpXWf^*wjwCx@nP%lpCo@^%olT!XrNS_EX-1a!k+rWLcD$KVtXS58WMVOPF7>69^aCM9ZU0iA_{sWFE?bgUAAviq{ zLe_A;I`pto_{ghV7Q@x3={9#gq^bzu&E4$|pzgAR+k$F` zozONU)ItbCX^z+DG(usTJI>_5Jsf2fBVP2`IO!OA0pW{DcIwK57ha3YDiSq{iOSSI z7w=n#^OTCAOD`XU#ewB8A>|rR%n6z?hKrhDJ&O^?IN?;T2g71m8#t+z@Br5^J4_Vk zy^B!x@(IwQPhbzN(9b5 zPZIMcVoX6RtR=@?Cf7vwe^vq;;d=wrRw?(mbrTj4-I+C7kvBC1`v!u`qL@cY#&w_Vl zHx5v2nQuabdLC@9G!4#-JhVcINdEqyBd5JkzOuAdntPs0c+!mbG z!stc7p}uG>Pfs`FSa|Y87x<+4N=~U$$0By~U3ImSbP(Zw5UC&+!TV<%vVu0@#C<82 zOQ>r#7Ym`dfU(PRn~@-E>4hFLnY^mnEW=6VOJdekCSPqWSYRpKewgc_iHo9F2iqz) zOrO4=A7ygSDn=`;Ls4mnVyELc2?9hWNFwpi5`-`%G2V&gwTKIOm?OTS29CwmeFGHiP@FqD_I`p&YsNuPuRG~LE7Y11(=V#nr=1YH}mMMz_ zEYr~J6I&G4Y*QZFi#tnHIk0&GV$J~QiKo5*wKf+^tI^c_Y;ep2u^1Ir^}j@5tz{!2 zrem?xi#A-M>IV+cl`Rf##ouDsu*+qH4(QPR_(#}1uvFSNleKa zQxav-SD%&0ETFF{==99rwm0Pbls2CTsP~I+DCFbI^lQ@b2P0ND;{{l4en055upI|G zph*iQ1_!ZH@(}hvSvW?N0q=7~EUrkWJuQqO$-3F$rHufVSc}QCCc^+H3y&I$nKQ5j zByO1Y0rue>{U?w4To{d;i^m;>E{$~f-{~1v=Gi$%6=BJ3$GOgSb-twvvVSMk6`U2B z>HI{&-hk<@#e4w17H&h(WG-wbD98{+fl5)07{tItP*yp7UV0}po6-MO_1P)$>9cCl zrG-W;V^xL!?q#Mi!d#nH<7fE;e<3*SPg6lDl&h&es#aHmMkL`S*hd+=#ufq8n~tMm z)DeM-70mw}76nzViKf|%e9bx2^<_GL@>j(+9C2M2s8zdG>vmxd{0k0y=$t$oJG2zc z6THCD?(oJ4{b|4BwlJ4zCuCSMvw;n!e)d9}hbfs0O6&l}@)`q7-hU07)GqI9^r9TU zLc@$4Oz|k=gE*+*;u%re*Chh!G;s7oyeCc6Bw|L%W`V08L7(-MHb=E4Z~7 z&lVv4l+4e3`0$noMh^?G3EJ#bxh4PD z6@s)r?rzItu3J`{g(aRByWX${N=|)2B~=Gz)q0A&nKE=^spBP6MQfYAB#_ZYz#6*R?MZ;&nIOP zOKt9%kWF*MV0G#O3|S?b<`WIIsO!9#Re?G;IkIScpcs3P%2x!YWyz^;gsdtEr=4^Y z7S4Pr=rGIr5TDZNxnBqIdgbKWc`0yJx6k1^Cp;^vvNG4jD>lXgAEba(#~zoB2Ih^| zD9mA@)%C&RhJ%~kR#r;Rqi~0{dwVL5guE_~yOAXwXRTzDehvez(%uI+vhCb84fYkx z5XK@;1Ikwx`Ls;i>WUkCX?30#Y0C$-JOv=%C>A3XsAZ%N&#T4J<)v!1k%Yiwb0A&_ zsVK(M=;tEL8AFRO7lx#G0REHHHi#=r8md5zx#S=&k@(seqs+B#0yMCzL2nz(!Lv8P zX;Qvuc^7Wtv}{6m9aO?@PJK5 z2&^CW>AKTTWd*+2H=?&XP0Vm>8R;b53(zGmxg}lt{GN`Msmz-c$ix;1^i_WsyC6zm z-iau?;<*O8ybTESb}L(q#p^rsaRhsoh>?m^YA=Qna-PFM9*Sq)!?g5jY7eblDkiGX zHT&^nuwG#RWofl@0f5vPOCxs=@qYC*-qahcrt%|jvLgbTm7Bpfl!u5xHO)ElU(tQq zKcclBmG_D$#XHvqLFr88KbAOp?w*#aTf^occ|x!gaL(uA&BPoC3d3Jbj9HNLZ>vHy zeml1mafxGC!_x||$c|ov_eGW3xqjN_kvjxX=|{Oka(^&($s2#$$_Q9gRK7CVwAv#K(TzC+X=jJTB`=f#wJy~8Iq$`e# zo;oyhcmduws7uM2#uoa=Hx4Zg@(P7<94YKeJ3jGb3D|7pWpgpzv++GYsV->Iypg77 z{b<@=KFmzsJep&E);^6LY+WeW;iSHI9=s#Z{RTVvD2P#=bboHPowA?RK=Emz4$yJG zW8aNega7l&sqJ+8Db5G`mcq=xJ{9RD`!`~ao|fvw(zof9GC<(4jC*CYQ+b0Zb*2`< z;iQ*xVaCRui+Kq7?ZO(BU1Ct6(m7t16#MACQbIv?gxnQFlWC+1$_AvH{NhP)uiAy& z7*=|HzPXgekNyGQMX86?L?+>}&f{2Sd~=b7N*Jg$lFHpG%48x|*sF^etw!?}Wb0_W z8muCDj_4l_O2skDL<|k5dGHh9HzlhjyOGY9)B4zV?`uO@VZzT?^qu2+f%O+rh~E>`_c=O>`CMgm~`#ZEkdv- zOT9~=Q+6$CBluge;3u28e{=FqCqB2T#~Y1G4dMeh6OXv}_Cdf7n!3 z_{J}2-(kxah(au#{rKh^0Rph>ccNuFtfJ{cvKkv2UnF>Hun!mLgs_gyIy*@yg<)vB ztV%NNn&rF{FMPiRf3`QyF~=9x87?F%u*j+tLNV~%G>fpwJA)lUaZT6;4p5q9P)RXD zd{1+ew9K25941X^hpj9B`<=^?#rbyj^bfABX!Q1Z?KE_p<0&rNBTJHNj0$*BH^zjky-Ul0(3$$^Qf*V5VVho@p|Ss)a&g z=KKZ59!$(Ryuw5tG6MSuZks50V3|KOa?8&Bw-AQA6xhsjW5GE?xzTYV!&l14evQqE zS9Ip0nr*INK+LVDIv*CN_b|3jF04Vx5G6bHc%8dP6-0B?W0X9|hegz^$8Y`1(Y%!r ziT|pMWN$72kN0MK=!s^9AdpS5f)MpJb)c;Rh0f*a?H_Cju)+(GFyN9GFzUE(%wzIU zxG3f6tL5B}y%UEj*VX|hi<->f@SW0kxk9iKi+%eiwh{R24KBhkxCl4sGQ7g|YIhZ> zLd-C5rm>jiDF^Vb#Wh9?(p4ZYCm1^(ip~svnV24%=7GP&ZnVqJa8YLmSJSn zqlmgCuqQWR@Gp&_B(Mg}=_|%6qbCcN*dJR5`vPp1uMRe5dchU9Yo5s#XZxof;Xdv5 z+_P@@vF_ct$i+k( zIQfT)2(4Ajd$NySDlpMsZfE;xqX|5IC?6SM%t2=Nrr@p0T#Z`_d8ud~pJ9|(e9&7k zf6352xIXz@Rd+E1dWkQ}|5}YYjpS%JxKorV*T29aDHSsCd}(REnAFpvVf?!))Gva~`5TX#DFwf( zoGcv8)>)iOiJ7TAC`r4;wQXBGFfiFFLTHln-`6ObIrZbT?i8;RBy z8vFxZsTNS%HJNLc29}zk<7rrG(zVTk0!1^hc4wkmqi&#LPZMI}26b3==Uj>?JNX*=ICd zPS4~F0hPLj^$9#K^5s5|ps8(&TL#L2$kJG1XiJ*{?)(rcu?B_$l&6WW1gD-^-V~_< zOt*c6%Ec^4k3g_R3RkK8taQ^-*hto|Hn~kq>e|j1)UfGdAS0|H%HxX}78VJtE6HMG zyF9}J*7Ql1ploOV5I5NULJ#0%Q~Ot9)@RI9_AaR4a-(|gFlt+y7kDT|3r%^t*u)2^ z$E|FJisZ@Qaij_O#M3 z;GA(aBG4r}w)5Ec?S_8AmBxyPYzEN`@xM}8S#h_{`9T(wYVqnO%UT7;ZJ&Ik1nY>l z1bsz^#j&ZJ`XeA4l5>tiW{~1Rkf5v&jSvHyy1axG ze;RY*5s}NsaAHrJAH(4a)7IGtIzW;*dpUO@0D}Q-R+>rEKHx2mi~qp4^sV{|$J~5f zb$s;Xv(-ieJGH8r%1)PA(38)Owi{scu=pqG_(JFLT=;qN`)x%g(Cc*t6QZ&k(6p0E z7diR-N$J3Ds3dt~dVU=B7!T18@RvTTGA%!%$Vm^) z3}CDIg&^7EnSueCy3SPeR-zByD~izNcEE$?e%CR>&g51XRXE&AK28Da9`aBZLd7_H zGMhu3hU_pKw+|96mFa^kys)nCVp!>^ydT@|;pl)}fncwu$}~}nTK%uZL?#fqL}x0k zaF_c>4{vh$q+Kp*ZM64%vA7cL)>hqO5 z3ngRgAVZb=72H_efMNN5w5lYq-2Llp5|gW}GzL+$5%duz<&FMt-bC+jK*)0QVq8PF z!vD$zQZ;6oH)F#F9pixRAX{g0OK$5SL8;TSZi4$|v=aKD-SId`Ai<^FM5K7&nx0 z9$wLxt&AST4PQVRJpVL1NSG;oFy=5%L(3NFICorzQLp19rz&nx6`qCxzB=@R= z>TC}wr}vEEj$WLuz9m>tny1`Q!ACjU2Z0DON*`-SM<2iEqA%B=YeZQrCVL?6`Vn^n zed-w9*U}NCEsQo?^(UwCHS*&Z;1aU^b7Kf-3?sN$p4%1qN=nx2QQC0e9gu7{A6({< zC7|04QQll)7$xS_r0Zkq7a{=y64d1@a9ui9)nCQo&99(ddj&hT&hec1YzKh1vn^XBXs%k! z(0Gf_0BQZw2?s9&h)*IQ@MaV>KJVaV}m(W42~*7COK(j#Qb zSv`F!=tTZFleZ+uHMhW=>-R3$CG|FZJ1YMm`rpGXQ=h^lPY-BaS-r;`qb+;pqBZ>s zM}kh7QQ)Faiq$&$^>cNEwmO1nRi4Dj?ZBtlWocU+5s_}fL#5q7Bxn4#AdsV$6h)8< z2+l+1J6aT>RRu;YKF$Zb5 z7uasnPBm_L?HOdQbQG#I?@JhF^5y!*03$`3To?UOfPLQUX>Ni(n&1YrYHIRP%u2aW zZ1`Na{g5njlYPc0Ah33EU6^t#+eI_FW1tl!m-SXFbq(g(O!@1xFk+-x4ctK{wYce4 zm~x=3;H=FgjAd~$jdJefgi$gohg%3?80IgBsGJPNi9#5Jt@9Pa)bH{Ef&g;+A24K* z)#@}c1x{;=ZYV5|Numrh`Hf8oXj%N#LqUt2-~XQDQv4foBXsrs+!*;o1dbEAvIN3| zd^;f<^rm+$0A062z|5r>LCVYC7d;&*rrEG``u!{;E-r91+d!{QDX`LB&l~~Tc^hQ2 zR}CYeXPP-o$3~4HRqb09v&i^@I1OgHt&BVvF1l)xxAgYL1no0=jB{*j1oJia;Ue2P zj5x1jfV#>bjg`mC`owBub$tc|X^MQhdi_2VIpwRI*K)lh?Eruw6ZL_< zbkC0<*0j?Q`8Rv3VuY(Kb)EJ=f?lf!=HxJ@pz=5ezQ4g zFDoe0xfWWu!)z4@ZQx-Qq?`9MCXOsmvjp`wU8Kg zm|)XqfR%NJ)W-vb(A{@DP_HN}RR|mp$+jr1FX>T%LSuwLw)@vD$DAx1aeU zRGx9xK;JqCZK2sW6{w}<4j3IIG^PMi*a^NU+D=YAGe+o|onjW^`|+X#UAZ2g zcv=~5ZSNs4&q>?)z95xe=}o9`s^azn6y~hjK<&9OD1m5Wz>IeL&nV-eMA3)GQP&|+ zfti{jBmleT)i|;!lJ?1(Fdw<8JcW-+k-ZKR8K&2cpvC(D^MQQF*^~&Z_MZx(^xc`N z1S7*&@Ti{L_*-*`ZeLmCrJuAd@&mGOAGE>1zs&)%Lj?MxTf<9r)c2xv-FZhb-8c<{ zF-W@TM0V0yVly$)aUn>h(F53Ey9R>>C6hp)re?gt$1c4T{k7=7Roq#)=D&S9baTz+ z!XWuCw|0c?cqPkb7f5u3qsTxHPtQ)!UrS-ElItFI0(E*=`;A|@YOwCY-N|q1^K`UV z(BY?Z#zC~nxtGj&^!d;D=4l%sZNAP^LCi0Yh^o86y{k=7Li=iP4ZTIoY6Qi8 z*A1~S<)PaHfB}=yrIF508GbAe-@8kNfO|yrjsjF(B_4j3M{fr2$T?HMs-X{ZFQB+##h3VQNpZZT~(5{kaFO`W8HYejKXVgWagem4~IPoBH{ z9;Utw#W~8;FF+nt{6-C!YYNAkoLt6z;lBt(PLChWaeB0fqs&X+VSlTqt4y#e_FP3@ z=$Za1e6I!NRKGD8WhQMbaOBWI z<%A%nBrU~&0H%z53_a8JQMR9q)<@dW4RJ_OqPn04ST1w5NFq* zrz1$3=o3bICo4OIDIX9G#9JRC+0{-|s?g#ci2jj3^oEMSjR@2uCCLdmsLc9MY-- zFIuGhoa8~t>+Tw^8Dj-c5O%ZzMkS~I|poe(0?Cy?iIw4i-r&u-e zy5`+sH;^V{3oX!gTVYDQ(-!+BRe6WkjZQZFICnVr5Vxt!33~i3yjW{yN9ofMkgCb5 zoLWEP_L+0vJqaPzLa>1gGwa@?+6$t$0+r8+Qb*cg6xjCMbA%2SW`X49%;t#Eqi1K! z^xu*B7Vd=S^`?6pLR{&~nnNh{xYCW)2D)TD_HXDS z%0?c($U$JHF+>kpbPd~WwL$HrY63|+D?K;CEPblLqRDwIW{sy!uW}pH)$pE|HXPs% zLxK(xp`I2k5vB5EFrv|zhkFt>oTT(~pfl->F^kDnc|qb8Hzd@smOPl^G~xsTpJpR> zxCXN!f{V2(Kc60upl-J+2ra4CZm02m+1&ON;^_6#zmw}i17ct*)l@Br(MIP~agAIs zv^PXStCO&1B!+Eo_7&vNFSi&?h+bX?Z)0SImK-ezBPHIuD2M);gN=3Dk{u)u^t#nF zy{W@MwNo5cdTSz&s>g==u&ITyFBAKCp?(ysiqcMWDY)C&2jb2{?LX6(6X( zWR@+#NX{rTZr7e`Lwe$8v!9^;vNC zo>n&J(BN#*ss(=+2kF`rIN);Q_6~`5e+1n>s-~!8v|a*M$mz`xHxtTnVLSrfG7MSe zO%c}BCJHeSZXtNyq0&TsawL6WgiYWijwmfovsoC~xdq>ray%Ddm|lGT$m?-}7V+@w zP5FJN&+#PyfwK#`?JZ-rm6k0+ohpgyLuUHmr7eVllF4{0JRPL)B?JgPH(za~y^otC zbWDp)5OudD-CO#oUw&)rQF>@1AMak-GXEv=2}5VMnd6z|fhLiJ%ghTby5t zGC@6;1>KzvboV~;6;p^587;%_^R~B~t(bsIwd!my{`zYaxOD#A0T~Od@+wrbGdoJ| zII!{?*Bp6t<^sM(cfJue|KQz5?6&++L>ZNt-$Rxy-U*wcSj4JBf93m`GC6^AHY0Ix`3{~>cIE15Xbmq0x33qi0!{V--D{SLcF=i4G1h>}%Xt8gG!jh> z$z(kOfUX<79Ee!IQbA9MdCQnm=X(Ss0iCW#f_dN++_N(7q{Bm}^b=#{>E59b#LCcC zI6-CY?W1UHwq5 zh2{lClZM*hwkF=dh3p?kLc zmg@4D8ihaj9Zz(XZn_IeX}G?$cWNwK<2rl%IaFd33&A=p^wn%ZTbCtIG!p{#00$ozlJ!_(sTBm5a7-2Aby?1S8JmCI9!p#|wCt+lT7_OsX(VO*Q$ZJT%q)x#>W%bN;(htT%G!41QtCOs&@`G${ z>Q5Xb?!l3CK{r`r=x}}~PWhDn!d__Y7m?nAvoRZOnV4$G)DUl_ErP2Xnjj9PCVOh+ zw5nxOqnR4T-Mdk0c&tXMH|$7i#HLXm5^HMdM6I0Ix8O!6Cu28{;?SE9>6e8~z3J zxiS|`^-1j8Iy>;Ypz?D8T6ltorTIP=`(;aK!HJHQ;xAH3cMYjH?CB`0M*i-?M&4kR zp57tV(n~{>9M*w{vq$Y&P$c>TX|_KAN&cm=uk)|U$^y|$oNuf+35rWz{mzYoQp*}4ZUO-Q4XC;a)rDkz#wL~+^H^}_ zYIlgW{HLs2W;vU?=9_>q;Lj&)?o1yp-gKaHzJW!n+63?0n)t4{?vwyk4u~$)tiB!x z(`Q{DUk+13qj>SJWoiwf*ua9<*Qt^)f5g%rz)@N#MDb3GkP*tQURy!i7)3t4Rf>j` zz3xkKvDo$VuwetOCz*jYP??*vzx3zr6iP@g!71+*BVe(i<^Ssus<08TB2+FB6+}%k z^`?FF7Fw^gRK6^ltZ;O<@M=mj?MI)Jd3)R|L^Z;`0gy9i=wP>j4cqbxuN|Z^M#6?| zn1h>;PCdb^-O>~1MYc^qP(%J&^o~TCPZk#IKfBRpM+<5Yet^~g-UCXUa`m7w z%9Iw{u^72v9`DuqNZgPgV*A#OamU$<7iHbW>`Cr1A+IO9HsnKyRpdsTkhipx1h`;IitqF}3d;QN=lSa-Ae~}vNtBI$tIG9?Rt&vLmN3i6No=yV0 zODAnhk6AVH)}epkYc+D46HD=4tIrp!bZmCRPWfobAG8cOYsB`;$gSAV?Yu0!zooi8 z#iLQCTx^{pYZQqr!as&)&)YyGkwGgCBJ@U2PKUo0Cl9f@pw$dF3Rk|oC9k7X#x~~| zi{EwN? zkFnMR|HjRZczlib_~d@H1D}YE;hwHjv)>nE!B2xiu@SS4fuEAWa&ji&BH5HQA7i?| zM-~**HC=>YEtJ?5;#8H-zV=y|p?c+fEmNu<$%nXFbV|_HXO=3{(Kf}LKj}cU+IJV= z)ioE*gh(cbPJ<_vsu81%xJo)t30`Z((OOBZF1+GQ`p1%Q(kPYJ_wN*WPd}@5ZO(?C(yp86= z3bMX{H^#hmx1cV;{CkKQxa6SQbZN$fpD-e$x07q z3p#9={F<5vipe>2LZz@^!E|E~l}kXQtHA7=DIO60=35>#ykpp2sAHb4%WECtrrLLrRndlpig=&)?O zgyL>&^oh*7@<}6)Dgl#X-LRA>3Z?4fYh2^iLI|xhLlQO!wDLw#66u%qK+^KrOK>4e z|AAHNy4HAJ3M#+;d2Eq>6VGhz0>t` z(39oz$2iqRv7hm&lff={odEEzEVgTQzhibS>D=e=mnjOXG5vmFh)rs=v`}H4r#!>^ zOTNCsdvbr-a~+3eXflwerIdviN-R7mCHH5+b!~-kMHmR~9vJGUJ~bE9x(7rWLi!N(U{wH>Oc>vAyzeuV0+7dg`DFt&O6~vq$tI9z{ z;2EmzC_*{lyK2L8gR}~l1j>r>uo?n4GmTCbJCMOwc(Vs~H(ztBIz5%(Nxb2TLHw zS7>LE-jgBZyLMTDZ3Wwp6+9K0?qMbmYL~tU7kZf|<0L107sukv**OeALCD+&ZWA+vru($a)nup7#A2*!zMmOhJb>@yx;vPY+Vch_3h>J^kv2yz z&d`O*Y0^^Bizx<8ekp<{4_p1f?fG{0vG@uCyQ8IWng;Z;gp9Zwl+jx>vM7PK}8Pp^5

C=2%LUOb% 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

7W%e;i$TfKpW#zhjrWD5Ln) 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

J3ND7A^KKB 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

da$Ql6OaJs4dxx!p1OG7VF1d-QT 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 6EJO=t>N;IkIM;QfC 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

A3IvKK>08|(%o9X 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�jX_Van&TSP2@QKx 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∈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

lAuQb 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

ZyQI>$_+ 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 Usl)%AJ@sEk-)k8e70j;x4|gmo^#A|> diff --git a/python/client-contract/src/dfo_client_contract/scenarios/resubmit-candidates-sibling.json b/python/client-contract/src/dfo_client_contract/scenarios/resubmit-candidates-sibling.json index 22deeff..37dacc3 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/resubmit-candidates-sibling.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/resubmit-candidates-sibling.json @@ -4,14 +4,14 @@ "description": "Choosing candidate 0 on part 0 of an answer with two candidates parts posts part 1 as a candidates entry: its candidate set in the server's order, each with its identity, and its ordering and truncated echoed. Part 1 answers candidates again in the same order.", "origin": { "kind": "recorded", - "base_url": "http://127.0.0.1:19493/api", - "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T13:07:14Z" + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "recorded_at": "2026-10-23T18:39:35Z" }, "call": [ { "op": "search", - "question": "GNI of Germany and tax revenue of Kenya from 2015 to 2022" + "question": "mortality in Kenya and emissions in Kenya from 2013 to 2022" }, { "op": "choose", @@ -28,7 +28,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "GNI of Germany and tax revenue of Kenya from 2015 to 2022" + "query": "mortality in Kenya and emissions in Kenya from 2013 to 2022" } } }, @@ -36,60 +36,72 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "7fc0d6eea9ea4a649201c235973bb649" + "x-dfo-trace-id": "dc9cc6e5c1a34ab295ff44b26137f6a1" }, "json": { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "GNI of Germany and tax revenue of Kenya from 2015 to 2022", - "normalized_query": "GNI of Germany and tax revenue of Kenya from 2015 to 2022", + "raw_query": "mortality in Kenya and emissions in Kenya from 2013 to 2022", + "normalized_query": "mortality in Kenya and emissions in Kenya from 2013 to 2022", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "7fc0d6eea9ea4a649201c235973bb649", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "dc9cc6e5c1a34ab295ff44b26137f6a1", "warnings": [], "timing_ms": { - "total": 4462, + "total": 2566, "by_step": { "coverage": 0, - "extract": 992 + "extract": 1061, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 11842, - "output_tokens": 437, - "cached_tokens": 862 + "input_tokens": 2241, + "output_tokens": 197, + "cached_tokens": 843, + "jev_input_tokens": 26474, + "jev_output_tokens": 5727 }, "timed_out": false }, "kind": "resolution", "parts": [ { - "variable_text": "GNI", + "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 1879, + "total": 1502, "by_step": { "recall": 1, - "shape_arcs": 2, - "shape_probe_coverage": 3, - "shape_probe": 255, - "shape_groups": 22, - "shape_labels": 7, - "shape_admission": 0, - "shape": 1035, - "bind": 839, - "materialise": 1, - "answer": 3 + "phase_resolve_places": 0, + "phase_check_entities": 0, + "shape_arcs": 4, + "shape_probe": 101, + "shape_groups": 5, + "shape_labels": 1, + "shape_admission": 1, + "phase_derive_shapes": 0, + "shape": 230, + "phase_prune_and_rank": 0, + "bind": 192, + "phase_bind": 3, + "phase_settle": 6, + "phase_place_bindings": 27, + "phase_facet_requests": 0, + "materialise": 250, + "phase_materialise": 0, + "answer": 25, + "phase_outcome": 768 } }, - "rendered_sentence": "3 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022.", + "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", "sentence_plan": [ { "kind": "text", - "text": "3 readings.", + "text": "2 readings.", "segment": "heading", "entity_refs": [], "states": [] @@ -103,95 +115,18 @@ }, { "kind": "text", - "text": "Primary income", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " for ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "gross of fixed capital consumption", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " in ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "Germany and Kenya", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": ".", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [] }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "OECD DAC1", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "2015 to 2022", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "Current US dollars", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [] - }, { "kind": "text", "text": " ", @@ -201,7 +136,7 @@ }, { "kind": "text", - "text": "Gross national income based on purchasing power parity", + "text": "deaths rate", "segment": "heading", "entity_refs": [], "states": [] @@ -215,21 +150,7 @@ }, { "kind": "text", - "text": "in international dollars", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " in ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "Germany and Kenya", + "text": "per capita", "segment": "heading", "entity_refs": [], "states": [] @@ -264,7 +185,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2022", "segment": "byline", "entity_refs": [], "states": [] @@ -285,35 +206,28 @@ }, { "kind": "text", - "text": "Gross national income based on purchasing power parity per capita", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": "in international dollars", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": "Germany and Kenya", + "text": "number of deaths", "segment": "heading", "entity_refs": [], "states": [] @@ -334,7 +248,7 @@ }, { "kind": "text", - "text": "World Development Indicators", + "text": "Kenya Census", "segment": "byline", "entity_refs": [], "states": [] @@ -348,7 +262,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2018 to 2022", "segment": "byline", "entity_refs": [], "states": [] @@ -362,16 +276,13 @@ } ], "restatement": { - "variable_text": "GNI", + "variable_text": "mortality", "entities": [ - { - "text": "Germany" - }, { "text": "Kenya" } ], - "time_text": "2015 to 2022", + "time_text": "2013 to 2022", "sources": [], "operations": [] }, @@ -384,70 +295,70 @@ "max_candidates": 6, "specs": [ { - "spec_id": "spec_9ce16f72ff8416d06a56f9fe82b10ad3", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "definition": { "schema_version": 1, - "spec_id": "spec_9ce16f72ff8416d06a56f9fe82b10ad3", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU", "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicunit_primaryincome_measuredvalue_nominal", - "label": "Gross national income", + "shape_id": "mortalityevent_count_measuredvalue_per_count_person", + "label": "Deaths Rate", "population_type": { - "ref": "EconomicUnit", - "label": "economic unit" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "primaryIncome", - "label": "primary income" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "Nominal", - "label": "Nominal" + "measurement_denominator": { + "ref": "Count_Person", + "label": "Total population" }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, { "axis": "where", @@ -462,13 +373,13 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", - "refine_supported": true, + "member_count": 133, + "member_digest": "c090b56d31a596a8be16dafb518382db666c6b100a80534c3cb81dbfe3111c5d", + "refine_supported": false, "data_commons": [ { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" } ] }, @@ -477,20 +388,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - }, - "value_kind": "enum_value" - } + "kind": "unbound" }, "summable": false }, @@ -500,23 +404,14 @@ "label": "place" }, "binding": { - "kind": "set", - "values": [ - { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" }, - { - "ref": { - "ref": "country/KEN", - "label": "Kenya" - }, - "value_kind": "entity" - } - ] + "value_kind": "entity" + } }, "summable": false }, @@ -530,7 +425,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } @@ -548,24 +443,20 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 2, "member_count_exact": false, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2013", "end": "2022" } }, "entities": [ - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/KEN", "label": "Kenya", @@ -576,16 +467,16 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 8, + "observation_count": 10, "evidence": "facet_metadata", "dimensions": [ { - "label": "countries", + "label": "sources", "count": 1 }, { "label": "observations", - "count": 8 + "count": 10 }, { "label": "variables", @@ -593,43 +484,46 @@ } ], "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, "download": { - "rows": 8, + "rows": 10, "rows_exact": true, "series": 1, "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, "licence": { - "label": "OECD Terms and Conditions" + "label": "Creative Commons Attribution License" } }, "facets": { "provenance": { "basis": "fallback", - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1", - "account": "provider" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "measurementMethod": { + "basis": "fallback", + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" }, "unit": { "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" + "ref": "Per1000Persons", + "label": "Per 1000 people" } }, "slot_options": [ @@ -637,17 +531,17 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" + "ref": "ICD10/X60-X84", + "label": "X60-X84 (Intentional self-harm)" }, "value_kind": "enum_value" } @@ -665,8 +559,8 @@ { "value": { "ref": { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1" + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" }, "value_kind": "source" } @@ -674,8 +568,8 @@ { "value": { "ref": { - "ref": "provenance/WorldBankInternationalDebtStatistics", - "label": "World Bank International Debt Statistics (IDS)" + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, "value_kind": "source" } @@ -684,71 +578,109 @@ "truncated": false, "source": "observed" }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "ref": { + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, { "axis": "unit", "options": [ { "value": { "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" + "ref": "Per1000Persons", + "label": "Per 1000 people" }, "value_kind": "enum_value" } + }, + { + "value": { + "value_kind": "enum_value" + } } ], "truncated": false, "source": "observed" } ], - "rendered_sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 2015 to 2022. Current US dollars · OECD DAC1.", + "rendered_sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators.", "sentence_plan": [ { "kind": "slot", - "text": "Primary income", - "axis": "what", + "text": "Kenya", + "axis": "where", "segment": "heading", + "binding_ref": "where:", "entity_refs": [], - "states": [], - "distinguishes": true + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] }, { "kind": "text", - "text": " for ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "gross of fixed capital consumption", - "axis": "how", + "text": "deaths rate", + "axis": "what", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ], + "states": [], "distinguishes": true }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "Germany and Kenya", - "axis": "where", + "text": "per capita", + "axis": "unit", "segment": "heading", - "binding_ref": "where:", "entity_refs": [], - "states": [ - "where:" - ] + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", + "entity_refs": [], + "states": [] }, { "kind": "text", @@ -759,14 +691,15 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", "entity_refs": [], "states": [ "when:" - ] + ], + "distinguishes": true }, { "kind": "text", @@ -784,26 +717,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -822,10 +736,6 @@ ], "trace": { "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -833,17 +743,17 @@ ], "resolved_sources": [ { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" } ], "slot_filters": [ @@ -851,18 +761,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -870,12 +775,8 @@ "axis": "where", "label": "place" }, - "binding_kind": "set", + "binding_kind": "value", "refs": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -904,38 +805,13 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] + "removed_stat_vars": [] } }, "confidence": "high", @@ -945,70 +821,161 @@ } }, { - "spec_id": "spec_bef1fcb184525d3bbe7cd6a0316b4a35", + "spec_id": "spec_7923e67e0706d6d9738c78cb374ee8fb", "definition": { "schema_version": 1, - "spec_id": "spec_bef1fcb184525d3bbe7cd6a0316b4a35", + "spec_id": "spec_7923e67e0706d6d9738c78cb374ee8fb", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicActivity", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "PurchasingPowerParity" + "population_type": "MortalityEvent", + "measured_property": "count", + "stat_type": "measuredValue" }, "slots": [ { - "property": "activitySource", + "property": "age", "binding": { - "state": "value", - "ref": "GrossNationalIncome" + "state": "unbound" } - } - ], - "entities": { - "observationAbout": [ - "country/DEU", + }, + { + "property": "ageGroupClassification", + "binding": { + "state": "unbound" + } + }, + { + "property": "causeOfDeath", + "binding": { + "state": "unbound" + } + }, + { + "property": "ethnicity", + "binding": { + "state": "unbound" + } + }, + { + "property": "gender", + "binding": { + "state": "unbound" + } + }, + { + "property": "incidentType", + "binding": { + "state": "unbound" + } + }, + { + "property": "race", + "binding": { + "state": "unbound" + } + }, + { + "property": "residentStatus", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity", - "label": "Gross National Income Based on Purchasing Power Parity", + "shape_id": "mortalityevent_count_measuredvalue", + "label": "Number of Deaths", "population_type": { - "ref": "EconomicActivity", - "label": "EconomicActivity" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "amount", - "label": "amount" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "PurchasingPowerParity", - "label": "PurchasingPowerParity" - }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" + }, + "label": "cause of death" + }, + { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" }, - "label": "activity source" + "label": "age group classification" }, { "axis": "where", @@ -1023,45 +990,125 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "833b9da89613fa6c1775652daac2388f38204c6c9f9929ca113deed9a0d08369", + "member_count": 2978, "refine_supported": true, "data_commons": [ { "id": "base", "label": "Data Commons by Google" } - ], - "upstream": { - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" - } - } + ] }, "slots": [ { "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - }, - "value_kind": "enum_value" - } + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + "binding": { + "kind": "unbound" }, "summable": false }, @@ -1071,23 +1118,14 @@ "label": "place" }, "binding": { - "kind": "set", - "values": [ - { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" }, - { - "ref": { - "ref": "country/KEN", - "label": "Kenya" - }, - "value_kind": "entity" - } - ] + "value_kind": "entity" + } }, "summable": false }, @@ -1101,7 +1139,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 } } @@ -1119,24 +1157,27 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath", + "gender", + "age", + "race", + "incidentType", + "ethnicity", + "residentStatus", + "ageGroupClassification" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 37, "member_count_exact": false, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2018", "end": "2022" } }, "entities": [ - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/KEN", "label": "Kenya", @@ -1147,16 +1188,16 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 16, + "observation_count": 5, "evidence": "facet_metadata", "dimensions": [ { - "label": "countries", - "count": 2 + "label": "sources", + "count": 1 }, { "label": "observations", - "count": 8 + "count": 5 }, { "label": "variables", @@ -1164,16 +1205,16 @@ } ], "window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 } }, "download": { - "rows": 16, + "rows": 5, "rows_exact": true, - "series": 2, + "series": 1, "window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 }, "licence": { @@ -1183,22 +1224,17 @@ "facets": { "provenance": { "basis": "fallback", - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census", "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "ref": "dc/s/OpenDataForAfrica", + "label": "Open Data for Africa" }, "data_commons": { "id": "base", "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" - }, - "unit": { - "basis": "fallback", - "ref": "InternationalDollar", - "label": "InternationalDollar" + "documentation": "/api/graph/documentation/dc/base/Kenya_Census" } }, "slot_options": [ @@ -1206,576 +1242,745 @@ "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + "ref": "ICD10/A00-B99", + "label": "A00-B99 (Certain infectious and parasitic diseases)" }, "value_kind": "enum_value" } - } - ], - "truncated": true, - "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ - { - "axis": "provenance", - "options": [ + }, { "value": { "ref": { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators" + "ref": "ICD10/D50-D89", + "label": "D50-D89 (Diseases of the blood and blood-forming organs and certain disorders involving the immune mechanism)" }, - "value_kind": "source" + "value_kind": "enum_value" } - } - ], - "truncated": false, - "source": "observed" - }, - { - "axis": "unit", - "options": [ + }, { "value": { "ref": { - "ref": "InternationalDollar", - "label": "InternationalDollar" + "ref": "ICD10/I00-I99", + "label": "I00-I99 (Diseases of the circulatory system)" }, "value_kind": "enum_value" } - } - ], - "truncated": false, - "source": "observed" - } - ], - "rendered_sentence": "Gross national income based on purchasing power parity in international dollars in Germany and Kenya, 2015 to 2022. World Development Indicators.", - "sentence_plan": [ - { - "kind": "slot", - "text": "Gross national income based on purchasing power parity", - "axis": "what", - "segment": "heading", - "entity_refs": [], - "states": [ - "how:activitySource" - ], - "distinguishes": true - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "in international dollars", - "axis": "unit", - "segment": "heading", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:" - ] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "activitySource", - "binding_ref": "how:activitySource", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " in ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "Germany and Kenya", - "axis": "where", - "segment": "heading", - "binding_ref": "where:", - "entity_refs": [], - "states": [ - "where:" - ] - }, - { - "kind": "text", - "text": ", ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "2015 to 2022", - "axis": "when", - "segment": "heading", - "binding_ref": "when:", - "entity_refs": [], - "states": [ - "when:" - ] - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] + }, + { + "value": { + "ref": { + "ref": "ICD10/K00-K92", + "label": "K00-K92 (Diseases of the digestive system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/N00-N98", + "label": "N00-N98 (Diseases of the genitourinary system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/M00-M99", + "label": "M00-M99 (Diseases of the musculoskeletal system and connective tissue)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/G00-G98", + "label": "G00-G98 (Diseases of the nervous system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/J00-J98", + "label": "J00-J98 (Diseases of the respiratory system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/L00-L98", + "label": "L00-L98 (Diseases of the skin and subcutaneous tissue)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/E00-E88", + "label": "E00-E88 (Endocrine, nutritional and metabolic diseases)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/F01-F99", + "label": "F01-F99 (Mental and behavioural disorders)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/O00-O99", + "label": "O00-O99 (Pregnancy, childbirth and the puerperium)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/U00-U99", + "label": "U00-U99 (Codes for special purposes)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Diabetes", + "label": "Diabetes" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Suicide", + "label": "Suicide" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/V01-Y89", + "label": "V01-Y89 (External causes of morbidity and mortality)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/C00-D48", + "label": "C00-D48 (Neoplasms)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/P00-P96", + "label": "P00-P96 (Certain conditions originating in the perinatal period)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/Q00-Q99", + "label": "Q00-Q99 (Congenital malformations, deformations and chromosomal abnormalities)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CerebrovascularDiseases", + "label": "CerebrovascularDiseases" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CongenitalAnomalies", + "label": "CongenitalAnomalies" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CongenitalHeartAnomalies", + "label": "CongenitalHeartAnomalies" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "GenitourinaryDiseases", + "label": "GenitourinaryDiseases" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "HypertensiveHeartDisease", + "label": "HypertensiveHeartDisease" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MalignantNeoplasms", + "label": "MalignantNeoplasms" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Neoplasms", + "label": "Neoplasms" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PerinatalInfection", + "label": "Perinatal Infection" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Pneumonia", + "label": "Pneumonia" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SGP_OtherDiseasesAndCauses", + "label": "SGP_OtherDiseasesAndCauses" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TransportAccidents", + "label": "TransportAccidents" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Tuberculosis", + "label": "Tuberculosis" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, { - "kind": "slot", - "text": "World Development Indicators", - "axis": "source", - "segment": "byline", - "entity_refs": [], - "states": [ - "source:" + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Female", + "label": "Female" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Male", + "label": "Male" + }, + "value_kind": "enum_value" + } + } ], - "distinguishes": true + "truncated": true, + "source": "observed" }, { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [] - } - ], - "trace": { - "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" }, - { - "ref": "country/KEN", - "label": "Kenya" - } - ], - "resolved_sources": [ - { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "options": [ + { + "value": { + "ref": { + "ref": "Years0To1", + "label": "Years 0 To 1" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Day0To27", + "label": "Day 0 To 27" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years10To14", + "label": "Years 10 To 14" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years15To19", + "label": "Years 15 To 19" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years15To24", + "label": "Years 15 To 24" + }, + "value_kind": "enum_value" + } }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" + { + "value": { + "ref": { + "ref": "Years1To4", + "label": "Years 1 To 4" + }, + "value_kind": "enum_value" + } }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" - } - ], - "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "activitySource", - "label": "activitySource" - }, - "label": "activity source" + { + "value": { + "ref": { + "ref": "Years20To24", + "label": "Years 20 To 24" + }, + "value_kind": "enum_value" + } }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + { + "value": { + "ref": { + "ref": "Years25To29", + "label": "Years 25 To 29" + }, + "value_kind": "enum_value" } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "where", - "label": "place" }, - "binding_kind": "set", - "refs": [ - { - "ref": "country/DEU", - "label": "Germany" - }, - { - "ref": "country/KEN", - "label": "Kenya" + { + "value": { + "ref": { + "ref": "Years25To34", + "label": "Years 25 To 34" + }, + "value_kind": "enum_value" } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "when", - "label": "time window" }, - "binding_kind": "value", - "refs": [], - "provenance": "binder" - }, - { - "key": { - "axis": "source", - "label": "data source" + { + "value": { + "ref": { + "ref": "Years30To34", + "label": "Years 30 To 34" + }, + "value_kind": "enum_value" + } }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - } - ], - "query_qualifiers": [], - "requested_window": { - "start_year": 2015, - "end_year": 2022 - }, - "capability_version": "cap_347a470e04c97eec", - "default_reading": { - "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] - } - }, - "confidence": "high", - "basis": "nominated", - "available_at_place": true, - "measure_label_axes": [], - "measure_axis_values": [] - } - }, - { - "spec_id": "spec_b77d2ebaaeb7e6d5f8499a8b0e3571a1", - "definition": { - "schema_version": 1, - "spec_id": "spec_b77d2ebaaeb7e6d5f8499a8b0e3571a1", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "EconomicActivity", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "PurchasingPowerParity", - "measurement_denominator": { - "unresolved": true - } - }, - "slots": [ - { - "property": "activitySource", - "binding": { - "state": "value", - "ref": "GrossNationalIncome" - } - } - ], - "entities": { - "observationAbout": [ - "country/DEU", - "country/KEN" - ] - }, - "requested_window": { - "kind": "range", - "start_year": 2015, - "end_year": 2022 - } - } - }, - "resolved": { - "shape": { - "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity_per_unresolved", - "label": "Gross National Income Based on Purchasing Power Parity Per Capita", - "population_type": { - "ref": "EconomicActivity", - "label": "EconomicActivity" - }, - "measured_property": { - "ref": "amount", - "label": "amount" - }, - "stat_type": { - "ref": "measuredValue", - "label": "measuredValue" - }, - "measurement_qualifier": { - "ref": "PurchasingPowerParity", - "label": "PurchasingPowerParity" - }, - "measurement_denominator": { - "ref": "PerCapita", - "label": "PerCapita" + { + "value": { + "ref": { + "ref": "Years35To39", + "label": "Years 35 To 39" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years35To44", + "label": "Years 35 To 44" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years40To44", + "label": "Years 40 To 44" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years45To49", + "label": "Years 45 To 49" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years45To54", + "label": "Years 45 To 54" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years50To54", + "label": "Years 50 To 54" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years55To59", + "label": "Years 55 To 59" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years55To64", + "label": "Years 55 To 64" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years5To9", + "label": "Years 5 To 9" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years60To64", + "label": "Years 60 To 64" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years65To69", + "label": "Years 65 To 69" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years65To74", + "label": "Years 65 To 74" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years70To74", + "label": "Years 70 To 74" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years75To79", + "label": "Years 75 To 79" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years75To84", + "label": "Years 75 To 84" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years80To84", + "label": "Years 80 To 84" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "USC_AgeNotStated", + "label": "USC_AgeNotStated" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years0To4", + "label": "Years 0 To 4" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, - "measurement_denominator_unresolved": true, - "slot_keys": [ - { + { + "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "race", + "label": "race" }, - "label": "activity source" - }, - { - "axis": "where", - "label": "place" - }, - { - "axis": "when", - "label": "time window" - }, - { - "axis": "source", - "label": "data source" - } - ], - "member_count": 1, - "member_digest": "7b2d5b0fc09cfc0215c8d7c6c21a5195fa21e79f2a148a6bca9ce6c3af8bbb9f", - "refine_supported": true, - "data_commons": [ - { - "id": "base", - "label": "Data Commons by Google" - } - ], - "upstream": { - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "label": "race" }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" - } - } - }, - "slots": [ + "options": [ + { + "value": { + "ref": { + "ref": "CDC_AmericanIndianAndAlaskaNativeAlone", + "label": "American Indian and Alaska native alone" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, { "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "incidentType", + "label": "incidentType" }, - "label": "activity source" + "label": "incident type" }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - }, - "value_kind": "enum_value" + "options": [ + { + "value": { + "ref": { + "ref": "COVID_19", + "label": "COVID-19" + }, + "value_kind": "enum_value" + } } - }, - "summable": false + ], + "truncated": true, + "source": "observed" }, { "key": { - "axis": "where", - "label": "place" + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" }, - "binding": { - "kind": "set", - "values": [ - { + "options": [ + { + "value": { "ref": { - "ref": "country/DEU", - "label": "Germany" + "ref": "Chinese", + "label": "Chinese" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/KEN", - "label": "Kenya" + "ref": "Indian", + "label": "Indian" }, - "value_kind": "entity" + "value_kind": "enum_value" } - ] - }, - "summable": false - }, - { - "key": { - "axis": "when", - "label": "time window" - }, - "binding": { - "kind": "value", - "value": { - "value_kind": "time_window", - "time_window": { - "start_year": 2015, - "end_year": 2022 + }, + { + "value": { + "ref": { + "ref": "Malay", + "label": "Malay" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SGP_OtherEthnicity", + "label": "SGP_OtherEthnicity" + }, + "value_kind": "enum_value" } } - }, - "summable": false + ], + "truncated": true, + "source": "observed" }, { "key": { - "axis": "source", - "label": "data source" - }, - "binding": { - "kind": "unbound" - }, - "summable": false - } - ], - "inapplicable_slots": [], - "unresolved_slots": [], - "stat_vars": { - "member_count": 1, - "member_count_exact": false, - "served_count": 1, - "data_date_range": { - "start": "2015", - "end": "2022" - } - }, - "entities": [ - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/KEN", - "label": "Kenya", - "entity_type": "Country", - "role": "observationAbout" - } - ], - "coverage": { - "kind": "exact", - "has_data": true, - "observation_count": 16, - "evidence": "facet_metadata", - "dimensions": [ - { - "label": "countries", - "count": 2 - }, - { - "label": "observations", - "count": 8 - }, - { - "label": "variables", - "count": 1 - } - ], - "window": { - "start_year": 2015, - "end_year": 2022 - } - }, - "download": { - "rows": 16, - "rows_exact": true, - "series": 2, - "window": { - "start_year": 2015, - "end_year": 2022 - }, - "licence": { - "label": "Creative Commons Attribution License" - } - }, - "facets": { - "provenance": { - "basis": "fallback", - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + "options": [ + { + "value": { + "ref": { + "ref": "Citizen", + "label": "Citizen" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Resident", + "label": "Resident" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, - "unit": { - "basis": "fallback", - "ref": "InternationalDollar", - "label": "InternationalDollar" - } - }, - "slot_options": [ { "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "ageGroupClassification", + "label": "ageGroupClassification" }, - "label": "activity source" + "label": "age group classification" }, "options": [ { "value": { "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + "ref": "Infant", + "label": "Infant" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Newborn", + "label": "Newborn" }, "value_kind": "enum_value" } @@ -1793,8 +1998,8 @@ { "value": { "ref": { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators" + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, "value_kind": "source" } @@ -1802,82 +2007,123 @@ ], "truncated": false, "source": "observed" + } + ], + "rendered_sentence": "Kenya's number of deaths, 2018 to 2022. Kenya Census.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "heading", + "entity_refs": [], + "states": [] }, - { - "axis": "unit", - "options": [ - { - "value": { - "ref": { - "ref": "InternationalDollar", - "label": "InternationalDollar" - }, - "value_kind": "enum_value" - } - } - ], - "truncated": false, - "source": "observed" - } - ], - "rendered_sentence": "Gross national income based on purchasing power parity per capita in international dollars in Germany and Kenya, 2015 to 2022. World Development Indicators.", - "sentence_plan": [ { "kind": "slot", - "text": "Gross national income based on purchasing power parity per capita", + "text": "number of deaths", "axis": "what", "segment": "heading", "entity_refs": [], - "states": [ - "how:activitySource" - ], + "states": [], "distinguishes": true }, { - "kind": "text", - "text": " ", + "kind": "slot", + "text": "", + "axis": "how", "segment": "heading", + "property_dcid": "age", + "binding_ref": "how:age", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "in international dollars", - "axis": "unit", + "text": "", + "axis": "how", "segment": "heading", - "binding_ref": "unit:", + "property_dcid": "ageGroupClassification", + "binding_ref": "how:ageGroupClassification", "entity_refs": [], - "states": [ - "unit:" - ] + "states": [] }, { "kind": "slot", "text": "", "axis": "how", "segment": "heading", - "property_dcid": "activitySource", - "binding_ref": "how:activitySource", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", "entity_refs": [], "states": [] }, { - "kind": "text", - "text": " in ", + "kind": "slot", + "text": "", + "axis": "how", "segment": "heading", + "property_dcid": "ethnicity", + "binding_ref": "how:ethnicity", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "Germany and Kenya", - "axis": "where", + "text": "", + "axis": "how", "segment": "heading", - "binding_ref": "where:", + "property_dcid": "gender", + "binding_ref": "how:gender", "entity_refs": [], - "states": [ - "where:" - ] + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "incidentType", + "binding_ref": "how:incidentType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "race", + "binding_ref": "how:race", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "residentStatus", + "binding_ref": "how:residentStatus", + "entity_refs": [], + "states": [] }, { "kind": "text", @@ -1888,14 +2134,15 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2018 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", "entity_refs": [], "states": [ "when:" - ] + ], + "distinguishes": true }, { "kind": "text", @@ -1913,7 +2160,7 @@ }, { "kind": "slot", - "text": "World Development Indicators", + "text": "Kenya Census", "axis": "source", "segment": "byline", "entity_refs": [], @@ -1932,10 +2179,6 @@ ], "trace": { "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -1943,17 +2186,17 @@ ], "resolved_sources": [ { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census", "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "ref": "dc/s/OpenDataForAfrica", + "label": "Open Data for Africa" }, "data_commons": { "id": "base", "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + "documentation": "/api/graph/documentation/dc/base/Kenya_Census" } ], "slot_filters": [ @@ -1961,18 +2204,104 @@ "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - } - ], + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -1980,12 +2309,8 @@ "axis": "where", "label": "place" }, - "binding_kind": "set", + "binding_kind": "value", "refs": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -2014,42 +2339,17 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] + "removed_stat_vars": [] } }, - "confidence": "high", - "basis": "nominated", + "confidence": "low", + "basis": "structural", "available_at_place": true, "measure_label_axes": [], "measure_axis_values": [] @@ -2059,37 +2359,53 @@ "truncated": false }, "reading_assumptions": { - "spec_9ce16f72ff8416d06a56f9fe82b10ad3": [], - "spec_bef1fcb184525d3bbe7cd6a0316b4a35": [], - "spec_b77d2ebaaeb7e6d5f8499a8b0e3571a1": [] + "spec_10bf62f9687154286b463d206f03a086": [], + "spec_7923e67e0706d6d9738c78cb374ee8fb": [] } }, { - "variable_text": "tax revenue", + "variable_text": "emissions", "warnings": [ { - "code": "retrieval_score_weak", - "severity": "info", - "message": "the chosen reading's match to the query is weak; treat it with less confidence than a strong match." + "code": "family_total_absent", + "severity": "warn", + "message": "No total for this family of variables was found, so the answer shows Annual Amount Of Emissions: Carbon Dioxide.", + "spec_id": "spec_25b6a1e19a0e6cb345e5832ed7282b14" + }, + { + "code": "family_total_absent", + "severity": "warn", + "message": "No total for this family of variables was found, so the answer shows Annual Amount Of Emissions: Carbon Dioxide.", + "spec_id": "spec_872ffc3f7b097020db2c8012b0f5648c" } ], "timing_ms": { - "total": 3302, + "total": 1199, "by_step": { - "recall": 797, - "shape_arcs": 1, - "shape_probe_coverage": 1, - "shape_probe": 211, - "shape_groups": 24, - "shape_labels": 0, + "recall": 1, + "phase_resolve_places": 0, + "phase_check_entities": 0, + "shape_arcs": 3, + "shape_probe_coverage": 8, + "shape_probe": 237, + "shape_groups": 22, + "shape_labels": 1, "shape_admission": 0, - "shape": 958, - "bind": 891, - "materialise": 152, - "answer": 504 + "phase_derive_shapes": 0, + "shape": 350, + "phase_prune_and_rank": 0, + "bind": 150, + "phase_bind": 8, + "phase_settle": 27, + "phase_place_bindings": 167, + "phase_facet_requests": 0, + "materialise": 218, + "phase_materialise": 0, + "answer": 11, + "phase_outcome": 267 } }, - "rendered_sentence": "2 readings. Total government revenue, in local currency in Germany and Kenya. SDG Global Database · 2015 to 2022. Total bugetary revenue of the central government as a proportion of GDP in Germany and Kenya. SDG Global Database · 2015 to 2022.", + "rendered_sentence": "2 readings. Kenya's annual amount of emissions: carbon dioxide. Air and GHG emissions · 2013 to 2020. Kenya's annual amount of emissions: carbon dioxide. Air and GHG emissions · 2013 to 2020.", "sentence_plan": [ { "kind": "text", @@ -2107,21 +2423,28 @@ }, { "kind": "text", - "text": "Total government revenue, in local currency", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": "Germany and Kenya", + "text": "annual amount of emissions: carbon dioxide", "segment": "heading", "entity_refs": [], "states": [] @@ -2142,7 +2465,7 @@ }, { "kind": "text", - "text": "SDG Global Database", + "text": "Air and GHG emissions", "segment": "byline", "entity_refs": [], "states": [] @@ -2156,7 +2479,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2020", "segment": "byline", "entity_refs": [], "states": [] @@ -2177,21 +2500,28 @@ }, { "kind": "text", - "text": "Total bugetary revenue of the central government as a proportion of GDP", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": "Germany and Kenya", + "text": "annual amount of emissions: carbon dioxide", "segment": "heading", "entity_refs": [], "states": [] @@ -2212,7 +2542,7 @@ }, { "kind": "text", - "text": "SDG Global Database", + "text": "Air and GHG emissions", "segment": "byline", "entity_refs": [], "states": [] @@ -2226,7 +2556,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2020", "segment": "byline", "entity_refs": [], "states": [] @@ -2240,16 +2570,13 @@ } ], "restatement": { - "variable_text": "tax revenue", + "variable_text": "emissions", "entities": [ - { - "text": "Germany" - }, { "text": "Kenya" } ], - "time_text": "2015 to 2022", + "time_text": "2013 to 2022", "sources": [], "operations": [] }, @@ -2262,50 +2589,83 @@ "max_candidates": 6, "specs": [ { - "spec_id": "spec_121a500dac8691cd699ac577bfab47a0", + "spec_id": "spec_25b6a1e19a0e6cb345e5832ed7282b14", "definition": { "schema_version": 1, - "spec_id": "spec_121a500dac8691cd699ac577bfab47a0", + "spec_id": "spec_25b6a1e19a0e6cb345e5832ed7282b14", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "undata/sdg/SERIES-GR_G14_XDC", - "measured_property": "value", - "stat_type": "measuredValue" + "population_type": "Emissions", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Annual" }, - "slots": [], + "slots": [ + { + "property": "emissionSource", + "binding": { + "state": "unbound" + } + }, + { + "property": "emittedThing", + "binding": { + "state": "unbound" + } + } + ], "entities": { "observationAbout": [ - "country/DEU", "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "undata/sdg/series-gr_g14_xdc_value_measuredvalue", - "label": "Total government revenue, in local currency", + "shape_id": "emissions_amount_measuredvalue_annual", + "label": "Annual Amount Of Emissions: Carbon Dioxide", "population_type": { - "ref": "undata/sdg/SERIES-GR_G14_XDC", - "label": "Total government revenue, in local currency" + "ref": "Emissions", + "label": "Emissions" }, "measured_property": { - "ref": "value", - "label": "value" + "ref": "amount", + "label": "amount" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, + "measurement_qualifier": { + "ref": "Annual", + "label": "Annual" + }, "measurement_denominator_unresolved": false, "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "emissionSource", + "label": "emissionSource" + }, + "label": "emission source" + }, + { + "axis": "how", + "property": { + "ref": "emittedThing", + "label": "emittedThing" + }, + "label": "emitted thing" + }, { "axis": "where", "label": "place" @@ -2319,50 +2679,59 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "a28ecf2dacf37e649080b176e0cab12f467a0af085fd4d9f5396d97b1c730597", + "member_count": 869, + "member_digest": "c14e826e3bbc769a4b453db4b59a905d131566184f5e8582ab4018f0e90311a9", "refine_supported": true, "data_commons": [ { - "id": "un_system", - "label": "UN System Data Commons" - } - ], - "upstream": { - "source": { - "ref": "undata/p/SDG", - "label": "SDG Global Database" - }, - "data_commons": { - "id": "un_system", - "label": "UN System Data Commons" + "id": "base", + "label": "Data Commons by Google" } - } + ] }, "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "emissionSource", + "label": "emissionSource" + }, + "label": "emission source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "emittedThing", + "label": "emittedThing" + }, + "label": "emitted thing" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, { "key": { "axis": "where", "label": "place" }, "binding": { - "kind": "set", - "values": [ - { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" }, - { - "ref": { - "ref": "country/KEN", - "label": "Kenya" - }, - "value_kind": "entity" - } - ] + "value_kind": "entity" + } }, "summable": false }, @@ -2376,8 +2745,8 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, - "end_year": 2022 + "start_year": 2013, + "end_year": 2020 } } }, @@ -2394,24 +2763,20 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "emissionSource" + ], "unresolved_slots": [], "stat_vars": { "member_count": 1, - "member_count_exact": true, - "served_count": 1, + "member_count_exact": false, + "served_count": 22, "data_date_range": { - "start": "2015", - "end": "2022" + "start": "2013", + "end": "2020" } }, "entities": [ - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/KEN", "label": "Kenya", @@ -2422,12 +2787,12 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 16, + "observation_count": 8, "evidence": "facet_metadata", "dimensions": [ { - "label": "countries", - "count": 2 + "label": "sources", + "count": 1 }, { "label": "observations", @@ -2439,41 +2804,246 @@ } ], "window": { - "start_year": 2015, - "end_year": 2022 + "start_year": 2013, + "end_year": 2020 } }, "download": { - "rows": 16, + "rows": 8, "rows_exact": true, - "series": 2, + "series": 1, "window": { - "start_year": 2015, - "end_year": 2022 + "start_year": 2013, + "end_year": 2020 + }, + "licence": { + "label": "PublicDomain" } }, "facets": { "provenance": { "basis": "fallback", - "ref": "undata/p/SDG", - "label": "SDG Global Database", + "ref": "dc/base/OECD_Air_GHG_emissions", + "label": "Air and GHG emissions", "source": { - "ref": "undata/p/SDG", - "label": "SDG Global Database" + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" }, "data_commons": { - "id": "un_system", - "label": "UN System Data Commons" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/undata/p/SDG" + "documentation": "/api/graph/documentation/dc/base/OECD_Air_GHG_emissions" }, "unit": { "basis": "fallback", - "ref": "undata/UNIT_MEASURE-CR_LCU", - "label": "Local currency" + "ref": "MetricTon", + "label": "MetricTon" } }, - "slot_options": [], + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "emissionSource", + "label": "emissionSource" + }, + "label": "emission source" + }, + "options": [ + { + "value": { + "ref": { + "ref": "EPA_SCC/1", + "label": "External Combustion (SCC 1)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ForestryAndLandUse", + "label": "Forestry And Land Use" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Agriculture", + "label": "Agriculture" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/21", + "label": "Stationary Source Fuel Combustion (SCC 21)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/22", + "label": "Mobile Sources (SCC 22)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/23", + "label": "Industrial Processes - NonPoint Source (SCC 23)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/24", + "label": "Solvent Utilization (SCC 24)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/25", + "label": "Storage and Transport (SCC 25)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/26", + "label": "Waste Disposal, Treatment, and Recovery (SCC 26)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/28", + "label": "Miscellaneous Area Sources (SCC 28)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/2", + "label": "Internal Combustion Engines (SCC 2)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/3", + "label": "Industrial Processes - Point Source (SCC 3)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/4", + "label": "Petroleum and Solvent Evaporation (SCC 4)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/5", + "label": "Waste Disposal (SCC 5)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/6", + "label": "MACT Source Categories (SCC 6)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/27", + "label": "Natural Sources (SCC 27)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "NaturalResource", + "label": "Natural Resource" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ClimateTrace_OtherAgriculturalSoilEmissions", + "label": "Other Agricultural Soil Emissions" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "emittedThing", + "label": "emittedThing" + }, + "label": "emitted thing" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CarbonDioxide", + "label": "CarbonDioxide" + }, + "value_kind": "enum_value" + }, + "served_rows": 8, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + } + ], "entity_options": [], "facet_options": [ { @@ -2482,8 +3052,8 @@ { "value": { "ref": { - "ref": "undata/p/SDG", - "label": "SDG Global Database" + "ref": "dc/base/OECD_Air_GHG_emissions", + "label": "Air and GHG emissions" }, "value_kind": "source" } @@ -2498,8 +3068,8 @@ { "value": { "ref": { - "ref": "undata/UNIT_MEASURE-CR_LCU", - "label": "Local currency" + "ref": "MetricTon", + "label": "MetricTon" }, "value_kind": "enum_value" } @@ -2509,35 +3079,63 @@ "source": "observed" } ], - "rendered_sentence": "Total government revenue, in local currency in Germany and Kenya, 2015 to 2022. SDG Global Database.", + "rendered_sentence": "Kenya's annual amount of emissions: carbon dioxide, 2013 to 2020. Air and GHG emissions.", "sentence_plan": [ { "kind": "slot", - "text": "Total government revenue, in local currency", - "axis": "what", + "text": "Kenya", + "axis": "where", "segment": "heading", + "binding_ref": "where:", "entity_refs": [], - "states": [], - "distinguishes": true + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "Germany and Kenya", - "axis": "where", + "text": "annual amount of emissions: carbon dioxide", + "axis": "what", "segment": "heading", - "binding_ref": "where:", "entity_refs": [], "states": [ - "where:" + "how:emittedThing" ] }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "emissionSource", + "binding_ref": "how:emissionSource", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "emittedThing", + "binding_ref": "how:emittedThing", + "entity_refs": [], + "states": [] + }, { "kind": "text", "text": ", ", @@ -2547,7 +3145,7 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2020", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -2572,7 +3170,7 @@ }, { "kind": "slot", - "text": "SDG Global Database", + "text": "Air and GHG emissions", "axis": "source", "segment": "byline", "entity_refs": [], @@ -2590,10 +3188,6 @@ ], "trace": { "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -2601,31 +3195,53 @@ ], "resolved_sources": [ { - "ref": "undata/p/SDG", - "label": "SDG Global Database", + "ref": "dc/base/OECD_Air_GHG_emissions", + "label": "Air and GHG emissions", "source": { - "ref": "undata/p/SDG", - "label": "SDG Global Database" + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" }, "data_commons": { - "id": "un_system", - "label": "UN System Data Commons" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/undata/p/SDG" + "documentation": "/api/graph/documentation/dc/base/OECD_Air_GHG_emissions" } ], "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "emissionSource", + "label": "emissionSource" + }, + "label": "emission source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "emittedThing", + "label": "emittedThing" + }, + "label": "emitted thing" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "where", "label": "place" }, - "binding_kind": "set", + "binding_kind": "value", "refs": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -2654,66 +3270,106 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, "removed_stat_vars": [] } }, - "confidence": "medium", + "confidence": "high", "available_at_place": true, "measure_label_axes": [], - "measure_axis_values": [] + "measure_axis_values": [], + "open_axis_facts": [ + { + "property": "emittedThing", + "varies": false, + "value": { + "ref": "CarbonDioxide", + "label": "Carbon Dioxide" + }, + "distinct_count": 1, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "CarbonDioxide", + "label": "Carbon Dioxide" + }, + "count": 1 + } + ] + } + ] } }, { - "spec_id": "spec_2de7abdab14ea1a63e82fd9eed8fd9e1", + "spec_id": "spec_872ffc3f7b097020db2c8012b0f5648c", "definition": { "schema_version": 1, - "spec_id": "spec_2de7abdab14ea1a63e82fd9eed8fd9e1", + "spec_id": "spec_872ffc3f7b097020db2c8012b0f5648c", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "undata/sdg/SERIES-GR_G14_GDP", - "measured_property": "value", - "stat_type": "measuredValue" + "population_type": "Emissions", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Annual" }, - "slots": [], + "slots": [ + { + "property": "emittedThing", + "binding": { + "state": "unbound" + } + } + ], "entities": { "observationAbout": [ - "country/DEU", "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "undata/sdg/series-gr_g14_gdp_value_measuredvalue", - "label": "Total bugetary revenue of the central government as a proportion of GDP", + "shape_id": "emissions_amount_measuredvalue_annual", + "label": "Annual Amount Of Emissions: Carbon Dioxide", "population_type": { - "ref": "undata/sdg/SERIES-GR_G14_GDP", - "label": "Total bugetary revenue of the central government as a proportion of GDP" + "ref": "Emissions", + "label": "Emissions" }, "measured_property": { - "ref": "value", - "label": "value" + "ref": "amount", + "label": "amount" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, + "measurement_qualifier": { + "ref": "Annual", + "label": "Annual" + }, "measurement_denominator_unresolved": false, "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "emittedThing", + "label": "emittedThing" + }, + "label": "emitted thing" + }, { "axis": "where", "label": "place" @@ -2727,50 +3383,55 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "701aca5bb048e7cfed0d4f9a49ffef4448dec8d682c9c6d4d7a4e6c33f639ecd", + "member_count": 6, + "member_digest": "f89e03b8c13d45c0487763c60aa66645b043bb4bed450bfe732381d4f9f26947", "refine_supported": true, "data_commons": [ { - "id": "un_system", - "label": "UN System Data Commons" + "id": "base", + "label": "Data Commons by Google" } ], "upstream": { "source": { - "ref": "undata/p/SDG", - "label": "SDG Global Database" + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" }, "data_commons": { - "id": "un_system", - "label": "UN System Data Commons" + "id": "base", + "label": "Data Commons by Google" } } }, "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "emittedThing", + "label": "emittedThing" + }, + "label": "emitted thing" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, { "key": { "axis": "where", "label": "place" }, "binding": { - "kind": "set", - "values": [ - { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" }, - { - "ref": { - "ref": "country/KEN", - "label": "Kenya" - }, - "value_kind": "entity" - } - ] + "value_kind": "entity" + } }, "summable": false }, @@ -2784,8 +3445,8 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, - "end_year": 2022 + "start_year": 2013, + "end_year": 2020 } } }, @@ -2806,20 +3467,14 @@ "unresolved_slots": [], "stat_vars": { "member_count": 1, - "member_count_exact": true, - "served_count": 1, + "member_count_exact": false, + "served_count": 6, "data_date_range": { - "start": "2015", - "end": "2022" + "start": "2013", + "end": "2020" } }, "entities": [ - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/KEN", "label": "Kenya", @@ -2830,12 +3485,12 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 16, + "observation_count": 8, "evidence": "facet_metadata", "dimensions": [ { - "label": "countries", - "count": 2 + "label": "sources", + "count": 1 }, { "label": "observations", @@ -2847,41 +3502,70 @@ } ], "window": { - "start_year": 2015, - "end_year": 2022 + "start_year": 2013, + "end_year": 2020 } }, "download": { - "rows": 16, + "rows": 8, "rows_exact": true, - "series": 2, + "series": 1, "window": { - "start_year": 2015, - "end_year": 2022 + "start_year": 2013, + "end_year": 2020 + }, + "licence": { + "label": "PublicDomain" } }, "facets": { "provenance": { "basis": "fallback", - "ref": "undata/p/SDG", - "label": "SDG Global Database", + "ref": "dc/base/OECD_Air_GHG_emissions", + "label": "Air and GHG emissions", "source": { - "ref": "undata/p/SDG", - "label": "SDG Global Database" + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" }, "data_commons": { - "id": "un_system", - "label": "UN System Data Commons" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/undata/p/SDG" + "documentation": "/api/graph/documentation/dc/base/OECD_Air_GHG_emissions" }, "unit": { "basis": "fallback", - "ref": "Percent", - "label": "Percent" + "ref": "MetricTon", + "label": "MetricTon" } }, - "slot_options": [], + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "emittedThing", + "label": "emittedThing" + }, + "label": "emitted thing" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CarbonDioxide", + "label": "CarbonDioxide" + }, + "value_kind": "enum_value" + }, + "served_rows": 8, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + } + ], "entity_options": [], "facet_options": [ { @@ -2890,8 +3574,8 @@ { "value": { "ref": { - "ref": "undata/p/SDG", - "label": "SDG Global Database" + "ref": "dc/base/OECD_Air_GHG_emissions", + "label": "Air and GHG emissions" }, "value_kind": "source" } @@ -2906,8 +3590,8 @@ { "value": { "ref": { - "ref": "Percent", - "label": "Percent" + "ref": "MetricTon", + "label": "MetricTon" }, "value_kind": "enum_value" } @@ -2917,35 +3601,53 @@ "source": "observed" } ], - "rendered_sentence": "Total bugetary revenue of the central government as a proportion of GDP in Germany and Kenya, 2015 to 2022. SDG Global Database.", + "rendered_sentence": "Kenya's annual amount of emissions: carbon dioxide, 2013 to 2020. Air and GHG emissions.", "sentence_plan": [ { "kind": "slot", - "text": "Total bugetary revenue of the central government as a proportion of GDP", - "axis": "what", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", "segment": "heading", "entity_refs": [], - "states": [], - "distinguishes": true + "states": [] }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "Germany and Kenya", - "axis": "where", + "text": "annual amount of emissions: carbon dioxide", + "axis": "what", "segment": "heading", - "binding_ref": "where:", "entity_refs": [], "states": [ - "where:" + "how:emittedThing" ] }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "emittedThing", + "binding_ref": "how:emittedThing", + "entity_refs": [], + "states": [] + }, { "kind": "text", "text": ", ", @@ -2955,7 +3657,7 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2020", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -2980,7 +3682,7 @@ }, { "kind": "slot", - "text": "SDG Global Database", + "text": "Air and GHG emissions", "axis": "source", "segment": "byline", "entity_refs": [], @@ -2998,10 +3700,6 @@ ], "trace": { "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -3009,31 +3707,40 @@ ], "resolved_sources": [ { - "ref": "undata/p/SDG", - "label": "SDG Global Database", + "ref": "dc/base/OECD_Air_GHG_emissions", + "label": "Air and GHG emissions", "source": { - "ref": "undata/p/SDG", - "label": "SDG Global Database" + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" }, "data_commons": { - "id": "un_system", - "label": "UN System Data Commons" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/undata/p/SDG" + "documentation": "/api/graph/documentation/dc/base/OECD_Air_GHG_emissions" } ], "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "emittedThing", + "label": "emittedThing" + }, + "label": "emitted thing" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "where", "label": "place" }, - "binding_kind": "set", + "binding_kind": "value", "refs": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -3061,166 +3768,83 @@ } ], "query_qualifiers": [], - "requested_window": { - "start_year": 2015, - "end_year": 2022 - }, - "capability_version": "cap_347a470e04c97eec", - "default_reading": { - "applied": true, - "removed_stat_vars": [] - } - }, - "confidence": "medium", - "basis": "nominated", - "available_at_place": true, - "measure_label_axes": [], - "measure_axis_values": [] - } - } - ], - "truncated": false - }, - "reading_assumptions": { - "spec_121a500dac8691cd699ac577bfab47a0": [], - "spec_2de7abdab14ea1a63e82fd9eed8fd9e1": [] - } - } - ], - "rendered_sentence": "GNI has 3 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022. Tax revenue has 2 readings. Total government revenue, in local currency in Germany and Kenya. SDG Global Database · 2015 to 2022. Total bugetary revenue of the central government as a proportion of GDP in Germany and Kenya. SDG Global Database · 2015 to 2022.", - "sentence_plan": [ - { - "kind": "slot", - "text": "GNI", - "axis": "what", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " has 3 readings.", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "Primary income", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " for ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "gross of fixed capital consumption", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " in ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "Germany and Kenya", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "OECD DAC1", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "2015 to 2022", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, + "requested_window": { + "start_year": 2013, + "end_year": 2022 + }, + "capability_version": "cap_94e25737d859392c", + "default_reading": { + "applied": true, + "removed_stat_vars": [] + } + }, + "confidence": "high", + "basis": "breakdown", + "available_at_place": true, + "measure_label_axes": [], + "measure_axis_values": [], + "open_axis_facts": [ + { + "property": "emittedThing", + "varies": false, + "value": { + "ref": "CarbonDioxide", + "label": "Carbon Dioxide" + }, + "distinct_count": 1, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "CarbonDioxide", + "label": "Carbon Dioxide" + }, + "count": 1 + } + ] + } + ] + } + } + ], + "truncated": false + }, + "reading_assumptions": { + "spec_25b6a1e19a0e6cb345e5832ed7282b14": [], + "spec_872ffc3f7b097020db2c8012b0f5648c": [] + } + } + ], + "rendered_sentence": "Mortality has 2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022. Emissions has 2 readings. Kenya's annual amount of emissions: carbon dioxide. Air and GHG emissions · 2013 to 2020. Kenya's annual amount of emissions: carbon dioxide. Air and GHG emissions · 2013 to 2020.", + "sentence_plan": [ { - "kind": "text", - "text": " · ", - "segment": "byline", + "kind": "slot", + "text": "Mortality", + "axis": "what", + "segment": "heading", "entity_refs": [], "states": [], "part_index": 0 }, { "kind": "text", - "text": "Current US dollars", - "segment": "byline", + "text": " has 2 readings.", + "segment": "heading", "entity_refs": [], "states": [], "part_index": 0 }, { "kind": "text", - "text": ".", - "segment": "byline", + "text": " ", + "segment": "heading", "entity_refs": [], "states": [], "part_index": 0 }, { "kind": "text", - "text": " ", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [], @@ -3228,7 +3852,7 @@ }, { "kind": "text", - "text": "Gross national income based on purchasing power parity", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [], @@ -3244,7 +3868,7 @@ }, { "kind": "text", - "text": "in international dollars", + "text": "deaths rate", "segment": "heading", "entity_refs": [], "states": [], @@ -3252,7 +3876,7 @@ }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [], @@ -3260,7 +3884,7 @@ }, { "kind": "text", - "text": "Germany and Kenya", + "text": "per capita", "segment": "heading", "entity_refs": [], "states": [], @@ -3300,7 +3924,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2022", "segment": "byline", "entity_refs": [], "states": [], @@ -3324,15 +3948,7 @@ }, { "kind": "text", - "text": "Gross national income based on purchasing power parity per capita", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [], @@ -3340,7 +3956,7 @@ }, { "kind": "text", - "text": "in international dollars", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [], @@ -3348,7 +3964,7 @@ }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [], @@ -3356,7 +3972,7 @@ }, { "kind": "text", - "text": "Germany and Kenya", + "text": "number of deaths", "segment": "heading", "entity_refs": [], "states": [], @@ -3380,7 +3996,7 @@ }, { "kind": "text", - "text": "World Development Indicators", + "text": "Kenya Census", "segment": "byline", "entity_refs": [], "states": [], @@ -3396,7 +4012,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2018 to 2022", "segment": "byline", "entity_refs": [], "states": [], @@ -3419,7 +4035,7 @@ }, { "kind": "slot", - "text": "Tax revenue", + "text": "Emissions", "axis": "what", "segment": "heading", "entity_refs": [], @@ -3444,7 +4060,15 @@ }, { "kind": "text", - "text": "Total government revenue, in local currency", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [], @@ -3452,7 +4076,7 @@ }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [], @@ -3460,7 +4084,7 @@ }, { "kind": "text", - "text": "Germany and Kenya", + "text": "annual amount of emissions: carbon dioxide", "segment": "heading", "entity_refs": [], "states": [], @@ -3484,7 +4108,7 @@ }, { "kind": "text", - "text": "SDG Global Database", + "text": "Air and GHG emissions", "segment": "byline", "entity_refs": [], "states": [], @@ -3500,7 +4124,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2020", "segment": "byline", "entity_refs": [], "states": [], @@ -3524,7 +4148,15 @@ }, { "kind": "text", - "text": "Total bugetary revenue of the central government as a proportion of GDP", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [], @@ -3532,7 +4164,7 @@ }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [], @@ -3540,7 +4172,7 @@ }, { "kind": "text", - "text": "Germany and Kenya", + "text": "annual amount of emissions: carbon dioxide", "segment": "heading", "entity_refs": [], "states": [], @@ -3564,7 +4196,7 @@ }, { "kind": "text", - "text": "SDG Global Database", + "text": "Air and GHG emissions", "segment": "byline", "entity_refs": [], "states": [], @@ -3580,7 +4212,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2020", "segment": "byline", "entity_refs": [], "states": [], @@ -3614,34 +4246,34 @@ "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU", "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, "assumptions": [], - "variable_text": "GNI" + "variable_text": "mortality" }, { "entry_kind": "candidates", @@ -3653,20 +4285,33 @@ "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "undata/sdg/SERIES-GR_G14_XDC", - "measured_property": "value", - "stat_type": "measuredValue" + "population_type": "Emissions", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Annual" }, - "slots": [], + "slots": [ + { + "property": "emissionSource", + "binding": { + "state": "unbound" + } + }, + { + "property": "emittedThing", + "binding": { + "state": "unbound" + } + } + ], "entities": { "observationAbout": [ - "country/DEU", "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, @@ -3677,27 +4322,34 @@ "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "undata/sdg/SERIES-GR_G14_GDP", - "measured_property": "value", - "stat_type": "measuredValue" + "population_type": "Emissions", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Annual" }, - "slots": [], + "slots": [ + { + "property": "emittedThing", + "binding": { + "state": "unbound" + } + } + ], "entities": { "observationAbout": [ - "country/DEU", "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, "assumptions": [] } ], - "variable_text": "tax revenue" + "variable_text": "emissions" } ] } @@ -3707,7 +4359,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4763dc6052244fba8ba9aa7f29e3bb61" + "x-dfo-trace-id": "f80a912e90f9426b91d135271778cff7" }, "json": { "schema_version": 1, @@ -3716,11 +4368,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "4763dc6052244fba8ba9aa7f29e3bb61", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "f80a912e90f9426b91d135271778cff7", "warnings": [], "timing_ms": { - "total": 173, + "total": 854, "by_step": { "coverage": 0 } @@ -3730,99 +4382,93 @@ "kind": "resolution", "parts": [ { - "variable_text": "GNI", + "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 1, + "total": 382, "by_step": { "validate": 0, "walk": 0, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 0, - "bind": 0, + "shape": 226, + "bind": 1, "where_places": 0, - "materialise": 1, - "answer": 0, - "options": 0 + "materialise": 152, + "answer": 2, + "options": 1 } }, "operations": [], - "departures": [ - { - "code": "entity_unavailable", - "binding_ref": "where:", - "text": "You asked for Kenya. The data holds no values for it." - } - ], + "departures": [], "assumptions": [], "status": "definite", "spec": { - "spec_id": "spec_9ce16f72ff8416d06a56f9fe82b10ad3", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "definition": { "schema_version": 1, - "spec_id": "spec_9ce16f72ff8416d06a56f9fe82b10ad3", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU", "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicunit_primaryincome_measuredvalue_nominal", - "label": "Gross national income", + "shape_id": "mortalityevent_count_measuredvalue_per_count_person", + "label": "Deaths Rate", "population_type": { - "ref": "EconomicUnit", - "label": "economic unit" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "primaryIncome", - "label": "primary income" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "Nominal", - "label": "Nominal" + "measurement_denominator": { + "ref": "Count_Person", + "label": "Total population" }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, { "axis": "where", @@ -3837,13 +4483,13 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", - "refine_supported": true, + "member_count": 133, + "member_digest": "c090b56d31a596a8be16dafb518382db666c6b100a80534c3cb81dbfe3111c5d", + "refine_supported": false, "data_commons": [ { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" } ] }, @@ -3852,20 +4498,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - }, - "value_kind": "enum_value" - } + "kind": "unbound" }, "summable": false }, @@ -3875,23 +4514,14 @@ "label": "place" }, "binding": { - "kind": "set", - "values": [ - { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" }, - { - "ref": { - "ref": "country/KEN", - "label": "Kenya" - }, - "value_kind": "entity" - } - ] + "value_kind": "entity" + } }, "summable": false }, @@ -3905,7 +4535,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } @@ -3923,24 +4553,20 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 2, "member_count_exact": true, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2013", "end": "2022" } }, "entities": [ - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/KEN", "label": "Kenya", @@ -3951,16 +4577,16 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 8, + "observation_count": 10, "evidence": "facet_metadata", "dimensions": [ { - "label": "countries", + "label": "sources", "count": 1 }, { "label": "observations", - "count": 8 + "count": 10 }, { "label": "variables", @@ -3968,43 +4594,46 @@ } ], "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, "download": { - "rows": 8, + "rows": 10, "rows_exact": true, "series": 1, "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, "licence": { - "label": "OECD Terms and Conditions" + "label": "Creative Commons Attribution License" } }, "facets": { "provenance": { "basis": "fallback", - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1", - "account": "provider" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "measurementMethod": { + "basis": "fallback", + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" }, "unit": { "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" + "ref": "Per1000Persons", + "label": "Per 1000 people" } }, "slot_options": [ @@ -4012,17 +4641,17 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" + "ref": "ICD10/X60-X84", + "label": "X60-X84 (Intentional self-harm)" }, "value_kind": "enum_value" } @@ -4040,8 +4669,8 @@ { "value": { "ref": { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1" + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" }, "value_kind": "source" } @@ -4049,8 +4678,8 @@ { "value": { "ref": { - "ref": "provenance/WorldBankInternationalDebtStatistics", - "label": "World Bank International Debt Statistics (IDS)" + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, "value_kind": "source" } @@ -4059,69 +4688,108 @@ "truncated": false, "source": "observed" }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "ref": { + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, { "axis": "unit", "options": [ { "value": { "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" + "ref": "Per1000Persons", + "label": "Per 1000 people" }, "value_kind": "enum_value" } + }, + { + "value": { + "value_kind": "enum_value" + } } ], "truncated": false, "source": "observed" } ], - "rendered_sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 2015 to 2022. Current US dollars · OECD DAC1.", + "rendered_sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators.", "sentence_plan": [ { "kind": "slot", - "text": "Primary income", - "axis": "what", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": " for ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "gross of fixed capital consumption", - "axis": "how", + "text": "deaths rate", + "axis": "what", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ] + "states": [] }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "Germany and Kenya", - "axis": "where", + "text": "per capita", + "axis": "unit", "segment": "heading", - "binding_ref": "where:", "entity_refs": [], - "states": [ - "where:" - ] + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", + "entity_refs": [], + "states": [] }, { "kind": "text", @@ -4132,7 +4800,7 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -4157,26 +4825,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -4194,10 +4843,6 @@ ], "trace": { "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -4205,17 +4850,17 @@ ], "resolved_sources": [ { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" } ], "slot_filters": [ @@ -4223,18 +4868,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -4242,12 +4882,8 @@ "axis": "where", "label": "place" }, - "binding_kind": "set", + "binding_kind": "value", "refs": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -4276,39 +4912,87 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec" + "capability_version": "cap_94e25737d859392c" }, "confidence": "high", "available_at_place": true, "measure_label_axes": [], "measure_axis_values": [], - "related_measures": [] + "related_group": { + "ref": "dc/g/MortalityEvent", + "label": "Mortality Event" + }, + "related_measures": [ + { + "stat_var": { + "ref": "Count_Death", + "label": "Number of Deaths" + }, + "definition": { + "schema_version": 1, + "spec_id": "spec_31961a9c9519bb4db004fa793f0457e5", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "MortalityEvent", + "measured_property": "count", + "stat_type": "measuredValue" + }, + "slots": [], + "entities": { + "observationAbout": [ + "country/KEN" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2013, + "end_year": 2022 + } + } + } + } + ] } } }, { - "variable_text": "tax revenue", - "warnings": [], + "variable_text": "emissions", + "warnings": [ + { + "code": "family_total_absent", + "severity": "warn", + "message": "No total for this family of variables was found, so the answer shows Annual Amount Of Emissions: Carbon Dioxide.", + "spec_id": "spec_25b6a1e19a0e6cb345e5832ed7282b14" + }, + { + "code": "family_total_absent", + "severity": "warn", + "message": "No total for this family of variables was found, so the answer shows Annual Amount Of Emissions: Carbon Dioxide.", + "spec_id": "spec_872ffc3f7b097020db2c8012b0f5648c" + } + ], "timing_ms": { - "total": 3, + "total": 1494, "by_step": { "validate": 0, - "walk": 0, - "reread_arcs": 0, + "walk": 1093, + "reread_arcs": 2, "detect_edits": 0, "resolve_survivors": 0, - "shape": 0, + "shape": 9, "bind": 0, "where_places": 0, - "materialise": 1, - "answer": 2, - "options": 0 + "materialise": 273, + "answer": 8, + "options": 109 } }, - "rendered_sentence": "2 readings. Total government revenue, in local currency in Germany and Kenya. SDG Global Database · 2015 to 2022. Total bugetary revenue of the central government as a proportion of GDP in Germany and Kenya. SDG Global Database · 2015 to 2022.", + "rendered_sentence": "2 readings. Kenya's annual amount of emissions: carbon dioxide. Air and GHG emissions · 2013 to 2020. Kenya's annual amount of emissions: carbon dioxide. Air and GHG emissions · 2013 to 2020.", "sentence_plan": [ { "kind": "text", @@ -4326,21 +5010,28 @@ }, { "kind": "text", - "text": "Total government revenue, in local currency", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": "Germany and Kenya", + "text": "annual amount of emissions: carbon dioxide", "segment": "heading", "entity_refs": [], "states": [] @@ -4361,7 +5052,7 @@ }, { "kind": "text", - "text": "SDG Global Database", + "text": "Air and GHG emissions", "segment": "byline", "entity_refs": [], "states": [] @@ -4375,7 +5066,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2020", "segment": "byline", "entity_refs": [], "states": [] @@ -4396,21 +5087,28 @@ }, { "kind": "text", - "text": "Total bugetary revenue of the central government as a proportion of GDP", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": "Germany and Kenya", + "text": "annual amount of emissions: carbon dioxide", "segment": "heading", "entity_refs": [], "states": [] @@ -4431,7 +5129,7 @@ }, { "kind": "text", - "text": "SDG Global Database", + "text": "Air and GHG emissions", "segment": "byline", "entity_refs": [], "states": [] @@ -4445,7 +5143,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2020", "segment": "byline", "entity_refs": [], "states": [] @@ -4467,50 +5165,83 @@ "max_candidates": 6, "specs": [ { - "spec_id": "spec_121a500dac8691cd699ac577bfab47a0", + "spec_id": "spec_25b6a1e19a0e6cb345e5832ed7282b14", "definition": { "schema_version": 1, - "spec_id": "spec_121a500dac8691cd699ac577bfab47a0", + "spec_id": "spec_25b6a1e19a0e6cb345e5832ed7282b14", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "undata/sdg/SERIES-GR_G14_XDC", - "measured_property": "value", - "stat_type": "measuredValue" + "population_type": "Emissions", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Annual" }, - "slots": [], + "slots": [ + { + "property": "emissionSource", + "binding": { + "state": "unbound" + } + }, + { + "property": "emittedThing", + "binding": { + "state": "unbound" + } + } + ], "entities": { "observationAbout": [ - "country/DEU", "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "undata/sdg/series-gr_g14_xdc_value_measuredvalue", - "label": "Total government revenue, in local currency", + "shape_id": "emissions_amount_measuredvalue_annual", + "label": "Annual Amount Of Emissions: Carbon Dioxide", "population_type": { - "ref": "undata/sdg/SERIES-GR_G14_XDC", - "label": "Total government revenue, in local currency" + "ref": "Emissions", + "label": "Emissions" }, "measured_property": { - "ref": "value", - "label": "value" + "ref": "amount", + "label": "amount" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, + "measurement_qualifier": { + "ref": "Annual", + "label": "Annual" + }, "measurement_denominator_unresolved": false, "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "emissionSource", + "label": "emissionSource" + }, + "label": "emission source" + }, + { + "axis": "how", + "property": { + "ref": "emittedThing", + "label": "emittedThing" + }, + "label": "emitted thing" + }, { "axis": "where", "label": "place" @@ -4524,161 +5255,351 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "a28ecf2dacf37e649080b176e0cab12f467a0af085fd4d9f5396d97b1c730597", + "member_count": 869, + "member_digest": "c14e826e3bbc769a4b453db4b59a905d131566184f5e8582ab4018f0e90311a9", "refine_supported": true, "data_commons": [ { - "id": "un_system", - "label": "UN System Data Commons" + "id": "base", + "label": "Data Commons by Google" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "emissionSource", + "label": "emissionSource" + }, + "label": "emission source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "emittedThing", + "label": "emittedThing" + }, + "label": "emitted thing" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + } + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2013, + "end_year": 2020 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + } + ], + "inapplicable_slots": [], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 22, + "data_date_range": { + "start": "2013", + "end": "2020" + } + }, + "entities": [ + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "observationAbout" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 8, + "evidence": "facet_metadata", + "dimensions": [ + { + "label": "sources", + "count": 1 + }, + { + "label": "observations", + "count": 8 + }, + { + "label": "variables", + "count": 1 } ], - "upstream": { + "window": { + "start_year": 2013, + "end_year": 2020 + } + }, + "download": { + "rows": 8, + "rows_exact": true, + "series": 1, + "window": { + "start_year": 2013, + "end_year": 2020 + }, + "licence": { + "label": "PublicDomain" + } + }, + "facets": { + "provenance": { + "basis": "fallback", + "ref": "dc/base/OECD_Air_GHG_emissions", + "label": "Air and GHG emissions", "source": { - "ref": "undata/p/SDG", - "label": "SDG Global Database" + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" }, "data_commons": { - "id": "un_system", - "label": "UN System Data Commons" - } + "id": "base", + "label": "Data Commons by Google" + }, + "documentation": "/api/graph/documentation/dc/base/OECD_Air_GHG_emissions" + }, + "unit": { + "basis": "fallback", + "ref": "MetricTon", + "label": "MetricTon" } }, - "slots": [ + "slot_options": [ { "key": { - "axis": "where", - "label": "place" + "axis": "how", + "property": { + "ref": "emissionSource", + "label": "emissionSource" + }, + "label": "emission source" }, - "binding": { - "kind": "set", - "values": [ - { + "options": [ + { + "value": { "ref": { - "ref": "country/DEU", - "label": "Germany" + "ref": "Agriculture", + "label": "Agriculture" }, - "value_kind": "entity" - }, - { + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ClimateTrace_OtherAgriculturalSoilEmissions", + "label": "Other Agricultural Soil Emissions" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/1", + "label": "External Combustion (SCC 1)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/21", + "label": "Stationary Source Fuel Combustion (SCC 21)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/22", + "label": "Mobile Sources (SCC 22)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/23", + "label": "Industrial Processes - NonPoint Source (SCC 23)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/24", + "label": "Solvent Utilization (SCC 24)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/25", + "label": "Storage and Transport (SCC 25)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/26", + "label": "Waste Disposal, Treatment, and Recovery (SCC 26)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/27", + "label": "Natural Sources (SCC 27)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/28", + "label": "Miscellaneous Area Sources (SCC 28)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/2", + "label": "Internal Combustion Engines (SCC 2)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/3", + "label": "Industrial Processes - Point Source (SCC 3)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/4", + "label": "Petroleum and Solvent Evaporation (SCC 4)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "EPA_SCC/5", + "label": "Waste Disposal (SCC 5)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { "ref": { - "ref": "country/KEN", - "label": "Kenya" + "ref": "EPA_SCC/6", + "label": "MACT Source Categories (SCC 6)" }, - "value_kind": "entity" - } - ] - }, - "summable": false - }, - { - "key": { - "axis": "when", - "label": "time window" - }, - "binding": { - "kind": "value", - "value": { - "value_kind": "time_window", - "time_window": { - "start_year": 2015, - "end_year": 2022 + "value_kind": "enum_value" } } - }, - "summable": false + ], + "truncated": true, + "source": "observed" }, { "key": { - "axis": "source", - "label": "data source" - }, - "binding": { - "kind": "unbound" + "axis": "how", + "property": { + "ref": "emittedThing", + "label": "emittedThing" + }, + "label": "emitted thing" }, - "summable": false - } - ], - "inapplicable_slots": [], - "unresolved_slots": [], - "stat_vars": { - "member_count": 1, - "member_count_exact": true, - "served_count": 1, - "data_date_range": { - "start": "2015", - "end": "2022" - } - }, - "entities": [ - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/KEN", - "label": "Kenya", - "entity_type": "Country", - "role": "observationAbout" + "options": [ + { + "value": { + "ref": { + "ref": "CarbonDioxide", + "label": "CarbonDioxide" + }, + "value_kind": "enum_value" + }, + "served_rows": 8, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" } ], - "coverage": { - "kind": "exact", - "has_data": true, - "observation_count": 16, - "evidence": "facet_metadata", - "dimensions": [ - { - "label": "countries", - "count": 2 - }, - { - "label": "observations", - "count": 8 - }, - { - "label": "variables", - "count": 1 - } - ], - "window": { - "start_year": 2015, - "end_year": 2022 - } - }, - "download": { - "rows": 16, - "rows_exact": true, - "series": 2, - "window": { - "start_year": 2015, - "end_year": 2022 - } - }, - "facets": { - "provenance": { - "basis": "fallback", - "ref": "undata/p/SDG", - "label": "SDG Global Database", - "source": { - "ref": "undata/p/SDG", - "label": "SDG Global Database" - }, - "data_commons": { - "id": "un_system", - "label": "UN System Data Commons" - }, - "documentation": "/api/graph/documentation/undata/p/SDG" - }, - "unit": { - "basis": "fallback", - "ref": "undata/UNIT_MEASURE-CR_LCU", - "label": "Local currency" - } - }, - "slot_options": [], "entity_options": [], "facet_options": [ { @@ -4687,8 +5608,8 @@ { "value": { "ref": { - "ref": "undata/p/SDG", - "label": "SDG Global Database" + "ref": "dc/base/OECD_Air_GHG_emissions", + "label": "Air and GHG emissions" }, "value_kind": "source" } @@ -4703,8 +5624,8 @@ { "value": { "ref": { - "ref": "undata/UNIT_MEASURE-CR_LCU", - "label": "Local currency" + "ref": "MetricTon", + "label": "MetricTon" }, "value_kind": "enum_value" } @@ -4714,34 +5635,60 @@ "source": "observed" } ], - "rendered_sentence": "Total government revenue, in local currency in Germany and Kenya, 2015 to 2022. SDG Global Database.", + "rendered_sentence": "Kenya's annual amount of emissions: carbon dioxide, 2013 to 2020. Air and GHG emissions.", "sentence_plan": [ { "kind": "slot", - "text": "Total government revenue, in local currency", - "axis": "what", + "text": "Kenya", + "axis": "where", "segment": "heading", + "binding_ref": "where:", "entity_refs": [], - "states": [], - "distinguishes": true + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "Germany and Kenya", - "axis": "where", + "text": "annual amount of emissions: carbon dioxide", + "axis": "what", "segment": "heading", - "binding_ref": "where:", "entity_refs": [], - "states": [ - "where:" - ] + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "emissionSource", + "binding_ref": "how:emissionSource", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "emittedThing", + "binding_ref": "how:emittedThing", + "entity_refs": [], + "states": [] }, { "kind": "text", @@ -4752,7 +5699,7 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2020", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -4777,7 +5724,7 @@ }, { "kind": "slot", - "text": "SDG Global Database", + "text": "Air and GHG emissions", "axis": "source", "segment": "byline", "entity_refs": [], @@ -4795,10 +5742,6 @@ ], "trace": { "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -4806,31 +5749,53 @@ ], "resolved_sources": [ { - "ref": "undata/p/SDG", - "label": "SDG Global Database", + "ref": "dc/base/OECD_Air_GHG_emissions", + "label": "Air and GHG emissions", "source": { - "ref": "undata/p/SDG", - "label": "SDG Global Database" + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" }, "data_commons": { - "id": "un_system", - "label": "UN System Data Commons" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/undata/p/SDG" + "documentation": "/api/graph/documentation/dc/base/OECD_Air_GHG_emissions" } ], "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "emissionSource", + "label": "emissionSource" + }, + "label": "emission source" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "emittedThing", + "label": "emittedThing" + }, + "label": "emitted thing" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "where", "label": "place" }, - "binding_kind": "set", + "binding_kind": "value", "refs": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -4859,63 +5824,253 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec" + "capability_version": "cap_94e25737d859392c" }, "confidence": "high", "available_at_place": true, "measure_label_axes": [], "measure_axis_values": [], - "related_measures": [] + "open_axis_facts": [ + { + "property": "emissionSource", + "varies": true, + "distinct_count": 16, + "undeclared_count": 6, + "values": [ + { + "value": { + "ref": "Agriculture", + "label": "Agriculture" + }, + "count": 1 + }, + { + "value": { + "ref": "EPA_SCC/4", + "label": "Chemical Evaporation (SCC 4)" + }, + "count": 1 + }, + { + "value": { + "ref": "EPA_SCC/1", + "label": "External Combustion (SCC 1)" + }, + "count": 1 + }, + { + "value": { + "ref": "EPA_SCC/23", + "label": "Industrial Processes - NonPoint Source (SCC 23)" + }, + "count": 1 + }, + { + "value": { + "ref": "EPA_SCC/3", + "label": "Industrial Processes - Point Source (SCC 3)" + }, + "count": 1 + }, + { + "value": { + "ref": "EPA_SCC/2", + "label": "Internal Combustion Engines (SCC 2)" + }, + "count": 1 + }, + { + "value": { + "ref": "EPA_SCC/6", + "label": "MACT Source Categories (SCC 6)" + }, + "count": 1 + }, + { + "value": { + "ref": "EPA_SCC/28", + "label": "Miscellaneous Area Sources (SCC 28)" + }, + "count": 1 + }, + { + "value": { + "ref": "EPA_SCC/22", + "label": "Mobile Sources (SCC 22)" + }, + "count": 1 + }, + { + "value": { + "ref": "EPA_SCC/27", + "label": "Natural Sources (SCC 27)" + }, + "count": 1 + }, + { + "value": { + "ref": "ClimateTrace_OtherAgriculturalSoilEmissions", + "label": "Other Agricultural Soil Emissions" + }, + "count": 1 + }, + { + "value": { + "ref": "EPA_SCC/24", + "label": "Solvent Utilization (SCC 24)" + }, + "count": 1 + }, + { + "value": { + "ref": "EPA_SCC/21", + "label": "Stationary Source Fuel Combustion (SCC 21)" + }, + "count": 1 + }, + { + "value": { + "ref": "EPA_SCC/25", + "label": "Storage and Transport (SCC 25)" + }, + "count": 1 + }, + { + "value": { + "ref": "EPA_SCC/5", + "label": "Waste Disposal (SCC 5)" + }, + "count": 1 + }, + { + "value": { + "ref": "EPA_SCC/26", + "label": "Waste Disposal, Treatment, and Recovery (SCC 26)" + }, + "count": 1 + } + ] + }, + { + "property": "emittedThing", + "varies": true, + "distinct_count": 6, + "undeclared_count": 16, + "values": [ + { + "value": { + "ref": "CarbonDioxide", + "label": "Carbon Dioxide" + }, + "count": 1 + }, + { + "value": { + "ref": "CarbonMonoxide", + "label": "CarbonMonoxide" + }, + "count": 1 + }, + { + "value": { + "ref": "GreenhouseGas", + "label": "GreenhouseGas" + }, + "count": 1 + }, + { + "value": { + "ref": "OxidesOfNitrogen", + "label": "Oxides Of Nitrogen (NOX)" + }, + "count": 1 + }, + { + "value": { + "ref": "OxidesOfSulfur", + "label": "OxidesOfSulfur" + }, + "count": 1 + }, + { + "value": { + "ref": "VolatileOrganicCompound", + "label": "Volatile Organic Compound (VOC)" + }, + "count": 1 + } + ] + } + ] } }, { - "spec_id": "spec_2de7abdab14ea1a63e82fd9eed8fd9e1", + "spec_id": "spec_872ffc3f7b097020db2c8012b0f5648c", "definition": { "schema_version": 1, - "spec_id": "spec_2de7abdab14ea1a63e82fd9eed8fd9e1", + "spec_id": "spec_872ffc3f7b097020db2c8012b0f5648c", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "undata/sdg/SERIES-GR_G14_GDP", - "measured_property": "value", - "stat_type": "measuredValue" + "population_type": "Emissions", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Annual" }, - "slots": [], + "slots": [ + { + "property": "emittedThing", + "binding": { + "state": "unbound" + } + } + ], "entities": { "observationAbout": [ - "country/DEU", "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "undata/sdg/series-gr_g14_gdp_value_measuredvalue", - "label": "Total bugetary revenue of the central government as a proportion of GDP", + "shape_id": "emissions_amount_measuredvalue_annual", + "label": "Annual Amount Of Emissions: Carbon Dioxide", "population_type": { - "ref": "undata/sdg/SERIES-GR_G14_GDP", - "label": "Total bugetary revenue of the central government as a proportion of GDP" + "ref": "Emissions", + "label": "Emissions" }, "measured_property": { - "ref": "value", - "label": "value" + "ref": "amount", + "label": "amount" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, + "measurement_qualifier": { + "ref": "Annual", + "label": "Annual" + }, "measurement_denominator_unresolved": false, "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "emittedThing", + "label": "emittedThing" + }, + "label": "emitted thing" + }, { "axis": "where", "label": "place" @@ -4929,50 +6084,55 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "701aca5bb048e7cfed0d4f9a49ffef4448dec8d682c9c6d4d7a4e6c33f639ecd", + "member_count": 6, + "member_digest": "f89e03b8c13d45c0487763c60aa66645b043bb4bed450bfe732381d4f9f26947", "refine_supported": true, "data_commons": [ { - "id": "un_system", - "label": "UN System Data Commons" + "id": "base", + "label": "Data Commons by Google" } ], "upstream": { "source": { - "ref": "undata/p/SDG", - "label": "SDG Global Database" + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" }, "data_commons": { - "id": "un_system", - "label": "UN System Data Commons" + "id": "base", + "label": "Data Commons by Google" } } }, "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "emittedThing", + "label": "emittedThing" + }, + "label": "emitted thing" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, { "key": { "axis": "where", "label": "place" }, "binding": { - "kind": "set", - "values": [ - { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" }, - { - "ref": { - "ref": "country/KEN", - "label": "Kenya" - }, - "value_kind": "entity" - } - ] + "value_kind": "entity" + } }, "summable": false }, @@ -4986,8 +6146,8 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, - "end_year": 2022 + "start_year": 2013, + "end_year": 2020 } } }, @@ -5009,19 +6169,13 @@ "stat_vars": { "member_count": 1, "member_count_exact": true, - "served_count": 1, + "served_count": 6, "data_date_range": { - "start": "2015", - "end": "2022" + "start": "2013", + "end": "2020" } }, "entities": [ - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/KEN", "label": "Kenya", @@ -5032,12 +6186,12 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 16, + "observation_count": 8, "evidence": "facet_metadata", "dimensions": [ { - "label": "countries", - "count": 2 + "label": "sources", + "count": 1 }, { "label": "observations", @@ -5049,41 +6203,70 @@ } ], "window": { - "start_year": 2015, - "end_year": 2022 + "start_year": 2013, + "end_year": 2020 } }, "download": { - "rows": 16, + "rows": 8, "rows_exact": true, - "series": 2, + "series": 1, "window": { - "start_year": 2015, - "end_year": 2022 + "start_year": 2013, + "end_year": 2020 + }, + "licence": { + "label": "PublicDomain" } }, "facets": { "provenance": { "basis": "fallback", - "ref": "undata/p/SDG", - "label": "SDG Global Database", + "ref": "dc/base/OECD_Air_GHG_emissions", + "label": "Air and GHG emissions", "source": { - "ref": "undata/p/SDG", - "label": "SDG Global Database" + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" }, "data_commons": { - "id": "un_system", - "label": "UN System Data Commons" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/undata/p/SDG" + "documentation": "/api/graph/documentation/dc/base/OECD_Air_GHG_emissions" }, "unit": { "basis": "fallback", - "ref": "Percent", - "label": "Percent" + "ref": "MetricTon", + "label": "MetricTon" } }, - "slot_options": [], + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "emittedThing", + "label": "emittedThing" + }, + "label": "emitted thing" + }, + "options": [ + { + "value": { + "ref": { + "ref": "CarbonDioxide", + "label": "CarbonDioxide" + }, + "value_kind": "enum_value" + }, + "served_rows": 8, + "served_rows_exact": true + } + ], + "truncated": true, + "source": "observed" + } + ], "entity_options": [], "facet_options": [ { @@ -5092,8 +6275,8 @@ { "value": { "ref": { - "ref": "undata/p/SDG", - "label": "SDG Global Database" + "ref": "dc/base/OECD_Air_GHG_emissions", + "label": "Air and GHG emissions" }, "value_kind": "source" } @@ -5108,8 +6291,8 @@ { "value": { "ref": { - "ref": "Percent", - "label": "Percent" + "ref": "MetricTon", + "label": "MetricTon" }, "value_kind": "enum_value" } @@ -5119,34 +6302,50 @@ "source": "observed" } ], - "rendered_sentence": "Total bugetary revenue of the central government as a proportion of GDP in Germany and Kenya, 2015 to 2022. SDG Global Database.", + "rendered_sentence": "Kenya's annual amount of emissions: carbon dioxide, 2013 to 2020. Air and GHG emissions.", "sentence_plan": [ { "kind": "slot", - "text": "Total bugetary revenue of the central government as a proportion of GDP", - "axis": "what", + "text": "Kenya", + "axis": "where", "segment": "heading", + "binding_ref": "where:", "entity_refs": [], - "states": [], - "distinguishes": true + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "Germany and Kenya", - "axis": "where", + "text": "annual amount of emissions: carbon dioxide", + "axis": "what", "segment": "heading", - "binding_ref": "where:", "entity_refs": [], - "states": [ - "where:" - ] + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "emittedThing", + "binding_ref": "how:emittedThing", + "entity_refs": [], + "states": [] }, { "kind": "text", @@ -5157,7 +6356,7 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2020", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -5182,7 +6381,7 @@ }, { "kind": "slot", - "text": "SDG Global Database", + "text": "Air and GHG emissions", "axis": "source", "segment": "byline", "entity_refs": [], @@ -5200,10 +6399,6 @@ ], "trace": { "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -5211,31 +6406,40 @@ ], "resolved_sources": [ { - "ref": "undata/p/SDG", - "label": "SDG Global Database", + "ref": "dc/base/OECD_Air_GHG_emissions", + "label": "Air and GHG emissions", "source": { - "ref": "undata/p/SDG", - "label": "SDG Global Database" + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" }, "data_commons": { - "id": "un_system", - "label": "UN System Data Commons" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/undata/p/SDG" + "documentation": "/api/graph/documentation/dc/base/OECD_Air_GHG_emissions" } ], "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "emittedThing", + "label": "emittedThing" + }, + "label": "emitted thing" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, { "key": { "axis": "where", "label": "place" }, - "binding_kind": "set", + "binding_kind": "value", "refs": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -5264,28 +6468,79 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec" + "capability_version": "cap_94e25737d859392c" }, "confidence": "high", "available_at_place": true, "measure_label_axes": [], "measure_axis_values": [], - "related_measures": [] + "open_axis_facts": [ + { + "property": "emittedThing", + "varies": true, + "distinct_count": 6, + "undeclared_count": 0, + "values": [ + { + "value": { + "ref": "CarbonDioxide", + "label": "Carbon Dioxide" + }, + "count": 1 + }, + { + "value": { + "ref": "CarbonMonoxide", + "label": "CarbonMonoxide" + }, + "count": 1 + }, + { + "value": { + "ref": "GreenhouseGas", + "label": "GreenhouseGas" + }, + "count": 1 + }, + { + "value": { + "ref": "OxidesOfNitrogen", + "label": "Oxides Of Nitrogen (NOX)" + }, + "count": 1 + }, + { + "value": { + "ref": "OxidesOfSulfur", + "label": "OxidesOfSulfur" + }, + "count": 1 + }, + { + "value": { + "ref": "VolatileOrganicCompound", + "label": "Volatile Organic Compound (VOC)" + }, + "count": 1 + } + ] + } + ] } } ], "truncated": false }, "reading_assumptions": { - "spec_121a500dac8691cd699ac577bfab47a0": [], - "spec_2de7abdab14ea1a63e82fd9eed8fd9e1": [] + "spec_25b6a1e19a0e6cb345e5832ed7282b14": [], + "spec_872ffc3f7b097020db2c8012b0f5648c": [] } } ], - "rendered_sentence": "Answered 1 of 2 parts. Primary income for gross of fixed capital consumption in Germany and Kenya, 2015 to 2022. Current US dollars · OECD DAC1. You asked for Kenya. The data holds no values for it. Tax revenue has 2 readings. Total government revenue, in local currency in Germany and Kenya. SDG Global Database · 2015 to 2022. Total bugetary revenue of the central government as a proportion of GDP in Germany and Kenya. SDG Global Database · 2015 to 2022.", + "rendered_sentence": "Answered 1 of 2 parts. Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators. Emissions has 2 readings. Kenya's annual amount of emissions: carbon dioxide. Air and GHG emissions · 2013 to 2020. Kenya's annual amount of emissions: carbon dioxide. Air and GHG emissions · 2013 to 2020.", "sentence_plan": [ { "kind": "text", @@ -5303,8 +6558,19 @@ }, { "kind": "slot", - "text": "Primary income", - "axis": "what", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [], @@ -5312,7 +6578,7 @@ }, { "kind": "text", - "text": " for ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [], @@ -5320,20 +6586,16 @@ }, { "kind": "slot", - "text": "gross of fixed capital consumption", - "axis": "how", + "text": "deaths rate", + "axis": "what", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ], + "states": [], "part_index": 0 }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [], @@ -5341,14 +6603,22 @@ }, { "kind": "slot", - "text": "Germany and Kenya", - "axis": "where", + "text": "per capita", + "axis": "unit", "segment": "heading", - "binding_ref": "where:", "entity_refs": [], - "states": [ - "where:" - ], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", + "entity_refs": [], + "states": [], "part_index": 0 }, { @@ -5361,7 +6631,7 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -5389,28 +6659,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ], - "part_index": 0 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -5427,22 +6676,6 @@ "states": [], "part_index": 0 }, - { - "kind": "text", - "text": " ", - "segment": "departure", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "You asked for Kenya. The data holds no values for it.", - "segment": "departure", - "entity_refs": [], - "states": [], - "part_index": 0 - }, { "kind": "text", "text": " ", @@ -5452,7 +6685,7 @@ }, { "kind": "slot", - "text": "Tax revenue", + "text": "Emissions", "axis": "what", "segment": "heading", "entity_refs": [], @@ -5477,7 +6710,15 @@ }, { "kind": "text", - "text": "Total government revenue, in local currency", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [], @@ -5485,7 +6726,7 @@ }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [], @@ -5493,7 +6734,7 @@ }, { "kind": "text", - "text": "Germany and Kenya", + "text": "annual amount of emissions: carbon dioxide", "segment": "heading", "entity_refs": [], "states": [], @@ -5517,7 +6758,7 @@ }, { "kind": "text", - "text": "SDG Global Database", + "text": "Air and GHG emissions", "segment": "byline", "entity_refs": [], "states": [], @@ -5533,7 +6774,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2020", "segment": "byline", "entity_refs": [], "states": [], @@ -5557,7 +6798,15 @@ }, { "kind": "text", - "text": "Total bugetary revenue of the central government as a proportion of GDP", + "text": "Kenya", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [], @@ -5565,7 +6814,7 @@ }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [], @@ -5573,7 +6822,7 @@ }, { "kind": "text", - "text": "Germany and Kenya", + "text": "annual amount of emissions: carbon dioxide", "segment": "heading", "entity_refs": [], "states": [], @@ -5597,7 +6846,7 @@ }, { "kind": "text", - "text": "SDG Global Database", + "text": "Air and GHG emissions", "segment": "byline", "entity_refs": [], "states": [], @@ -5613,7 +6862,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2020", "segment": "byline", "entity_refs": [], "states": [], @@ -5638,14 +6887,14 @@ "answer": { "kind": "resolution", "status": "candidates", - "sentence": "GNI has 3 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022. Tax revenue has 2 readings. Total government revenue, in local currency in Germany and Kenya. SDG Global Database · 2015 to 2022. Total bugetary revenue of the central government as a proportion of GDP in Germany and Kenya. SDG Global Database · 2015 to 2022.", + "sentence": "Mortality has 2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022. Emissions has 2 readings. Kenya's annual amount of emissions: carbon dioxide. Air and GHG emissions · 2013 to 2020. Kenya's annual amount of emissions: carbon dioxide. Air and GHG emissions · 2013 to 2020.", "complete": false, "specs": [], "gaps": [ { "part": 0, "kind": "choice", - "options": 3 + "options": 2 }, { "part": 1, @@ -5659,10 +6908,10 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "Answered 1 of 2 parts. Primary income for gross of fixed capital consumption in Germany and Kenya, 2015 to 2022. Current US dollars · OECD DAC1. You asked for Kenya. The data holds no values for it. Tax revenue has 2 readings. Total government revenue, in local currency in Germany and Kenya. SDG Global Database · 2015 to 2022. Total bugetary revenue of the central government as a proportion of GDP in Germany and Kenya. SDG Global Database · 2015 to 2022.", + "sentence": "Answered 1 of 2 parts. Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators. Emissions has 2 readings. Kenya's annual amount of emissions: carbon dioxide. Air and GHG emissions · 2013 to 2020. Kenya's annual amount of emissions: carbon dioxide. Air and GHG emissions · 2013 to 2020.", "complete": false, "specs": [ - "spec_9ce16f72ff8416d06a56f9fe82b10ad3" + "spec_10bf62f9687154286b463d206f03a086" ], "gaps": [ { diff --git a/python/client-contract/src/dfo_client_contract/scenarios/resubmit-placeholder-without-restatement.json b/python/client-contract/src/dfo_client_contract/scenarios/resubmit-placeholder-without-restatement.json index 44622b5..ba20654 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/resubmit-placeholder-without-restatement.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/resubmit-placeholder-without-restatement.json @@ -4,14 +4,14 @@ "description": "Choosing candidate 0 on part 0 posts part 1, a no_data part with no restatement, as a placeholder entry with its variable_text, status and reason.", "origin": { "kind": "recorded", - "base_url": "http://127.0.0.1:19493/api", - "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T13:07:30Z" + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "recorded_at": "2026-10-23T18:39:49Z" }, "call": [ { "op": "search", - "question": "GNI of Germany and debt of Kenya from 2015 to 2022" + "question": "mortality in Kenya and savings of Kenya from 2013 to 2022" }, { "op": "choose", @@ -28,7 +28,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "GNI of Germany and debt of Kenya from 2015 to 2022" + "query": "mortality in Kenya and savings of Kenya from 2013 to 2022" } } }, @@ -36,60 +36,72 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "1516d9564a5a493fa7008b64841ffdc1" + "x-dfo-trace-id": "392e75ae92374ca4b32bda343566ed60" }, "json": { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "GNI of Germany and debt of Kenya from 2015 to 2022", - "normalized_query": "GNI of Germany and debt of Kenya from 2015 to 2022", + "raw_query": "mortality in Kenya and savings of Kenya from 2013 to 2022", + "normalized_query": "mortality in Kenya and savings of Kenya from 2013 to 2022", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "1516d9564a5a493fa7008b64841ffdc1", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "392e75ae92374ca4b32bda343566ed60", "warnings": [], "timing_ms": { - "total": 4391, + "total": 2549, "by_step": { "coverage": 0, - "extract": 1887 + "extract": 1164, + "cache_lookup": 1 } }, "llm_usage": { - "input_tokens": 12163, - "output_tokens": 848, - "cached_tokens": 2448 + "input_tokens": 2241, + "output_tokens": 196, + "cached_tokens": 843, + "jev_input_tokens": 15830, + "jev_output_tokens": 3276 }, "timed_out": false }, "kind": "resolution", "parts": [ { - "variable_text": "GNI", + "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 1770, + "total": 1381, "by_step": { - "recall": 2, - "shape_arcs": 2, - "shape_probe_coverage": 8, - "shape_probe": 9, - "shape_groups": 28, - "shape_labels": 8, + "recall": 1, + "phase_resolve_places": 0, + "phase_check_entities": 0, + "shape_arcs": 6, + "shape_probe": 223, + "shape_groups": 5, + "shape_labels": 1, "shape_admission": 1, - "shape": 852, - "bind": 913, - "materialise": 1, - "answer": 2 + "phase_derive_shapes": 0, + "shape": 339, + "phase_prune_and_rank": 0, + "bind": 125, + "phase_bind": 4, + "phase_settle": 8, + "phase_place_bindings": 25, + "phase_facet_requests": 0, + "materialise": 14, + "phase_materialise": 0, + "answer": 25, + "phase_outcome": 840 } }, - "rendered_sentence": "3 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022.", + "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", "sentence_plan": [ { "kind": "text", - "text": "3 readings.", + "text": "2 readings.", "segment": "heading", "entity_refs": [], "states": [] @@ -103,95 +115,18 @@ }, { "kind": "text", - "text": "Primary income", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": " for ", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [] }, - { - "kind": "text", - "text": "gross of fixed capital consumption", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " in ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "Germany and Kenya", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "OECD DAC1", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "2015 to 2022", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "Current US dollars", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [] - }, { "kind": "text", "text": " ", @@ -201,7 +136,7 @@ }, { "kind": "text", - "text": "Gross national income based on purchasing power parity", + "text": "deaths rate", "segment": "heading", "entity_refs": [], "states": [] @@ -215,21 +150,7 @@ }, { "kind": "text", - "text": "in international dollars", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " in ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": "Germany and Kenya", + "text": "per capita", "segment": "heading", "entity_refs": [], "states": [] @@ -264,7 +185,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2022", "segment": "byline", "entity_refs": [], "states": [] @@ -285,35 +206,28 @@ }, { "kind": "text", - "text": "Gross national income based on purchasing power parity per capita", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": "in international dollars", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": "Germany and Kenya", + "text": "number of deaths", "segment": "heading", "entity_refs": [], "states": [] @@ -334,7 +248,7 @@ }, { "kind": "text", - "text": "World Development Indicators", + "text": "Kenya Census", "segment": "byline", "entity_refs": [], "states": [] @@ -348,7 +262,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2018 to 2022", "segment": "byline", "entity_refs": [], "states": [] @@ -362,16 +276,13 @@ } ], "restatement": { - "variable_text": "GNI", + "variable_text": "mortality", "entities": [ - { - "text": "Germany" - }, { "text": "Kenya" } ], - "time_text": "2015 to 2022", + "time_text": "2013 to 2022", "sources": [], "operations": [] }, @@ -384,70 +295,70 @@ "max_candidates": 6, "specs": [ { - "spec_id": "spec_9ce16f72ff8416d06a56f9fe82b10ad3", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "definition": { "schema_version": 1, - "spec_id": "spec_9ce16f72ff8416d06a56f9fe82b10ad3", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU", "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicunit_primaryincome_measuredvalue_nominal", - "label": "Gross national income", + "shape_id": "mortalityevent_count_measuredvalue_per_count_person", + "label": "Deaths Rate", "population_type": { - "ref": "EconomicUnit", - "label": "economic unit" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "primaryIncome", - "label": "primary income" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "Nominal", - "label": "Nominal" + "measurement_denominator": { + "ref": "Count_Person", + "label": "Total population" }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, { "axis": "where", @@ -462,13 +373,13 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", - "refine_supported": true, + "member_count": 133, + "member_digest": "c090b56d31a596a8be16dafb518382db666c6b100a80534c3cb81dbfe3111c5d", + "refine_supported": false, "data_commons": [ { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" } ] }, @@ -477,20 +388,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - }, - "value_kind": "enum_value" - } + "kind": "unbound" }, "summable": false }, @@ -500,23 +404,14 @@ "label": "place" }, "binding": { - "kind": "set", - "values": [ - { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" }, - { - "ref": { - "ref": "country/KEN", - "label": "Kenya" - }, - "value_kind": "entity" - } - ] + "value_kind": "entity" + } }, "summable": false }, @@ -530,7 +425,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } @@ -548,24 +443,20 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 2, "member_count_exact": false, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2013", "end": "2022" } }, "entities": [ - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/KEN", "label": "Kenya", @@ -576,16 +467,16 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 8, + "observation_count": 10, "evidence": "facet_metadata", "dimensions": [ { - "label": "countries", + "label": "sources", "count": 1 }, { "label": "observations", - "count": 8 + "count": 10 }, { "label": "variables", @@ -593,43 +484,46 @@ } ], "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, "download": { - "rows": 8, + "rows": 10, "rows_exact": true, "series": 1, "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, "licence": { - "label": "OECD Terms and Conditions" + "label": "Creative Commons Attribution License" } }, "facets": { "provenance": { "basis": "fallback", - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1", - "account": "provider" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "measurementMethod": { + "basis": "fallback", + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" }, "unit": { "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" + "ref": "Per1000Persons", + "label": "Per 1000 people" } }, "slot_options": [ @@ -637,17 +531,17 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" + "ref": "ICD10/X60-X84", + "label": "X60-X84 (Intentional self-harm)" }, "value_kind": "enum_value" } @@ -665,8 +559,8 @@ { "value": { "ref": { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1" + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" }, "value_kind": "source" } @@ -674,8 +568,8 @@ { "value": { "ref": { - "ref": "provenance/WorldBankInternationalDebtStatistics", - "label": "World Bank International Debt Statistics (IDS)" + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, "value_kind": "source" } @@ -684,71 +578,109 @@ "truncated": false, "source": "observed" }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "ref": { + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, { "axis": "unit", "options": [ { "value": { "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" + "ref": "Per1000Persons", + "label": "Per 1000 people" }, "value_kind": "enum_value" } + }, + { + "value": { + "value_kind": "enum_value" + } } ], "truncated": false, "source": "observed" } ], - "rendered_sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 2015 to 2022. Current US dollars · OECD DAC1.", + "rendered_sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators.", "sentence_plan": [ { "kind": "slot", - "text": "Primary income", - "axis": "what", + "text": "Kenya", + "axis": "where", "segment": "heading", + "binding_ref": "where:", "entity_refs": [], - "states": [], - "distinguishes": true + "states": [ + "where:" + ] }, { "kind": "text", - "text": " for ", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "gross of fixed capital consumption", - "axis": "how", + "text": "deaths rate", + "axis": "what", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ], + "states": [], "distinguishes": true }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "Germany and Kenya", - "axis": "where", + "text": "per capita", + "axis": "unit", "segment": "heading", - "binding_ref": "where:", "entity_refs": [], - "states": [ - "where:" - ] + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", + "entity_refs": [], + "states": [] }, { "kind": "text", @@ -759,14 +691,15 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", "entity_refs": [], "states": [ "when:" - ] + ], + "distinguishes": true }, { "kind": "text", @@ -784,26 +717,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -822,10 +736,6 @@ ], "trace": { "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -833,17 +743,17 @@ ], "resolved_sources": [ { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" } ], "slot_filters": [ @@ -851,18 +761,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -870,12 +775,8 @@ "axis": "where", "label": "place" }, - "binding_kind": "set", + "binding_kind": "value", "refs": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -904,38 +805,13 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] + "removed_stat_vars": [] } }, "confidence": "high", @@ -945,70 +821,161 @@ } }, { - "spec_id": "spec_bef1fcb184525d3bbe7cd6a0316b4a35", + "spec_id": "spec_7923e67e0706d6d9738c78cb374ee8fb", "definition": { "schema_version": 1, - "spec_id": "spec_bef1fcb184525d3bbe7cd6a0316b4a35", + "spec_id": "spec_7923e67e0706d6d9738c78cb374ee8fb", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicActivity", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "PurchasingPowerParity" + "population_type": "MortalityEvent", + "measured_property": "count", + "stat_type": "measuredValue" }, "slots": [ { - "property": "activitySource", + "property": "age", "binding": { - "state": "value", - "ref": "GrossNationalIncome" + "state": "unbound" } - } - ], - "entities": { - "observationAbout": [ - "country/DEU", - "country/KEN" - ] - }, - "requested_window": { - "kind": "range", - "start_year": 2015, - "end_year": 2022 - } - } - }, - "resolved": { - "shape": { - "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity", - "label": "Gross National Income Based on Purchasing Power Parity", - "population_type": { - "ref": "EconomicActivity", - "label": "EconomicActivity" - }, - "measured_property": { - "ref": "amount", - "label": "amount" - }, - "stat_type": { - "ref": "measuredValue", - "label": "measuredValue" + }, + { + "property": "ageGroupClassification", + "binding": { + "state": "unbound" + } + }, + { + "property": "causeOfDeath", + "binding": { + "state": "unbound" + } + }, + { + "property": "ethnicity", + "binding": { + "state": "unbound" + } + }, + { + "property": "gender", + "binding": { + "state": "unbound" + } + }, + { + "property": "incidentType", + "binding": { + "state": "unbound" + } + }, + { + "property": "race", + "binding": { + "state": "unbound" + } + }, + { + "property": "residentStatus", + "binding": { + "state": "unbound" + } + } + ], + "entities": { + "observationAbout": [ + "country/KEN" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2013, + "end_year": 2022 + } + } + }, + "resolved": { + "shape": { + "shape_id": "mortalityevent_count_measuredvalue", + "label": "Number of Deaths", + "population_type": { + "ref": "MortalityEvent", + "label": "MortalityEvent" + }, + "measured_property": { + "ref": "count", + "label": "count" }, - "measurement_qualifier": { - "ref": "PurchasingPowerParity", - "label": "PurchasingPowerParity" + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" + }, + "label": "cause of death" + }, + { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" }, - "label": "activity source" + "label": "resident status" + }, + { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" }, { "axis": "where", @@ -1023,45 +990,125 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "833b9da89613fa6c1775652daac2388f38204c6c9f9929ca113deed9a0d08369", + "member_count": 2978, "refine_supported": true, "data_commons": [ { "id": "base", "label": "Data Commons by Google" } - ], - "upstream": { - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" - } - } + ] }, "slots": [ { "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - }, - "value_kind": "enum_value" - } + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + "binding": { + "kind": "unbound" }, "summable": false }, @@ -1071,23 +1118,14 @@ "label": "place" }, "binding": { - "kind": "set", - "values": [ - { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" }, - { - "ref": { - "ref": "country/KEN", - "label": "Kenya" - }, - "value_kind": "entity" - } - ] + "value_kind": "entity" + } }, "summable": false }, @@ -1101,7 +1139,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 } } @@ -1119,24 +1157,27 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath", + "gender", + "age", + "race", + "incidentType", + "ethnicity", + "residentStatus", + "ageGroupClassification" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 37, "member_count_exact": false, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2018", "end": "2022" } }, "entities": [ - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/KEN", "label": "Kenya", @@ -1147,16 +1188,16 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 16, + "observation_count": 5, "evidence": "facet_metadata", "dimensions": [ { - "label": "countries", - "count": 2 + "label": "sources", + "count": 1 }, { "label": "observations", - "count": 8 + "count": 5 }, { "label": "variables", @@ -1164,16 +1205,16 @@ } ], "window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 } }, "download": { - "rows": 16, + "rows": 5, "rows_exact": true, - "series": 2, + "series": 1, "window": { - "start_year": 2015, + "start_year": 2018, "end_year": 2022 }, "licence": { @@ -1183,22 +1224,17 @@ "facets": { "provenance": { "basis": "fallback", - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census", "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "ref": "dc/s/OpenDataForAfrica", + "label": "Open Data for Africa" }, "data_commons": { "id": "base", "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" - }, - "unit": { - "basis": "fallback", - "ref": "InternationalDollar", - "label": "InternationalDollar" + "documentation": "/api/graph/documentation/dc/base/Kenya_Census" } }, "slot_options": [ @@ -1206,576 +1242,713 @@ "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + "ref": "ICD10/A00-B99", + "label": "A00-B99 (Certain infectious and parasitic diseases)" }, "value_kind": "enum_value" } - } - ], - "truncated": true, - "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ - { - "axis": "provenance", - "options": [ + }, { "value": { "ref": { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators" + "ref": "ICD10/D50-D89", + "label": "D50-D89 (Diseases of the blood and blood-forming organs and certain disorders involving the immune mechanism)" }, - "value_kind": "source" + "value_kind": "enum_value" } - } - ], - "truncated": false, - "source": "observed" - }, - { - "axis": "unit", - "options": [ + }, { "value": { "ref": { - "ref": "InternationalDollar", - "label": "InternationalDollar" + "ref": "ICD10/I00-I99", + "label": "I00-I99 (Diseases of the circulatory system)" }, "value_kind": "enum_value" } - } - ], - "truncated": false, - "source": "observed" - } - ], - "rendered_sentence": "Gross national income based on purchasing power parity in international dollars in Germany and Kenya, 2015 to 2022. World Development Indicators.", - "sentence_plan": [ - { - "kind": "slot", - "text": "Gross national income based on purchasing power parity", - "axis": "what", - "segment": "heading", - "entity_refs": [], - "states": [ - "how:activitySource" - ], - "distinguishes": true - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "in international dollars", - "axis": "unit", - "segment": "heading", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:" - ] - }, - { - "kind": "slot", - "text": "", - "axis": "how", - "segment": "heading", - "property_dcid": "activitySource", - "binding_ref": "how:activitySource", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " in ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "Germany and Kenya", - "axis": "where", - "segment": "heading", - "binding_ref": "where:", - "entity_refs": [], - "states": [ - "where:" - ] - }, - { - "kind": "text", - "text": ", ", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "2015 to 2022", - "axis": "when", - "segment": "heading", - "binding_ref": "when:", - "entity_refs": [], - "states": [ - "when:" - ] - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [] - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [] + }, + { + "value": { + "ref": { + "ref": "ICD10/K00-K92", + "label": "K00-K92 (Diseases of the digestive system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/N00-N98", + "label": "N00-N98 (Diseases of the genitourinary system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/M00-M99", + "label": "M00-M99 (Diseases of the musculoskeletal system and connective tissue)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/G00-G98", + "label": "G00-G98 (Diseases of the nervous system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/J00-J98", + "label": "J00-J98 (Diseases of the respiratory system)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/L00-L98", + "label": "L00-L98 (Diseases of the skin and subcutaneous tissue)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/E00-E88", + "label": "E00-E88 (Endocrine, nutritional and metabolic diseases)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/F01-F99", + "label": "F01-F99 (Mental and behavioural disorders)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/O00-O99", + "label": "O00-O99 (Pregnancy, childbirth and the puerperium)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/U00-U99", + "label": "U00-U99 (Codes for special purposes)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Diabetes", + "label": "Diabetes" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Suicide", + "label": "Suicide" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/V01-Y89", + "label": "V01-Y89 (External causes of morbidity and mortality)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/C00-D48", + "label": "C00-D48 (Neoplasms)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/P00-P96", + "label": "P00-P96 (Certain conditions originating in the perinatal period)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "ICD10/Q00-Q99", + "label": "Q00-Q99 (Congenital malformations, deformations and chromosomal abnormalities)" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CerebrovascularDiseases", + "label": "CerebrovascularDiseases" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CongenitalAnomalies", + "label": "CongenitalAnomalies" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "CongenitalHeartAnomalies", + "label": "CongenitalHeartAnomalies" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "GenitourinaryDiseases", + "label": "GenitourinaryDiseases" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "HypertensiveHeartDisease", + "label": "HypertensiveHeartDisease" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "MalignantNeoplasms", + "label": "MalignantNeoplasms" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Neoplasms", + "label": "Neoplasms" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "PerinatalInfection", + "label": "Perinatal Infection" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Pneumonia", + "label": "Pneumonia" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SGP_OtherDiseasesAndCauses", + "label": "SGP_OtherDiseasesAndCauses" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "TransportAccidents", + "label": "TransportAccidents" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Tuberculosis", + "label": "Tuberculosis" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": true, + "source": "observed" }, { - "kind": "slot", - "text": "World Development Indicators", - "axis": "source", - "segment": "byline", - "entity_refs": [], - "states": [ - "source:" + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "options": [ + { + "value": { + "ref": { + "ref": "Female", + "label": "Female" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Male", + "label": "Male" + }, + "value_kind": "enum_value" + } + } ], - "distinguishes": true + "truncated": true, + "source": "observed" }, { - "kind": "text", - "text": ".", - "segment": "byline", - "entity_refs": [], - "states": [] - } - ], - "trace": { - "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" }, - { - "ref": "country/KEN", - "label": "Kenya" - } - ], - "resolved_sources": [ - { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "options": [ + { + "value": { + "ref": { + "ref": "Years0To1", + "label": "Years 0 To 1" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Day0To27", + "label": "Day 0 To 27" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years10To14", + "label": "Years 10 To 14" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years15To19", + "label": "Years 15 To 19" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years15To24", + "label": "Years 15 To 24" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years1To4", + "label": "Years 1 To 4" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years20To24", + "label": "Years 20 To 24" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years25To29", + "label": "Years 25 To 29" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years25To34", + "label": "Years 25 To 34" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years30To34", + "label": "Years 30 To 34" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years35To39", + "label": "Years 35 To 39" + }, + "value_kind": "enum_value" + } }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" + { + "value": { + "ref": { + "ref": "Years35To44", + "label": "Years 35 To 44" + }, + "value_kind": "enum_value" + } }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" - } - ], - "slot_filters": [ - { - "key": { - "axis": "how", - "property": { - "ref": "activitySource", - "label": "activitySource" - }, - "label": "activity source" + { + "value": { + "ref": { + "ref": "Years40To44", + "label": "Years 40 To 44" + }, + "value_kind": "enum_value" + } }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + { + "value": { + "ref": { + "ref": "Years45To49", + "label": "Years 45 To 49" + }, + "value_kind": "enum_value" } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "where", - "label": "place" }, - "binding_kind": "set", - "refs": [ - { - "ref": "country/DEU", - "label": "Germany" - }, - { - "ref": "country/KEN", - "label": "Kenya" + { + "value": { + "ref": { + "ref": "Years45To54", + "label": "Years 45 To 54" + }, + "value_kind": "enum_value" } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "when", - "label": "time window" }, - "binding_kind": "value", - "refs": [], - "provenance": "binder" - }, - { - "key": { - "axis": "source", - "label": "data source" + { + "value": { + "ref": { + "ref": "Years50To54", + "label": "Years 50 To 54" + }, + "value_kind": "enum_value" + } }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - } - ], - "query_qualifiers": [], - "requested_window": { - "start_year": 2015, - "end_year": 2022 - }, - "capability_version": "cap_347a470e04c97eec", - "default_reading": { - "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] - } - }, - "confidence": "high", - "basis": "nominated", - "available_at_place": true, - "measure_label_axes": [], - "measure_axis_values": [] - } - }, - { - "spec_id": "spec_b77d2ebaaeb7e6d5f8499a8b0e3571a1", - "definition": { - "schema_version": 1, - "spec_id": "spec_b77d2ebaaeb7e6d5f8499a8b0e3571a1", - "identity": { - "identity_version": "spec1", - "shape": { - "kind": "statvar_schema", - "population_type": "EconomicActivity", - "measured_property": "amount", - "stat_type": "measuredValue", - "measurement_qualifier": "PurchasingPowerParity", - "measurement_denominator": { - "unresolved": true - } - }, - "slots": [ - { - "property": "activitySource", - "binding": { - "state": "value", - "ref": "GrossNationalIncome" + { + "value": { + "ref": { + "ref": "Years55To59", + "label": "Years 55 To 59" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years55To64", + "label": "Years 55 To 64" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years5To9", + "label": "Years 5 To 9" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years60To64", + "label": "Years 60 To 64" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years65To69", + "label": "Years 65 To 69" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years65To74", + "label": "Years 65 To 74" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years70To74", + "label": "Years 70 To 74" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years75To79", + "label": "Years 75 To 79" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years75To84", + "label": "Years 75 To 84" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years80To84", + "label": "Years 80 To 84" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "USC_AgeNotStated", + "label": "USC_AgeNotStated" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Years0To4", + "label": "Years 0 To 4" + }, + "value_kind": "enum_value" + } } - } - ], - "entities": { - "observationAbout": [ - "country/DEU", - "country/KEN" - ] - }, - "requested_window": { - "kind": "range", - "start_year": 2015, - "end_year": 2022 - } - } - }, - "resolved": { - "shape": { - "shape_id": "economicactivity_amount_measuredvalue_purchasingpowerparity_per_unresolved", - "label": "Gross National Income Based on Purchasing Power Parity Per Capita", - "population_type": { - "ref": "EconomicActivity", - "label": "EconomicActivity" - }, - "measured_property": { - "ref": "amount", - "label": "amount" - }, - "stat_type": { - "ref": "measuredValue", - "label": "measuredValue" - }, - "measurement_qualifier": { - "ref": "PurchasingPowerParity", - "label": "PurchasingPowerParity" - }, - "measurement_denominator": { - "ref": "PerCapita", - "label": "PerCapita" + ], + "truncated": true, + "source": "observed" }, - "measurement_denominator_unresolved": true, - "slot_keys": [ - { - "axis": "how", - "property": { - "ref": "activitySource", - "label": "activitySource" - }, - "label": "activity source" - }, - { - "axis": "where", - "label": "place" - }, - { - "axis": "when", - "label": "time window" - }, - { - "axis": "source", - "label": "data source" - } - ], - "member_count": 1, - "member_digest": "7b2d5b0fc09cfc0215c8d7c6c21a5195fa21e79f2a148a6bca9ce6c3af8bbb9f", - "refine_supported": true, - "data_commons": [ - { - "id": "base", - "label": "Data Commons by Google" - } - ], - "upstream": { - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" - } - } - }, - "slots": [ { "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "race", + "label": "race" }, - "label": "activity source" + "label": "race" }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - }, - "value_kind": "enum_value" + "options": [ + { + "value": { + "ref": { + "ref": "CDC_AmericanIndianAndAlaskaNativeAlone", + "label": "American Indian and Alaska native alone" + }, + "value_kind": "enum_value" + } } - }, - "summable": false + ], + "truncated": true, + "source": "observed" }, { "key": { - "axis": "where", - "label": "place" + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" }, - "binding": { - "kind": "set", - "values": [ - { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" - }, - { + "options": [ + { + "value": { "ref": { - "ref": "country/KEN", - "label": "Kenya" + "ref": "COVID_19", + "label": "COVID-19" }, - "value_kind": "entity" + "value_kind": "enum_value" } - ] - }, - "summable": false + } + ], + "truncated": true, + "source": "observed" }, { "key": { - "axis": "when", - "label": "time window" + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" }, - "binding": { - "kind": "value", - "value": { - "value_kind": "time_window", - "time_window": { - "start_year": 2015, - "end_year": 2022 + "options": [ + { + "value": { + "ref": { + "ref": "Chinese", + "label": "Chinese" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Indian", + "label": "Indian" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Malay", + "label": "Malay" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "SGP_OtherEthnicity", + "label": "SGP_OtherEthnicity" + }, + "value_kind": "enum_value" } } - }, - "summable": false - }, - { - "key": { - "axis": "source", - "label": "data source" - }, - "binding": { - "kind": "unbound" - }, - "summable": false - } - ], - "inapplicable_slots": [], - "unresolved_slots": [], - "stat_vars": { - "member_count": 1, - "member_count_exact": false, - "served_count": 1, - "data_date_range": { - "start": "2015", - "end": "2022" - } - }, - "entities": [ - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - }, - { - "ref": "country/KEN", - "label": "Kenya", - "entity_type": "Country", - "role": "observationAbout" - } - ], - "coverage": { - "kind": "exact", - "has_data": true, - "observation_count": 16, - "evidence": "facet_metadata", - "dimensions": [ - { - "label": "countries", - "count": 2 - }, - { - "label": "observations", - "count": 8 - }, - { - "label": "variables", - "count": 1 - } - ], - "window": { - "start_year": 2015, - "end_year": 2022 - } - }, - "download": { - "rows": 16, - "rows_exact": true, - "series": 2, - "window": { - "start_year": 2015, - "end_year": 2022 - }, - "licence": { - "label": "Creative Commons Attribution License" - } - }, - "facets": { - "provenance": { - "basis": "fallback", - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", - "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" - }, - "data_commons": { - "id": "base", - "label": "Data Commons by Google" - }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + ], + "truncated": true, + "source": "observed" }, - "unit": { - "basis": "fallback", - "ref": "InternationalDollar", - "label": "InternationalDollar" - } - }, - "slot_options": [ { "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "residentStatus", + "label": "residentStatus" }, - "label": "activity source" + "label": "resident status" }, "options": [ { "value": { "ref": { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" + "ref": "Citizen", + "label": "Citizen" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Resident", + "label": "Resident" }, "value_kind": "enum_value" } @@ -1783,36 +1956,52 @@ ], "truncated": true, "source": "observed" - } - ], - "entity_options": [], - "facet_options": [ + }, { - "axis": "provenance", + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, "options": [ { "value": { "ref": { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators" + "ref": "Infant", + "label": "Infant" }, - "value_kind": "source" + "value_kind": "enum_value" + } + }, + { + "value": { + "ref": { + "ref": "Newborn", + "label": "Newborn" + }, + "value_kind": "enum_value" } } ], - "truncated": false, + "truncated": true, "source": "observed" - }, + } + ], + "entity_options": [], + "facet_options": [ { - "axis": "unit", + "axis": "provenance", "options": [ { "value": { "ref": { - "ref": "InternationalDollar", - "label": "InternationalDollar" + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, - "value_kind": "enum_value" + "value_kind": "source" } } ], @@ -1820,18 +2009,25 @@ "source": "observed" } ], - "rendered_sentence": "Gross national income based on purchasing power parity per capita in international dollars in Germany and Kenya, 2015 to 2022. World Development Indicators.", + "rendered_sentence": "Kenya's number of deaths, 2018 to 2022. Kenya Census.", "sentence_plan": [ { "kind": "slot", - "text": "Gross national income based on purchasing power parity per capita", - "axis": "what", + "text": "Kenya", + "axis": "where", "segment": "heading", + "binding_ref": "where:", "entity_refs": [], "states": [ - "how:activitySource" - ], - "distinguishes": true + "where:" + ] + }, + { + "kind": "text", + "text": "'s", + "segment": "heading", + "entity_refs": [], + "states": [] }, { "kind": "text", @@ -1842,42 +2038,92 @@ }, { "kind": "slot", - "text": "in international dollars", - "axis": "unit", + "text": "number of deaths", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "distinguishes": true + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "age", + "binding_ref": "how:age", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "ageGroupClassification", + "binding_ref": "how:ageGroupClassification", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "ethnicity", + "binding_ref": "how:ethnicity", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", "segment": "heading", - "binding_ref": "unit:", + "property_dcid": "gender", + "binding_ref": "how:gender", "entity_refs": [], - "states": [ - "unit:" - ] + "states": [] }, { "kind": "slot", "text": "", "axis": "how", "segment": "heading", - "property_dcid": "activitySource", - "binding_ref": "how:activitySource", + "property_dcid": "incidentType", + "binding_ref": "how:incidentType", "entity_refs": [], "states": [] }, { - "kind": "text", - "text": " in ", + "kind": "slot", + "text": "", + "axis": "how", "segment": "heading", + "property_dcid": "race", + "binding_ref": "how:race", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "Germany and Kenya", - "axis": "where", + "text": "", + "axis": "how", "segment": "heading", - "binding_ref": "where:", + "property_dcid": "residentStatus", + "binding_ref": "how:residentStatus", "entity_refs": [], - "states": [ - "where:" - ] + "states": [] }, { "kind": "text", @@ -1888,14 +2134,15 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2018 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", "entity_refs": [], "states": [ "when:" - ] + ], + "distinguishes": true }, { "kind": "text", @@ -1913,7 +2160,7 @@ }, { "kind": "slot", - "text": "World Development Indicators", + "text": "Kenya Census", "axis": "source", "segment": "byline", "entity_refs": [], @@ -1932,10 +2179,6 @@ ], "trace": { "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -1943,17 +2186,17 @@ ], "resolved_sources": [ { - "ref": "dc/base/WorldDevelopmentIndicators", - "label": "World Development Indicators", + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census", "source": { - "ref": "dc/s/WorldBank", - "label": "World Bank" + "ref": "dc/s/OpenDataForAfrica", + "label": "Open Data for Africa" }, "data_commons": { "id": "base", "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + "documentation": "/api/graph/documentation/dc/base/Kenya_Census" } ], "slot_filters": [ @@ -1961,18 +2204,104 @@ "key": { "axis": "how", "property": { - "ref": "activitySource", - "label": "activitySource" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "activity source" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossNationalIncome", - "label": "GrossNationalIncome" - } - ], + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "gender", + "label": "gender" + }, + "label": "gender" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "age", + "label": "age" + }, + "label": "age" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "race", + "label": "race" + }, + "label": "race" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "incidentType", + "label": "incidentType" + }, + "label": "incident type" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ethnicity", + "label": "ethnicity" + }, + "label": "ethnicity" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "residentStatus", + "label": "residentStatus" + }, + "label": "resident status" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "ageGroupClassification", + "label": "ageGroupClassification" + }, + "label": "age group classification" + }, + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -1980,12 +2309,8 @@ "axis": "where", "label": "place" }, - "binding_kind": "set", + "binding_kind": "value", "refs": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -2014,42 +2339,17 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, - "removed_stat_vars": [ - "Amount_EconomicActivity_GrossDomesticProduction_NAICSAgricultureForestryFishingHunting_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSArtsEntertainmentRecreation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSConstruction_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSEducationalServices_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSHealthCareSocialAssistance_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSInformation_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSManagementOfCompaniesEnterprises_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSRealEstateRentalLeasing_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_NAICSUtilities_RealValue", - "Amount_EconomicActivity_GrossDomesticProduction_RealValue", - "InflationAdjustedGDP", - "RealValue_Amount_EconomicActivity_GrossValueAdded_AgricultureForestryFishingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ConstructionSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ElectricityGasSteamAirConditionSupply", - "RealValue_Amount_EconomicActivity_GrossValueAdded_FinanceService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_ManufacturingSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_MiningQuarrying", - "RealValue_Amount_EconomicActivity_GrossValueAdded_PublicAdministrationAndDefenceOrMOSPIOtherService", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSector", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TradeSectorOrTransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_Amount_EconomicActivity_GrossValueAdded_TransportStorageSectorOrPublishingBroadcastingInformationActivities", - "RealValue_GrowthRate_Amount_EconomicActivity_GrossDomesticProduction", - "dc/qt7ewllmt3826" - ] + "removed_stat_vars": [] } }, - "confidence": "high", - "basis": "nominated", + "confidence": "low", + "basis": "structural", "available_at_place": true, "measure_label_axes": [], "measure_axis_values": [] @@ -2059,255 +2359,88 @@ "truncated": false }, "reading_assumptions": { - "spec_9ce16f72ff8416d06a56f9fe82b10ad3": [], - "spec_bef1fcb184525d3bbe7cd6a0316b4a35": [], - "spec_b77d2ebaaeb7e6d5f8499a8b0e3571a1": [] + "spec_10bf62f9687154286b463d206f03a086": [], + "spec_7923e67e0706d6d9738c78cb374ee8fb": [] } }, { - "variable_text": "debt", - "warnings": [ - { - "code": "retrieval_score_weak", - "severity": "info", - "message": "the chosen reading's match to the query is weak; treat it with less confidence than a strong match." - } - ], + "variable_text": "savings", + "warnings": [], "timing_ms": { - "total": 2495, + "total": 356, "by_step": { - "recall": 0, + "recall": 1, + "phase_resolve_places": 0, + "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe_coverage": 51, - "shape_probe": 245, + "shape_probe": 110, "shape_groups": 3, - "shape_labels": 0, + "shape_labels": 1, "shape_admission": 0, - "shape": 912, - "bind": 1583 + "phase_derive_shapes": 0, + "shape": 264, + "phase_prune_and_rank": 0, + "bind": 88, + "phase_bind": 3 } }, - "rendered_sentence": "Could not tell who is giving and who is receiving among \"Germany\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "rendered_sentence": "Could not match \"savings\" to a supported indicator. Try a different wording or a related indicator.", "sentence_plan": [ { - "kind": "text", - "text": "Could not tell who is giving and who is receiving among \"Germany\" and \"Kenya\". Put \"from\" or \"to\" before a name.", - "segment": "heading", - "entity_refs": [], - "states": [] - } - ], - "operations": [], - "departures": [], - "assumptions": [], - "status": "no_data", - "no_data": { - "reason": "role_not_resolved", - "category": "unresolved", - "message": "Could not tell who is giving and who is receiving among \"Germany\" and \"Kenya\". Put \"from\" or \"to\" before a name.", - "entity_terms": [ - "Germany", - "Kenya" - ], - "ambiguous_entities": [], - "source_terms": [], - "ambiguous_sources": [], - "unbound_qualifiers": [], - "options": [ - { - "mentions": [ - "Germany", - "Kenya" - ], - "label": "Germany to Kenya", - "data_query": { - "kind": "parsed", - "parts": [ - { - "variable_text": "debt", - "entities": [ - { - "text": "Germany", - "role_text": "from" - }, - { - "text": "Kenya", - "role_text": "to" - } - ], - "time_text": "2015 to 2022", - "sources": [], - "operations": [] - } - ] - } - }, - { - "mentions": [ - "Germany", - "Kenya" - ], - "label": "Kenya to Germany", - "data_query": { - "kind": "parsed", - "parts": [ - { - "variable_text": "debt", - "entities": [ - { - "text": "Germany", - "role_text": "to" - }, - { - "text": "Kenya", - "role_text": "from" - } - ], - "time_text": "2015 to 2022", - "sources": [], - "operations": [] - } - ] - } - } - ] - } - } - ], - "rendered_sentence": "GNI has 3 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022. Could not tell who is giving and who is receiving among \"Germany\" and \"Kenya\". Put \"from\" or \"to\" before a name.", - "sentence_plan": [ - { - "kind": "slot", - "text": "GNI", - "axis": "what", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " has 3 readings.", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "Primary income", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " for ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "gross of fixed capital consumption", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " in ", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "Germany and Kenya", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": ".", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "OECD DAC1", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "2015 to 2022", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, + "kind": "text", + "text": "Could not match \"savings\" to a supported indicator. Try a different wording or a related indicator.", + "segment": "heading", + "entity_refs": [], + "states": [] + } + ], + "operations": [], + "departures": [], + "assumptions": [], + "status": "no_data", + "no_data": { + "reason": "variable_not_resolved", + "category": "unresolved", + "message": "Could not match \"savings\" to a supported indicator. Try a different wording or a related indicator.", + "entity_terms": [], + "ambiguous_entities": [], + "source_terms": [], + "ambiguous_sources": [], + "unbound_qualifiers": [], + "options": [] + } + } + ], + "rendered_sentence": "Mortality has 2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022. No match for savings. Try a different wording or a related indicator.", + "sentence_plan": [ { - "kind": "text", - "text": " · ", - "segment": "byline", + "kind": "slot", + "text": "Mortality", + "axis": "what", + "segment": "heading", "entity_refs": [], "states": [], "part_index": 0 }, { "kind": "text", - "text": "Current US dollars", - "segment": "byline", + "text": " has 2 readings.", + "segment": "heading", "entity_refs": [], "states": [], "part_index": 0 }, { "kind": "text", - "text": ".", - "segment": "byline", + "text": " ", + "segment": "heading", "entity_refs": [], "states": [], "part_index": 0 }, { "kind": "text", - "text": " ", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [], @@ -2315,7 +2448,7 @@ }, { "kind": "text", - "text": "Gross national income based on purchasing power parity", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [], @@ -2331,7 +2464,7 @@ }, { "kind": "text", - "text": "in international dollars", + "text": "deaths rate", "segment": "heading", "entity_refs": [], "states": [], @@ -2339,7 +2472,7 @@ }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [], @@ -2347,7 +2480,7 @@ }, { "kind": "text", - "text": "Germany and Kenya", + "text": "per capita", "segment": "heading", "entity_refs": [], "states": [], @@ -2387,7 +2520,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2013 to 2022", "segment": "byline", "entity_refs": [], "states": [], @@ -2411,15 +2544,7 @@ }, { "kind": "text", - "text": "Gross national income based on purchasing power parity per capita", - "segment": "heading", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": " ", + "text": "Kenya", "segment": "heading", "entity_refs": [], "states": [], @@ -2427,7 +2552,7 @@ }, { "kind": "text", - "text": "in international dollars", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [], @@ -2435,7 +2560,7 @@ }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [], @@ -2443,7 +2568,7 @@ }, { "kind": "text", - "text": "Germany and Kenya", + "text": "number of deaths", "segment": "heading", "entity_refs": [], "states": [], @@ -2467,7 +2592,7 @@ }, { "kind": "text", - "text": "World Development Indicators", + "text": "Kenya Census", "segment": "byline", "entity_refs": [], "states": [], @@ -2483,7 +2608,7 @@ }, { "kind": "text", - "text": "2015 to 2022", + "text": "2018 to 2022", "segment": "byline", "entity_refs": [], "states": [], @@ -2506,7 +2631,24 @@ }, { "kind": "text", - "text": "Could not tell who is giving and who is receiving among \"Germany\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "text": "No match for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "slot", + "text": "savings", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 1 + }, + { + "kind": "text", + "text": ". Try a different wording or a related indicator.", "segment": "heading", "entity_refs": [], "states": [], @@ -2532,40 +2674,40 @@ "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU", "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, "assumptions": [], - "variable_text": "GNI" + "variable_text": "mortality" }, { "entry_kind": "placeholder", "status": "no_data", - "reason": "role_not_resolved", - "variable_text": "debt" + "reason": "variable_not_resolved", + "variable_text": "savings" } ] } @@ -2575,7 +2717,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "92d259a7691d424b9ec4d329f99e63fa" + "x-dfo-trace-id": "f61373c01c6c48ac82fb99f413a0f978" }, "json": { "schema_version": 1, @@ -2584,11 +2726,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "92d259a7691d424b9ec4d329f99e63fa", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "f61373c01c6c48ac82fb99f413a0f978", "warnings": [], "timing_ms": { - "total": 3, + "total": 380, "by_step": { "coverage": 0 } @@ -2598,99 +2740,93 @@ "kind": "resolution", "parts": [ { - "variable_text": "GNI", + "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 1, + "total": 323, "by_step": { "validate": 0, - "walk": 1, + "walk": 0, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 0, + "shape": 204, "bind": 0, "where_places": 0, - "materialise": 0, - "answer": 0, + "materialise": 117, + "answer": 2, "options": 0 } }, "operations": [], - "departures": [ - { - "code": "entity_unavailable", - "binding_ref": "where:", - "text": "You asked for Kenya. The data holds no values for it." - } - ], + "departures": [], "assumptions": [], "status": "definite", "spec": { - "spec_id": "spec_9ce16f72ff8416d06a56f9fe82b10ad3", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "definition": { "schema_version": 1, - "spec_id": "spec_9ce16f72ff8416d06a56f9fe82b10ad3", + "spec_id": "spec_10bf62f9687154286b463d206f03a086", "identity": { "identity_version": "spec1", "shape": { "kind": "statvar_schema", - "population_type": "EconomicUnit", - "measured_property": "primaryIncome", + "population_type": "MortalityEvent", + "measured_property": "count", "stat_type": "measuredValue", - "measurement_qualifier": "Nominal" + "measurement_denominator": { + "ref": "Count_Person" + } }, "slots": [ { - "property": "fixedCapitalConsumptionBasis", + "property": "causeOfDeath", "binding": { - "state": "value", - "ref": "GrossOfFixedCapitalConsumption" + "state": "unbound" } } ], "entities": { "observationAbout": [ - "country/DEU", "country/KEN" ] }, "requested_window": { "kind": "range", - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } }, "resolved": { "shape": { - "shape_id": "economicunit_primaryincome_measuredvalue_nominal", - "label": "Gross national income", + "shape_id": "mortalityevent_count_measuredvalue_per_count_person", + "label": "Deaths Rate", "population_type": { - "ref": "EconomicUnit", - "label": "economic unit" + "ref": "MortalityEvent", + "label": "MortalityEvent" }, "measured_property": { - "ref": "primaryIncome", - "label": "primary income" + "ref": "count", + "label": "count" }, "stat_type": { "ref": "measuredValue", "label": "measuredValue" }, - "measurement_qualifier": { - "ref": "Nominal", - "label": "Nominal" + "measurement_denominator": { + "ref": "Count_Person", + "label": "Total population" }, "measurement_denominator_unresolved": false, "slot_keys": [ { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, { "axis": "where", @@ -2705,13 +2841,13 @@ "label": "data source" } ], - "member_count": 1, - "member_digest": "e118bc2c1c5ac817a6d4a269c5276b7d2c74f3033dde9cad5925de58239c55b4", - "refine_supported": true, + "member_count": 133, + "member_digest": "c090b56d31a596a8be16dafb518382db666c6b100a80534c3cb81dbfe3111c5d", + "refine_supported": false, "data_commons": [ { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" } ] }, @@ -2720,20 +2856,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - }, - "value_kind": "enum_value" - } + "kind": "unbound" }, "summable": false }, @@ -2743,23 +2872,14 @@ "label": "place" }, "binding": { - "kind": "set", - "values": [ - { - "ref": { - "ref": "country/DEU", - "label": "Germany" - }, - "value_kind": "entity" + "kind": "value", + "value": { + "ref": { + "ref": "country/KEN", + "label": "Kenya" }, - { - "ref": { - "ref": "country/KEN", - "label": "Kenya" - }, - "value_kind": "entity" - } - ] + "value_kind": "entity" + } }, "summable": false }, @@ -2773,7 +2893,7 @@ "value": { "value_kind": "time_window", "time_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } } @@ -2791,24 +2911,20 @@ "summable": false } ], - "inapplicable_slots": [], + "inapplicable_slots": [ + "causeOfDeath" + ], "unresolved_slots": [], "stat_vars": { - "member_count": 1, + "member_count": 2, "member_count_exact": true, "served_count": 1, "data_date_range": { - "start": "2015", + "start": "2013", "end": "2022" } }, "entities": [ - { - "ref": "country/DEU", - "label": "Germany", - "entity_type": "Country", - "role": "observationAbout" - }, { "ref": "country/KEN", "label": "Kenya", @@ -2819,16 +2935,16 @@ "coverage": { "kind": "exact", "has_data": true, - "observation_count": 8, + "observation_count": 10, "evidence": "facet_metadata", "dimensions": [ { - "label": "countries", + "label": "sources", "count": 1 }, { "label": "observations", - "count": 8 + "count": 10 }, { "label": "variables", @@ -2836,43 +2952,46 @@ } ], "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 } }, "download": { - "rows": 8, + "rows": 10, "rows_exact": true, "series": 1, "window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, "licence": { - "label": "OECD Terms and Conditions" + "label": "Creative Commons Attribution License" } }, "facets": { "provenance": { "basis": "fallback", - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1", - "account": "provider" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" + }, + "measurementMethod": { + "basis": "fallback", + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" }, "unit": { "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" + "ref": "Per1000Persons", + "label": "Per 1000 people" } }, "slot_options": [ @@ -2880,17 +2999,17 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, "options": [ { "value": { "ref": { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" + "ref": "ICD10/X60-X84", + "label": "X60-X84 (Intentional self-harm)" }, "value_kind": "enum_value" } @@ -2908,8 +3027,8 @@ { "value": { "ref": { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1" + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators" }, "value_kind": "source" } @@ -2917,8 +3036,8 @@ { "value": { "ref": { - "ref": "provenance/WorldBankInternationalDebtStatistics", - "label": "World Bank International Debt Statistics (IDS)" + "ref": "dc/base/Kenya_Census", + "label": "Kenya Census" }, "value_kind": "source" } @@ -2927,69 +3046,108 @@ "truncated": false, "source": "observed" }, + { + "axis": "measurementMethod", + "options": [ + { + "value": { + "ref": { + "ref": "WorldBankWeightedAverage", + "label": "World Bank Weighted Average" + }, + "value_kind": "enum_value" + } + }, + { + "value": { + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + }, { "axis": "unit", "options": [ { "value": { "ref": { - "ref": "CurrencyUSD", - "label": "US Dollar" + "ref": "Per1000Persons", + "label": "Per 1000 people" }, "value_kind": "enum_value" } + }, + { + "value": { + "value_kind": "enum_value" + } } ], "truncated": false, "source": "observed" } ], - "rendered_sentence": "Primary income for gross of fixed capital consumption in Germany and Kenya, 2015 to 2022. Current US dollars · OECD DAC1.", + "rendered_sentence": "Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators.", "sentence_plan": [ { "kind": "slot", - "text": "Primary income", - "axis": "what", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "text", - "text": " for ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "gross of fixed capital consumption", - "axis": "how", + "text": "deaths rate", + "axis": "what", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ] + "states": [] }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [] }, { "kind": "slot", - "text": "Germany and Kenya", - "axis": "where", + "text": "per capita", + "axis": "unit", "segment": "heading", - "binding_ref": "where:", "entity_refs": [], - "states": [ - "where:" - ] + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", + "entity_refs": [], + "states": [] }, { "kind": "text", @@ -3000,7 +3158,7 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -3025,26 +3183,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ] - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [] - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -3062,10 +3201,6 @@ ], "trace": { "resolved_entities": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -3073,17 +3208,17 @@ ], "resolved_sources": [ { - "ref": "provenance/OECDDAC1", - "label": "OECD DAC1", + "ref": "dc/base/WorldDevelopmentIndicators", + "label": "World Development Indicators", "source": { - "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", - "label": "Organisation for Economic Co-operation and Development (OECD)" + "ref": "dc/s/WorldBank", + "label": "World Bank" }, "data_commons": { - "id": "dfo", - "label": "Development Finance Observatory" + "id": "base", + "label": "Data Commons by Google" }, - "documentation": "/api/graph/documentation/provenance/OECDDAC1" + "documentation": "/api/graph/documentation/dc/base/WorldDevelopmentIndicators" } ], "slot_filters": [ @@ -3091,18 +3226,13 @@ "key": { "axis": "how", "property": { - "ref": "fixedCapitalConsumptionBasis", - "label": "fixed capital consumption basis" + "ref": "causeOfDeath", + "label": "causeOfDeath" }, - "label": "fixed capital consumption basis" + "label": "cause of death" }, - "binding_kind": "value", - "refs": [ - { - "ref": "GrossOfFixedCapitalConsumption", - "label": "gross of fixed capital consumption" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" }, { @@ -3110,12 +3240,8 @@ "axis": "where", "label": "place" }, - "binding_kind": "set", + "binding_kind": "value", "refs": [ - { - "ref": "country/DEU", - "label": "Germany" - }, { "ref": "country/KEN", "label": "Kenya" @@ -3144,36 +3270,71 @@ ], "query_qualifiers": [], "requested_window": { - "start_year": 2015, + "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec" + "capability_version": "cap_94e25737d859392c" }, "confidence": "high", "available_at_place": true, "measure_label_axes": [], "measure_axis_values": [], - "related_measures": [] + "related_group": { + "ref": "dc/g/MortalityEvent", + "label": "Mortality Event" + }, + "related_measures": [ + { + "stat_var": { + "ref": "Count_Death", + "label": "Number of Deaths" + }, + "definition": { + "schema_version": 1, + "spec_id": "spec_31961a9c9519bb4db004fa793f0457e5", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "MortalityEvent", + "measured_property": "count", + "stat_type": "measuredValue" + }, + "slots": [], + "entities": { + "observationAbout": [ + "country/KEN" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2013, + "end_year": 2022 + } + } + } + } + ] } } }, { - "variable_text": "debt", + "variable_text": "savings", "warnings": [ { "code": "part_restated", "severity": "info", - "message": "'debt' was restated from a posted no_data outcome; not re-resolved." + "message": "'savings' was restated from a posted no_data outcome; not re-resolved." } ], "timing_ms": { "total": 0 }, - "rendered_sentence": "Could not tell who is giving and who is receiving in this query. Put \"from\" or \"to\" before a name.", + "rendered_sentence": "Could not match \"savings\" to a supported indicator. Try a different wording or a related indicator.", "sentence_plan": [ { "kind": "text", - "text": "Could not tell who is giving and who is receiving in this query. Put \"from\" or \"to\" before a name.", + "text": "Could not match \"savings\" to a supported indicator. Try a different wording or a related indicator.", "segment": "heading", "entity_refs": [], "states": [] @@ -3184,9 +3345,9 @@ "assumptions": [], "status": "no_data", "no_data": { - "reason": "role_not_resolved", + "reason": "variable_not_resolved", "category": "unresolved", - "message": "Could not tell who is giving and who is receiving in this query. Put \"from\" or \"to\" before a name.", + "message": "Could not match \"savings\" to a supported indicator. Try a different wording or a related indicator.", "entity_terms": [], "ambiguous_entities": [], "source_terms": [], @@ -3196,7 +3357,7 @@ } } ], - "rendered_sentence": "Answered 1 of 2 parts. Primary income for gross of fixed capital consumption in Germany and Kenya, 2015 to 2022. Current US dollars · OECD DAC1. You asked for Kenya. The data holds no values for it. Could not tell who is giving and who is receiving in this query. Put \"from\" or \"to\" before a name.", + "rendered_sentence": "Answered 1 of 2 parts. Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators. No match for savings. Try a different wording or a related indicator.", "sentence_plan": [ { "kind": "text", @@ -3214,8 +3375,19 @@ }, { "kind": "slot", - "text": "Primary income", - "axis": "what", + "text": "Kenya", + "axis": "where", + "segment": "heading", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": "'s", "segment": "heading", "entity_refs": [], "states": [], @@ -3223,7 +3395,7 @@ }, { "kind": "text", - "text": " for ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [], @@ -3231,20 +3403,16 @@ }, { "kind": "slot", - "text": "gross of fixed capital consumption", - "axis": "how", + "text": "deaths rate", + "axis": "what", "segment": "heading", - "property_dcid": "fixedCapitalConsumptionBasis", - "binding_ref": "how:fixedCapitalConsumptionBasis", "entity_refs": [], - "states": [ - "how:fixedCapitalConsumptionBasis" - ], + "states": [], "part_index": 0 }, { "kind": "text", - "text": " in ", + "text": " ", "segment": "heading", "entity_refs": [], "states": [], @@ -3252,14 +3420,22 @@ }, { "kind": "slot", - "text": "Germany and Kenya", - "axis": "where", + "text": "per capita", + "axis": "unit", "segment": "heading", - "binding_ref": "where:", "entity_refs": [], - "states": [ - "where:" - ], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "causeOfDeath", + "binding_ref": "how:causeOfDeath", + "entity_refs": [], + "states": [], "part_index": 0 }, { @@ -3272,7 +3448,7 @@ }, { "kind": "slot", - "text": "2015 to 2022", + "text": "2013 to 2022", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -3300,28 +3476,7 @@ }, { "kind": "slot", - "text": "Current US dollars", - "axis": "unit", - "segment": "byline", - "binding_ref": "unit:", - "entity_refs": [], - "states": [ - "unit:", - "axis:measurementQualifier" - ], - "part_index": 0 - }, - { - "kind": "text", - "text": " · ", - "segment": "byline", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "slot", - "text": "OECD DAC1", + "text": "World Development Indicators", "axis": "source", "segment": "byline", "entity_refs": [], @@ -3341,29 +3496,30 @@ { "kind": "text", "text": " ", - "segment": "departure", + "segment": "heading", "entity_refs": [], - "states": [], - "part_index": 0 + "states": [] }, { "kind": "text", - "text": "You asked for Kenya. The data holds no values for it.", - "segment": "departure", + "text": "No match for ", + "segment": "heading", "entity_refs": [], "states": [], - "part_index": 0 + "part_index": 1 }, { - "kind": "text", - "text": " ", + "kind": "slot", + "text": "savings", + "axis": "what", "segment": "heading", "entity_refs": [], - "states": [] + "states": [], + "part_index": 1 }, { "kind": "text", - "text": "Could not tell who is giving and who is receiving in this query. Put \"from\" or \"to\" before a name.", + "text": ". Try a different wording or a related indicator.", "segment": "heading", "entity_refs": [], "states": [], @@ -3380,19 +3536,19 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "GNI has 3 readings. Primary income for gross of fixed capital consumption in Germany and Kenya. OECD DAC1 · 2015 to 2022 · Current US dollars. Gross national income based on purchasing power parity in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022. Gross national income based on purchasing power parity per capita in international dollars in Germany and Kenya. World Development Indicators · 2015 to 2022. Could not tell who is giving and who is receiving among \"Germany\" and \"Kenya\". Put \"from\" or \"to\" before a name.", + "sentence": "Mortality has 2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022. No match for savings. Try a different wording or a related indicator.", "complete": false, "specs": [], "gaps": [ { "part": 0, "kind": "choice", - "options": 3 + "options": 2 }, { "part": 1, - "kind": "choice", - "options": 2 + "kind": "not_understood", + "options": 0 } ] } @@ -3401,15 +3557,15 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "Answered 1 of 2 parts. Primary income for gross of fixed capital consumption in Germany and Kenya, 2015 to 2022. Current US dollars · OECD DAC1. You asked for Kenya. The data holds no values for it. Could not tell who is giving and who is receiving in this query. Put \"from\" or \"to\" before a name.", + "sentence": "Answered 1 of 2 parts. Kenya's deaths rate per capita, 2013 to 2022. World Development Indicators. No match for savings. Try a different wording or a related indicator.", "complete": false, "specs": [ - "spec_9ce16f72ff8416d06a56f9fe82b10ad3" + "spec_10bf62f9687154286b463d206f03a086" ], "gaps": [ { "part": 1, - "kind": "choice", + "kind": "not_understood", "options": 0 } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json b/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json index 8ee2ace..ddc05c0 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json @@ -10,7 +10,7 @@ "call": [ { "op": "search", - "question": "ODA disbursements from Germany to Congo" + "question": "ODA disbursements from Germany to Congo in 2018" } ], "exchanges": [ @@ -22,7 +22,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, @@ -30,32 +30,33 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d" + "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f" }, "json": [ { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "ODA disbursements from Germany to Congo", - "normalized_query": "ODA disbursements from Germany to Congo", + "raw_query": "ODA disbursements from Germany to Congo in 2018", + "normalized_query": "ODA disbursements from Germany to Congo in 2018", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "95b872cf11e44fffb92260b2bb583f0d", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "a321fb82bfba461b9dc922634789650f", "warnings": [], "timing_ms": { - "total": 1697, + "total": 1126, "by_step": { "coverage": 0, - "extract": 982 + "extract": 1119, + "cache_lookup": 1 } }, "llm_usage": { - "input_tokens": 2249, - "output_tokens": 154, - "cached_tokens": 859 + "input_tokens": 2233, + "output_tokens": 193, + "cached_tokens": 841 }, "timed_out": false }, @@ -65,9 +66,11 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 715, + "total": 1, "by_step": { - "recall": 715 + "recall": 1, + "phase_resolve_places": 0, + "phase_check_entities": 0 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -108,6 +111,7 @@ "role_text": "to" } ], + "time_text": "2018", "sources": [], "operations": [] }, @@ -165,6 +169,7 @@ "dcid": "country/COD" } ], + "time_text": "2018", "sources": [], "operations": [] } @@ -193,6 +198,7 @@ "dcid": "country/COG" } ], + "time_text": "2018", "sources": [], "operations": [] } @@ -243,7 +249,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "95b872cf11e44fffb92260b2bb583f0d" + "trace_id": "a321fb82bfba461b9dc922634789650f" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-no-json-body.json b/python/client-contract/src/dfo_client_contract/scenarios/search-no-json-body.json index 269e29d..cc8102f 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-no-json-body.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-no-json-body.json @@ -10,7 +10,7 @@ "call": [ { "op": "search", - "question": "ODA disbursements from Germany to Congo" + "question": "ODA disbursements from Germany to Congo in 2018" } ], "exchanges": [ @@ -22,7 +22,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json b/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json index 83f93ab..e1bbc3c 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json @@ -4,14 +4,14 @@ "description": "A question naming a place that matches two countries answers with one no_data part whose entity_ambiguous reason makes a choice gap, with one option per country: each option's data_query pins that country on the ambiguous wording.", "origin": { "kind": "recorded", - "base_url": "http://127.0.0.1:19493/api", - "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T13:06:46Z" + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "recorded_at": "2026-10-23T18:39:11Z" }, "call": [ { "op": "search", - "question": "ODA disbursements from Germany to Congo" + "question": "ODA disbursements from Germany to Congo in 2018" } ], "exchanges": [ @@ -23,7 +23,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, @@ -31,31 +31,32 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d" + "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f" }, "json": { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "ODA disbursements from Germany to Congo", - "normalized_query": "ODA disbursements from Germany to Congo", + "raw_query": "ODA disbursements from Germany to Congo in 2018", + "normalized_query": "ODA disbursements from Germany to Congo in 2018", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "95b872cf11e44fffb92260b2bb583f0d", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "a321fb82bfba461b9dc922634789650f", "warnings": [], "timing_ms": { - "total": 1697, + "total": 1126, "by_step": { "coverage": 0, - "extract": 982 + "extract": 1119, + "cache_lookup": 1 } }, "llm_usage": { - "input_tokens": 2249, - "output_tokens": 154, - "cached_tokens": 859 + "input_tokens": 2233, + "output_tokens": 193, + "cached_tokens": 841 }, "timed_out": false }, @@ -65,9 +66,11 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 715, + "total": 1, "by_step": { - "recall": 715 + "recall": 1, + "phase_resolve_places": 0, + "phase_check_entities": 0 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -108,6 +111,7 @@ "role_text": "to" } ], + "time_text": "2018", "sources": [], "operations": [] }, @@ -165,6 +169,7 @@ "dcid": "country/COD" } ], + "time_text": "2018", "sources": [], "operations": [] } @@ -193,6 +198,7 @@ "dcid": "country/COG" } ], + "time_text": "2018", "sources": [], "operations": [] } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json index 9c1e6d7..cbd9c6c 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json @@ -10,7 +10,7 @@ "call": [ { "op": "search", - "question": "ODA disbursements from Germany to Congo" + "question": "ODA disbursements from Germany to Congo in 2018" } ], "exchanges": [ @@ -22,7 +22,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, @@ -47,7 +47,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, @@ -55,31 +55,32 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d" + "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f" }, "json": { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "ODA disbursements from Germany to Congo", - "normalized_query": "ODA disbursements from Germany to Congo", + "raw_query": "ODA disbursements from Germany to Congo in 2018", + "normalized_query": "ODA disbursements from Germany to Congo in 2018", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "95b872cf11e44fffb92260b2bb583f0d", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "a321fb82bfba461b9dc922634789650f", "warnings": [], "timing_ms": { - "total": 1697, + "total": 1126, "by_step": { "coverage": 0, - "extract": 982 + "extract": 1119, + "cache_lookup": 1 } }, "llm_usage": { - "input_tokens": 2249, - "output_tokens": 154, - "cached_tokens": 859 + "input_tokens": 2233, + "output_tokens": 193, + "cached_tokens": 841 }, "timed_out": false }, @@ -89,9 +90,11 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 715, + "total": 1, "by_step": { - "recall": 715 + "recall": 1, + "phase_resolve_places": 0, + "phase_check_entities": 0 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -132,6 +135,7 @@ "role_text": "to" } ], + "time_text": "2018", "sources": [], "operations": [] }, @@ -189,6 +193,7 @@ "dcid": "country/COD" } ], + "time_text": "2018", "sources": [], "operations": [] } @@ -217,6 +222,7 @@ "dcid": "country/COG" } ], + "time_text": "2018", "sources": [], "operations": [] } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json index 8382069..db4e3ad 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json @@ -10,7 +10,7 @@ "call": [ { "op": "search", - "question": "ODA disbursements from Germany to Congo" + "question": "ODA disbursements from Germany to Congo in 2018" } ], "exchanges": [ @@ -22,7 +22,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, @@ -46,7 +46,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, @@ -70,7 +70,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-refused-without-code.json b/python/client-contract/src/dfo_client_contract/scenarios/search-refused-without-code.json index 5cb7282..6c55cba 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-refused-without-code.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-refused-without-code.json @@ -10,7 +10,7 @@ "call": [ { "op": "search", - "question": "ODA disbursements from Germany to Congo" + "question": "ODA disbursements from Germany to Congo in 2018" } ], "exchanges": [ @@ -22,7 +22,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json b/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json index e993fb6..97da3dc 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json @@ -10,7 +10,7 @@ "call": [ { "op": "search", - "question": "ODA disbursements from Germany to Congo" + "question": "ODA disbursements from Germany to Congo in 2018" } ], "exchanges": [ @@ -22,7 +22,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, @@ -52,7 +52,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, @@ -60,31 +60,32 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d" + "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f" }, "json": { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "ODA disbursements from Germany to Congo", - "normalized_query": "ODA disbursements from Germany to Congo", + "raw_query": "ODA disbursements from Germany to Congo in 2018", + "normalized_query": "ODA disbursements from Germany to Congo in 2018", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "95b872cf11e44fffb92260b2bb583f0d", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "a321fb82bfba461b9dc922634789650f", "warnings": [], "timing_ms": { - "total": 1697, + "total": 1126, "by_step": { "coverage": 0, - "extract": 982 + "extract": 1119, + "cache_lookup": 1 } }, "llm_usage": { - "input_tokens": 2249, - "output_tokens": 154, - "cached_tokens": 859 + "input_tokens": 2233, + "output_tokens": 193, + "cached_tokens": 841 }, "timed_out": false }, @@ -94,9 +95,11 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 715, + "total": 1, "by_step": { - "recall": 715 + "recall": 1, + "phase_resolve_places": 0, + "phase_check_entities": 0 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -137,6 +140,7 @@ "role_text": "to" } ], + "time_text": "2018", "sources": [], "operations": [] }, @@ -194,6 +198,7 @@ "dcid": "country/COD" } ], + "time_text": "2018", "sources": [], "operations": [] } @@ -222,6 +227,7 @@ "dcid": "country/COG" } ], + "time_text": "2018", "sources": [], "operations": [] } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-server-warning.json b/python/client-contract/src/dfo_client_contract/scenarios/search-server-warning.json index 1429b59..b540d6f 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-server-warning.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-server-warning.json @@ -10,15 +10,15 @@ "call": [ { "op": "search", - "question": "ODA disbursements from Germany to Congo" + "question": "ODA disbursements from Germany to Congo in 2018" }, { "op": "search", - "question": "ODA disbursements from Germany to Congo" + "question": "ODA disbursements from Germany to Congo in 2018" }, { "op": "search", - "question": "ODA disbursements from Germany to Congo" + "question": "ODA disbursements from Germany to Congo in 2018" } ], "exchanges": [ @@ -30,7 +30,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, @@ -38,32 +38,33 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d", + "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f", "x-dfo-warning": "Search runs on a reduced index while it is rebuilt." }, "json": { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "ODA disbursements from Germany to Congo", - "normalized_query": "ODA disbursements from Germany to Congo", + "raw_query": "ODA disbursements from Germany to Congo in 2018", + "normalized_query": "ODA disbursements from Germany to Congo in 2018", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "95b872cf11e44fffb92260b2bb583f0d", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "a321fb82bfba461b9dc922634789650f", "warnings": [], "timing_ms": { - "total": 1697, + "total": 1126, "by_step": { "coverage": 0, - "extract": 982 + "extract": 1119, + "cache_lookup": 1 } }, "llm_usage": { - "input_tokens": 2249, - "output_tokens": 154, - "cached_tokens": 859 + "input_tokens": 2233, + "output_tokens": 193, + "cached_tokens": 841 }, "timed_out": false }, @@ -73,9 +74,11 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 715, + "total": 1, "by_step": { - "recall": 715 + "recall": 1, + "phase_resolve_places": 0, + "phase_check_entities": 0 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -116,6 +119,7 @@ "role_text": "to" } ], + "time_text": "2018", "sources": [], "operations": [] }, @@ -173,6 +177,7 @@ "dcid": "country/COD" } ], + "time_text": "2018", "sources": [], "operations": [] } @@ -201,6 +206,7 @@ "dcid": "country/COG" } ], + "time_text": "2018", "sources": [], "operations": [] } @@ -252,7 +258,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, @@ -260,7 +266,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d", + "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f", "x-dfo-warning": "Search runs on a reduced index while it is rebuilt.", "sunset": "Sat, 01 May 2027 00:00:00 GMT" }, @@ -268,25 +274,26 @@ "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "ODA disbursements from Germany to Congo", - "normalized_query": "ODA disbursements from Germany to Congo", + "raw_query": "ODA disbursements from Germany to Congo in 2018", + "normalized_query": "ODA disbursements from Germany to Congo in 2018", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "95b872cf11e44fffb92260b2bb583f0d", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "a321fb82bfba461b9dc922634789650f", "warnings": [], "timing_ms": { - "total": 1697, + "total": 1126, "by_step": { "coverage": 0, - "extract": 982 + "extract": 1119, + "cache_lookup": 1 } }, "llm_usage": { - "input_tokens": 2249, - "output_tokens": 154, - "cached_tokens": 859 + "input_tokens": 2233, + "output_tokens": 193, + "cached_tokens": 841 }, "timed_out": false }, @@ -296,9 +303,11 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 715, + "total": 1, "by_step": { - "recall": 715 + "recall": 1, + "phase_resolve_places": 0, + "phase_check_entities": 0 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -339,6 +348,7 @@ "role_text": "to" } ], + "time_text": "2018", "sources": [], "operations": [] }, @@ -396,6 +406,7 @@ "dcid": "country/COD" } ], + "time_text": "2018", "sources": [], "operations": [] } @@ -424,6 +435,7 @@ "dcid": "country/COG" } ], + "time_text": "2018", "sources": [], "operations": [] } @@ -475,7 +487,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, @@ -483,7 +495,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d", + "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f", "x-dfo-warning": "Search answers from a cached release.", "deprecation": "@1777593600", "sunset": "Sat, 01 May 2027 00:00:00 GMT" @@ -492,25 +504,26 @@ "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "ODA disbursements from Germany to Congo", - "normalized_query": "ODA disbursements from Germany to Congo", + "raw_query": "ODA disbursements from Germany to Congo in 2018", + "normalized_query": "ODA disbursements from Germany to Congo in 2018", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "95b872cf11e44fffb92260b2bb583f0d", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "a321fb82bfba461b9dc922634789650f", "warnings": [], "timing_ms": { - "total": 1697, + "total": 1126, "by_step": { "coverage": 0, - "extract": 982 + "extract": 1119, + "cache_lookup": 1 } }, "llm_usage": { - "input_tokens": 2249, - "output_tokens": 154, - "cached_tokens": 859 + "input_tokens": 2233, + "output_tokens": 193, + "cached_tokens": 841 }, "timed_out": false }, @@ -520,9 +533,11 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 715, + "total": 1, "by_step": { - "recall": 715 + "recall": 1, + "phase_resolve_places": 0, + "phase_check_entities": 0 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -563,6 +578,7 @@ "role_text": "to" } ], + "time_text": "2018", "sources": [], "operations": [] }, @@ -620,6 +636,7 @@ "dcid": "country/COD" } ], + "time_text": "2018", "sources": [], "operations": [] } @@ -648,6 +665,7 @@ "dcid": "country/COG" } ], + "time_text": "2018", "sources": [], "operations": [] } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-sunset-warning.json b/python/client-contract/src/dfo_client_contract/scenarios/search-sunset-warning.json index 13fe4d0..f3915bc 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-sunset-warning.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-sunset-warning.json @@ -10,11 +10,11 @@ "call": [ { "op": "search", - "question": "ODA disbursements from Germany to Congo" + "question": "ODA disbursements from Germany to Congo in 2018" }, { "op": "search", - "question": "ODA disbursements from Germany to Congo" + "question": "ODA disbursements from Germany to Congo in 2018" } ], "exchanges": [ @@ -26,7 +26,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, @@ -34,32 +34,33 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d", + "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f", "sunset": "Sat, 01 May 2027 00:00:00 GMT" }, "json": { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "ODA disbursements from Germany to Congo", - "normalized_query": "ODA disbursements from Germany to Congo", + "raw_query": "ODA disbursements from Germany to Congo in 2018", + "normalized_query": "ODA disbursements from Germany to Congo in 2018", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "95b872cf11e44fffb92260b2bb583f0d", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "a321fb82bfba461b9dc922634789650f", "warnings": [], "timing_ms": { - "total": 1697, + "total": 1126, "by_step": { "coverage": 0, - "extract": 982 + "extract": 1119, + "cache_lookup": 1 } }, "llm_usage": { - "input_tokens": 2249, - "output_tokens": 154, - "cached_tokens": 859 + "input_tokens": 2233, + "output_tokens": 193, + "cached_tokens": 841 }, "timed_out": false }, @@ -69,9 +70,11 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 715, + "total": 1, "by_step": { - "recall": 715 + "recall": 1, + "phase_resolve_places": 0, + "phase_check_entities": 0 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -112,6 +115,7 @@ "role_text": "to" } ], + "time_text": "2018", "sources": [], "operations": [] }, @@ -169,6 +173,7 @@ "dcid": "country/COD" } ], + "time_text": "2018", "sources": [], "operations": [] } @@ -197,6 +202,7 @@ "dcid": "country/COG" } ], + "time_text": "2018", "sources": [], "operations": [] } @@ -248,7 +254,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, @@ -256,32 +262,33 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "95b872cf11e44fffb92260b2bb583f0d", + "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f", "sunset": "Sat, 01 May 2027 00:00:00 GMT" }, "json": { "schema_version": 1, "query_echo": { "entry_path": "raw_text", - "raw_query": "ODA disbursements from Germany to Congo", - "normalized_query": "ODA disbursements from Germany to Congo", + "raw_query": "ODA disbursements from Germany to Congo in 2018", + "normalized_query": "ODA disbursements from Germany to Congo in 2018", "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "95b872cf11e44fffb92260b2bb583f0d", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "a321fb82bfba461b9dc922634789650f", "warnings": [], "timing_ms": { - "total": 1697, + "total": 1126, "by_step": { "coverage": 0, - "extract": 982 + "extract": 1119, + "cache_lookup": 1 } }, "llm_usage": { - "input_tokens": 2249, - "output_tokens": 154, - "cached_tokens": 859 + "input_tokens": 2233, + "output_tokens": 193, + "cached_tokens": 841 }, "timed_out": false }, @@ -291,9 +298,11 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 715, + "total": 1, "by_step": { - "recall": 715 + "recall": 1, + "phase_resolve_places": 0, + "phase_check_entities": 0 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -334,6 +343,7 @@ "role_text": "to" } ], + "time_text": "2018", "sources": [], "operations": [] }, @@ -391,6 +401,7 @@ "dcid": "country/COD" } ], + "time_text": "2018", "sources": [], "operations": [] } @@ -419,6 +430,7 @@ "dcid": "country/COG" } ], + "time_text": "2018", "sources": [], "operations": [] } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json b/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json index 58073d3..329f75d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json @@ -4,9 +4,9 @@ "description": "A two-part question naming a place that matches two countries answers no_data on both parts, each an entity_ambiguous choice gap with one option per country.", "origin": { "kind": "recorded", - "base_url": "http://127.0.0.1:19493/api", - "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T13:06:48Z" + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "recorded_at": "2026-10-23T18:39:12Z" }, "call": [ { @@ -31,7 +31,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4a421114e5a2429284f5bb99860796e7" + "x-dfo-trace-id": "88156a0c48754c7fb0d5c5a544daed09" }, "json": { "schema_version": 1, @@ -42,20 +42,21 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "4a421114e5a2429284f5bb99860796e7", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "88156a0c48754c7fb0d5c5a544daed09", "warnings": [], "timing_ms": { - "total": 1225, + "total": 1686, "by_step": { "coverage": 0, - "extract": 1221 + "extract": 1680, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 2256, + "input_tokens": 2234, "output_tokens": 207, - "cached_tokens": 861 + "cached_tokens": 841 }, "timed_out": false }, @@ -67,7 +68,9 @@ "timing_ms": { "total": 1, "by_step": { - "recall": 1 + "recall": 1, + "phase_resolve_places": 0, + "phase_check_entities": 0 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", @@ -220,9 +223,11 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 2, "by_step": { - "recall": 1 + "recall": 2, + "phase_resolve_places": 0, + "phase_check_entities": 0 } }, "rendered_sentence": "\"Congo\" matches more than one entity: \"Congo [DRC]\" and \"Congo [Republic]\". Be more specific.", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-unauthorized.json b/python/client-contract/src/dfo_client_contract/scenarios/search-unauthorized.json index 0a65d0d..d55e007 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-unauthorized.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-unauthorized.json @@ -10,7 +10,7 @@ "call": [ { "op": "search", - "question": "ODA disbursements from Germany to Congo" + "question": "ODA disbursements from Germany to Congo in 2018" } ], "exchanges": [ @@ -22,7 +22,7 @@ "schema_version": 1, "input": { "kind": "raw_text", - "query": "ODA disbursements from Germany to Congo" + "query": "ODA disbursements from Germany to Congo in 2018" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json b/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json index 3d8e984..f32ec45 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json @@ -4,9 +4,9 @@ "description": "A question asking for a ranking answers one definite part that does not run the rank, with a departure and two warn-severity warnings. A strict fetch raises SearchWarning before any build; a fetch that is not strict builds the dataset and issues one SearchWarning for all of them.", "origin": { "kind": "recorded", - "base_url": "http://127.0.0.1:19493/api", - "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T13:06:59Z" + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "recorded_at": "2026-10-23T18:39:17Z" }, "call": [ { @@ -38,7 +38,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "2b349555f60d4b9aa5c17d3f59541531" + "x-dfo-trace-id": "9574dd6f16974328a119e8d83e6e7818" }, "json": { "schema_version": 1, @@ -49,20 +49,23 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "2b349555f60d4b9aa5c17d3f59541531", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "9574dd6f16974328a119e8d83e6e7818", "warnings": [], "timing_ms": { - "total": 4816, + "total": 2030, "by_step": { "coverage": 0, - "extract": 1848 + "extract": 1077, + "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 6103, - "output_tokens": 381, - "cached_tokens": 860 + "input_tokens": 2233, + "output_tokens": 188, + "cached_tokens": 841, + "jev_input_tokens": 4485, + "jev_output_tokens": 849 }, "timed_out": false }, @@ -74,29 +77,50 @@ { "code": "slot_defaulted", "severity": "warn", - "message": "No aid type was named, so the answer covers official development assistance." + "message": "The answer covers official development assistance of every aid type." }, { "code": "role_scope_defaulted", "severity": "warn", "message": "no provider was named; the answer was resolved across every provider with data." + }, + { + "code": "whole_total_available", + "severity": "info", + "message": "The source publishes the total of every official donor as official donors (DAC); a sum of the listed donors includes private donors and differs from it.", + "spec_id": "spec_7778beed72f8433bb7fde4293acfd175", + "params": { + "total": "DACOfficialDonors", + "total_label": "official donors (DAC)", + "whole_of": "official" + } } ], "timing_ms": { - "total": 2929, + "total": 947, "by_step": { - "recall": 819, - "shape_arcs": 2, - "shape_probe_coverage": 2, - "shape_probe": 201, - "shape_groups": 2, + "recall": 391, + "phase_resolve_places": 0, + "phase_check_entities": 0, + "shape_arcs": 3, + "shape_probe_coverage": 5, + "shape_probe": 154, + "shape_groups": 4, "shape_labels": 0, "shape_admission": 1, - "shape": 935, - "bind": 1152, - "materialise": 12, - "answer": 8, - "options": 3 + "phase_derive_shapes": 0, + "shape": 309, + "phase_prune_and_rank": 0, + "bind": 112, + "phase_bind": 14, + "phase_settle": 7, + "phase_place_bindings": 1, + "phase_facet_requests": 0, + "materialise": 31, + "phase_materialise": 0, + "answer": 14, + "options": 8, + "phase_outcome": 60 } }, "restatement": { @@ -501,7 +525,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "facets": { "provenance": { "basis": "fallback", @@ -950,7 +974,7 @@ "start_year": 2022, "end_year": 2022 }, - "capability_version": "cap_347a470e04c97eec", + "capability_version": "cap_94e25737d859392c", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3369,7 +3393,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "f0557d404d0d4f34aa2ad0fd2784dfac" + "x-dfo-trace-id": "204cdb090cb6492b829defbe74a5dfbf" }, "json": { "schema_version": 1, @@ -3430,7 +3454,7 @@ } }, "content_version": "cv_534dd4c2bf9bdafc837d51a3ba4bcf3e", - "prepared_at": "2026-10-21T13:07:05Z", + "prepared_at": "2026-10-20T16:52:43Z", "coverage": { "rows": 110, "dimensions": [ @@ -3459,9 +3483,9 @@ ], "window": { "kind": "range", - "start_year": 2022, + "origin": "query", "end_year": 2022, - "origin": "query" + "start_year": 2022 } }, "citation": { @@ -3547,25 +3571,56 @@ ] }, "trace": { + "facets": [ + { + "ref": "provenance/OECDDAC2A", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + }, + { + "ref": null, + "axis": "measurementMethod", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + } + ], "applied_window": { "kind": "range", - "start_year": 2022, + "origin": "query", "end_year": 2022, - "origin": "query" + "start_year": 2022 }, - "graph_revision": null, + "graph_revision": "dfo-dev-dc-datacommons-service-00259-rpx", + "normalisations": [], "code_index_stamp": { + "exported_at": "2026-10-20T13:18:18Z", "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", - "exported_at": "2026-10-20T19:50:14Z", "graph_endpoint": "graph_release" }, - "origin_catalogue_build_id": "20261021T070020Z-7262111e", "source_revisions": [ { "source": "provenance/OECDDAC2A", "revision": "2026-10-15" } ], + "capability_version": "dset_1e6cd9546fac19e9", + "materialiser_build": "7175fe98eec005479f1397936dc011ad120092d5", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", @@ -3576,43 +3631,12 @@ "observation_count": 110 } ], - "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", "family_member_count": 1, - "facets": [ - { - "axis": "provenance", - "ref": "provenance/OECDDAC2A", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "1962969911839422253" - }, - { - "axis": "measurementMethod", - "ref": null, - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "absent_on_selected_facet", - "dispatch_facet_id": "1962969911839422253" - }, - { - "axis": "unit", - "ref": "CurrencyUSD", - "basis": "deployment_fallback", - "default_policy": "dfo/facet-policy/most-observations", - "default_policy_version": "1", - "selection_reason": "sole_candidate", - "dispatch_facet_id": "1962969911839422253" - } - ], - "normalisations": [], + "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", "frame_grammar_version": "1.1.0", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "capability_version": "dset_88fecfec3c5b89d1", - "served_from": "materialise", - "confirmed_at": "2026-10-21T13:07:05.722653+00:00" + "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", + "served_from": "head", + "confirmed_at": "2026-10-23T18:39:20.385608+00:00" }, "warnings": [], "diagnostics": [ @@ -3624,17 +3648,18 @@ ], "artifacts": [ { - "artifact_digest": "sha256:7ca72626eed07dafebc7eaa78713c1c5a36ef05a19d8da96b723dec80d50317f", + "artifact_digest": "sha256:f0ac1a058c4addb59b1974b73706b12ddc112b409aac006d6a561279f61f0c6a", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 10828, + "bytes": 10927, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:07:05.693889+00:00", + "created_at": "2026-10-23T16:59:51.176407+00:00", "tier": "working", - "url": "/api/datasets/spec_7778beed72f8433bb7fde4293acfd175/cv_534dd4c2bf9bdafc837d51a3ba4bcf3e/files/sha256:7ca72626eed07dafebc7eaa78713c1c5a36ef05a19d8da96b723dec80d50317f" + "url": "/api/datasets/spec_7778beed72f8433bb7fde4293acfd175/cv_534dd4c2bf9bdafc837d51a3ba4bcf3e/files/sha256:f0ac1a058c4addb59b1974b73706b12ddc112b409aac006d6a561279f61f0c6a", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { "artifact_digest": "sha256:5b508be6b46ce8e01315f9c89a1837e17ed7b49d7d2554011cfdba9f32203084", @@ -3643,14 +3668,14 @@ }, "bytes": 10167, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:07:05.693889+00:00", + "created_at": "2026-10-20T16:52:44.112078+00:00", "tier": "working", "url": "/api/datasets/spec_7778beed72f8433bb7fde4293acfd175/cv_534dd4c2bf9bdafc837d51a3ba4bcf3e/files/sha256:5b508be6b46ce8e01315f9c89a1837e17ed7b49d7d2554011cfdba9f32203084" } ], "series_count": 110, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -3867,6 +3892,30 @@ "missing": [], "truncated": false }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 110, + "covered": 110 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 110, + "covered": 110 + }, + "missing": [], + "truncated": false + }, { "column": "financingRecipient", "field": "iso3", @@ -3926,13 +3975,37 @@ }, "missing": [], "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 1, + "covered": 1 + }, + "missing": [], + "truncated": false } ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" + "financingRecipient_kind" ], "long_layout_totals": [ "financingProvider" @@ -3956,10 +4029,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:07:05.693915Z" + "held_until": "2026-11-19T16:52:44.112184Z" } } } @@ -3967,26 +4040,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_7778beed72f8433bb7fde4293acfd175/cv_534dd4c2bf9bdafc837d51a3ba4bcf3e/files/sha256:7ca72626eed07dafebc7eaa78713c1c5a36ef05a19d8da96b723dec80d50317f" + "origin_path": "/api/datasets/spec_7778beed72f8433bb7fde4293acfd175/cv_534dd4c2bf9bdafc837d51a3ba4bcf3e/files/sha256:f0ac1a058c4addb59b1974b73706b12ddc112b409aac006d6a561279f61f0c6a" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3A7ca72626eed07dafebc7eaa78713c1c5a36ef05a19d8da96b723dec80d50317f?X-Goog-Signature=redacted", - "x-dfo-trace-id": "5b1ffba527ed4c2b9ae59df39ceb3482" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Af0ac1a058c4addb59b1974b73706b12ddc112b409aac006d6a561279f61f0c6a?X-Goog-Signature=redacted", + "x-dfo-trace-id": "6ea497e67fff4becbcee2656441d0dac" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3A7ca72626eed07dafebc7eaa78713c1c5a36ef05a19d8da96b723dec80d50317f?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Af0ac1a058c4addb59b1974b73706b12ddc112b409aac006d6a561279f61f0c6a?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "b1b959d03f9943679a50cfe0f8e1ad5d" + "content-type": "application/vnd.apache.parquet" }, "body_file": "search-warning-top5.parquet" } @@ -4009,7 +4082,7 @@ "error": { "class": "SearchWarning", "code": null, - "trace_id": "2b349555f60d4b9aa5c17d3f59541531" + "trace_id": "9574dd6f16974328a119e8d83e6e7818" } }, { @@ -4019,10 +4092,10 @@ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "dac2aAidType", "dac2aAidType_label", "time_period", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.parquet b/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.parquet index c670090925d3b8802a0a5b73e02ef76e52167c0e..7f04cba913c887e70dd44deddcff05227bacc325 100644 GIT binary patch delta 1238 zcmZ`(ZD?Cn7``|4CRtZp(t6XxC22lSvQ2y1^fQGmJ!wALTH7RU$r84vH#c9m&6jDK ztOapO5fp#r^~V@0a}4yC7A7cI2bQ6K2L2G{pCTw@f1S?KO|Ry2@vkcs0-TGYtM*%`i+gpO-{QC~?$oR2xD`MU7frY6^|qQEIk| z)l$yV$?yz6!=HJMKV*3gujG}+NydHjiM(F@&tY0EWtwU|bU$QS#lWsDzLn^GYgWu-aoYuHGv@Y!=$8N}wQl&ryujTEqgx@kteuA* zYd?rXBi!``^k5zyYlq?MA+M?(NBfILJw*8dSmq5BrG@W@o`$kn4M~fZ+e@Mc=b>s5 zxIa_q;}mS@hAGC!9b7=~T!64O#@)S$u3d!pt?{RRT1B_vT^k0M&Bz_3(Ty~`XB&p5 z&Bk3{L%VC#3m*AYK=;;UjlkOZwtbCji|B3!T6!}W?ERiAT7%Mn=tH8LHPSsmKn-lkmGEs1$JoV-NV9KJ|zkZS8pBP3M?$T8^*4fpc6n zx9+9P4S3`nSH>e_7*D_yqG5vb7&oDgu<~U&dxPFR;gYb&W zdt|<2k5Iy6H-=wbeQ8glmMKTcW@L(jb|`Y13JHdSbSHCE19jxBv#2U6tt=!aikb2< zsfh5*z&+6HkE3 delta 1189 zcmZ`(%}--h6n_uqm5vz$G`^Q6tmV4Whv^ z!;K2Mr(e(`dwXeUU!s%BHqY}HJ5IXy>|7^rqTd|+)BUw%5~X>uLua^XJ7a*Mz89W9 zE%BrheA*-4@$|lC?6>3#RjrySRBuHawXH%n*GTJJ@UA yoI0=ORTBN4fS;vt*ctK(Cn@wx z3cepwg#9;A`*jfQapB_?w6_9vdqg-{K@XTV4u9C~7w)g3BdFOi$iscY<1{)*!|L$1 za8E<~8nlOJowwiS>AsLrI$Gn*mi|jbQ5Mx#H!|zFiq?N{3A5vdtB#i3MVkqA6 z?4xPJ27_;a7rDCRqL(Jdpov@tB|43<3l16F!g-7v@EgL03WL319r5u5R!0{3ARLbP zx&p;93QxeFBi`LG)5l793uD@@EGtwJ)+sfZI6YZ*r7Gpkr0Ones=FGi#EV)&uBTM@ zL}FTA&r}t6VyanRt1Qt-e~s01M_<91Ra%NMkjyhdbXC{FRALfN(WKC3a;m(Unv9g` z-O|+fW;W#ANUD+YnjRX^8@wLH@SW2dx<#?`(wK{`2v06k;h|PA6l5jn3(%vhx+b?^ z_lo6mE18H)-totals.csv; an XLSX writes them on a second sheet, totals. A bare CSV has no README and drops them, so this list names the roles whose totals it drops. Parquet, a pivot and the frame layout keep every row. Empty when no role can hold a total row" + "description": "the roles whose total rows ({role}_kind is total or whole total) a long-layout CSV or XLSX download keeps out of its main table. A private party stays in it. A role is listed when the definition binds it to several entities one of which the code index declares a total, or leaves it open and the code index lists a total on its axis in a dataset the definition read (any dataset, when the read selected none). A role bound to several parties holds no total row and is not listed. A bundle's CSV writes those rows to a second data file, data/-totals.csv; an XLSX writes them on a second sheet, totals. A bare CSV has no README and drops them, so this list names the roles whose totals it drops. Parquet, a pivot and the frame layout keep every row. Empty when no role can hold a total row" }, "pivots": { "items": { @@ -14359,7 +14437,7 @@ } ], "title": "Evidence", - "description": "what read the term: a code label or synonym, the bind model, \"uncovered\" for words no reader covers beside a recognised code, \"unavailable\" for a code no table holds, \"unsupported\" for a distinction no binding expresses" + "description": "what read the term: a code label or synonym, the bind model, \"uncovered\" for words no reader covers on the elected shape, unbound beside a recognised code and no_vocabulary beside none when the binder rated them as not stated by its series, \"unavailable\" for a code no table holds, \"unsupported\" for a distinction no binding expresses" }, "operation": { "anyOf": [ @@ -14394,7 +14472,7 @@ "disposition" ], "title": "ResolvedQualifier", - "description": "One narrowing term the request's text named, and what became of it.\n\nThe term's text can come from the variable phrase, from the verbatim\n`query_text`, or from an admitted qualifier tie (see\n`_resolve_query_qualifiers`). `text` is the verbatim span of whichever\nsource named it. `named` is every code row -- any system -- that span\nnames in the packaged index;\nempty when the text names no code at all (a `no_vocabulary` term). `slot`\nis the constraint property dcid of the `slot_filters` entry whose\nbinding consumed the term, or, on an `\"unbound\"` value the answer's shape\nhas a slot for but leaves unmet, that slot's property; `None` otherwise.\n`disposition` is\n`\"bound\"` when some final binding on a named row's code system covers\nit (that row or a descendant), `\"unbound\"` when a row was named but no\nbinding covers it, and `\"no_vocabulary\"` when the term names no code at\nall -- an LLM-reported phrase (`bind`'s own `unplaced` output) that no\ntaxonomy in this deployment's index can express.\n\n`start` and `end` locate the term in the part's variable phrase. `evidence` says what\nread it, and `None` means a code's label or synonym matched the term as the query\nspelled it, the reading every recognised span records:\n\n- `\"label\"` and `\"synonym\"` name a match on a code's label or synonym; no record sets\n them, since a recognised span records `None`.\n- `\"model\"` marks a phrase the bind model read through a code it chose from the\n phrase's candidate menu, a lexical hit of the menu or a descendant of one\n (`phase_rank_bind._model_records`); `named` holds the chosen codes.\n- `\"uncovered\"` marks words no reader covers beside a recognised code\n (`phase_rank_bind._coverage_records`), recorded `\"unbound\"` with that code's rows as\n `named`.\n- `\"unavailable\"` marks a code term the elected shape cannot apply: one naming only\n codes no shape can bind, or, on a part naming a dataset, one no row of that dataset\n holds (`phase_rank_bind._unavailable_qualifiers`), recorded `\"unbound\"`.\n- `\"unsupported\"` marks an exclusion or comparison phrase no binding expresses\n (`phase_rank_bind._unsupported_records`), recorded `\"no_vocabulary\"`.\n\n`operation` and `selected` describe how the term's codes combine with\nanother term's on one code system, and the codes it asked for before that\ncombination simplified." + "description": "One narrowing term the request's text named, and what became of it.\n\nThe term's text can come from the variable phrase, from the verbatim\n`query_text`, or from an admitted qualifier tie (see\n`_resolve_query_qualifiers`). `text` is the verbatim span of whichever\nsource named it. `named` is every code row -- any system -- that span\nnames in the packaged index;\nempty when the text names no code at all (a `no_vocabulary` term). `slot`\nis the constraint property dcid of the `slot_filters` entry whose\nbinding consumed the term, or, on an `\"unbound\"` value the answer's shape\nhas a slot for but leaves unmet, that slot's property; `None` otherwise.\n`disposition` is\n`\"bound\"` when some final binding on a named row's code system covers\nit (that row or a descendant), `\"unbound\"` when a row was named but no\nbinding covers it, and `\"no_vocabulary\"` when the term names no code at\nall: an LLM-reported phrase (`bind`'s own `unplaced` output) that no\ntaxonomy in this deployment's index can express, an exclusion or comparison\nphrase (`\"unsupported\"`), or words beside no code the binder rated as not\nstated on the elected shape (`\"uncovered\"`).\n\n`start` and `end` locate the term in the part's variable phrase. `evidence` says what\nread it, and `None` means a code's label or synonym matched the term as the query\nspelled it, the reading every recognised span records:\n\n- `\"label\"` and `\"synonym\"` name a match on a code's label or synonym; no record sets\n them, since a recognised span records `None`.\n- `\"model\"` marks a phrase the bind model read through a code it chose from the\n phrase's candidate menu, a lexical hit of the menu or a descendant of one\n (`phase_rank_bind._model_records`); `named` holds the chosen codes.\n- `\"uncovered\"` marks words no reader covers on the elected shape\n (`phase_rank_bind._coverage_records`). Beside a recognised code they are recorded\n `\"unbound\"` with that code's rows as `named`. Beside no code they are recorded\n `\"no_vocabulary\"` with `named` empty when the binder rates them below\n `SearchSettings.stated_word_bar` as not stated by the shape's series; a word it rates\n at the bar or above, or leaves unrated, reads as stated.\n- `\"unavailable\"` marks a code term the elected shape cannot apply: one naming only\n codes no shape can bind, or, on a part naming a dataset, one no row of that dataset\n holds (`phase_rank_bind._unavailable_qualifiers`), recorded `\"unbound\"`.\n- `\"unsupported\"` marks an exclusion or comparison phrase no binding expresses\n (`phase_rank_bind._unsupported_records`), recorded `\"no_vocabulary\"`.\n\n`operation` and `selected` describe how the term's codes combine with\nanother term's on one code system, and the codes it asked for before that\ncombination simplified." }, "ResolvedScope": { "properties": { @@ -14438,7 +14516,7 @@ }, "type": "array", "title": "Slots", - "description": "one entry per slot the shape defines, each in a binding state" + "description": "one entry per slot the shape defines, each in a binding state. Its what/how entries are the identity's slots, so a what/how property it leaves out is one no served member asserts" }, "inapplicable_slots": { "items": { @@ -14650,7 +14728,8 @@ "structural", "nominated", "twin", - "direction" + "direction", + "breakdown" ] }, { @@ -14658,7 +14737,7 @@ } ], "title": "Basis", - "description": "why the part offers this Spec as one of its candidates: 'structural', a reading that differs from the elected one only on a stat type, price basis or denominator the request leaves open; 'nominated', a reading the model named as a genuine reading of the request's phrase; 'twin', an equivalent reading of the elected one, offered where the elected one holds no data; 'direction', the same reading with the other direction for a place the request names without one, which a client shows as a direction prompt. The elected reading, listed first, carries none. None on a definite answer and on every Spec outside CandidateSet.specs." + "description": "why the part offers this Spec as one of its candidates: 'structural', a reading that differs from the elected one only on a stat type, price basis or denominator the request leaves open; 'nominated', a reading the model named as a genuine reading of the request's phrase; 'twin', an equivalent reading of the elected one, offered where the elected one holds no data; 'direction', the same reading with the other direction for a place the request names without one, which a client shows as a direction prompt; 'breakdown', the same measure broken down by another set of slots, offered when its family holds no total and the request names no breakdown that serves a member. The elected reading, listed first, carries none. None on a definite answer and on every Spec outside CandidateSet.specs." }, "available_at_place": { "anyOf": [ @@ -18118,7 +18197,7 @@ "total" ], "title": "Timing", - "description": "Latency breakdown, reused at two scopes: the envelope's own\ndiagnostics.timing_ms, where total is the whole request's wall-clock\nelapsed time and by_step names the steps that run once per request,\nshared across every part (e.g. extract), and a part's own timing_ms,\nwhere total sums that part's own by_step values and by_step names only\nthe phases that part ran, excluding the shared steps already reported\non the envelope. A part's shape_arcs, shape_probe, shape_probe_coverage,\nshape_labels, shape_groups and shape_admission steps are nested inside\nits shape step, so its total leaves them out." + "description": "Latency breakdown, reused at two scopes: the envelope's own\ndiagnostics.timing_ms, where total is the whole request's wall-clock\nelapsed time and by_step names the steps that run once per request,\nshared across every part (coverage; extract; cache_lookup on a raw-text\nrequest with the response cache active; entity_check on a request that\nruns the place check), and a part's own timing_ms, where total sums\nthat part's own by_step values and by_step names the steps that part\nran plus a phase_ entry for each phase it ran, holding the time\nno step booked, excluding the shared steps already reported on the\nenvelope. A part's shape_arcs, shape_probe, shape_probe_coverage,\nshape_labels, shape_groups and shape_admission steps are nested inside\nits shape step, so its total leaves them out." }, "TraceConversion": { "properties": { @@ -18780,7 +18859,7 @@ }, "type": "array", "title": "Departures", - "description": "every way this part's answer differs from what its request asked, ordered by how much each changes the number: closest_match, measure_not_applied, operation_not_applied, breakdown_not_applied, entity_unavailable, year_unavailable, modelled_values, group_read_as_members, direction_discarded, direction_inferred, scope_limited. [] when the answer is what was asked. A client that renders its own sentence reads them here; each one's text also closes the sentence that carries this part (see Departure.text). A warning on the same part reports run health and stays separate" + "description": "every way this part's answer differs from what its request asked, ordered by how much each changes the number: closest_match, measure_not_applied, operation_not_applied, breakdown_not_applied, entity_unavailable, year_unavailable, modelled_values, group_read_as_members, whole_total_read, whole_total_unpublished, direction_discarded, direction_inferred, scope_limited. [] when the answer is what was asked. A client that renders its own sentence reads them here; each one's text also closes the sentence that carries this part (see Departure.text). A warning on the same part reports run health and stays separate" }, "assumptions": { "items": { @@ -19144,7 +19223,7 @@ } ], "title": "Params", - "description": "the counts and labels the message states, for a client to compose its own text. observations_series_truncated: {shown, total, order}, the series shown, the confirmed series behind them, and how the shown series were chosen: 'ranked' (the most recent and largest) or 'fixed' (a selection made before values were read, not ranked by value). elected_shape_no_data: {no_data, elected}, the labels of the readings with no data and of the readings answered instead. un_system_unavailable: {places, variables, variable_labels}, the place dcids the UN front door refused, the variables of the UN reads that failed, each empty when none, and each variable's graph name, in variables order, '' where the graph holds none; a warning without params says the UN search itself was unavailable. Omitted for every other code" + "description": "the counts and labels the message states, for a client to compose its own text. observations_series_truncated: {shown, total, order}, the series shown, the confirmed series behind them, and how the shown series were chosen: 'ranked' (the most recent and largest) or 'fixed' (a selection made before values were read, not ranked by value). elected_shape_no_data: {no_data, elected}, the labels of the readings with no data and of the readings answered instead. un_system_unavailable: {places, variables, variable_labels}, the place dcids the UN front door refused, the variables of the UN reads that failed, each empty when none, and each variable's graph name, in variables order, '' where the graph holds none; a warning without params says the UN search itself was unavailable. whole_total_available: {total, total_label, whole_of}, the dcid and label of the total the source publishes for the side the answer lists member by member, and the classes of party it covers, comma-joined (official, private, residual). Omitted for every other code" } }, "additionalProperties": false, @@ -19155,7 +19234,7 @@ "message" ], "title": "Warning", - "description": "A run-health signal. Note: this name shadows the Python builtin Warning.\n\nOnly `observations_series_truncated`, `elected_shape_no_data` and `un_system_unavailable`\nset `params`. A `None` `params` is left out of every dump, so other codes' warnings stay\nexactly `{code, severity, message}` plus `spec_id` where one applies." + "description": "A run-health signal. Note: this name shadows the Python builtin Warning.\n\nOnly `observations_series_truncated`, `elected_shape_no_data`, `un_system_unavailable`\nand `whole_total_available` set `params`. A `None` `params` is left out of every dump, so other codes' warnings stay\nexactly `{code, severity, message}` plus `spec_id` where one applies." }, "WarningModel": { "properties": { @@ -19488,7 +19567,7 @@ }, "type": "array", "title": "Enrichment Fields", - "description": "enrichment field names this deployment enables. A live token qualifies one as {entity_column}_{field} on the columns option. party_kind is a party's kind (party, total, residual) from the code index's declaration for it. Long output writes {role}_party_kind beside {role}_label for every role on a flow axis without a token; a bare party_kind token requests it for every role on a flow axis the table has. party_kind qualifies no subject role, so observationAbout_party_kind refuses column_unknown. A party the index does not list gets an empty cell and an enrichment_unavailable warning" + "description": "enrichment field names this deployment enables. A live token qualifies one as {entity_column}_{field} on the columns option. Three fields come from the code index's declaration of a party: party_kind is its kind (party, total, residual); party_class is official, private or residual, and for a total the one class its whole markers cover, empty when they cover none or several; party_whole is true on a row whose party is a total that holds every party of its classes on its axis in that row's dataset and year, such as Official Donors, Total, false on a row where it is not, and empty where the row names no one dataset and year, as in a pivot. A bare party field token requests it for every role on a flow axis the table has, and a file holds a party field only when a token asks for it. Long output writes one {role}_kind beside {role}_label for every role on a flow axis instead, in words: official or private for a provider or creditor, country or organisation for a recipient or debtor, total, whole total or unallocated, and ignores party field tokens. A party field qualifies no subject role, so observationAbout_party_kind refuses column_unknown. A party the index does not list gets an empty cell and an enrichment_unavailable warning" }, "decode_code_systems": { "items": { diff --git a/tools/capture_client_contract.py b/tools/capture_client_contract.py index 08310de..c7da7e9 100644 --- a/tools/capture_client_contract.py +++ b/tools/capture_client_contract.py @@ -41,8 +41,9 @@ two specs the server has not built, so a local recording starts on a fresh datasets database. `--scenarios-dir` writes outside the package, unvalidated. The run ends by validating the whole contract with -`tools/validate_client_contract.py`, and fails when it reports a problem or -the binary bodies pass 5 MB. +`tools/validate_client_contract.py`, and fails when it reports a problem, +when the binary bodies pass 5 MB, or when the records and bodies together pass +`SCENARIOS_BUDGET`, 16 MB. The outcome rules, error classes, gap kinds and long-build pacing come from `tools/validate_client_contract.py`, so a record's `expect` is written @@ -80,6 +81,7 @@ POLL_BACKOFF_CAP, POLL_BACKOFF_FIRST, POLL_PATH, + SCENARIOS_BUDGET, SIGNED_FETCH_STATUS, STORAGE_ORIGIN, TRACE_HEADER, @@ -107,7 +109,7 @@ header_warnings, held_spec, may_retry, - newest_listed, + newest_plain, owns_body_file, part_label, pick_artifact, @@ -118,6 +120,7 @@ rendering_for, resubmitted_sentence, retry_wait, + scenarios_size, search_body, search_warning_code, search_warns, @@ -1111,12 +1114,15 @@ def _stored_file( def _newest(self, spec_id: str) -> str | None: try: - body = self._acted(self._api("GET", versions_path(spec_id))) + return newest_plain( + lambda cursor: self._acted( + self._api("GET", versions_path(spec_id, cursor)) + ) + ) except ClientError as error: if error.error_class(self.client_codes) in NO_VERSIONS: return None raise - return newest_listed(body) def _acted(self, response: Response) -> Any: """The JSON body of a success. A refusal raises its error, and a @@ -1171,32 +1177,45 @@ def _build_body( # --- scenarios -------------------------------------------------------------- DEFINITE = "ODA disbursements from Germany to Nigeria for basic health care" -CANDIDATES = "GNI of Germany from 2015 to 2022" +CANDIDATES = "mortality in Kenya from 2013 to 2022" MIXED = "debt service of Kenya and the price of tea in Kenya" FOLDED = "ODA disbursements for health and for education from Germany to Kenya, and GDP of Kenya" -PLACE = "ODA disbursements from Germany to Congo" +PLACE = "ODA disbursements from Germany to Congo in 2018" TWO_PLACES = "Kenya's GDP, and ODA disbursements from Germany to Congo" DECLINED = "should donors give more aid to Kenya?" CATALOGUE = "what data do you have?" TOP5 = "top 5 donors to Ethiopia in 2022" PLACE_LABELS = ["Congo [DRC]", "Congo [Republic]"] CANDIDATES_BESIDE_GROUP = ( - "GNI of Germany from 2015 to 2022, and ODA disbursements from Germany to " - "sub-Saharan Africa" + "mortality in Kenya from 2013 to 2022, and GDP of sub-Saharan Africa" +) +TWO_CANDIDATES = "mortality in Kenya and emissions in Kenya from 2013 to 2022" +CANDIDATES_BESIDE_UNRESTATED = ( + "mortality in Kenya and savings of Kenya from 2013 to 2022" ) -TWO_CANDIDATES = "GNI of Germany and tax revenue of Kenya from 2015 to 2022" -CANDIDATES_BESIDE_UNRESTATED = "GNI of Germany and debt of Kenya from 2015 to 2022" GROUP_DEFINITE = "GDP of the least developed countries" -# A definite part whose places are a named group, beside a part whose -# direction the question leaves open, which offers one option per direction. -GROUP_BESIDE_OPTIONS = "GDP of sub-Saharan Africa, and debt of Kenya" +# A definite part whose places are a named group, beside a flow part whose +# direction the question leaves open, which offers one option per way to set +# the places on the flow's two sides. Search reads the flow's places into the +# group part too, so they are members of the group, which keeps it one group. +GROUP_BESIDE_OPTIONS = "GDP of the G20 in 2015, and Germany India ODA" GROUPED_FLOW = "Germany's ODA to the least developed countries" -CANDIDATES_BESIDE_ASSUMED = "GNI of Germany and aid flows to Kenya" +CANDIDATES_BESIDE_ASSUMED = ( + "mortality in Kenya and aid flows to Kenya from 2013 to 2022" +) # Two specs just above the 100,000-row sync budget, one for the mint and one # for the operation another process started: a version the server has built # answers inline, so each long build needs a spec the server has not built. -ASYNC = "ODA received by every recipient country from every provider (DAC2a) from 2018 to 2024" -ASYNC_RESUMED = "ODA received by every recipient country from every provider (DAC2a) from 2017 to 2024" +# A flow side the question leaves unnamed reads as its source's whole total, so +# both sides name groups read as their members: about 3,700 donor and +# recipient pairs of one variable over 60 years. A variable broken down by +# sector would list thousands of variables in the done manifest. +ASYNC = ( + "ODA disbursements from the DAC countries to the G77 countries from 1963 to 2024" +) +ASYNC_RESUMED = ( + "ODA disbursements from the OECD countries to the G77 countries from 1966 to 2024" +) NARROW_WINDOW = (2020, 2023) REBOUND_ORIGIN = "country/FRA" SYNC_ROWS = 100_000 @@ -1576,6 +1595,11 @@ def _fetch_ref_newest_version(s: Session, ctx: Context) -> None: spec = ctx.definite_spec(DEFINITE) newest = s.newest_version(spec) require(newest == member["content_version"], "the stored version is the newest") + listed = s.recorder.exchanges[-1]["response"]["json"]["versions"] + require( + listed[0]["base_content_version"] is not None, + "a version derived from the stored one is listed before it", + ) def _resubmit_placeholder(s: Session, ctx: Context) -> None: @@ -1600,7 +1624,7 @@ def _resubmit_placeholder(s: Session, ctx: Context) -> None: ), Recorded( "answer-candidates-choose-fetch", - "A question with three readings answers one candidates part, a choice gap with three " + "A question with two readings answers one candidates part, a choice gap with two " "options. Choosing option 0 posts that candidate's identity to Search as the one " "dataset_resubmit identity entry, echoing the part's reading_assumptions under its " "spec_id as assumptions. Search answers that reading definite with its own sentence, " @@ -1795,13 +1819,15 @@ def _resubmit_placeholder(s: Session, ctx: Context) -> None: "open, beside a definite part whose places are a named group posts dataset_resubmit " "with the definite part's identity, entity_groups and assumptions as an identity " "entry, and the chosen option's data_query part as a parsed entry. Part 0 answers " - "definite again, and part 1 answers the debt read in the chosen direction.", + "definite again, and part 1 answers the ODA read in the chosen direction.", _choose_option_beside_definite, ), Recorded( "fetch-ref-newest-version", - "The newest stored version of a spec is the one the versions route lists first, so " - "the client asks for it alone with limit=1. The route needs no key.", + "The newest stored version of a spec is the first version the versions route lists " + "with no base_content_version, the newest plain build, so a version derived from it " + "and listed first is skipped. The client reads the route a page of 100 versions at a " + "time, following next_cursor until a plain version is listed. The route needs no key.", _fetch_ref_newest_version, ), Recorded( @@ -3532,7 +3558,7 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: "whose snapshot refuses 410 artifact_expired and whose rebuild refuses 422 " "member_not_resolvable, comes before the parent's versions exchange.", "When the stored version has expired and the build is refused, the client asks the " - "versions route for the newest version alone with limit=1, and raises " + "versions route for the newest plain version, and raises " "VersionUnavailableError with the snapshot's artifact_expired code and that version " "as the newest.", _expired_not_reproducible, @@ -4440,12 +4466,22 @@ def run_record(args: argparse.Namespace) -> int: record_synthetic(synthetic, ctx, directory) count += 1 total = binary_total(directory) - print(f"{count} scenario(s) written; binary bodies {total:,} bytes") + size = scenarios_size(directory) + print( + f"{count} scenario(s) written; binary bodies {total:,} bytes, " + f"records and bodies {size:,} bytes" + ) if count == 0: return 1 if total > BINARY_BUDGET: print(f"binary bodies pass the {BINARY_BUDGET:,}-byte budget", file=sys.stderr) return 1 + if size > SCENARIOS_BUDGET: + print( + f"records and bodies pass the {SCENARIOS_BUDGET:,}-byte budget", + file=sys.stderr, + ) + return 1 if args.scenarios_dir is not None: return 0 return validate_main() diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index c824b32..58fa9c3 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -8,7 +8,8 @@ unredacted URL, and a ref example with the wrong verdict. Each case validates a whole copy of the contract, the served document's -bodies included, which takes about a third of a second. +bodies included, which takes about a third of a second. The copy hard-links +the package's files, so it writes no data where the file system allows. Run with: uv run --with jsonschema --with pytest pytest tools/tests -q """ @@ -18,6 +19,7 @@ import copy import importlib.util import json +import os import shutil import sys from collections.abc import Callable @@ -59,11 +61,23 @@ def _posted(index: int, change: Callable[[Any], None]) -> Callable[[Any], None]: ) +def _link_or_copy(source: str, target: str) -> None: + """Hard-links `source` at `target`, or copies it where the two paths are + on different file systems.""" + try: + os.link(source, target) + except OSError: + shutil.copy2(source, target) + + @pytest.fixture def package_dir(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path: - """A copy of the real contract and registry the test may break.""" + """A copy of the real contract and registry the test may break. The + package's files are hard links, so the copy writes no data; a test + changes a file only through `_edit`, which replaces it, or adds, renames + or removes files, none of which reaches the real package.""" copy = tmp_path / "dfo_client_contract" - shutil.copytree(validator.PACKAGE_DIR, copy) + shutil.copytree(validator.PACKAGE_DIR, copy, copy_function=_link_or_copy) registry = tmp_path / "codes.json" shutil.copyfile(validator.REGISTRY_PATH, registry) monkeypatch.setattr(validator, "PACKAGE_DIR", copy) @@ -74,6 +88,8 @@ def package_dir(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path: def _edit(path: Path, change: Callable[[Any], None]) -> None: document = json.loads(path.read_text(encoding="utf-8")) change(document) + # A hard link written in place would change the real package's file. + path.unlink() path.write_text(json.dumps(document), encoding="utf-8") @@ -346,6 +362,14 @@ def _second_fetch_served(doc: Any) -> None: _BUSY_THEN_CUT_OFF = "scenarios/fetch-spec-503-then-504.json" +def _recorded_origin(name: str) -> str: + """The origin of the API the recorded scenario `name` was recorded against.""" + path = validator.PACKAGE_DIR / "scenarios" / f"{name}.json" + base_url = json.loads(path.read_text(encoding="utf-8"))["origin"]["base_url"] + parts = urlsplit(base_url) + return f"{parts.scheme}://{parts.netloc}" + + def _artifact_urls(origin: str) -> Callable[[Any], None]: """The build's artifact urls become absolute on `origin`.""" @@ -682,7 +706,7 @@ def change(doc: Any) -> None: ), ( "scenarios/choose-refused-option-out-of-range.json", - _set_step(1, option=2), + _set_step(1, option=1), "the steps make a POST /search/resolve the record lacks", ), ( @@ -825,6 +849,30 @@ def change(doc: Any) -> None: lambda doc: doc["ref"]["members"].pop(), "breaks rule None, expected 'repeated_spec_id'", ), + ( + "refs/ref-one-member.json", + lambda doc: doc["ref"]["members"][0]["artifact"].update( + digest="sha256:" + "0" * 64 + ), + f"member 0 digest sha256:{'0' * 64} is no file", + ), + ( + "refs/ref-one-member.json", + lambda doc: doc["ref"]["members"][0].update( + content_version="cv_" + "0" * 32 + ), + "member 0 content_version is not fetch-spec-known-sentence's", + ), + ( + "refs/ref-one-member.json", + lambda doc: doc.update(scenario="fetch-spec-frame-layout"), + "member 0 is no member fetch-spec-frame-layout serves", + ), + ( + "refs/ref-one-member.json", + lambda doc: doc.pop("scenario"), + "names no scenario that serves its members", + ), ( "rules/key-format.json", lambda doc: doc["vectors"].append(doc["vectors"][0]), @@ -1020,7 +1068,7 @@ def change(doc: Any) -> None: ( _NOT_REPRODUCIBLE, lambda doc: doc["exchanges"][-1]["request"].update( - path=doc["exchanges"][-1]["request"]["path"].removesuffix("?limit=1") + path=doc["exchanges"][-1]["request"]["path"].partition("?")[0] ), "where the steps make a GET", ), @@ -1277,7 +1325,7 @@ def change(doc: Any) -> None: ), ( _FOREIGN_ARTIFACT, - _artifact_urls("http://127.0.0.1:19493"), + _artifact_urls(_recorded_origin("fetch-spec-known-sentence")), "the steps make a GET /api/datasets/", ), ( @@ -1294,7 +1342,7 @@ def change(doc: Any) -> None: ), (_SERVER_WARNING, _warned(2, ["route_deprecated"]), "step 2 expects"), (_SERVER_WARNING, _warned(2, ["server_warning"]), "step 2 expects"), - (_POLL_REFUSED, _repeat(4, 1), "the steps never make exchanges 7 to 15"), + (_POLL_REFUSED, _repeat(4, 1), "the steps never make exchanges 7 to"), ( _POLL_REFUSED, _set_outcome( @@ -1631,6 +1679,10 @@ def change(doc: Any) -> None: "body-file-misnamed", "ref-example-both-verdicts", "ref-example-wrong-verdict", + "ref-digest-stale", + "ref-content-version-stale", + "ref-member-not-served", + "ref-without-scenario", "rule-vector-repeated", "client-code-without-condition", "client-codes-unsorted", @@ -2125,17 +2177,82 @@ def test_a_candidate_label_is_its_heading_or_its_sentence( assert validator.candidate_label(_candidate(**resolved)) == label +_PLAIN = {"content_version": "cv_plain", "base_content_version": None} +_DERIVED = {"content_version": "cv_derived", "base_content_version": "cv_plain"} + + +@pytest.mark.parametrize( + ("pages", "newest"), + [ + ([{"versions": [_PLAIN], "next_cursor": None}], "cv_plain"), + ([{"versions": [_DERIVED, _PLAIN], "next_cursor": None}], "cv_plain"), + ( + [ + {"versions": [_DERIVED], "next_cursor": "c1"}, + {"versions": [_PLAIN], "next_cursor": None}, + ], + "cv_plain", + ), + ([{"versions": [_DERIVED], "next_cursor": None}], None), + ([{"versions": [], "next_cursor": None}], None), + ], +) +def test_the_newest_version_is_the_first_plain_one_listed( + pages: list[dict[str, Any]], newest: str | None +) -> None: + cursors: list[str | None] = [] + + def page(cursor: str | None) -> dict[str, Any]: + cursors.append(cursor) + return pages[len(cursors) - 1] + + assert validator.newest_plain(page) == newest + assert cursors == [None, *(p["next_cursor"] for p in pages[:-1])] + + +@pytest.mark.parametrize( + "body", + [ + {"items": [_PLAIN], "next_cursor": None}, + {"versions": [{"content_version": "cv_plain"}], "next_cursor": None}, + {"versions": [{**_PLAIN, "base_content_version": 1}], "next_cursor": None}, + {"versions": [_DERIVED], "next_cursor": 1}, + {"versions": [_PLAIN], "next_cursor": 1}, + ], +) +def test_an_unreadable_versions_page_raises(body: dict[str, Any]) -> None: + with pytest.raises(validator.ClientError) as raised: + validator.newest_plain(lambda _: body) + assert raised.value.code == "contract_violation" + + def test_a_required_member_that_admits_null_stays_required() -> None: """A recorded body must carry a required member, null or not.""" served = validator.PACKAGE_DIR / "served" / "openapi.json" routes = validator._Routes(json.loads(served.read_text(encoding="utf-8"))) page = "/components/schemas/DatasetVersionsPage" - body = {"spec_id": "spec_" + "0" * 32, "versions": [], "complete": True} + body = { + "spec_id": "spec_" + "0" * 32, + "enrichment_stamp": "0" * 64, + "versions": [], + "complete": True, + } assert routes.validate(page, {**body, "next_cursor": None}) == [] problems = routes.validate(page, body) assert any("'next_cursor' is a required property" in p for p in problems) +def test_scenarios_past_their_budget_are_reported( + package_dir: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + size = validator.scenarios_size(package_dir / "scenarios") + assert f"scenarios: {size:,} bytes pass" not in " ".join(validator.validate()) + monkeypatch.setattr(validator, "SCENARIOS_BUDGET", size - 1) + assert f"scenarios: {size:,} bytes pass the {size - 1:,}-byte budget" in ( + validator.validate() + ) + + def test_no_scenarios_is_a_hard_failure(package_dir: Path) -> None: for path in (package_dir / "scenarios").iterdir(): path.unlink() diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index 64a2174..3ead4d7 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -75,10 +75,15 @@ a record holds, a `url` request or a `location` header, is a signed URL on the storage host with the query `X-Goog-Signature=redacted`, or a `location` under the base URL. +- `scenarios/`, records and body files together, holds at most + SCENARIOS_BUDGET bytes. - Each ref example's file name matches its `name` and gets the verdict it states: from `dataset-ref.schema.json`, then from the rules that each member's definition carries its own `spec_id` and that members hold - distinct `spec_id`s. + distinct `spec_id`s. A ref example whose ref holds members names the + recorded `scenario` that serves them, and each member's `spec_id`, + `content_version` and `sentence` are a dataset member's of that scenario, + and its artifact digest is the digest of a file the scenario downloads. - Each rule file under `rules/` validates against `rules.schema.json`, names the rule its file name names, and names each vector once. @@ -98,7 +103,7 @@ from functools import partial from pathlib import Path from typing import Any -from urllib.parse import urljoin, urlsplit, urlunsplit +from urllib.parse import quote, urljoin, urlsplit, urlunsplit import jsonschema from referencing import Registry, Resource @@ -107,6 +112,9 @@ REPO_ROOT = Path(__file__).resolve().parent.parent PACKAGE_DIR = REPO_ROOT / "python" / "client-contract" / "src" / "dfo_client_contract" REGISTRY_PATH = REPO_ROOT / "registries" / "codes.json" +# The bytes `scenarios/` may hold, records and body files together. Each test +# of this module copies the whole package, so the budget bounds their disk use. +SCENARIOS_BUDGET = 16_000_000 _OPENAPI_URI = "urn:dfo-client-contract:served-openapi" _ACTION_CHANNELS = {"problem_details", "no_data_reason"} @@ -1773,10 +1781,15 @@ def posted_scope(step: Mapping[str, Any]) -> dict[str, Any] | None: return scope or None -def versions_path(spec_id: str) -> str: - """The versions route asked for the newest stored version alone. The - route lists versions newest first, so `limit=1` returns just it.""" - return f"/datasets/{spec_id}/versions?limit=1" +# The versions a client asks the versions route for on each page. +VERSIONS_PAGE = 100 + + +def versions_path(spec_id: str, cursor: str | None = None) -> str: + """One page of the versions route, VERSIONS_PAGE versions newest first, + continuing after `cursor` when one is given.""" + path = f"/datasets/{spec_id}/versions?limit={VERSIONS_PAGE}" + return path if cursor is None else f"{path}&cursor={quote(cursor, safe='')}" def search_body(input_: Mapping[str, Any]) -> dict[str, Any]: @@ -1784,17 +1797,41 @@ def search_body(input_: Mapping[str, Any]) -> dict[str, Any]: return {"schema_version": 1, "input": input_} -def newest_listed(body: Any) -> str | None: - """The newest version a versions page lists, its first, or None when it - lists none. A body whose `versions` is not a list of versions, each with - a `content_version`, raises ContractError.""" - versions = body.get("versions") if isinstance(body, dict) else None - if not isinstance(versions, list) or not all( - isinstance(v, dict) and isinstance(v.get("content_version"), str) - for v in versions - ): - raise ClientError("contract_violation") - return versions[0]["content_version"] if versions else None +def _listed_version(version: Any) -> bool: + return ( + isinstance(version, dict) + and isinstance(version.get("content_version"), str) + and "base_content_version" in version + and isinstance(version["base_content_version"], str | None) + ) + + +def newest_plain(page: Callable[[str | None], Any]) -> str | None: + """The newest stored version, the first the versions route lists with no + `base_content_version`, a plain build and never a version derived from + one, or None when the list ends without one. `page` answers the page + after a cursor, the first for None, and the walk follows `next_cursor` + until it is null. Each page is read whole before any version on it is + taken: a page whose `versions` is not a list of versions, each with a + `content_version` and a `base_content_version` that is a string or + null, or whose `next_cursor` is neither a string nor null, raises + ContractError, even when it lists a plain version.""" + cursor: str | None = None + while True: + body = page(cursor) + versions = body.get("versions") if isinstance(body, dict) else None + cursor = body.get("next_cursor") if isinstance(body, dict) else None + if ( + not isinstance(versions, list) + or not all(map(_listed_version, versions)) + or not isinstance(cursor, str | None) + ): + raise ClientError("contract_violation") + for version in versions: + if version["base_content_version"] is None: + return version["content_version"] + if cursor is None: + return None def stored_version[T]( @@ -2528,16 +2565,18 @@ def stored_file( return True, None def newest(self, spec_id: str) -> str | None: - """The newest stored version, the one the versions route lists first, - or None when it lists none or refuses the spec as unknown. A page - that lists no versions in the form `newest_listed` reads raises.""" + """The newest stored version, as `newest_plain` reads the versions + route, or None when the route refuses the spec as unknown.""" try: - body = self.acted_on(self.call("GET", versions_path(spec_id))) + return newest_plain( + lambda cursor: self.acted_on( + self.call("GET", versions_path(spec_id, cursor)) + ) + ) except ClientError as error: if error.error_class(self.client_codes) in NO_VERSIONS: return None raise - return newest_listed(body) # -- steps -- @@ -3189,6 +3228,57 @@ def _ref_rule(ref: dict[str, Any]) -> str | None: return None +def _served_by(label: str, record: dict[str, Any]) -> list[str]: + """Where a ref example's members differ from the members its `scenario` + serves: a `spec_id` no dataset member of it has, another + `content_version` or `sentence`, or an artifact digest that is not the + digest of a file the scenario downloads. A ref with no members names no + scenario.""" + ref = record.get("ref") + members = ref.get("members") if isinstance(ref, dict) else None + if not isinstance(members, list) or not members: + return [] + name = record.get("scenario") + directory = PACKAGE_DIR / "scenarios" + path = directory / f"{name}.json" + scenario = _load(path) if isinstance(name, str) and path.is_file() else None + if not isinstance(scenario, dict): + return [f"{label}: names no scenario that serves its members"] + served = { + member.get("spec_id"): member + for outcome in read_objects(scenario, "expect") + for member in read_objects(read_object(outcome, "dataset"), "members") + } + digests = set() + for exchange in read_objects(scenario, "exchanges"): + body_file = read_string(read_object(exchange, "response"), "body_file") + try: + path = body_path(directory, body_file) if body_file else None + except ValueError: + continue # the scenario check reports a body file it cannot read + if path is not None and path.is_file(): + digests.add(digest_of(path.read_bytes())) + problems = [] + for index, member in enumerate(members): + spec = member.get("spec") if isinstance(member, dict) else None + found = served.get(spec.get("spec_id") if isinstance(spec, dict) else None) + if found is None: + problems.append(f"{label}: member {index} is no member {name} serves") + continue + problems.extend( + f"{label}: member {index} {key} is not {name}'s {found.get(key)!r}" + for key in ("content_version", "sentence") + if member.get(key) != found.get(key) + ) + artifact = member.get("artifact") + digest = artifact.get("digest") if isinstance(artifact, dict) else None + if digest not in digests: + problems.append( + f"{label}: member {index} digest {digest} is no file {name} downloads" + ) + return problems + + def _check_refs(validator: jsonschema.Draft202012Validator) -> list[str]: paths = sorted((PACKAGE_DIR / "refs").glob("*.json")) problems = [] if paths else ["refs: no ref examples found"] @@ -3199,6 +3289,7 @@ def _check_refs(validator: jsonschema.Draft202012Validator) -> list[str]: if not isinstance(record, dict) or record.get("name") != path.stem: problems.append(f"{label}: name does not match the file name") continue + problems.extend(_served_by(label, record)) error = record.get("error") if ("expect" in record) == isinstance(error, dict): problems.append(f"{label}: carries neither or both of expect and error") @@ -3253,6 +3344,14 @@ def _check_rules(validator: jsonschema.Draft202012Validator) -> list[str]: return problems +def scenarios_size(directory: Path) -> int: + """The bytes of every file in `directory`, records and body files, or 0 + when it does not exist.""" + if not directory.is_dir(): + return 0 + return sum(path.stat().st_size for path in directory.iterdir() if path.is_file()) + + def validate() -> list[str]: validators = _contract_validators() openapi = _load(PACKAGE_DIR / "served" / "openapi.json") @@ -3332,6 +3431,11 @@ def validate() -> list[str]: served_commit=source.get("commit") if isinstance(source, dict) else None, ) ) + size = scenarios_size(PACKAGE_DIR / "scenarios") + if size > SCENARIOS_BUDGET: + problems.append( + f"scenarios: {size:,} bytes pass the {SCENARIOS_BUDGET:,}-byte budget" + ) problems.extend(_check_refs(validators["dataset-ref.schema.json"])) problems.extend(_check_rules(validators["rules/rules.schema.json"])) return problems From d8a82713d718a23b3ce88844c51741a6f9d96085 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Fri, 23 Oct 2026 23:06:09 +0200 Subject: [PATCH 35/39] feat(client-contract): add client codes for unsafe keys, headers, base URLs, transport and oversized bodies (#16) key_invalid, credentials_file_unreadable, header_invalid, insecure_transport, base_url_invalid and response_too_large let the clients refuse an unsafe key, header value or base URL, a key over plain http to a remote host, an unreadable credentials file and a decoded body past its cap, each under its own code. None is retryable. --- python/client-contract/CHANGELOG.md | 2 +- python/client-contract/README.md | 2 +- .../src/dfo_client_contract/client-codes.json | 36 +++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index 52d87a2..37e7d4c 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -12,7 +12,7 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be - `actions.json` and its schema: the caller's next step for each of the 101 active refusal codes on `problem_details` or `no_data_reason`, with the gap kind of each no_data reason. - The status fallback for a refusal whose code has no row: 400 and 422 to `InvalidRequestError`, 401 to `AuthenticationError`, 403 to `PermissionDeniedError`, 404 and 410 to `NotFoundError`, 408 to `DfoTimeoutError`, 429 to `RateLimitError`, and any other 4xx or 5xx to `InvalidRequestError` or `ServerError`. - `scenario.schema.json`, the scenario record, and 118 scenarios: 31 recorded against the deployed dfo-apis dev app at `035d29cd0`, and 87 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 1,124,502 bytes and records and bodies together 13,080,568 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, a part without variable_text, an unknown status without a restatement, a shared label, a one-part option whose data_query holds two parts, the separate and operations echo, an unsupported part's placeholder, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a cut-off build retried after its Retry-After, a build refused 504 then 503 and one refused 503 then 504, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, a signed URL refused on both rounds, a relative files-route Location, an artifact url on a foreign origin, on the storage host and absolute on the API's origin, a manifest definition without identity or schema_version, a Search spec without identity or resolved, nested specs no rule reads, an empty parts list, a Search body that is not an object, a codeless 503 problem document that is not retryable, a 401, an identity resubmit answering another spec, a part whose status is not a string, a Search spec whose definition names another spec_id, a Search response with no JSON body, an option with no data_query, empty entities and facets, a Sunset header issued once, `x-dfo-warning` messages and a Deprecation and Sunset pair, an unreadable versions page, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, 503 polls retried within the budget an answered poll restores, a 404 poll that raises, a failed operation posted again, a failed operation with no error, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route: the first version it lists with no `base_content_version`, the newest plain build, so a derived version listed before it is skipped. -- `client-codes.json` and its schema: the 17 codes a client sets on the errors it raises itself, each with its error class, retryable flag and condition, disjoint from `actions.json` and `registries/codes.json`, and the `client_codes()` and `client_codes_schema()` accessors. Every scenario error the client raises itself carries its code, and `refusal_without_code` names a refusal whose body carries no code. +- `client-codes.json` and its schema: the 23 codes a client sets on the errors it raises itself, each with its error class, retryable flag and condition, disjoint from `actions.json` and `registries/codes.json`, and the `client_codes()` and `client_codes_schema()` accessors. Every scenario error the client raises itself carries its code, and `refusal_without_code` names a refusal whose body carries no code. - `proxy-codes.json` and its schema, the website proxy's `rate_limited` and `transient_unavailable` codes with their statuses, and `warning-codes.json` and its schema, the 5 codes a client sets on the warnings it issues itself, with the `proxy_codes()` and `warning_codes()` accessors. - Error outcomes give the error's `trace_id`, the body's, else the `x-dfo-trace-id` header's, else null. Scenario outcomes give `retry_waits`, the waits before each retry, and `warnings`, the warning codes a step's responses issued. Scenario steps take no `timeout`. - `dataset-ref.schema.json`, the frozen `DatasetRef` format, with accepted and rejected examples. diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 711d150..6ab5070 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -118,7 +118,7 @@ An answer's gaps follow from its parts. A candidates part is a `choice` gap, its ## Client codes -`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, `retryable`, and a one-line `condition`. `retryable` is the flag both clients generate onto the error: `deadline_exceeded`, `download_failed` and `network_error` are retryable, `digest_mismatch` and the rest are not, and `refusal_without_code` is retryable as its status is, which its row gives as `by_status`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps the server's code: the problem document's `code`, or the website proxy's `error`. A refusal whose body carries neither raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`. No other row does. A problem document without a code still gives the error its `retryable` and `trace_id`, so a 503 whose body says `retryable: false` raises at once, which `search-refused-without-code` pins. Every refusal's trace id is the response's trace id, as the trace-id rule under Scenarios gives it. `search-refused-without-code` pins the body's winning over the header, and `search-unauthorized` the header's for a refusal with no body. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. Each reason the key-lookup rule raises, `key_empty`, `profile_not_found`, `profile_without_key` and `credentials_file_invalid`, is a row of class `AuthenticationError`. The list holds no warning. `warning-codes.json` lists, sorted by code, each code a client sets on a warning it issues itself, with its class and condition: `route_deprecated`, a `DfoDeprecationWarning`, for a `Deprecation` or `Sunset` header; `server_warning`, a `DfoWarning`, for an `x-dfo-warning` header; and `key_checksum_mismatch`, `key_not_base62` and `key_unknown_prefix`, each a `DfoWarning`, for a key that fails the key-format rule with that reason. Both clients generate their warning codes from it and issue no other. No warning code is a code in another table or in `registries/codes.json`. A `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and a null code when they differ in several ways. A `DataWarning` carries the manifest warning's code. +`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, `retryable`, and a one-line `condition`. `retryable` is the flag both clients generate onto the error: `deadline_exceeded`, `download_failed` and `network_error` are retryable, `digest_mismatch` and the rest are not, and `refusal_without_code` is retryable as its status is, which its row gives as `by_status`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps the server's code: the problem document's `code`, or the website proxy's `error`. A refusal whose body carries neither raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`. No other row does. A problem document without a code still gives the error its `retryable` and `trace_id`, so a 503 whose body says `retryable: false` raises at once, which `search-refused-without-code` pins. Every refusal's trace id is the response's trace id, as the trace-id rule under Scenarios gives it. `search-refused-without-code` pins the body's winning over the header, and `search-unauthorized` the header's for a refusal with no body. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. Each reason the key-lookup rule raises, `key_empty`, `profile_not_found`, `profile_without_key` and `credentials_file_invalid`, is a row of class `AuthenticationError`, as are `key_invalid`, a key outside visible ASCII, and `credentials_file_unreadable`, a credentials file that exists but cannot be read. `header_invalid`, a header value with a control character, `insecure_transport`, a key over plain http to a non-loopback host, and `base_url_invalid`, a base URL that is empty, not absolute http or https, or carries userinfo, are `InvalidRequestError` rows. `response_too_large`, a decoded body past its cap, is a `ServerError` row. None of these six is retryable. The list holds no warning. `warning-codes.json` lists, sorted by code, each code a client sets on a warning it issues itself, with its class and condition: `route_deprecated`, a `DfoDeprecationWarning`, for a `Deprecation` or `Sunset` header; `server_warning`, a `DfoWarning`, for an `x-dfo-warning` header; and `key_checksum_mismatch`, `key_not_base62` and `key_unknown_prefix`, each a `DfoWarning`, for a key that fails the key-format rule with that reason. Both clients generate their warning codes from it and issue no other. No warning code is a code in another table or in `registries/codes.json`. A `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and a null code when they differ in several ways. A `DataWarning` carries the manifest warning's code. ## Scenarios diff --git a/python/client-contract/src/dfo_client_contract/client-codes.json b/python/client-contract/src/dfo_client_contract/client-codes.json index f1bedd5..e4486fe 100644 --- a/python/client-contract/src/dfo_client_contract/client-codes.json +++ b/python/client-contract/src/dfo_client_contract/client-codes.json @@ -13,6 +13,12 @@ "retryable": false, "condition": "Fetching an answer with a part that has no reading, when the fetch is not partial or no part has a reading." }, + { + "code": "base_url_invalid", + "class": "InvalidRequestError", + "retryable": false, + "condition": "A base URL is empty, is not an absolute http or https URL, or carries userinfo." + }, { "code": "choice_invalid", "class": "InvalidRequestError", @@ -31,6 +37,12 @@ "retryable": false, "condition": "The credentials file breaks the credentials-file rule." }, + { + "code": "credentials_file_unreadable", + "class": "AuthenticationError", + "retryable": false, + "condition": "The credentials file exists but cannot be read." + }, { "code": "deadline_exceeded", "class": "DfoTimeoutError", @@ -49,6 +61,18 @@ "retryable": true, "condition": "The signed URL a files route names refused, or its fetch failed, after the route was asked once more." }, + { + "code": "header_invalid", + "class": "InvalidRequestError", + "retryable": false, + "condition": "A header value holds a control character." + }, + { + "code": "insecure_transport", + "class": "InvalidRequestError", + "retryable": false, + "condition": "A key would travel over plain http to a host that is not loopback." + }, { "code": "invalid_argument", "class": "InvalidRequestError", @@ -61,6 +85,12 @@ "retryable": false, "condition": "The api_key argument is an empty string." }, + { + "code": "key_invalid", + "class": "AuthenticationError", + "retryable": false, + "condition": "The api_key holds a character outside visible ASCII." + }, { "code": "network_error", "class": "NetworkError", @@ -91,6 +121,12 @@ "retryable": "by_status", "condition": "A refusal whose body carries no code: neither a problem document nor the website proxy's own body." }, + { + "code": "response_too_large", + "class": "ServerError", + "retryable": false, + "condition": "A decoded response body passes its size cap." + }, { "code": "unexpected_response", "class": "ContractError", From ca98b118a1faab6bce12b44cff055704302d6624 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Sat, 24 Oct 2026 00:09:07 +0200 Subject: [PATCH 36/39] feat(client-contract): admit without_party_totals in a ref's artifact rendering (#17) dataset-ref.schema.json closes the rendering selector with additionalProperties false, so a ref to a version minted with without_party_totals could not be written by either client. The selector now takes without_party_totals: true beside layout. The key is written only when true, so a plain ref keeps its bytes and false is refused. ref-without-party-totals is the accepted example and ref-without-party-totals-false-rejected pins false. --- python/client-contract/CHANGELOG.md | 1 + python/client-contract/README.md | 2 +- .../dataset-ref.schema.json | 4 + ...f-without-party-totals-false-rejected.json | 99 +++++++++++++++++++ .../refs/ref-without-party-totals.json | 97 ++++++++++++++++++ 5 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 python/client-contract/src/dfo_client_contract/refs/ref-without-party-totals-false-rejected.json create mode 100644 python/client-contract/src/dfo_client_contract/refs/ref-without-party-totals.json diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index 37e7d4c..87cfe85 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -16,6 +16,7 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be - `proxy-codes.json` and its schema, the website proxy's `rate_limited` and `transient_unavailable` codes with their statuses, and `warning-codes.json` and its schema, the 5 codes a client sets on the warnings it issues itself, with the `proxy_codes()` and `warning_codes()` accessors. - Error outcomes give the error's `trace_id`, the body's, else the `x-dfo-trace-id` header's, else null. Scenario outcomes give `retry_waits`, the waits before each retry, and `warnings`, the warning codes a step's responses issued. Scenario steps take no `timeout`. - `dataset-ref.schema.json`, the frozen `DatasetRef` format, with accepted and rejected examples. +- `without_party_totals` in the ref's artifact rendering, `true` for the version rendered with party totals left out and absent for a plain rendering, with `ref-without-party-totals` and `ref-without-party-totals-false-rejected` as its examples. - `tools/capture_client_contract.py`, which captures `served/openapi.json` from a dfo-apis checkout in process and records the scenarios against a base URL, dev by default, or with `record --offline` derives their outcomes again from the records with no request. A local app's signed URLs are written as the storage URLs a deployment signs. - `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, checks `client-codes.json` against them and against the reasons the key-lookup rule raises, and checks each scenario's `expect` against the outcomes its exchanges, `actions.json` and `client-codes.json` give, each Search request against the input its steps derive, a sentence lookup's `entity_groups` included, each build's `input.scope` against the narrowing its step names over the spec's bound roles, each build's options against its layout, each Search request's whole body, each download against its artifact's digest, each recorded scenario's commit against `served/SOURCE.json`, each proxy refusal's code against `proxy-codes.json`, and each absolute URL against the storage host, each ref example's members against the dataset members and downloaded files of the scenario it names, and the scenarios directory against a 16,000,000-byte budget for records and bodies together. A record that ends a run of retries while a retry remains does not fit. The outcomes include each long build's operation id, poll waits and resubmissions, and a `VersionUnavailableError`'s newest version. - The client rules and their vectors: the credentials path and file format, the key lookup order, with an empty `api_key` refused as `key_empty` and an empty profile key as `profile_without_key`, the key format check, and the cache directory and layout. diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 6ab5070..1a175ec 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -211,7 +211,7 @@ A record's `origin.base_url` is the base URL the run was given, a local app's in ## DatasetRef -`dataset-ref.schema.json` is the frozen format a client writes for `data.ref` and reads back in any language: `format_version: 1` and one or more `members`, each `{parts, sentence, spec: {spec_id, definition}, content_version, artifact: {digest, rendering}}`. `parts` holds the variable text of each answer part the member answers, in query order, and is empty for a spec fetched outside an answer. `definition` is the server's definition unmodified, so it holds the `schema_version`, `spec_id` and `identity` the served `CanonicalDefinition` requires and no other member, and a rebuild posts it as it is. The format takes any integer `schema_version` and leaves the version to the server, which checks it when a rebuild posts the definition. `rendering` is the selector a client matches an artifact on, `{format, bundle}` with `layout: "frame"` for the frame layout, never the server's rendering object. Beyond the schema, each member's `definition.spec_id` equals its `spec.spec_id`, and members hold distinct `spec_id`s. `ref-bare-definition-rejected`, `ref-definition-without-identity-rejected` and `ref-definition-without-schema-version-rejected` pin the definition's required members, and `ref-definition-extra-member-rejected` a member it does not admit. `refs/` holds accepted examples and rejected ones, each `{format_version, name, description, scenario, ref}` with `expect: "accept"` or `error`, `{by: "schema"}` or `{by: "rule", reason}`, the reason `definition_spec_id_mismatch` or `repeated_spec_id`. `scenario` names the recorded scenario that serves the ref's members, and is left out of a ref with no members. Each member's `spec_id`, `content_version` and `sentence` are those of a dataset member of that scenario, and its artifact digest is the digest of a file the scenario downloads, so a re-recording that changes a member also fails the refs that still name the old one. +`dataset-ref.schema.json` is the frozen format a client writes for `data.ref` and reads back in any language: `format_version: 1` and one or more `members`, each `{parts, sentence, spec: {spec_id, definition}, content_version, artifact: {digest, rendering}}`. `parts` holds the variable text of each answer part the member answers, in query order, and is empty for a spec fetched outside an answer. `definition` is the server's definition unmodified, so it holds the `schema_version`, `spec_id` and `identity` the served `CanonicalDefinition` requires and no other member, and a rebuild posts it as it is. The format takes any integer `schema_version` and leaves the version to the server, which checks it when a rebuild posts the definition. `rendering` is the selector a client matches an artifact on, `{format, bundle}` with `layout: "frame"` for the frame layout and `without_party_totals: true` for the version rendered with party totals left out, never the server's rendering object. The `without_party_totals` key is written only when true, so a plain rendering omits it and `false` is not a valid value. Beyond the schema, each member's `definition.spec_id` equals its `spec.spec_id`, and members hold distinct `spec_id`s. `ref-bare-definition-rejected`, `ref-definition-without-identity-rejected` and `ref-definition-without-schema-version-rejected` pin the definition's required members, and `ref-definition-extra-member-rejected` a member it does not admit. `ref-without-party-totals` is the accepted cut rendering and `ref-without-party-totals-false-rejected` pins `false`. `refs/` holds accepted examples and rejected ones, each `{format_version, name, description, scenario, ref}` with `expect: "accept"` or `error`, `{by: "schema"}` or `{by: "rule", reason}`, the reason `definition_spec_id_mismatch` or `repeated_spec_id`. `scenario` names the recorded scenario that serves the ref's members, and is left out of a ref with no members. Each member's `spec_id`, `content_version` and `sentence` are those of a dataset member of that scenario, and its artifact digest is the digest of a file the scenario downloads, so a re-recording that changes a member also fails the refs that still name the old one. ## Rules diff --git a/python/client-contract/src/dfo_client_contract/dataset-ref.schema.json b/python/client-contract/src/dfo_client_contract/dataset-ref.schema.json index 88cbedf..4e59f21 100644 --- a/python/client-contract/src/dfo_client_contract/dataset-ref.schema.json +++ b/python/client-contract/src/dfo_client_contract/dataset-ref.schema.json @@ -117,6 +117,10 @@ }, "layout": { "const": "frame" + }, + "without_party_totals": { + "description": "Selects the artifact rendered with party totals left out. The key is absent for a plain rendering, so `false` is not a valid value.", + "const": true } } } diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-without-party-totals-false-rejected.json b/python/client-contract/src/dfo_client_contract/refs/ref-without-party-totals-false-rejected.json new file mode 100644 index 0000000..d59e933 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/refs/ref-without-party-totals-false-rejected.json @@ -0,0 +1,99 @@ +{ + "format_version": 1, + "name": "ref-without-party-totals-false-rejected", + "description": "The rendering names without_party_totals only when it is true, so false is not a ref.", + "scenario": "fetch-spec-known-sentence", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "artifact": { + "digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", + "rendering": { + "format": "parquet", + "bundle": false, + "without_party_totals": false + } + } + } + ] + }, + "error": { + "by": "schema" + } +} diff --git a/python/client-contract/src/dfo_client_contract/refs/ref-without-party-totals.json b/python/client-contract/src/dfo_client_contract/refs/ref-without-party-totals.json new file mode 100644 index 0000000..e458ea3 --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/refs/ref-without-party-totals.json @@ -0,0 +1,97 @@ +{ + "format_version": 1, + "name": "ref-without-party-totals", + "description": "A ref to the version rendered with party totals left out, the member of fetch-spec-known-sentence.", + "scenario": "fetch-spec-known-sentence", + "ref": { + "format_version": 1, + "members": [ + { + "parts": [], + "sentence": "Germany's gross ODA disbursements to Nigeria for basic health care, 2020 to 2023. Current US dollars · OECD Creditor Reporting System (CRS).", + "spec": { + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "definition": { + "schema_version": 1, + "spec_id": "spec_cb5baa4161de718f18583060674dbca6", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "crsCooperationModality", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsPurpose", + "binding": { + "state": "value", + "ref": "CRSPurposeCode12220" + } + }, + { + "property": "crsTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "crsTypeOfFlow", + "binding": { + "state": "value", + "ref": "CRSTypeOfFlow10" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/NGA" + ], + "origin": [ + "country/DEU" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 2020, + "end_year": 2023 + } + } + } + }, + "content_version": "cv_bf242138f8d0a892c97da9373d1626f4", + "artifact": { + "digest": "sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", + "rendering": { + "format": "parquet", + "bundle": false, + "without_party_totals": true + } + } + } + ] + }, + "expect": "accept" +} From ec9fb5dda6288a2dceaa17a7a4f62658c3ce377a Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Sat, 24 Oct 2026 00:29:07 +0200 Subject: [PATCH 37/39] feat(client-contract): add the ref_digest_changed client warning (#18) A ref names one rendering's digest. When the server renders the same content_version again, the file a client downloads hashes differently, and the client returns the data. warning-codes.json gains ref_digest_changed, a DfoWarning, so both clients issue that warning with a code the contract lists, and the validator requires the row. --- python/client-contract/CHANGELOG.md | 3 ++- python/client-contract/README.md | 2 +- .../src/dfo_client_contract/warning-codes.json | 5 +++++ tools/tests/test_validate_client_contract.py | 6 ++++++ tools/validate_client_contract.py | 18 +++++++++++++----- 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index 87cfe85..5cf3edf 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -13,7 +13,8 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be - The status fallback for a refusal whose code has no row: 400 and 422 to `InvalidRequestError`, 401 to `AuthenticationError`, 403 to `PermissionDeniedError`, 404 and 410 to `NotFoundError`, 408 to `DfoTimeoutError`, 429 to `RateLimitError`, and any other 4xx or 5xx to `InvalidRequestError` or `ServerError`. - `scenario.schema.json`, the scenario record, and 118 scenarios: 31 recorded against the deployed dfo-apis dev app at `035d29cd0`, and 87 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 1,124,502 bytes and records and bodies together 13,080,568 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, a part without variable_text, an unknown status without a restatement, a shared label, a one-part option whose data_query holds two parts, the separate and operations echo, an unsupported part's placeholder, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a cut-off build retried after its Retry-After, a build refused 504 then 503 and one refused 503 then 504, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, a signed URL refused on both rounds, a relative files-route Location, an artifact url on a foreign origin, on the storage host and absolute on the API's origin, a manifest definition without identity or schema_version, a Search spec without identity or resolved, nested specs no rule reads, an empty parts list, a Search body that is not an object, a codeless 503 problem document that is not retryable, a 401, an identity resubmit answering another spec, a part whose status is not a string, a Search spec whose definition names another spec_id, a Search response with no JSON body, an option with no data_query, empty entities and facets, a Sunset header issued once, `x-dfo-warning` messages and a Deprecation and Sunset pair, an unreadable versions page, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, 503 polls retried within the budget an answered poll restores, a 404 poll that raises, a failed operation posted again, a failed operation with no error, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route: the first version it lists with no `base_content_version`, the newest plain build, so a derived version listed before it is skipped. - `client-codes.json` and its schema: the 23 codes a client sets on the errors it raises itself, each with its error class, retryable flag and condition, disjoint from `actions.json` and `registries/codes.json`, and the `client_codes()` and `client_codes_schema()` accessors. Every scenario error the client raises itself carries its code, and `refusal_without_code` names a refusal whose body carries no code. -- `proxy-codes.json` and its schema, the website proxy's `rate_limited` and `transient_unavailable` codes with their statuses, and `warning-codes.json` and its schema, the 5 codes a client sets on the warnings it issues itself, with the `proxy_codes()` and `warning_codes()` accessors. +- `proxy-codes.json` and its schema, the website proxy's `rate_limited` and `transient_unavailable` codes with their statuses, and `warning-codes.json` and its schema, the 6 codes a client sets on the warnings it issues itself, with the `proxy_codes()` and `warning_codes()` accessors. +- `ref_digest_changed` in `warning-codes.json`, a `DfoWarning` for a ref member whose `content_version` serves a file with another digest than the ref's, because the server rendered the same data again. The client returns the data, with no error under strict. - Error outcomes give the error's `trace_id`, the body's, else the `x-dfo-trace-id` header's, else null. Scenario outcomes give `retry_waits`, the waits before each retry, and `warnings`, the warning codes a step's responses issued. Scenario steps take no `timeout`. - `dataset-ref.schema.json`, the frozen `DatasetRef` format, with accepted and rejected examples. - `without_party_totals` in the ref's artifact rendering, `true` for the version rendered with party totals left out and absent for a plain rendering, with `ref-without-party-totals` and `ref-without-party-totals-false-rejected` as its examples. diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 1a175ec..3e323d6 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -118,7 +118,7 @@ An answer's gaps follow from its parts. A candidates part is a `choice` gap, its ## Client codes -`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, `retryable`, and a one-line `condition`. `retryable` is the flag both clients generate onto the error: `deadline_exceeded`, `download_failed` and `network_error` are retryable, `digest_mismatch` and the rest are not, and `refusal_without_code` is retryable as its status is, which its row gives as `by_status`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps the server's code: the problem document's `code`, or the website proxy's `error`. A refusal whose body carries neither raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`. No other row does. A problem document without a code still gives the error its `retryable` and `trace_id`, so a 503 whose body says `retryable: false` raises at once, which `search-refused-without-code` pins. Every refusal's trace id is the response's trace id, as the trace-id rule under Scenarios gives it. `search-refused-without-code` pins the body's winning over the header, and `search-unauthorized` the header's for a refusal with no body. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. Each reason the key-lookup rule raises, `key_empty`, `profile_not_found`, `profile_without_key` and `credentials_file_invalid`, is a row of class `AuthenticationError`, as are `key_invalid`, a key outside visible ASCII, and `credentials_file_unreadable`, a credentials file that exists but cannot be read. `header_invalid`, a header value with a control character, `insecure_transport`, a key over plain http to a non-loopback host, and `base_url_invalid`, a base URL that is empty, not absolute http or https, or carries userinfo, are `InvalidRequestError` rows. `response_too_large`, a decoded body past its cap, is a `ServerError` row. None of these six is retryable. The list holds no warning. `warning-codes.json` lists, sorted by code, each code a client sets on a warning it issues itself, with its class and condition: `route_deprecated`, a `DfoDeprecationWarning`, for a `Deprecation` or `Sunset` header; `server_warning`, a `DfoWarning`, for an `x-dfo-warning` header; and `key_checksum_mismatch`, `key_not_base62` and `key_unknown_prefix`, each a `DfoWarning`, for a key that fails the key-format rule with that reason. Both clients generate their warning codes from it and issue no other. No warning code is a code in another table or in `registries/codes.json`. A `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and a null code when they differ in several ways. A `DataWarning` carries the manifest warning's code. +`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, `retryable`, and a one-line `condition`. `retryable` is the flag both clients generate onto the error: `deadline_exceeded`, `download_failed` and `network_error` are retryable, `digest_mismatch` and the rest are not, and `refusal_without_code` is retryable as its status is, which its row gives as `by_status`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps the server's code: the problem document's `code`, or the website proxy's `error`. A refusal whose body carries neither raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`. No other row does. A problem document without a code still gives the error its `retryable` and `trace_id`, so a 503 whose body says `retryable: false` raises at once, which `search-refused-without-code` pins. Every refusal's trace id is the response's trace id, as the trace-id rule under Scenarios gives it. `search-refused-without-code` pins the body's winning over the header, and `search-unauthorized` the header's for a refusal with no body. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. Each reason the key-lookup rule raises, `key_empty`, `profile_not_found`, `profile_without_key` and `credentials_file_invalid`, is a row of class `AuthenticationError`, as are `key_invalid`, a key outside visible ASCII, and `credentials_file_unreadable`, a credentials file that exists but cannot be read. `header_invalid`, a header value with a control character, `insecure_transport`, a key over plain http to a non-loopback host, and `base_url_invalid`, a base URL that is empty, not absolute http or https, or carries userinfo, are `InvalidRequestError` rows. `response_too_large`, a decoded body past its cap, is a `ServerError` row. None of these six is retryable. The list holds no warning. `warning-codes.json` lists, sorted by code, each code a client sets on a warning it issues itself, with its class and condition: `ref_digest_changed`, a `DfoWarning`, for a ref member whose `content_version` serves a file with another digest than the ref's, because the server rendered the same data again, where the client returns the data; `route_deprecated`, a `DfoDeprecationWarning`, for a `Deprecation` or `Sunset` header; `server_warning`, a `DfoWarning`, for an `x-dfo-warning` header; and `key_checksum_mismatch`, `key_not_base62` and `key_unknown_prefix`, each a `DfoWarning`, for a key that fails the key-format rule with that reason. Both clients generate their warning codes from it and issue no other. No warning code is a code in another table or in `registries/codes.json`. A `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and a null code when they differ in several ways. A `DataWarning` carries the manifest warning's code. ## Scenarios diff --git a/python/client-contract/src/dfo_client_contract/warning-codes.json b/python/client-contract/src/dfo_client_contract/warning-codes.json index 337e2a7..5d55edf 100644 --- a/python/client-contract/src/dfo_client_contract/warning-codes.json +++ b/python/client-contract/src/dfo_client_contract/warning-codes.json @@ -16,6 +16,11 @@ "class": "DfoWarning", "condition": "The resolved key starts with neither dfo_k_ nor dfo_p_, by the key-format rule; the client sends it anyway." }, + { + "code": "ref_digest_changed", + "class": "DfoWarning", + "condition": "A ref member's content_version serves a file whose digest differs from the ref's, because the server rendered the same data again; the client returns the data." + }, { "code": "route_deprecated", "class": "DfoDeprecationWarning", diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index 58fa9c3..7ce8bde 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -1184,6 +1184,11 @@ def change(doc: Any) -> None: _add_action({"code": "spec_not_found", "status": 404, "condition": "x"}), "'spec_not_found' is also a code in registries/codes.json", ), + ( + "warning-codes.json", + _drop_action("ref_digest_changed"), + "no row for 'ref_digest_changed'", + ), ( "warning-codes.json", _drop_action("route_deprecated"), @@ -1742,6 +1747,7 @@ def change(doc: Any) -> None: "proxy-code-unlisted", "proxy-code-wrong-status", "proxy-code-is-a-registry-code", + "warning-code-ref-digest-changed-missing", "warning-code-missing", "warning-code-no-rule-issues", "warning-code-is-a-client-code", diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index 3ead4d7..44ac99f 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -34,8 +34,8 @@ row of class `AuthenticationError`. - `proxy-codes.json` and `warning-codes.json` list codes in order, each once, none of them a code another table or `registries/codes.json` holds, and the - warning codes are those the client rules issue: `route_deprecated`, - `server_warning`, and one `key_` per key-format reason. + warning codes are those the client rules issue: `ref_digest_changed`, + `route_deprecated`, `server_warning`, and one `key_` per key-format reason. - Each scenario's file name matches its `name`, names are unique, `expect` holds one outcome per step, a step that acts on an earlier result follows one, a synthetic scenario derives from a recorded one, and every body file @@ -490,11 +490,16 @@ def _check_warning_codes( key_reasons: Sequence[str], ) -> list[str]: """As `_check_other_codes`, and the codes are those a client's rules - issue: each header warning, and one `key_` warning per - key-format reason.""" + issue: `ref_digest_changed`, each header warning, and one `key_` + warning per key-format reason.""" codes = [row["code"] for row in document["codes"]] problems = _check_other_codes("warning-codes.json", codes, taken) - wanted = {ROUTE_DEPRECATED, SERVER_WARNING, *(f"key_{r}" for r in key_reasons)} + wanted = { + REF_DIGEST_CHANGED, + ROUTE_DEPRECATED, + SERVER_WARNING, + *(f"key_{r}" for r in key_reasons), + } problems.extend( f"warning-codes.json: no row for {code!r}, a warning a client issues" for code in sorted(wanted - set(codes)) @@ -836,6 +841,9 @@ def retry_wait(headers: Mapping[str, str], attempt: int) -> float: return min(RETRY_BACKOFF_FIRST * 2**attempt, RETRY_BACKOFF_CAP) +# The warning a client issues when a ref's file digest has changed. +REF_DIGEST_CHANGED = "ref_digest_changed" + # The headers a client warns on, and the warning-codes.json code of each. DEPRECATION_HEADERS = ("deprecation", "sunset") ROUTE_DEPRECATED = "route_deprecated" From ba976a2a74173e1c31b6c03d802cbcf71a022273 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Sat, 24 Oct 2026 11:06:26 +0200 Subject: [PATCH 38/39] feat(client-contract): add the timed_out no_data reason (#19) Search gives a part its request deadline cut short a no_data reason of its own. The registry and actions.json gain timed_out, with action ask_data_question and gap kind timed_out, which actions.schema.json now admits. The name keeps clear of the client code timeout, a transport timeout with action report. --- python/client-contract/CHANGELOG.md | 3 ++- python/client-contract/README.md | 2 +- .../src/dfo_client_contract/actions.json | 5 +++++ .../dfo_client_contract/actions.schema.json | 3 ++- .../src/dfo_spec_kit/registry/codes.json | 20 +++++++++++++++++++ registries/codes.json | 20 +++++++++++++++++++ tools/tests/test_validate_client_contract.py | 2 ++ 7 files changed, 52 insertions(+), 3 deletions(-) diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index 5cf3edf..a48bc05 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -9,12 +9,13 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be - Package scaffolding (uv, ruff, ty, pytest). - `served/openapi.json`, the composed dfo-apis app's OpenAPI document, and `served/SOURCE.json`, naming dfo-apis commit `035d29cd05fb31d7cb47cfb33197d4002f773df6`. - `strict-fields.json` and its schema: 29 members that stay required and non-nullable, each one a client reads, and the answer kinds, part statuses and operation statuses the clients branch on. -- `actions.json` and its schema: the caller's next step for each of the 101 active refusal codes on `problem_details` or `no_data_reason`, with the gap kind of each no_data reason. +- `actions.json` and its schema: the caller's next step for each of the 102 active refusal codes on `problem_details` or `no_data_reason`, with the gap kind of each no_data reason. - The status fallback for a refusal whose code has no row: 400 and 422 to `InvalidRequestError`, 401 to `AuthenticationError`, 403 to `PermissionDeniedError`, 404 and 410 to `NotFoundError`, 408 to `DfoTimeoutError`, 429 to `RateLimitError`, and any other 4xx or 5xx to `InvalidRequestError` or `ServerError`. - `scenario.schema.json`, the scenario record, and 118 scenarios: 31 recorded against the deployed dfo-apis dev app at `035d29cd0`, and 87 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 1,124,502 bytes and records and bodies together 13,080,568 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, a part without variable_text, an unknown status without a restatement, a shared label, a one-part option whose data_query holds two parts, the separate and operations echo, an unsupported part's placeholder, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a cut-off build retried after its Retry-After, a build refused 504 then 503 and one refused 503 then 504, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, a signed URL refused on both rounds, a relative files-route Location, an artifact url on a foreign origin, on the storage host and absolute on the API's origin, a manifest definition without identity or schema_version, a Search spec without identity or resolved, nested specs no rule reads, an empty parts list, a Search body that is not an object, a codeless 503 problem document that is not retryable, a 401, an identity resubmit answering another spec, a part whose status is not a string, a Search spec whose definition names another spec_id, a Search response with no JSON body, an option with no data_query, empty entities and facets, a Sunset header issued once, `x-dfo-warning` messages and a Deprecation and Sunset pair, an unreadable versions page, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, 503 polls retried within the budget an answered poll restores, a 404 poll that raises, a failed operation posted again, a failed operation with no error, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route: the first version it lists with no `base_content_version`, the newest plain build, so a derived version listed before it is skipped. - `client-codes.json` and its schema: the 23 codes a client sets on the errors it raises itself, each with its error class, retryable flag and condition, disjoint from `actions.json` and `registries/codes.json`, and the `client_codes()` and `client_codes_schema()` accessors. Every scenario error the client raises itself carries its code, and `refusal_without_code` names a refusal whose body carries no code. - `proxy-codes.json` and its schema, the website proxy's `rate_limited` and `transient_unavailable` codes with their statuses, and `warning-codes.json` and its schema, the 6 codes a client sets on the warnings it issues itself, with the `proxy_codes()` and `warning_codes()` accessors. - `ref_digest_changed` in `warning-codes.json`, a `DfoWarning` for a ref member whose `content_version` serves a file with another digest than the ref's, because the server rendered the same data again. The client returns the data, with no error under strict. +- `timed_out` in `actions.json` and `registries/codes.json`, the no_data reason Search gives a part it left unresolved at the request's time limit, with action `ask_data_question` and gap kind `timed_out`, which `actions.schema.json` now admits. The client-side `timeout` code, a transport timeout, is unchanged. - Error outcomes give the error's `trace_id`, the body's, else the `x-dfo-trace-id` header's, else null. Scenario outcomes give `retry_waits`, the waits before each retry, and `warnings`, the warning codes a step's responses issued. Scenario steps take no `timeout`. - `dataset-ref.schema.json`, the frozen `DatasetRef` format, with accepted and rejected examples. - `without_party_totals` in the ref's artifact rendering, `true` for the version rendered with party totals left out and absent for a plain rendering, with `ref-without-party-totals` and `ref-without-party-totals-false-rejected` as its examples. diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 3e323d6..601c45b 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -97,7 +97,7 @@ The required members are each part's `status` and its payload (`spec`, `candidat | `report` | `ServerError` | Reports the trace id, after the client's retries | | `upgrade` | `ContractError` | Upgrades the client | -A code that maps to `no_data_reason` also carries `gap_kind`, the kind of gap a no_data part with that reason becomes: `choice`, `no_data`, `not_understood` or `unsupported`. `choose` goes with `choice` and only with it. `choose` and `ask_data_question` name a next step inside an answer, so a code that also reaches a problem document takes another action. The website proxy's own `{error, retry, detail}` body carries its code in `error`. `proxy-codes.json` lists those codes with their status, `rate_limited` at 429 and `transient_unavailable` at 502, and the validator refuses a proxy body whose `error` it does not list at that status. No proxy code has a row here, so a client raises a proxy refusal with the class its status maps to. `capability_unavailable` is a well-formed request for a format, reshape or conversion class the deployment does not enable, answered 501; its action is `fix_request`, since the caller asks for another one, and `fetch-spec-capability-unavailable` pins it. +A code that maps to `no_data_reason` also carries `gap_kind`, the kind of gap a no_data part with that reason becomes: `choice`, `no_data`, `not_understood`, `unsupported` or `timed_out`. `timed_out` is a part Search left unresolved at its time limit; sending the question again, or a narrower one, may answer it. `choose` goes with `choice` and only with it. `choose` and `ask_data_question` name a next step inside an answer, so a code that also reaches a problem document takes another action. The website proxy's own `{error, retry, detail}` body carries its code in `error`. `proxy-codes.json` lists those codes with their status, `rate_limited` at 429 and `transient_unavailable` at 502, and the validator refuses a proxy body whose `error` it does not list at that status. No proxy code has a row here, so a client raises a proxy refusal with the class its status maps to. `capability_unavailable` is a well-formed request for a format, reshape or conversion class the deployment does not enable, answered 501; its action is `fix_request`, since the caller asks for another one, and `fetch-spec-capability-unavailable` pins it. A client maps a refusal whose code has no row, or that carries no code, on its HTTP status: diff --git a/python/client-contract/src/dfo_client_contract/actions.json b/python/client-contract/src/dfo_client_contract/actions.json index 7220529..34b2b09 100644 --- a/python/client-contract/src/dfo_client_contract/actions.json +++ b/python/client-contract/src/dfo_client_contract/actions.json @@ -388,6 +388,11 @@ "code": "spec_not_found", "action": "check_id" }, + { + "code": "timed_out", + "action": "ask_data_question", + "gap_kind": "timed_out" + }, { "code": "timeout", "action": "report" diff --git a/python/client-contract/src/dfo_client_contract/actions.schema.json b/python/client-contract/src/dfo_client_contract/actions.schema.json index 70c6fa2..a102481 100644 --- a/python/client-contract/src/dfo_client_contract/actions.schema.json +++ b/python/client-contract/src/dfo_client_contract/actions.schema.json @@ -48,7 +48,8 @@ "choice", "no_data", "not_understood", - "unsupported" + "unsupported", + "timed_out" ] } } diff --git a/python/spec-kit/src/dfo_spec_kit/registry/codes.json b/python/spec-kit/src/dfo_spec_kit/registry/codes.json index 976cd64..0a351ae 100644 --- a/python/spec-kit/src/dfo_spec_kit/registry/codes.json +++ b/python/spec-kit/src/dfo_spec_kit/registry/codes.json @@ -4662,6 +4662,26 @@ ], "lifecycle": "active" }, + { + "code": "timed_out", + "classification": "refusal", + "definition": "Search stopped at the request's time limit before it resolved this part; the same question, or a narrower one, may answer when sent again.", + "owning_contract": "search", + "owner": "platform", + "introduced_in": "v1", + "mappings": [ + { + "endpoint": "search.resolve", + "doors": [ + "raw_text", + "parsed", + "dataset_resubmit" + ], + "channel": "no_data_reason" + } + ], + "lifecycle": "active" + }, { "code": "timeout", "classification": "refusal", diff --git a/registries/codes.json b/registries/codes.json index 976cd64..0a351ae 100644 --- a/registries/codes.json +++ b/registries/codes.json @@ -4662,6 +4662,26 @@ ], "lifecycle": "active" }, + { + "code": "timed_out", + "classification": "refusal", + "definition": "Search stopped at the request's time limit before it resolved this part; the same question, or a narrower one, may answer when sent again.", + "owning_contract": "search", + "owner": "platform", + "introduced_in": "v1", + "mappings": [ + { + "endpoint": "search.resolve", + "doors": [ + "raw_text", + "parsed", + "dataset_resubmit" + ], + "channel": "no_data_reason" + } + ], + "lifecycle": "active" + }, { "code": "timeout", "classification": "refusal", diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index 7ce8bde..fd00276 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -511,6 +511,7 @@ def change(doc: Any) -> None: "is listed twice", ), ("actions.json", _drop_action("spec_not_found"), "'spec_not_found' has no row"), + ("actions.json", _drop_action("timed_out"), "'timed_out' has no row"), ( "actions.json", _add_action({"code": "alternates_unevaluated", "action": "report"}), @@ -1621,6 +1622,7 @@ def change(doc: Any) -> None: "strict-enum-value-gone", "strict-pointer-repeated", "action-row-missing", + "action-row-timed-out-missing", "action-row-for-a-warning", "action-row-for-an-unknown-code", "actions-unsorted", From 0d19172e3695c311ed48ff43a885a9995869e6a5 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Sat, 24 Oct 2026 21:06:41 +0200 Subject: [PATCH 39/39] feat(client-contract): read proxy refusals as problem documents and re-record at apis 0ba344270 (#20) The website proxy's own refusals (rate_limited at 429, transient_unavailable at 502) are application/problem+json documents with code, retryable and trace_id, as every other refusal is. The README, proxy-codes.json, client-codes.json, the scenario schema, the validator and the capture tool drop the {error, retry, detail} body. The validator checks a proxy problem document's media type, members and retryable, and refuses a 202 whose operation reads done. A 202 operation reads pending or running, or failed for a deterministic failure. fetch-spec-accepted-running pins running, and fetch-spec-poll-pacing-changes pins a retry_after_ms that changes from one poll to the next. served/openapi.json is re-captured from apis 0ba344270, which adds the timed_out no-data reason and the optional entity_refs member, and the 31 recorded scenarios are re-recorded live against dev at that commit. Two validator nits: a wrapped docstring line and the test id action-row-no-data-reason-missing. --- python/client-contract/CHANGELOG.md | 8 +- python/client-contract/README.md | 10 +- .../src/dfo_client_contract/client-codes.json | 2 +- .../src/dfo_client_contract/proxy-codes.json | 4 +- .../proxy-codes.schema.json | 2 +- .../dfo_client_contract/scenario.schema.json | 2 +- .../answer-candidate-specs-not-a-list.json | 52 +- .../answer-candidates-choose-fetch.json | 87 +- .../scenarios/answer-catalogue.json | 16 +- .../scenarios/answer-declined.json | 20 +- .../scenarios/answer-definite-fetch.json | 82 +- .../answer-definition-spec-id-mismatch.json | 70 +- .../scenarios/answer-empty-parts.json | 14 +- .../answer-folded-parts-unnamed.json | 204 ++- .../scenarios/answer-mixed-fetch-partial.json | 63 +- .../scenarios/answer-mixed-fetch-raises.json | 63 +- .../answer-nested-specs-unchecked.json | 72 +- .../answer-operations-not-a-list.json | 78 +- .../answer-part-status-not-a-string.json | 59 +- .../answer-several-readings-folded.json | 208 ++- .../answer-spec-without-identity.json | 70 +- .../answer-spec-without-resolved.json | 66 +- .../scenarios/answer-timed-out.json | 55 +- .../scenarios/answer-unknown-enum-value.json | 26 +- .../scenarios/answer-unknown-kind.json | 28 +- .../scenarios/answer-unknown-part-status.json | 59 +- .../scenarios/answer-unsupported-part.json | 59 +- .../choose-candidate-assumed-reading.json | 75 +- .../scenarios/choose-candidate-by-label.json | 75 +- .../choose-candidate-echoes-assumptions.json | 132 +- .../scenarios/choose-candidate-two-parts.json | 268 ++- .../choose-echo-drops-malformed-items.json | 128 +- ...choose-echoes-separate-and-operations.json | 188 ++- .../choose-option-beside-definite.json | 192 ++- .../choose-option-two-part-query.json | 22 +- .../choose-option-without-data-query.json | 22 +- .../scenarios/choose-part-by-mention.json | 78 +- .../scenarios/choose-place-one-part.json | 76 +- .../scenarios/choose-place-two-parts.json | 108 +- .../choose-posts-unsupported-placeholder.json | 184 +- .../choose-refused-answered-part.json | 57 +- ...hoose-refused-mention-names-two-parts.json | 42 +- .../scenarios/choose-refused-no-choice.json | 68 +- .../scenarios/choose-refused-no-options.json | 26 +- .../choose-refused-option-out-of-range.json | 50 +- ...se-refused-part-without-variable-text.json | 102 +- ...choose-refused-shared-candidate-label.json | 50 +- .../choose-refused-shared-label.json | 18 +- .../scenarios/choose-refused-two-choices.json | 42 +- ...hoose-refused-unknown-candidate-label.json | 50 +- .../choose-refused-unknown-label.json | 26 +- .../choose-refused-unknown-part.json | 57 +- .../choose-refused-unknown-status.json | 102 +- .../fetch-frame-several-readings.json | 186 ++- .../scenarios/fetch-null-member.json | 78 +- .../fetch-partial-nothing-answered.json | 28 +- .../fetch-ref-artifact-unlisted.json | 4 +- .../fetch-ref-expired-file-selector.json | 6 +- .../fetch-ref-expired-newer-version.json | 8 +- .../fetch-ref-expired-not-reproducible.json | 12 +- .../fetch-ref-expired-rebuild-other-spec.json | 10 +- ...etch-ref-expired-rebuild-same-version.json | 10 +- .../scenarios/fetch-ref-newest-version.json | 16 +- .../fetch-ref-signed-url-refused-twice.json | 8 +- .../fetch-ref-signed-url-refused.json | 8 +- .../scenarios/fetch-ref-unknown-version.json | 10 +- .../scenarios/fetch-ref.json | 10 +- .../scenarios/fetch-renamed-strict-field.json | 78 +- .../scenarios/fetch-retry-after-504.json | 78 +- .../scenarios/fetch-spec-503-then-504.json | 10 +- .../scenarios/fetch-spec-504-retry-after.json | 10 +- .../fetch-spec-accepted-running.json | 1474 +++++++++++++++++ .../scenarios/fetch-spec-async-build.json | 294 +--- .../scenarios/fetch-spec-digest-mismatch.json | 12 +- .../scenarios/fetch-spec-empty-narrowing.json | 10 +- .../scenarios/fetch-spec-entity-dropped.json | 43 +- .../scenarios/fetch-spec-entity-rebound.json | 43 +- .../fetch-spec-files-route-no-content.json | 12 +- .../fetch-spec-files-route-serves-file.json | 10 +- ...h-spec-files-route-temporary-redirect.json | 12 +- .../fetch-spec-foreign-artifact-url.json | 10 +- .../scenarios/fetch-spec-frame-layout.json | 12 +- .../scenarios/fetch-spec-group-narrowed.json | 39 +- .../fetch-spec-group-origin-rebound.json | 43 +- .../scenarios/fetch-spec-known-sentence.json | 14 +- .../fetch-spec-manifest-without-identity.json | 10 +- ...-spec-manifest-without-schema-version.json | 10 +- .../scenarios/fetch-spec-narrowed.json | 41 +- ...tch-spec-operation-failed-resubmitted.json | 298 +--- .../scenarios/fetch-spec-poll-not-found.json | 2 +- .../fetch-spec-poll-pacing-changes.json | 1474 +++++++++++++++++ ...-spec-poll-rate-limited-not-retryable.json | 2 +- .../fetch-spec-poll-rate-limited.json | 294 +--- .../fetch-spec-poll-refused-backoff.json | 272 +-- .../fetch-spec-poll-refused-retry-after.json | 294 +--- .../scenarios/fetch-spec-poll-refused.json | 294 +--- .../fetch-spec-relative-location.json | 10 +- .../scenarios/fetch-spec-request-invalid.json | 10 +- .../fetch-spec-resubmit-other-spec.json | 37 +- .../fetch-spec-same-origin-artifact-url.json | 10 +- .../fetch-spec-signed-fetch-partial.json | 12 +- .../fetch-spec-storage-artifact-url.json | 10 +- .../scenarios/fetch-spec-strict-warning.json | 6 +- .../scenarios/fetch-strict-info-notice.json | 78 +- .../scenarios/mint-async-build.json | 298 +--- .../newest-version-unreadable-page.json | 14 +- .../operation-failed-without-error.json | 6 +- .../scenarios/operation-resume.json | 184 +- .../resubmit-candidates-sibling.json | 124 +- ...ubmit-placeholder-without-restatement.json | 96 +- .../scenarios/search-body-not-an-object.json | 28 +- .../scenarios/search-place-ambiguous.json | 30 +- .../scenarios/search-proxy-rate-limited.json | 44 +- .../scenarios/search-proxy-unavailable.json | 48 +- .../scenarios/search-retry-after-503.json | 26 +- .../scenarios/search-server-warning.json | 78 +- .../scenarios/search-sunset-warning.json | 52 +- .../search-two-parts-place-ambiguous.json | 46 +- .../scenarios/search-warning-top5.json | 74 +- .../dfo_client_contract/served/SOURCE.json | 2 +- .../dfo_client_contract/served/openapi.json | 71 +- tools/README.md | 2 +- tools/capture_client_contract.py | 123 +- tools/tests/test_validate_client_contract.py | 63 +- tools/validate_client_contract.py | 90 +- 125 files changed, 6747 insertions(+), 4231 deletions(-) create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-accepted-running.json create mode 100644 python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-pacing-changes.json diff --git a/python/client-contract/CHANGELOG.md b/python/client-contract/CHANGELOG.md index a48bc05..ce4270a 100644 --- a/python/client-contract/CHANGELOG.md +++ b/python/client-contract/CHANGELOG.md @@ -7,20 +7,20 @@ All notable changes to the `dfo-spec-kit-client-contract` Python package will be ### Added - Package scaffolding (uv, ruff, ty, pytest). -- `served/openapi.json`, the composed dfo-apis app's OpenAPI document, and `served/SOURCE.json`, naming dfo-apis commit `035d29cd05fb31d7cb47cfb33197d4002f773df6`. +- `served/openapi.json`, the composed dfo-apis app's OpenAPI document, and `served/SOURCE.json`, naming dfo-apis commit `0ba344270784ae9929a369da8acd00b399dfced8`. The document admits `timed_out` as a no_data reason and the optional `entity_refs` on each answer part, a list of `EntityRefs`, the graph nodes each restatement entity text binds. - `strict-fields.json` and its schema: 29 members that stay required and non-nullable, each one a client reads, and the answer kinds, part statuses and operation statuses the clients branch on. - `actions.json` and its schema: the caller's next step for each of the 102 active refusal codes on `problem_details` or `no_data_reason`, with the gap kind of each no_data reason. - The status fallback for a refusal whose code has no row: 400 and 422 to `InvalidRequestError`, 401 to `AuthenticationError`, 403 to `PermissionDeniedError`, 404 and 410 to `NotFoundError`, 408 to `DfoTimeoutError`, 429 to `RateLimitError`, and any other 4xx or 5xx to `InvalidRequestError` or `ServerError`. -- `scenario.schema.json`, the scenario record, and 118 scenarios: 31 recorded against the deployed dfo-apis dev app at `035d29cd0`, and 87 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 1,124,502 bytes and records and bodies together 13,080,568 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, a part without variable_text, an unknown status without a restatement, a shared label, a one-part option whose data_query holds two parts, the separate and operations echo, an unsupported part's placeholder, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a cut-off build retried after its Retry-After, a build refused 504 then 503 and one refused 503 then 504, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, a signed URL refused on both rounds, a relative files-route Location, an artifact url on a foreign origin, on the storage host and absolute on the API's origin, a manifest definition without identity or schema_version, a Search spec without identity or resolved, nested specs no rule reads, an empty parts list, a Search body that is not an object, a codeless 503 problem document that is not retryable, a 401, an identity resubmit answering another spec, a part whose status is not a string, a Search spec whose definition names another spec_id, a Search response with no JSON body, an option with no data_query, empty entities and facets, a Sunset header issued once, `x-dfo-warning` messages and a Deprecation and Sunset pair, an unreadable versions page, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, 503 polls retried within the budget an answered poll restores, a 404 poll that raises, a failed operation posted again, a failed operation with no error, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route: the first version it lists with no `base_content_version`, the newest plain build, so a derived version listed before it is skipped. +- `scenario.schema.json`, the scenario record, and 120 scenarios: 31 recorded against the deployed dfo-apis dev app at `0ba344270`, and 89 synthetic, each derived from a recorded one by a one-line edit, with 19 binary bodies totalling 1,124,502 bytes and records and bodies together 13,161,129 bytes. The scenarios cover the several-part choice entries and the assumptions each identity entry echoes, a picked reading whose assumption Search states in its answer, the place choice through a no_data part's options, the choice refusals, a part without variable_text, an unknown status without a restatement, a shared label, a one-part option whose data_query holds two parts, the separate and operations echo, an unsupported part's placeholder, the timed_out, unsupported and unknown gaps, an unknown answer kind, the `SearchWarning` rule, the stacked dataset's `part` column, the frame layout, a strict fetch's `DataWarning`, a spec fetch that rebinds one of two entity roles and keeps the other, one that drops a role bound to null, a spec whose destination is a named group fetched with a window or with its origin rebound, whose sentence lookup posts the groups of the roles the build left bound, a twice cut-off build, a cut-off build retried after its Retry-After, a build refused 504 then 503 and one refused 503 then 504, a refused build, a build refused 501 `capability_unavailable`, a digest mismatch, a signed URL refused on both rounds, a relative files-route Location, an artifact url on a foreign origin, on the storage host and absolute on the API's origin, a manifest definition without identity or schema_version, a Search spec without identity or resolved, nested specs no rule reads, an empty parts list, a Search body that is not an object, a codeless 503 problem document that is not retryable, a 401, an identity resubmit answering another spec, a part whose status is not a string, a Search spec whose definition names another spec_id, a Search response with no JSON body, an option with no data_query, empty entities and facets, a Sunset header issued once, `x-dfo-warning` messages and a Deprecation and Sunset pair, an unreadable versions page, a mint and a spec fetch whose build answers 202 and is polled to done, a resumed operation, a rate-limited poll, 503 polls retried within the budget an answered poll restores, a 202 that reads running, polls whose `retry_after_ms` changes from one to the next, a 404 poll that raises, a failed operation posted again, a failed operation with no error, and a ref whose stored file expired, read through the file selector, rebuilt at the same version, at a newer one, or refused with the newest version read from the versions route: the first version it lists with no `base_content_version`, the newest plain build, so a derived version listed before it is skipped. - `client-codes.json` and its schema: the 23 codes a client sets on the errors it raises itself, each with its error class, retryable flag and condition, disjoint from `actions.json` and `registries/codes.json`, and the `client_codes()` and `client_codes_schema()` accessors. Every scenario error the client raises itself carries its code, and `refusal_without_code` names a refusal whose body carries no code. -- `proxy-codes.json` and its schema, the website proxy's `rate_limited` and `transient_unavailable` codes with their statuses, and `warning-codes.json` and its schema, the 6 codes a client sets on the warnings it issues itself, with the `proxy_codes()` and `warning_codes()` accessors. +- `proxy-codes.json` and its schema, the website proxy's `rate_limited` and `transient_unavailable` codes with their statuses, which the proxy sends in problem documents of the shape every refusal has, both retryable, with `Retry-After` on the 429, so a client reads one refusal shape, and `warning-codes.json` and its schema, the 6 codes a client sets on the warnings it issues itself, with the `proxy_codes()` and `warning_codes()` accessors. - `ref_digest_changed` in `warning-codes.json`, a `DfoWarning` for a ref member whose `content_version` serves a file with another digest than the ref's, because the server rendered the same data again. The client returns the data, with no error under strict. - `timed_out` in `actions.json` and `registries/codes.json`, the no_data reason Search gives a part it left unresolved at the request's time limit, with action `ask_data_question` and gap kind `timed_out`, which `actions.schema.json` now admits. The client-side `timeout` code, a transport timeout, is unchanged. - Error outcomes give the error's `trace_id`, the body's, else the `x-dfo-trace-id` header's, else null. Scenario outcomes give `retry_waits`, the waits before each retry, and `warnings`, the warning codes a step's responses issued. Scenario steps take no `timeout`. - `dataset-ref.schema.json`, the frozen `DatasetRef` format, with accepted and rejected examples. - `without_party_totals` in the ref's artifact rendering, `true` for the version rendered with party totals left out and absent for a plain rendering, with `ref-without-party-totals` and `ref-without-party-totals-false-rejected` as its examples. - `tools/capture_client_contract.py`, which captures `served/openapi.json` from a dfo-apis checkout in process and records the scenarios against a base URL, dev by default, or with `record --offline` derives their outcomes again from the records with no request. A local app's signed URLs are written as the storage URLs a deployment signs. -- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, checks `client-codes.json` against them and against the reasons the key-lookup rule raises, and checks each scenario's `expect` against the outcomes its exchanges, `actions.json` and `client-codes.json` give, each Search request against the input its steps derive, a sentence lookup's `entity_groups` included, each build's `input.scope` against the narrowing its step names over the spec's bound roles, each build's options against its layout, each Search request's whole body, each download against its artifact's digest, each recorded scenario's commit against `served/SOURCE.json`, each proxy refusal's code against `proxy-codes.json`, and each absolute URL against the storage host, each ref example's members against the dataset members and downloaded files of the scenario it names, and the scenarios directory against a 16,000,000-byte budget for records and bodies together. A record that ends a run of retries while a retry remains does not fit. The outcomes include each long build's operation id, poll waits and resubmissions, and a `VersionUnavailableError`'s newest version. +- `tools/validate_client_contract.py`, which checks the contract against its schemas, the served document and `registries/codes.json`, checks `client-codes.json` against them and against the reasons the key-lookup rule raises, and checks each scenario's `expect` against the outcomes its exchanges, `actions.json` and `client-codes.json` give, each Search request against the input its steps derive, a sentence lookup's `entity_groups` included, each build's `input.scope` against the narrowing its step names over the spec's bound roles, each build's options against its layout, each Search request's whole body, each download against its artifact's digest, each recorded scenario's commit against `served/SOURCE.json`, each problem document's code against `registries/codes.json` or, for the website proxy's, `proxy-codes.json`, each proxy problem document's content type, members and `retryable: true`, each 202 against an operation that reads `done`, and each absolute URL against the storage host, each ref example's members against the dataset members and downloaded files of the scenario it names, and the scenarios directory against a 16,000,000-byte budget for records and bodies together. A record that ends a run of retries while a retry remains does not fit. The outcomes include each long build's operation id, poll waits and resubmissions, and a `VersionUnavailableError`'s newest version. - The client rules and their vectors: the credentials path and file format, the key lookup order, with an empty `api_key` refused as `key_empty` and an empty profile key as `profile_without_key`, the key format check, and the cache directory and layout. [unreleased]: https://github.com/DevelopmentFinanceObservatory/spec-kit/commits/main/python diff --git a/python/client-contract/README.md b/python/client-contract/README.md index 601c45b..b0e93d9 100644 --- a/python/client-contract/README.md +++ b/python/client-contract/README.md @@ -97,7 +97,7 @@ The required members are each part's `status` and its payload (`spec`, `candidat | `report` | `ServerError` | Reports the trace id, after the client's retries | | `upgrade` | `ContractError` | Upgrades the client | -A code that maps to `no_data_reason` also carries `gap_kind`, the kind of gap a no_data part with that reason becomes: `choice`, `no_data`, `not_understood`, `unsupported` or `timed_out`. `timed_out` is a part Search left unresolved at its time limit; sending the question again, or a narrower one, may answer it. `choose` goes with `choice` and only with it. `choose` and `ask_data_question` name a next step inside an answer, so a code that also reaches a problem document takes another action. The website proxy's own `{error, retry, detail}` body carries its code in `error`. `proxy-codes.json` lists those codes with their status, `rate_limited` at 429 and `transient_unavailable` at 502, and the validator refuses a proxy body whose `error` it does not list at that status. No proxy code has a row here, so a client raises a proxy refusal with the class its status maps to. `capability_unavailable` is a well-formed request for a format, reshape or conversion class the deployment does not enable, answered 501; its action is `fix_request`, since the caller asks for another one, and `fetch-spec-capability-unavailable` pins it. +A code that maps to `no_data_reason` also carries `gap_kind`, the kind of gap a no_data part with that reason becomes: `choice`, `no_data`, `not_understood`, `unsupported` or `timed_out`. `timed_out` is a part Search left unresolved at its time limit. Sending the question again, or a narrower one, may answer it. `choose` goes with `choice` and only with it. `choose` and `ask_data_question` name a next step inside an answer, so a code that also reaches a problem document takes another action. The website proxy answers its own refusals with problem documents of the same shape, with `type`, `title`, `status`, `detail`, `code`, `retryable` and `trace_id`, the trace id repeated in the `x-dfo-trace-id` header. `proxy-codes.json` lists their codes with their status, `rate_limited` at 429, which also sends `Retry-After`, and `transient_unavailable` at 502, both retryable. The validator refuses a problem document whose code is neither an active registry code nor a proxy code at that status. No proxy code has a row here, so a client raises a proxy refusal with the class its status maps to: `RateLimitError` for `rate_limited`, which `search-proxy-rate-limited` pins, and `ServerError` for `transient_unavailable`, which `search-proxy-unavailable` pins. `capability_unavailable` is a well-formed request for a format, reshape or conversion class the deployment does not enable, answered 501. Its action is `fix_request`, since the caller asks for another one, and `fetch-spec-capability-unavailable` pins it. A client maps a refusal whose code has no row, or that carries no code, on its HTTP status: @@ -112,13 +112,13 @@ A client maps a refusal whose code has no row, or that carries no code, on its H | any other 4xx | `InvalidRequestError` | | any other 5xx | `ServerError` | -A 408 is a timeout the caller retries, and a 410 names a resource that is gone, so the caller stops as it does on a 404. A client reads a refusal's body, a problem document or the proxy's own, when its content type is `application/problem+json` or `application/json`; a body of any other type reads as no body, so the refusal carries no code. A no_data reason with no row becomes a `no_data` gap. +A 408 is a timeout the caller retries, and a 410 names a resource that is gone, so the caller stops as it does on a 404. A client reads a refusal's body as a problem document when its content type is `application/problem+json` or `application/json`; a body of any other type reads as no body, so the refusal carries no code. A no_data reason with no row becomes a `no_data` gap. An answer's gaps follow from its parts. A candidates part is a `choice` gap, its options the candidates. A no_data part is a gap of its reason's `gap_kind`, its options the no_data `options`, and of kind `timed_out` instead when the answer's `diagnostics.timed_out` is true. An unsupported part is an `unsupported` gap. A part whose status a client does not know is an `unknown` gap. ## Client codes -`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, `retryable`, and a one-line `condition`. `retryable` is the flag both clients generate onto the error: `deadline_exceeded`, `download_failed` and `network_error` are retryable, `digest_mismatch` and the rest are not, and `refusal_without_code` is retryable as its status is, which its row gives as `by_status`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps the server's code: the problem document's `code`, or the website proxy's `error`. A refusal whose body carries neither raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`. No other row does. A problem document without a code still gives the error its `retryable` and `trace_id`, so a 503 whose body says `retryable: false` raises at once, which `search-refused-without-code` pins. Every refusal's trace id is the response's trace id, as the trace-id rule under Scenarios gives it. `search-refused-without-code` pins the body's winning over the header, and `search-unauthorized` the header's for a refusal with no body. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. Each reason the key-lookup rule raises, `key_empty`, `profile_not_found`, `profile_without_key` and `credentials_file_invalid`, is a row of class `AuthenticationError`, as are `key_invalid`, a key outside visible ASCII, and `credentials_file_unreadable`, a credentials file that exists but cannot be read. `header_invalid`, a header value with a control character, `insecure_transport`, a key over plain http to a non-loopback host, and `base_url_invalid`, a base URL that is empty, not absolute http or https, or carries userinfo, are `InvalidRequestError` rows. `response_too_large`, a decoded body past its cap, is a `ServerError` row. None of these six is retryable. The list holds no warning. `warning-codes.json` lists, sorted by code, each code a client sets on a warning it issues itself, with its class and condition: `ref_digest_changed`, a `DfoWarning`, for a ref member whose `content_version` serves a file with another digest than the ref's, because the server rendered the same data again, where the client returns the data; `route_deprecated`, a `DfoDeprecationWarning`, for a `Deprecation` or `Sunset` header; `server_warning`, a `DfoWarning`, for an `x-dfo-warning` header; and `key_checksum_mismatch`, `key_not_base62` and `key_unknown_prefix`, each a `DfoWarning`, for a key that fails the key-format rule with that reason. Both clients generate their warning codes from it and issue no other. No warning code is a code in another table or in `registries/codes.json`. A `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and a null code when they differ in several ways. A `DataWarning` carries the manifest warning's code. +`client-codes.json` lists, sorted by code, each code a client sets on an error it raises when no problem document carries one: the `code`, the error `class` it raises, `retryable`, and a one-line `condition`. `retryable` is the flag both clients generate onto the error: `deadline_exceeded`, `download_failed` and `network_error` are retryable, `digest_mismatch` and the rest are not, and `refusal_without_code` is retryable as its status is, which its row gives as `by_status`. Both clients set an error's `code` from this list, so every error a client raises carries a code. A refusal keeps its problem document's `code`, the website proxy's included. A refusal whose body carries no code raises `refusal_without_code` with the class its HTTP status maps to, which its row gives as `by_status`. No other row does. A problem document without a code still gives the error its `retryable` and `trace_id`, so a 503 whose body says `retryable: false` raises at once, which `search-refused-without-code` pins. Every refusal's trace id is the response's trace id, as the trace-id rule under Scenarios gives it. `search-refused-without-code` pins the body's winning over the header, and `search-unauthorized` the header's for a refusal with no body. No client code is a code in `actions.json` or `registries/codes.json`, and each class is one the scenario schema names. Each reason the key-lookup rule raises, `key_empty`, `profile_not_found`, `profile_without_key` and `credentials_file_invalid`, is a row of class `AuthenticationError`, as are `key_invalid`, a key outside visible ASCII, and `credentials_file_unreadable`, a credentials file that exists but cannot be read. `header_invalid`, a header value with a control character, `insecure_transport`, a key over plain http to a non-loopback host, and `base_url_invalid`, a base URL that is empty, not absolute http or https, or carries userinfo, are `InvalidRequestError` rows. `response_too_large`, a decoded body past its cap, is a `ServerError` row. None of these six is retryable. The list holds no warning. `warning-codes.json` lists, sorted by code, each code a client sets on a warning it issues itself, with its class and condition: `ref_digest_changed`, a `DfoWarning`, for a ref member whose `content_version` serves a file with another digest than the ref's, because the server rendered the same data again, where the client returns the data; `route_deprecated`, a `DfoDeprecationWarning`, for a `Deprecation` or `Sunset` header; `server_warning`, a `DfoWarning`, for an `x-dfo-warning` header; and `key_checksum_mismatch`, `key_not_base62` and `key_unknown_prefix`, each a `DfoWarning`, for a key that fails the key-format rule with that reason. Both clients generate their warning codes from it and issue no other. No warning code is a code in another table or in `registries/codes.json`. A `SearchWarning` carries the code of the one way the readings differ from the question, a departure's or a warning's code or the verb of an operation Search did not run, and a null code when they differ in several ways. A `DataWarning` carries the manifest warning's code. ## Scenarios @@ -176,9 +176,9 @@ The records also fix these client rules: - Fetching an answer with a gap raises `IncompleteAnswerError` before any request, unless the fetch is partial and some part has a reading. - A fetch of an answer issues one `SearchWarning` when a definite part has an operation Search did not run, a departure, or a warning at severity `warn` or `degraded` with a `message`, or the answer's `diagnostics.warnings` holds such a warning. An `info` warning, a warning with no `message`, and an operation that does not read under Strict fields issue nothing. Each way is one line a client shows: `Not done: ()` coded by the verb, the phrase quoted as a JSON string that keeps non-ASCII characters as they are, the departure's `text` coded by its code, or `Note: ` coded by the warning's code, in part order with the diagnostics warnings last, and ways that show the same line count once, under the first one's code. A strict fetch raises the `SearchWarning` before any build, with the code of its one line, or a null code when there are several lines. A strict fetch raises it before the `frame` layout's several-member check. - A ref's version is found in this order: the snapshot route and the files route at the stored digest; the file selector, `GET /datasets/{id}/{content_version}/file` with the ref's rendering as the query; and a build of the ref's spec in the ref's rendering, which must answer the ref's `spec_id` and the same `content_version`. Both recovery steps keep the ref's identity, so a recovered member carries the ref's `spec_id` and `content_version`: a snapshot manifest whose `definition.spec_id` or `content_version` is not the ref's, or a rebuild manifest whose `definition.spec_id` is not the ref's, raises `ContractError` `contract_violation` before any download, which `fetch-ref-expired-rebuild-other-spec` pins for the rebuild. A snapshot refusal other than `artifact_expired` ends the lookup, so `snapshot_not_found` raises `NotFoundError` with no further request. A files route or selector refusal of `artifact_expired`, `artifact_not_found` or `not_found` takes the next step, and a selector file of another digest is not the stored file. A snapshot manifest whose artifacts list no artifact of the ref member's digest sends the client to the selector in the ref member's own rendering, and a file that hashes to that digest gives the dataset, which `fetch-ref-artifact-unlisted` pins. A rebuild that answers another version, or that raises `InvalidRequestError`, `NotFoundError` or `VersionUnavailableError`, ends in `VersionUnavailableError` with the first refusal's code, or `version_unavailable` when nothing refused. Its `newest_version` is the version the rebuild answered, or else the newest stored version, as a `newest_version` step finds it: the first version `GET /datasets/{id}/versions?limit=100` lists with a null `base_content_version`, the newest plain build, read page by page through `&cursor=` with each page's `next_cursor` until one is listed. The route lists versions newest first and needs no key. A version with a `base_content_version` is derived from a plain build, a groupby collapse or a party-totals cut, and is skipped, which `fetch-ref-newest-version` pins. The newest version is null when the list ends without a plain version or the route refuses with `NotFoundError`. Any other refusal of the versions route raises, and a page whose `versions` is not a list of versions each with a `content_version` and a `base_content_version` that is a string or null, or whose `next_cursor` is neither a string nor null, raises `ContractError` `contract_violation`, which `newest-version-unreadable-page` pins. -- A build answers 200 with the manifest, or 202 with an operation the client polls at `/datasets/operations/{operation_id}`, the id of the operation it holds. A mint's build answers 202. A record whose mint answers 200 fits no mint step. Before each poll it waits the `Retry-After` of the refusal that answered the last poll, whatever its status, as every retry of a refused request waits; else the last operation resource's `retry_after_ms`, else the `Retry-After` of the last answered poll, the response that carried that resource, else a backoff of 1, 2, 4 and then 8 seconds that advances one step each time it is used, a poll after a refusal included. +- A build answers 200 with the manifest, or 202 with an operation the client polls at `/datasets/operations/{operation_id}`, the id of the operation it holds. The 202 reads `pending` or `running`, because a submission starts a build or joins one under way, and a `done` operation left by an earlier submission of a rejected head is built again. A deterministic failure answers a 202 that reads `failed`. `fetch-spec-async-build` pins `pending` and `fetch-spec-accepted-running` pins `running`. A mint's build answers 202. A record whose mint answers 200 fits no mint step. Before each poll it waits the `Retry-After` of the refusal that answered the last poll, whatever its status, as every retry of a refused request waits; else the last operation resource's `retry_after_ms`, else the `Retry-After` of the last answered poll, the response that carried that resource, else a backoff of 1, 2, 4 and then 8 seconds that advances one step each time it is used, a poll after a refusal included. `fetch-spec-poll-pacing-changes` pins a `retry_after_ms` that changes from one poll to the next, so a client waits each poll's own value. - A retryable 429 poll spends no retry, and a 429 whose body says it is not retryable raises at once, as a refusal's `retryable` outranks its status, which `fetch-spec-poll-rate-limited-not-retryable` pins. Any other retryable refused poll spends one of the two retries, which a poll that answers restores, and a refusal that is not retryable raises. `fetch-spec-poll-refused` pins two 503s polled again after an answered poll, `fetch-spec-poll-refused-backoff` a 503 with no `Retry-After` among polls no response paces, after which the backoff advances, `fetch-spec-poll-refused-retry-after` a 503 whose `Retry-After` paces the next poll, and `fetch-spec-poll-not-found` a 404 that raises at once. A poll that answers a failed operation whose error is retryable posts the same build once more and polls the operation it starts; a second failure, an error that is not retryable, and a resumed operation, whose build request the client does not hold, raise the operation's error. A refused poll whose code is `operation_failed` is a failed operation with that error. A failed operation whose resource carries no `error` raises `ServerError` with `operation_failed`, retryable by status 500 as a refusal without a document is, which `operation-failed-without-error` pins. A 202 or resumed operation that already reads `failed` raises its error before any poll. -- Any other refusal is retried when it is retryable: as a problem document's `retryable` says, or the website proxy's `retry` of `retry_after_delay`, else when its status is 408, 429, 500, 502, 503 or 504. A client makes two retries by default, and the scenarios assume that default. A build's POST shares those two retries with every other refusal of it, and once a 504 cuts the build off the client posts it once more only, whatever that post answers: a build refused 504 then 503 raises the 503, a build refused 503 then 504 is posted once more after the 504, and a second 504 raises. `fetch-spec-504-then-503`, `fetch-spec-503-then-504` and `fetch-spec-504-twice` pin the three. A refusal that is not retryable, or one past the retries, raises its error. +- Any other refusal is retried when it is retryable: as its problem document's `retryable` says, else when its status is 408, 429, 500, 502, 503 or 504. A client makes two retries by default, and the scenarios assume that default. A build's POST shares those two retries with every other refusal of it, and once a 504 cuts the build off the client posts it once more only, whatever that post answers: a build refused 504 then 503 raises the 503, a build refused 503 then 504 is posted once more after the 504, and a second 504 raises. `fetch-spec-504-then-503`, `fetch-spec-503-then-504` and `fetch-spec-504-twice` pin the three. A refusal that is not retryable, or one past the retries, raises its error. - Each retry waits the refusal's `Retry-After` when it carries one, and otherwise the client's backoff for that attempt: 0.5 seconds before the first retry, doubling to at most 8. The build's 504 cut-off retry follows the same rule. `retry_waits` pins these waits, and `fetch-spec-504-retry-after` pins a cut-off that carries `Retry-After`. - A 401 resolves the key again by the key-lookup rule. When the key changed, the client sends the request once more at once, with no wait and spending no retry. When it did not, or the second answer is a 401 too, the 401 raises `AuthenticationError`. A replay's key never changes, so `search-unauthorized` pins the second case and no scenario the first. - A `request(method, path)` whose `path` is not a path on the base URL, because it starts with `//` or names a scheme, raises `InvalidRequestError` `invalid_argument` before any request. No scenario step makes such a request. diff --git a/python/client-contract/src/dfo_client_contract/client-codes.json b/python/client-contract/src/dfo_client_contract/client-codes.json index e4486fe..025fdf5 100644 --- a/python/client-contract/src/dfo_client_contract/client-codes.json +++ b/python/client-contract/src/dfo_client_contract/client-codes.json @@ -119,7 +119,7 @@ "code": "refusal_without_code", "class": "by_status", "retryable": "by_status", - "condition": "A refusal whose body carries no code: neither a problem document nor the website proxy's own body." + "condition": "A refusal whose body carries no code: no problem document, or one without a code." }, { "code": "response_too_large", diff --git a/python/client-contract/src/dfo_client_contract/proxy-codes.json b/python/client-contract/src/dfo_client_contract/proxy-codes.json index abba574..3bdf54e 100644 --- a/python/client-contract/src/dfo_client_contract/proxy-codes.json +++ b/python/client-contract/src/dfo_client_contract/proxy-codes.json @@ -4,12 +4,12 @@ { "code": "rate_limited", "status": 429, - "condition": "The website proxy's rate limit for the caller's address is spent; the response carries Retry-After." + "condition": "The website proxy's rate limit for the caller's address is spent; the problem document is retryable and the response carries Retry-After." }, { "code": "transient_unavailable", "status": 502, - "condition": "The website proxy could not reach the API behind it." + "condition": "The website proxy could not reach the API behind it; the problem document is retryable." } ] } diff --git a/python/client-contract/src/dfo_client_contract/proxy-codes.schema.json b/python/client-contract/src/dfo_client_contract/proxy-codes.schema.json index 6cec2dd..7e79f73 100644 --- a/python/client-contract/src/dfo_client_contract/proxy-codes.schema.json +++ b/python/client-contract/src/dfo_client_contract/proxy-codes.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://raw.githubusercontent.com/DevelopmentFinanceObservatory/spec-kit/main/python/client-contract/src/dfo_client_contract/proxy-codes.schema.json", "title": "Proxy codes", - "description": "Each code the website proxy's own {error, retry, detail} body carries in error, with the HTTP status it answers and the condition, sorted by code. A client raises such a refusal with the error's code and the class its status maps to.", + "description": "Each code the website proxy's own problem documents carry, with the HTTP status it answers and the condition, sorted by code. A client raises such a refusal with its code and the class its status maps to.", "type": "object", "additionalProperties": false, "required": [ diff --git a/python/client-contract/src/dfo_client_contract/scenario.schema.json b/python/client-contract/src/dfo_client_contract/scenario.schema.json index f0d9256..5499a73 100644 --- a/python/client-contract/src/dfo_client_contract/scenario.schema.json +++ b/python/client-contract/src/dfo_client_contract/scenario.schema.json @@ -906,7 +906,7 @@ ] }, "code": { - "description": "A refusal's code: the problem document's code, the website proxy's error member, or refusal_without_code for a body with neither. A SearchWarning's code is the server's warning or departure code, or the verb of an operation Search did not run, or null when the readings differ from the question in several ways. A DataWarning's code is the manifest warning's. Any other error the client raises itself carries its code from client-codes.json.", + "description": "A refusal's code: its problem document's code, the website proxy's included, or refusal_without_code for a body without one. A SearchWarning's code is the server's warning or departure code, or the verb of an operation Search did not run, or null when the readings differ from the question in several ways. A DataWarning's code is the manifest warning's. Any other error the client raises itself carries its code from client-codes.json.", "type": [ "string", "null" diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-candidate-specs-not-a-list.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidate-specs-not-a-list.json index 1fe86c2..20a8675 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-candidate-specs-not-a-list.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidate-specs-not-a-list.json @@ -30,7 +30,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "2fefffc9aac84b4fae2eb1888a1d3b74" + "x-dfo-trace-id": "21bb19c92c824a70b2eb378e85a9cfd0" }, "json": { "schema_version": 1, @@ -41,15 +41,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "2fefffc9aac84b4fae2eb1888a1d3b74", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "21bb19c92c824a70b2eb378e85a9cfd0", "warnings": [], "timing_ms": { - "total": 2300, + "total": 8287, "by_step": { "coverage": 0, - "extract": 1022, - "cache_lookup": 0 + "extract": 1330, + "cache_lookup": 2 } }, "llm_usage": { @@ -67,28 +67,28 @@ "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 1274, + "total": 6951, "by_step": { - "recall": 0, + "recall": 261, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 4, - "shape_probe": 112, - "shape_groups": 5, + "shape_arcs": 7, + "shape_probe": 122, + "shape_groups": 6, "shape_labels": 1, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 237, + "shape": 241, "phase_prune_and_rank": 0, - "bind": 214, - "phase_bind": 3, - "phase_settle": 7, - "phase_place_bindings": 27, + "bind": 142, + "phase_bind": 17, + "phase_settle": 6, + "phase_place_bindings": 490, "phase_facet_requests": 0, - "materialise": 124, + "materialise": 115, "phase_materialise": 1, - "answer": 25, - "phase_outcome": 636 + "answer": 243, + "phase_outcome": 5435 } }, "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", @@ -280,6 +280,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -802,7 +810,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2336,7 +2344,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2571,7 +2579,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "2fefffc9aac84b4fae2eb1888a1d3b74" + "trace_id": "21bb19c92c824a70b2eb378e85a9cfd0" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json index 023638d..524967e 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-candidates-choose-fetch.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:36:53Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:30:07Z" }, "call": [ { @@ -38,7 +38,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "2fefffc9aac84b4fae2eb1888a1d3b74" + "x-dfo-trace-id": "21bb19c92c824a70b2eb378e85a9cfd0" }, "json": { "schema_version": 1, @@ -49,15 +49,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "2fefffc9aac84b4fae2eb1888a1d3b74", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "21bb19c92c824a70b2eb378e85a9cfd0", "warnings": [], "timing_ms": { - "total": 2300, + "total": 8287, "by_step": { "coverage": 0, - "extract": 1022, - "cache_lookup": 0 + "extract": 1330, + "cache_lookup": 2 } }, "llm_usage": { @@ -75,28 +75,28 @@ "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 1274, + "total": 6951, "by_step": { - "recall": 0, + "recall": 261, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 4, - "shape_probe": 112, - "shape_groups": 5, + "shape_arcs": 7, + "shape_probe": 122, + "shape_groups": 6, "shape_labels": 1, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 237, + "shape": 241, "phase_prune_and_rank": 0, - "bind": 214, - "phase_bind": 3, - "phase_settle": 7, - "phase_place_bindings": 27, + "bind": 142, + "phase_bind": 17, + "phase_settle": 6, + "phase_place_bindings": 490, "phase_facet_requests": 0, - "materialise": 124, + "materialise": 115, "phase_materialise": 1, - "answer": 25, - "phase_outcome": 636 + "answer": 243, + "phase_outcome": 5435 } }, "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", @@ -288,6 +288,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -810,7 +818,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2344,7 +2352,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2625,7 +2633,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "8122d1bf0e034c8b833ac2f202e2a9c0" + "x-dfo-trace-id": "bb50ec0b45244567bf259cee9e6de857" }, "json": { "schema_version": 1, @@ -2634,11 +2642,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "8122d1bf0e034c8b833ac2f202e2a9c0", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "bb50ec0b45244567bf259cee9e6de857", "warnings": [], "timing_ms": { - "total": 637, + "total": 486, "by_step": { "coverage": 0 } @@ -2651,21 +2659,22 @@ "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 590, + "total": 436, "by_step": { - "validate": 0, - "walk": 215, + "validate": 1, + "walk": 182, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 257, - "bind": 0, + "shape": 158, + "bind": 1, "where_places": 0, - "materialise": 116, + "materialise": 93, "answer": 1, - "options": 1 + "options": 0 } }, + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -3181,7 +3190,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -3402,7 +3411,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "5e77a52f3b71403a8932a67a979c4608" + "x-dfo-trace-id": "cbcf0bde995644728537c2ed3abc531e" }, "json": { "schema_version": 1, @@ -3610,7 +3619,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "head", - "confirmed_at": "2026-10-23T18:36:57.109042+00:00" + "confirmed_at": "2026-10-24T16:30:17.280841+00:00" }, "warnings": [], "diagnostics": [ @@ -3787,7 +3796,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-22T17:34:00.253769Z" @@ -3805,7 +3814,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A38f1b5db24567c68f9791ac00bce803082c607f23c78688edf2d95e0778a070a?X-Goog-Signature=redacted", - "x-dfo-trace-id": "4893fb552b5f47aa836ba70d4d4512b9" + "x-dfo-trace-id": "86f0988c26f742f59efa2fba3ebcf738" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json index 9b83090..a15c230 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-catalogue.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:39:10Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:31:26Z" }, "call": [ { @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "766195ed73194e73a4a9ab62bcdac9cf" + "x-dfo-trace-id": "a1f54c790c9c4278af93e96086733481" }, "json": { "schema_version": 1, @@ -45,14 +45,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "766195ed73194e73a4a9ab62bcdac9cf", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "a1f54c790c9c4278af93e96086733481", "warnings": [], "timing_ms": { - "total": 787, + "total": 1079, "by_step": { "coverage": 0, - "extract": 785, + "extract": 1079, "entity_check": 0, "cache_lookup": 0 } @@ -84,7 +84,7 @@ "error": { "class": "DeclinedError", "code": "answer_declined", - "trace_id": "766195ed73194e73a4a9ab62bcdac9cf" + "trace_id": "a1f54c790c9c4278af93e96086733481" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json index b29eb4b..dfd7f8d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-declined.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:39:09Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:31:24Z" }, "call": [ { @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "b0408d5777d8455dbb1147f8ad74ed96" + "x-dfo-trace-id": "5b2bc45dc7f7419cb3dfb98ed9bf68a3" }, "json": { "schema_version": 1, @@ -45,15 +45,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "b0408d5777d8455dbb1147f8ad74ed96", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "5b2bc45dc7f7419cb3dfb98ed9bf68a3", "warnings": [], "timing_ms": { - "total": 900, + "total": 1050, "by_step": { - "coverage": 0, - "extract": 898, - "entity_check": 1, + "coverage": 1, + "extract": 1049, + "entity_check": 0, "cache_lookup": 0 } }, @@ -90,7 +90,7 @@ "error": { "class": "DeclinedError", "code": "answer_declined", - "trace_id": "b0408d5777d8455dbb1147f8ad74ed96" + "trace_id": "5b2bc45dc7f7419cb3dfb98ed9bf68a3" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-definite-fetch.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-definite-fetch.json index 45f4ec1..4275254 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-definite-fetch.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-definite-fetch.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:36:46Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:30:01Z" }, "call": [ { @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "8ff5daac36fe403ab946f5b02785cb0d" + "x-dfo-trace-id": "bf6613bf82be4bddb4d60879aaf907d9" }, "json": { "schema_version": 1, @@ -45,21 +45,23 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "8ff5daac36fe403ab946f5b02785cb0d", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "bf6613bf82be4bddb4d60879aaf907d9", "warnings": [], "timing_ms": { - "total": 4716, + "total": 2620, "by_step": { "coverage": 0, - "extract": 1242, + "extract": 1068, "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 6216, - "output_tokens": 423, - "cached_tokens": 841 + "input_tokens": 2231, + "output_tokens": 102, + "cached_tokens": 841, + "jev_input_tokens": 6586, + "jev_output_tokens": 2060 }, "timed_out": false }, @@ -69,30 +71,30 @@ "variable_text": "ODA disbursements for basic health care", "warnings": [], "timing_ms": { - "total": 3468, + "total": 1548, "by_step": { - "recall": 547, + "recall": 437, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 1, - "shape_probe_coverage": 6, - "shape_probe": 136, - "shape_groups": 43, + "shape_arcs": 2, + "shape_probe_coverage": 4, + "shape_probe": 161, + "shape_groups": 45, "shape_labels": 1, - "shape_admission": 0, + "shape_admission": 3, "phase_derive_shapes": 0, - "shape": 1190, + "shape": 326, "phase_prune_and_rank": 0, - "bind": 1278, - "phase_bind": 149, - "phase_settle": 50, - "phase_place_bindings": 19, + "bind": 225, + "phase_bind": 158, + "phase_settle": 56, + "phase_place_bindings": 18, "phase_facet_requests": 0, - "materialise": 30, + "materialise": 41, "phase_materialise": 0, - "answer": 110, - "options": 38, - "phase_outcome": 57 + "answer": 186, + "options": 40, + "phase_outcome": 61 } }, "restatement": { @@ -110,6 +112,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Nigeria", + "refs": [ + "country/NGA" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -525,7 +541,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1178,7 +1194,7 @@ "selected": [] } ], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3776,7 +3792,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "c1f0030e84b5418d89553827b503d006" + "x-dfo-trace-id": "42460c90e7274dd19ecba24a6a0377e9" }, "json": { "schema_version": 1, @@ -4177,7 +4193,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261011T194155Z-80081f08", "served_from": "head", - "confirmed_at": "2026-10-23T18:36:51.837863+00:00" + "confirmed_at": "2026-10-24T16:30:05.017544+00:00" }, "warnings": [ { @@ -4206,7 +4222,7 @@ "created_at": "2026-10-23T16:56:32.058938+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", @@ -4505,7 +4521,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": true } @@ -4522,7 +4538,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db?X-Goog-Signature=redacted", - "x-dfo-trace-id": "b2396d674b5848e7b1828fca235d84a1" + "x-dfo-trace-id": "b9b4b3a90d6546e09cc738a29bbbb1d6" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json index f76ba2b..9c3c84d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-definition-spec-id-mismatch.json @@ -30,7 +30,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "8ff5daac36fe403ab946f5b02785cb0d" + "x-dfo-trace-id": "bf6613bf82be4bddb4d60879aaf907d9" }, "json": { "schema_version": 1, @@ -41,21 +41,23 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "8ff5daac36fe403ab946f5b02785cb0d", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "bf6613bf82be4bddb4d60879aaf907d9", "warnings": [], "timing_ms": { - "total": 4716, + "total": 2620, "by_step": { "coverage": 0, - "extract": 1242, + "extract": 1068, "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 6216, - "output_tokens": 423, - "cached_tokens": 841 + "input_tokens": 2231, + "output_tokens": 102, + "cached_tokens": 841, + "jev_input_tokens": 6586, + "jev_output_tokens": 2060 }, "timed_out": false }, @@ -65,30 +67,30 @@ "variable_text": "ODA disbursements for basic health care", "warnings": [], "timing_ms": { - "total": 3468, + "total": 1548, "by_step": { - "recall": 547, + "recall": 437, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 1, - "shape_probe_coverage": 6, - "shape_probe": 136, - "shape_groups": 43, + "shape_arcs": 2, + "shape_probe_coverage": 4, + "shape_probe": 161, + "shape_groups": 45, "shape_labels": 1, - "shape_admission": 0, + "shape_admission": 3, "phase_derive_shapes": 0, - "shape": 1190, + "shape": 326, "phase_prune_and_rank": 0, - "bind": 1278, - "phase_bind": 149, - "phase_settle": 50, - "phase_place_bindings": 19, + "bind": 225, + "phase_bind": 158, + "phase_settle": 56, + "phase_place_bindings": 18, "phase_facet_requests": 0, - "materialise": 30, + "materialise": 41, "phase_materialise": 0, - "answer": 110, - "options": 38, - "phase_outcome": 57 + "answer": 186, + "options": 40, + "phase_outcome": 61 } }, "restatement": { @@ -106,6 +108,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Nigeria", + "refs": [ + "country/NGA" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -521,7 +537,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1174,7 +1190,7 @@ "selected": [] } ], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3691,7 +3707,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "8ff5daac36fe403ab946f5b02785cb0d" + "trace_id": "bf6613bf82be4bddb4d60879aaf907d9" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json index 781f7ea..35da4e4 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-empty-parts.json @@ -30,7 +30,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f" + "x-dfo-trace-id": "304fe92b998b45849ff11a547aadc3e8" }, "json": { "schema_version": 1, @@ -41,15 +41,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "a321fb82bfba461b9dc922634789650f", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "304fe92b998b45849ff11a547aadc3e8", "warnings": [], "timing_ms": { - "total": 1126, + "total": 1416, "by_step": { "coverage": 0, - "extract": 1119, - "cache_lookup": 1 + "extract": 1297, + "cache_lookup": 0 } }, "llm_usage": { @@ -100,7 +100,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "a321fb82bfba461b9dc922634789650f" + "trace_id": "304fe92b998b45849ff11a547aadc3e8" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-folded-parts-unnamed.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-folded-parts-unnamed.json index deece61..40f0122 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-folded-parts-unnamed.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-folded-parts-unnamed.json @@ -33,7 +33,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "6d68317966c44c48a0701ff661a5e655" + "x-dfo-trace-id": "74e9acc99aff40f7a653093976c55e3b" }, "json": { "schema_version": 1, @@ -44,14 +44,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "6d68317966c44c48a0701ff661a5e655", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "74e9acc99aff40f7a653093976c55e3b", "warnings": [], "timing_ms": { - "total": 4868, + "total": 4632, "by_step": { "coverage": 0, - "extract": 1143, + "extract": 1209, "cache_lookup": 0 } }, @@ -59,8 +59,8 @@ "input_tokens": 2237, "output_tokens": 215, "cached_tokens": 842, - "jev_input_tokens": 25205, - "jev_output_tokens": 5698 + "jev_input_tokens": 25612, + "jev_output_tokens": 5740 }, "timed_out": false }, @@ -69,30 +69,30 @@ { "warnings": [], "timing_ms": { - "total": 3437, + "total": 3118, "by_step": { - "recall": 538, + "recall": 753, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 85, + "shape_arcs": 75, "shape_probe_coverage": 3, - "shape_probe": 426, - "shape_groups": 43, + "shape_probe": 164, + "shape_groups": 44, "shape_labels": 9, - "shape_admission": 1, + "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 1403, + "shape": 695, "phase_prune_and_rank": 0, - "bind": 228, - "phase_bind": 458, - "phase_settle": 103, - "phase_place_bindings": 23, + "bind": 275, + "phase_bind": 190, + "phase_settle": 91, + "phase_place_bindings": 19, "phase_facet_requests": 0, - "materialise": 385, - "phase_materialise": 1, - "answer": 18, - "options": 174, - "phase_outcome": 106 + "materialise": 616, + "phase_materialise": 0, + "answer": 20, + "options": 307, + "phase_outcome": 152 } }, "restatement": { @@ -110,6 +110,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -577,12 +591,6 @@ ] }, "facets": { - "unit": { - "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" - }, "provenance": { "basis": "fallback", "ref": "provenance/OECDCreditorReportingSystem", @@ -597,6 +605,12 @@ }, "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" } }, "slot_options": [ @@ -1422,7 +1436,7 @@ "selected": [] } ], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3750,30 +3764,30 @@ } ], "timing_ms": { - "total": 3091, + "total": 3017, "by_step": { - "recall": 450, - "phase_resolve_places": 0, + "recall": 704, + "phase_resolve_places": 1, "phase_check_entities": 0, - "shape_arcs": 93, + "shape_arcs": 82, "shape_probe_coverage": 2, - "shape_probe": 98, - "shape_groups": 44, - "shape_labels": 9, + "shape_probe": 99, + "shape_groups": 47, + "shape_labels": 10, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 374, + "shape": 365, "phase_prune_and_rank": 0, - "bind": 223, - "phase_bind": 160, - "phase_settle": 51, - "phase_place_bindings": 27, + "bind": 402, + "phase_bind": 196, + "phase_settle": 88, + "phase_place_bindings": 44, "phase_facet_requests": 0, - "materialise": 1197, + "materialise": 512, "phase_materialise": 0, - "answer": 20, - "options": 455, - "phase_outcome": 134 + "answer": 58, + "options": 511, + "phase_outcome": 136 } }, "restatement": { @@ -3791,6 +3805,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -4258,12 +4286,6 @@ ] }, "facets": { - "unit": { - "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" - }, "provenance": { "basis": "fallback", "ref": "provenance/OECDCreditorReportingSystem", @@ -4278,6 +4300,12 @@ }, "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" } }, "slot_options": [ @@ -5103,7 +5131,7 @@ "selected": [] } ], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -7436,30 +7464,30 @@ } ], "timing_ms": { - "total": 707, + "total": 1849, "by_step": { - "recall": 3, + "recall": 391, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 3, - "shape_probe_coverage": 6, - "shape_probe": 146, - "shape_groups": 48, - "shape_labels": 9, + "shape_arcs": 4, + "shape_probe_coverage": 2, + "shape_probe": 126, + "shape_groups": 55, + "shape_labels": 10, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 316, + "shape": 311, "phase_prune_and_rank": 0, - "bind": 143, - "phase_bind": 4, - "phase_settle": 16, - "phase_place_bindings": 7, + "bind": 139, + "phase_bind": 15, + "phase_settle": 27, + "phase_place_bindings": 426, "phase_facet_requests": 0, - "materialise": 98, - "phase_materialise": 1, - "answer": 6, - "options": 108, - "phase_outcome": 5 + "materialise": 93, + "phase_materialise": 0, + "answer": 244, + "options": 193, + "phase_outcome": 10 } }, "restatement": { @@ -7477,6 +7505,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [ { @@ -8882,7 +8924,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -9415,7 +9457,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -9996,7 +10038,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a13e0dc54c8e45028d75f8588accdaff" + "x-dfo-trace-id": "fc2f3ffbd0f448d2a6dcade27ac985bb" }, "json": { "schema_version": 1, @@ -14596,7 +14638,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:07.941117+00:00" + "confirmed_at": "2026-10-24T16:30:28.193872+00:00" }, "warnings": [], "diagnostics": [ @@ -14619,7 +14661,7 @@ "created_at": "2026-10-23T16:58:41.714148+00:00", "tier": "working", "url": "/api/datasets/spec_25f482395c5d012ec278118f38dff29c/cv_d6ce435ea267b46680c94eae9423d420/files/sha256:a189b171faab41729ddc1317add46add9b5eefb5fcac62a98cb735cb5f20f0f8", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:a5d2d7627c8fe1357519ca0ac021c791182ab08c76f44e8055b4bb50a6059179", @@ -14918,7 +14960,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T15:55:47.734809Z" @@ -14936,7 +14978,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Aa189b171faab41729ddc1317add46add9b5eefb5fcac62a98cb735cb5f20f0f8?X-Goog-Signature=redacted", - "x-dfo-trace-id": "98ab007ae74543b6ba88210aaea181bb" + "x-dfo-trace-id": "c0e0b1a4539f4af3b08693b51621e3cb" } } }, @@ -15029,7 +15071,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "0a0ec8988f20490a80444b30363ade09" + "x-dfo-trace-id": "8afa9ef2f2b54f89b6c8c836c84efd26" }, "json": { "schema_version": 1, @@ -15206,7 +15248,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:09.348368+00:00" + "confirmed_at": "2026-10-24T16:30:29.978390+00:00" }, "warnings": [], "diagnostics": [ @@ -15398,7 +15440,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T15:55:49.978519Z" @@ -15416,7 +15458,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839?X-Goog-Signature=redacted", - "x-dfo-trace-id": "9bd6e2b9ac8b4778b2cd39f9aca71a71" + "x-dfo-trace-id": "af76c3e1b057409e8bbc7a9647e9aacc" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json index 87e46cc..70fb08f 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-partial.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:37:00Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:30:20Z" }, "call": [ { @@ -35,7 +35,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "b78bde3ba929452aab7d7cdd34bad909" + "x-dfo-trace-id": "5974af081db54d0babd26f8b1de79beb" }, "json": { "schema_version": 1, @@ -46,15 +46,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "b78bde3ba929452aab7d7cdd34bad909", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "5974af081db54d0babd26f8b1de79beb", "warnings": [], "timing_ms": { - "total": 377, + "total": 328, "by_step": { "coverage": 0, - "extract": 1, - "cache_lookup": 0 + "extract": 0, + "cache_lookup": 1 } }, "llm_usage": { @@ -72,30 +72,30 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 372, + "total": 323, "by_step": { "recall": 1, "phase_resolve_places": 0, "phase_check_entities": 0, "shape_arcs": 2, - "shape_probe_coverage": 14, - "shape_probe": 14, + "shape_probe_coverage": 15, + "shape_probe": 16, "shape_groups": 5, "shape_labels": 10, "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 128, + "shape": 104, "phase_prune_and_rank": 0, - "bind": 144, - "phase_bind": 10, + "bind": 101, + "phase_bind": 11, "phase_settle": 12, "phase_place_bindings": 11, "phase_facet_requests": 0, "materialise": 9, "phase_materialise": 0, - "answer": 1, + "answer": 2, "options": 7, - "phase_outcome": 49 + "phase_outcome": 65 } }, "restatement": { @@ -108,6 +108,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [ @@ -562,7 +570,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1280,7 +1288,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3265,18 +3273,18 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 13, + "total": 15, "by_step": { - "recall": 0, + "recall": 1, "phase_resolve_places": 0, "phase_check_entities": 0, "shape_arcs": 1, "shape_probe": 4, - "shape_groups": 1, + "shape_groups": 2, "shape_labels": 0, "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 13, + "shape": 14, "phase_prune_and_rank": 0 } }, @@ -3290,6 +3298,7 @@ "states": [] } ], + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -3714,7 +3723,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a0264860a3af4be098e96eefef69bf74" + "x-dfo-trace-id": "b8b4bbcd49e14cd49ecea658aea24ec5" }, "json": { "schema_version": 1, @@ -3954,7 +3963,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261012T000033Z-84777283", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:01.252594+00:00" + "confirmed_at": "2026-10-24T16:30:21.793459+00:00" }, "warnings": [ { @@ -3983,7 +3992,7 @@ "created_at": "2026-10-23T16:58:25.889079+00:00", "tier": "working", "url": "/api/datasets/spec_78d04fefc3b3f1ef71acd622957e4995/cv_2c981b422e8f8bdf5dee6067837cff13/files/sha256:ab0bfec276a23aaefea6dbc3f1b57854ea520b3a7ae5feeade202f292446ed2c", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:8da8a5b081cc06acba677ac2c668e4bcafb796bf040bede5de00740acda9c9ee", @@ -4175,7 +4184,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": true } @@ -4192,7 +4201,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Aab0bfec276a23aaefea6dbc3f1b57854ea520b3a7ae5feeade202f292446ed2c?X-Goog-Signature=redacted", - "x-dfo-trace-id": "6d3da0693a134de395cfe22836258dd3" + "x-dfo-trace-id": "1ac27caa67d74511b31d6ca9016617df" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json index 3cbdd02..254d0f6 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-mixed-fetch-raises.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:36:58Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:30:18Z" }, "call": [ { @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4d9323abf43e4fccadfbd64caf2b371c" + "x-dfo-trace-id": "1e95940d311043d0b63bd27a87996439" }, "json": { "schema_version": 1, @@ -45,14 +45,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "4d9323abf43e4fccadfbd64caf2b371c", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "1e95940d311043d0b63bd27a87996439", "warnings": [], "timing_ms": { - "total": 1772, + "total": 2200, "by_step": { "coverage": 0, - "extract": 876, + "extract": 1432, "cache_lookup": 0 } }, @@ -71,30 +71,30 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 892, + "total": 757, "by_step": { - "recall": 414, + "recall": 316, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 3, - "shape_probe_coverage": 6, - "shape_probe": 93, + "shape_arcs": 2, + "shape_probe_coverage": 8, + "shape_probe": 72, "shape_groups": 5, "shape_labels": 10, "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 205, + "shape": 179, "phase_prune_and_rank": 0, - "bind": 101, + "bind": 89, "phase_bind": 10, - "phase_settle": 12, - "phase_place_bindings": 11, + "phase_settle": 13, + "phase_place_bindings": 12, "phase_facet_requests": 0, "materialise": 9, "phase_materialise": 0, - "answer": 2, - "options": 81, - "phase_outcome": 47 + "answer": 1, + "options": 79, + "phase_outcome": 49 } }, "restatement": { @@ -107,6 +107,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [ @@ -561,7 +569,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1279,7 +1287,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3264,18 +3272,18 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 466, + "total": 330, "by_step": { - "recall": 339, + "recall": 216, "phase_resolve_places": 1, "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe": 122, - "shape_groups": 1, + "shape_probe": 108, + "shape_groups": 2, "shape_labels": 0, "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 126, + "shape": 113, "phase_prune_and_rank": 0 } }, @@ -3289,6 +3297,7 @@ "states": [] } ], + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -3644,7 +3653,7 @@ "error": { "class": "IncompleteAnswerError", "code": "answer_incomplete", - "trace_id": "4d9323abf43e4fccadfbd64caf2b371c" + "trace_id": "1e95940d311043d0b63bd27a87996439" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-nested-specs-unchecked.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-nested-specs-unchecked.json index df7af53..7cd013e 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-nested-specs-unchecked.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-nested-specs-unchecked.json @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "febf95d73157448f9ad342fe31a897d4" + "x-dfo-trace-id": "6c90259bc5dc43649740c2e47cb555bc" }, "json": { "schema_version": 1, @@ -45,8 +45,8 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "febf95d73157448f9ad342fe31a897d4", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "6c90259bc5dc43649740c2e47cb555bc", "warnings": [], "timing_ms": { "total": 1, @@ -68,9 +68,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -117,6 +117,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -293,7 +303,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "9254a776588b49739881b71f3257f9b7" + "x-dfo-trace-id": "67793b9246794fc18d48484eb317d58f" }, "json": { "schema_version": 1, @@ -302,11 +312,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "9254a776588b49739881b71f3257f9b7", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "67793b9246794fc18d48484eb317d58f", "warnings": [], "timing_ms": { - "total": 1072, + "total": 932, "by_step": { "coverage": 0 } @@ -332,30 +342,30 @@ } ], "timing_ms": { - "total": 1070, + "total": 907, "by_step": { - "recall": 1, + "recall": 0, "phase_resolve_places": 0, "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe_coverage": 7, - "shape_probe": 131, - "shape_groups": 44, + "shape_probe_coverage": 6, + "shape_probe": 109, + "shape_groups": 41, "shape_labels": 1, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 524, + "shape": 387, "phase_prune_and_rank": 0, - "bind": 104, - "phase_bind": 177, - "phase_settle": 8, - "phase_place_bindings": 73, + "bind": 111, + "phase_bind": 175, + "phase_settle": 9, + "phase_place_bindings": 67, "phase_facet_requests": 0, "materialise": 15, "phase_materialise": 0, - "answer": 7, - "options": 6, - "phase_outcome": 155 + "answer": 10, + "options": 13, + "phase_outcome": 120 } }, "restatement": { @@ -376,6 +386,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Congo", + "refs": [ + "country/COD" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -745,7 +769,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1199,7 +1223,7 @@ "start_year": 2018, "end_year": 2018 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-operations-not-a-list.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-operations-not-a-list.json index ad1f32e..a9a4400 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-operations-not-a-list.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-operations-not-a-list.json @@ -33,7 +33,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "8ff5daac36fe403ab946f5b02785cb0d" + "x-dfo-trace-id": "bf6613bf82be4bddb4d60879aaf907d9" }, "json": { "schema_version": 1, @@ -44,21 +44,23 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "8ff5daac36fe403ab946f5b02785cb0d", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "bf6613bf82be4bddb4d60879aaf907d9", "warnings": [], "timing_ms": { - "total": 4716, + "total": 2620, "by_step": { "coverage": 0, - "extract": 1242, + "extract": 1068, "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 6216, - "output_tokens": 423, - "cached_tokens": 841 + "input_tokens": 2231, + "output_tokens": 102, + "cached_tokens": 841, + "jev_input_tokens": 6586, + "jev_output_tokens": 2060 }, "timed_out": false }, @@ -68,30 +70,30 @@ "variable_text": "ODA disbursements for basic health care", "warnings": [], "timing_ms": { - "total": 3468, + "total": 1548, "by_step": { - "recall": 547, + "recall": 437, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 1, - "shape_probe_coverage": 6, - "shape_probe": 136, - "shape_groups": 43, + "shape_arcs": 2, + "shape_probe_coverage": 4, + "shape_probe": 161, + "shape_groups": 45, "shape_labels": 1, - "shape_admission": 0, + "shape_admission": 3, "phase_derive_shapes": 0, - "shape": 1190, + "shape": 326, "phase_prune_and_rank": 0, - "bind": 1278, - "phase_bind": 149, - "phase_settle": 50, - "phase_place_bindings": 19, + "bind": 225, + "phase_bind": 158, + "phase_settle": 56, + "phase_place_bindings": 18, "phase_facet_requests": 0, - "materialise": 30, + "materialise": 41, "phase_materialise": 0, - "answer": 110, - "options": 38, - "phase_outcome": 57 + "answer": 186, + "options": 40, + "phase_outcome": 61 } }, "restatement": { @@ -109,6 +111,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Nigeria", + "refs": [ + "country/NGA" + ] + } + ], "operations": { "verb": "growth", "phrase": "growth of GDP", @@ -528,7 +544,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1181,7 +1197,7 @@ "selected": [] } ], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3779,7 +3795,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "c1f0030e84b5418d89553827b503d006" + "x-dfo-trace-id": "42460c90e7274dd19ecba24a6a0377e9" }, "json": { "schema_version": 1, @@ -4180,7 +4196,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261011T194155Z-80081f08", "served_from": "head", - "confirmed_at": "2026-10-23T18:36:51.837863+00:00" + "confirmed_at": "2026-10-24T16:30:05.017544+00:00" }, "warnings": [ { @@ -4209,7 +4225,7 @@ "created_at": "2026-10-23T16:56:32.058938+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", @@ -4508,7 +4524,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": true } @@ -4525,7 +4541,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db?X-Goog-Signature=redacted", - "x-dfo-trace-id": "b2396d674b5848e7b1828fca235d84a1" + "x-dfo-trace-id": "b9b4b3a90d6546e09cc738a29bbbb1d6" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-part-status-not-a-string.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-part-status-not-a-string.json index 64e0d4f..08f9ae8 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-part-status-not-a-string.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-part-status-not-a-string.json @@ -30,7 +30,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4d9323abf43e4fccadfbd64caf2b371c" + "x-dfo-trace-id": "1e95940d311043d0b63bd27a87996439" }, "json": { "schema_version": 1, @@ -41,14 +41,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "4d9323abf43e4fccadfbd64caf2b371c", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "1e95940d311043d0b63bd27a87996439", "warnings": [], "timing_ms": { - "total": 1772, + "total": 2200, "by_step": { "coverage": 0, - "extract": 876, + "extract": 1432, "cache_lookup": 0 } }, @@ -67,30 +67,30 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 892, + "total": 757, "by_step": { - "recall": 414, + "recall": 316, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 3, - "shape_probe_coverage": 6, - "shape_probe": 93, + "shape_arcs": 2, + "shape_probe_coverage": 8, + "shape_probe": 72, "shape_groups": 5, "shape_labels": 10, "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 205, + "shape": 179, "phase_prune_and_rank": 0, - "bind": 101, + "bind": 89, "phase_bind": 10, - "phase_settle": 12, - "phase_place_bindings": 11, + "phase_settle": 13, + "phase_place_bindings": 12, "phase_facet_requests": 0, "materialise": 9, "phase_materialise": 0, - "answer": 2, - "options": 81, - "phase_outcome": 47 + "answer": 1, + "options": 79, + "phase_outcome": 49 } }, "restatement": { @@ -103,6 +103,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [ @@ -557,7 +565,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1275,7 +1283,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3260,18 +3268,18 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 466, + "total": 330, "by_step": { - "recall": 339, + "recall": 216, "phase_resolve_places": 1, "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe": 122, - "shape_groups": 1, + "shape_probe": 108, + "shape_groups": 2, "shape_labels": 0, "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 126, + "shape": 113, "phase_prune_and_rank": 0 } }, @@ -3285,6 +3293,7 @@ "states": [] } ], + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -3622,7 +3631,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "4d9323abf43e4fccadfbd64caf2b371c" + "trace_id": "1e95940d311043d0b63bd27a87996439" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json index 427b029..93272d8 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-several-readings-folded.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:37:02Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:30:22Z" }, "call": [ { @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "6d68317966c44c48a0701ff661a5e655" + "x-dfo-trace-id": "74e9acc99aff40f7a653093976c55e3b" }, "json": { "schema_version": 1, @@ -45,14 +45,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "6d68317966c44c48a0701ff661a5e655", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "74e9acc99aff40f7a653093976c55e3b", "warnings": [], "timing_ms": { - "total": 4868, + "total": 4632, "by_step": { "coverage": 0, - "extract": 1143, + "extract": 1209, "cache_lookup": 0 } }, @@ -60,8 +60,8 @@ "input_tokens": 2237, "output_tokens": 215, "cached_tokens": 842, - "jev_input_tokens": 25205, - "jev_output_tokens": 5698 + "jev_input_tokens": 25612, + "jev_output_tokens": 5740 }, "timed_out": false }, @@ -71,30 +71,30 @@ "variable_text": "health ODA disbursements", "warnings": [], "timing_ms": { - "total": 3437, + "total": 3118, "by_step": { - "recall": 538, + "recall": 753, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 85, + "shape_arcs": 75, "shape_probe_coverage": 3, - "shape_probe": 426, - "shape_groups": 43, + "shape_probe": 164, + "shape_groups": 44, "shape_labels": 9, - "shape_admission": 1, + "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 1403, + "shape": 695, "phase_prune_and_rank": 0, - "bind": 228, - "phase_bind": 458, - "phase_settle": 103, - "phase_place_bindings": 23, + "bind": 275, + "phase_bind": 190, + "phase_settle": 91, + "phase_place_bindings": 19, "phase_facet_requests": 0, - "materialise": 385, - "phase_materialise": 1, - "answer": 18, - "options": 174, - "phase_outcome": 106 + "materialise": 616, + "phase_materialise": 0, + "answer": 20, + "options": 307, + "phase_outcome": 152 } }, "restatement": { @@ -112,6 +112,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -579,12 +593,6 @@ ] }, "facets": { - "unit": { - "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" - }, "provenance": { "basis": "fallback", "ref": "provenance/OECDCreditorReportingSystem", @@ -599,6 +607,12 @@ }, "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" } }, "slot_options": [ @@ -1424,7 +1438,7 @@ "selected": [] } ], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3752,30 +3766,30 @@ } ], "timing_ms": { - "total": 3091, + "total": 3017, "by_step": { - "recall": 450, - "phase_resolve_places": 0, + "recall": 704, + "phase_resolve_places": 1, "phase_check_entities": 0, - "shape_arcs": 93, + "shape_arcs": 82, "shape_probe_coverage": 2, - "shape_probe": 98, - "shape_groups": 44, - "shape_labels": 9, + "shape_probe": 99, + "shape_groups": 47, + "shape_labels": 10, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 374, + "shape": 365, "phase_prune_and_rank": 0, - "bind": 223, - "phase_bind": 160, - "phase_settle": 51, - "phase_place_bindings": 27, + "bind": 402, + "phase_bind": 196, + "phase_settle": 88, + "phase_place_bindings": 44, "phase_facet_requests": 0, - "materialise": 1197, + "materialise": 512, "phase_materialise": 0, - "answer": 20, - "options": 455, - "phase_outcome": 134 + "answer": 58, + "options": 511, + "phase_outcome": 136 } }, "restatement": { @@ -3793,6 +3807,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -4260,12 +4288,6 @@ ] }, "facets": { - "unit": { - "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" - }, "provenance": { "basis": "fallback", "ref": "provenance/OECDCreditorReportingSystem", @@ -4280,6 +4302,12 @@ }, "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" } }, "slot_options": [ @@ -5105,7 +5133,7 @@ "selected": [] } ], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -7438,30 +7466,30 @@ } ], "timing_ms": { - "total": 707, + "total": 1849, "by_step": { - "recall": 3, + "recall": 391, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 3, - "shape_probe_coverage": 6, - "shape_probe": 146, - "shape_groups": 48, - "shape_labels": 9, + "shape_arcs": 4, + "shape_probe_coverage": 2, + "shape_probe": 126, + "shape_groups": 55, + "shape_labels": 10, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 316, + "shape": 311, "phase_prune_and_rank": 0, - "bind": 143, - "phase_bind": 4, - "phase_settle": 16, - "phase_place_bindings": 7, + "bind": 139, + "phase_bind": 15, + "phase_settle": 27, + "phase_place_bindings": 426, "phase_facet_requests": 0, - "materialise": 98, - "phase_materialise": 1, - "answer": 6, - "options": 108, - "phase_outcome": 5 + "materialise": 93, + "phase_materialise": 0, + "answer": 244, + "options": 193, + "phase_outcome": 10 } }, "restatement": { @@ -7479,6 +7507,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [ { @@ -8884,7 +8926,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -9417,7 +9459,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -9998,7 +10040,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a13e0dc54c8e45028d75f8588accdaff" + "x-dfo-trace-id": "fc2f3ffbd0f448d2a6dcade27ac985bb" }, "json": { "schema_version": 1, @@ -14598,7 +14640,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:07.941117+00:00" + "confirmed_at": "2026-10-24T16:30:28.193872+00:00" }, "warnings": [], "diagnostics": [ @@ -14621,7 +14663,7 @@ "created_at": "2026-10-23T16:58:41.714148+00:00", "tier": "working", "url": "/api/datasets/spec_25f482395c5d012ec278118f38dff29c/cv_d6ce435ea267b46680c94eae9423d420/files/sha256:a189b171faab41729ddc1317add46add9b5eefb5fcac62a98cb735cb5f20f0f8", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:a5d2d7627c8fe1357519ca0ac021c791182ab08c76f44e8055b4bb50a6059179", @@ -14920,7 +14962,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T15:55:47.734809Z" @@ -14938,7 +14980,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Aa189b171faab41729ddc1317add46add9b5eefb5fcac62a98cb735cb5f20f0f8?X-Goog-Signature=redacted", - "x-dfo-trace-id": "98ab007ae74543b6ba88210aaea181bb" + "x-dfo-trace-id": "c0e0b1a4539f4af3b08693b51621e3cb" } } }, @@ -15031,7 +15073,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "0a0ec8988f20490a80444b30363ade09" + "x-dfo-trace-id": "8afa9ef2f2b54f89b6c8c836c84efd26" }, "json": { "schema_version": 1, @@ -15208,7 +15250,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:09.348368+00:00" + "confirmed_at": "2026-10-24T16:30:29.978390+00:00" }, "warnings": [], "diagnostics": [ @@ -15400,7 +15442,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T15:55:49.978519Z" @@ -15418,7 +15460,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9ff8d7d0df398e2b298b22f54828fb187c705888db1816d223137c950d037839?X-Goog-Signature=redacted", - "x-dfo-trace-id": "9bd6e2b9ac8b4778b2cd39f9aca71a71" + "x-dfo-trace-id": "af76c3e1b057409e8bbc7a9647e9aacc" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json index 9bbb96b..ddf62a5 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-identity.json @@ -30,7 +30,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "8ff5daac36fe403ab946f5b02785cb0d" + "x-dfo-trace-id": "bf6613bf82be4bddb4d60879aaf907d9" }, "json": { "schema_version": 1, @@ -41,21 +41,23 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "8ff5daac36fe403ab946f5b02785cb0d", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "bf6613bf82be4bddb4d60879aaf907d9", "warnings": [], "timing_ms": { - "total": 4716, + "total": 2620, "by_step": { "coverage": 0, - "extract": 1242, + "extract": 1068, "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 6216, - "output_tokens": 423, - "cached_tokens": 841 + "input_tokens": 2231, + "output_tokens": 102, + "cached_tokens": 841, + "jev_input_tokens": 6586, + "jev_output_tokens": 2060 }, "timed_out": false }, @@ -65,30 +67,30 @@ "variable_text": "ODA disbursements for basic health care", "warnings": [], "timing_ms": { - "total": 3468, + "total": 1548, "by_step": { - "recall": 547, + "recall": 437, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 1, - "shape_probe_coverage": 6, - "shape_probe": 136, - "shape_groups": 43, + "shape_arcs": 2, + "shape_probe_coverage": 4, + "shape_probe": 161, + "shape_groups": 45, "shape_labels": 1, - "shape_admission": 0, + "shape_admission": 3, "phase_derive_shapes": 0, - "shape": 1190, + "shape": 326, "phase_prune_and_rank": 0, - "bind": 1278, - "phase_bind": 149, - "phase_settle": 50, - "phase_place_bindings": 19, + "bind": 225, + "phase_bind": 158, + "phase_settle": 56, + "phase_place_bindings": 18, "phase_facet_requests": 0, - "materialise": 30, + "materialise": 41, "phase_materialise": 0, - "answer": 110, - "options": 38, - "phase_outcome": 57 + "answer": 186, + "options": 40, + "phase_outcome": 61 } }, "restatement": { @@ -106,6 +108,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Nigeria", + "refs": [ + "country/NGA" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -458,7 +474,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1111,7 +1127,7 @@ "selected": [] } ], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3628,7 +3644,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "8ff5daac36fe403ab946f5b02785cb0d" + "trace_id": "bf6613bf82be4bddb4d60879aaf907d9" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json index b661d6f..67702d7 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-spec-without-resolved.json @@ -30,7 +30,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "8ff5daac36fe403ab946f5b02785cb0d" + "x-dfo-trace-id": "bf6613bf82be4bddb4d60879aaf907d9" }, "json": { "schema_version": 1, @@ -41,21 +41,23 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "8ff5daac36fe403ab946f5b02785cb0d", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "bf6613bf82be4bddb4d60879aaf907d9", "warnings": [], "timing_ms": { - "total": 4716, + "total": 2620, "by_step": { "coverage": 0, - "extract": 1242, + "extract": 1068, "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 6216, - "output_tokens": 423, - "cached_tokens": 841 + "input_tokens": 2231, + "output_tokens": 102, + "cached_tokens": 841, + "jev_input_tokens": 6586, + "jev_output_tokens": 2060 }, "timed_out": false }, @@ -65,30 +67,30 @@ "variable_text": "ODA disbursements for basic health care", "warnings": [], "timing_ms": { - "total": 3468, + "total": 1548, "by_step": { - "recall": 547, + "recall": 437, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 1, - "shape_probe_coverage": 6, - "shape_probe": 136, - "shape_groups": 43, + "shape_arcs": 2, + "shape_probe_coverage": 4, + "shape_probe": 161, + "shape_groups": 45, "shape_labels": 1, - "shape_admission": 0, + "shape_admission": 3, "phase_derive_shapes": 0, - "shape": 1190, + "shape": 326, "phase_prune_and_rank": 0, - "bind": 1278, - "phase_bind": 149, - "phase_settle": 50, - "phase_place_bindings": 19, + "bind": 225, + "phase_bind": 158, + "phase_settle": 56, + "phase_place_bindings": 18, "phase_facet_requests": 0, - "materialise": 30, + "materialise": 41, "phase_materialise": 0, - "answer": 110, - "options": 38, - "phase_outcome": 57 + "answer": 186, + "options": 40, + "phase_outcome": 61 } }, "restatement": { @@ -106,6 +108,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Nigeria", + "refs": [ + "country/NGA" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -408,7 +424,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "8ff5daac36fe403ab946f5b02785cb0d" + "trace_id": "bf6613bf82be4bddb4d60879aaf907d9" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json index f4f913b..54b6e48 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-timed-out.json @@ -44,14 +44,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "4d9323abf43e4fccadfbd64caf2b371c", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "1e95940d311043d0b63bd27a87996439", "warnings": [], "timing_ms": { - "total": 1772, + "total": 2200, "by_step": { "coverage": 0, - "extract": 876, + "extract": 1432, "cache_lookup": 0 } }, @@ -70,30 +70,30 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 892, + "total": 757, "by_step": { - "recall": 414, + "recall": 316, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 3, - "shape_probe_coverage": 6, - "shape_probe": 93, + "shape_arcs": 2, + "shape_probe_coverage": 8, + "shape_probe": 72, "shape_groups": 5, "shape_labels": 10, "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 205, + "shape": 179, "phase_prune_and_rank": 0, - "bind": 101, + "bind": 89, "phase_bind": 10, - "phase_settle": 12, - "phase_place_bindings": 11, + "phase_settle": 13, + "phase_place_bindings": 12, "phase_facet_requests": 0, "materialise": 9, "phase_materialise": 0, - "answer": 2, - "options": 81, - "phase_outcome": 47 + "answer": 1, + "options": 79, + "phase_outcome": 49 } }, "restatement": { @@ -106,6 +106,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [ @@ -560,7 +568,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1278,7 +1286,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3263,18 +3271,18 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 466, + "total": 330, "by_step": { - "recall": 339, + "recall": 216, "phase_resolve_places": 1, "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe": 122, - "shape_groups": 1, + "shape_probe": 108, + "shape_groups": 2, "shape_labels": 0, "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 126, + "shape": 113, "phase_prune_and_rank": 0 } }, @@ -3288,6 +3296,7 @@ "states": [] } ], + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json index fca486e..d55e0ec 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-enum-value.json @@ -30,7 +30,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f" + "x-dfo-trace-id": "304fe92b998b45849ff11a547aadc3e8" }, "json": { "schema_version": 1, @@ -41,15 +41,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "a321fb82bfba461b9dc922634789650f", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "304fe92b998b45849ff11a547aadc3e8", "warnings": [], "timing_ms": { - "total": 1126, + "total": 1416, "by_step": { "coverage": 0, - "extract": 1119, - "cache_lookup": 1 + "extract": 1297, + "cache_lookup": 0 } }, "llm_usage": { @@ -65,9 +65,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -114,6 +114,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json index 4a04035..bf2b909 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-kind.json @@ -30,7 +30,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f" + "x-dfo-trace-id": "304fe92b998b45849ff11a547aadc3e8" }, "json": { "schema_version": 1, @@ -41,15 +41,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "a321fb82bfba461b9dc922634789650f", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "304fe92b998b45849ff11a547aadc3e8", "warnings": [], "timing_ms": { - "total": 1126, + "total": 1416, "by_step": { "coverage": 0, - "extract": 1119, - "cache_lookup": 1 + "extract": 1297, + "cache_lookup": 0 } }, "llm_usage": { @@ -65,9 +65,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -114,6 +114,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -247,7 +257,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "a321fb82bfba461b9dc922634789650f" + "trace_id": "304fe92b998b45849ff11a547aadc3e8" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json index d0ba462..1ca39fd 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unknown-part-status.json @@ -33,7 +33,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4d9323abf43e4fccadfbd64caf2b371c" + "x-dfo-trace-id": "1e95940d311043d0b63bd27a87996439" }, "json": { "schema_version": 1, @@ -44,14 +44,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "4d9323abf43e4fccadfbd64caf2b371c", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "1e95940d311043d0b63bd27a87996439", "warnings": [], "timing_ms": { - "total": 1772, + "total": 2200, "by_step": { "coverage": 0, - "extract": 876, + "extract": 1432, "cache_lookup": 0 } }, @@ -70,30 +70,30 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 892, + "total": 757, "by_step": { - "recall": 414, + "recall": 316, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 3, - "shape_probe_coverage": 6, - "shape_probe": 93, + "shape_arcs": 2, + "shape_probe_coverage": 8, + "shape_probe": 72, "shape_groups": 5, "shape_labels": 10, "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 205, + "shape": 179, "phase_prune_and_rank": 0, - "bind": 101, + "bind": 89, "phase_bind": 10, - "phase_settle": 12, - "phase_place_bindings": 11, + "phase_settle": 13, + "phase_place_bindings": 12, "phase_facet_requests": 0, "materialise": 9, "phase_materialise": 0, - "answer": 2, - "options": 81, - "phase_outcome": 47 + "answer": 1, + "options": 79, + "phase_outcome": 49 } }, "restatement": { @@ -106,6 +106,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [ @@ -560,7 +568,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1278,7 +1286,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3263,18 +3271,18 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 466, + "total": 330, "by_step": { - "recall": 339, + "recall": 216, "phase_resolve_places": 1, "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe": 122, - "shape_groups": 1, + "shape_probe": 108, + "shape_groups": 2, "shape_labels": 0, "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 126, + "shape": 113, "phase_prune_and_rank": 0 } }, @@ -3288,6 +3296,7 @@ "states": [] } ], + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -3643,7 +3652,7 @@ "error": { "class": "IncompleteAnswerError", "code": "answer_incomplete", - "trace_id": "4d9323abf43e4fccadfbd64caf2b371c" + "trace_id": "1e95940d311043d0b63bd27a87996439" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json b/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json index ea402dc..3471fd6 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/answer-unsupported-part.json @@ -33,7 +33,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4d9323abf43e4fccadfbd64caf2b371c" + "x-dfo-trace-id": "1e95940d311043d0b63bd27a87996439" }, "json": { "schema_version": 1, @@ -44,14 +44,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "4d9323abf43e4fccadfbd64caf2b371c", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "1e95940d311043d0b63bd27a87996439", "warnings": [], "timing_ms": { - "total": 1772, + "total": 2200, "by_step": { "coverage": 0, - "extract": 876, + "extract": 1432, "cache_lookup": 0 } }, @@ -70,30 +70,30 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 892, + "total": 757, "by_step": { - "recall": 414, + "recall": 316, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 3, - "shape_probe_coverage": 6, - "shape_probe": 93, + "shape_arcs": 2, + "shape_probe_coverage": 8, + "shape_probe": 72, "shape_groups": 5, "shape_labels": 10, "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 205, + "shape": 179, "phase_prune_and_rank": 0, - "bind": 101, + "bind": 89, "phase_bind": 10, - "phase_settle": 12, - "phase_place_bindings": 11, + "phase_settle": 13, + "phase_place_bindings": 12, "phase_facet_requests": 0, "materialise": 9, "phase_materialise": 0, - "answer": 2, - "options": 81, - "phase_outcome": 47 + "answer": 1, + "options": 79, + "phase_outcome": 49 } }, "restatement": { @@ -106,6 +106,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [ @@ -560,7 +568,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1278,7 +1286,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3263,18 +3271,18 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 466, + "total": 330, "by_step": { - "recall": 339, + "recall": 216, "phase_resolve_places": 1, "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe": 122, - "shape_groups": 1, + "shape_probe": 108, + "shape_groups": 2, "shape_labels": 0, "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 126, + "shape": 113, "phase_prune_and_rank": 0 } }, @@ -3288,6 +3296,7 @@ "states": [] } ], + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -3637,7 +3646,7 @@ "error": { "class": "IncompleteAnswerError", "code": "answer_incomplete", - "trace_id": "4d9323abf43e4fccadfbd64caf2b371c" + "trace_id": "1e95940d311043d0b63bd27a87996439" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-assumed-reading.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-assumed-reading.json index 370fea6..d4a4d89 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-assumed-reading.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-assumed-reading.json @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "2fefffc9aac84b4fae2eb1888a1d3b74" + "x-dfo-trace-id": "21bb19c92c824a70b2eb378e85a9cfd0" }, "json": { "schema_version": 1, @@ -45,15 +45,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "2fefffc9aac84b4fae2eb1888a1d3b74", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "21bb19c92c824a70b2eb378e85a9cfd0", "warnings": [], "timing_ms": { - "total": 2300, + "total": 8287, "by_step": { "coverage": 0, - "extract": 1022, - "cache_lookup": 0 + "extract": 1330, + "cache_lookup": 2 } }, "llm_usage": { @@ -71,28 +71,28 @@ "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 1274, + "total": 6951, "by_step": { - "recall": 0, + "recall": 261, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 4, - "shape_probe": 112, - "shape_groups": 5, + "shape_arcs": 7, + "shape_probe": 122, + "shape_groups": 6, "shape_labels": 1, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 237, + "shape": 241, "phase_prune_and_rank": 0, - "bind": 214, - "phase_bind": 3, - "phase_settle": 7, - "phase_place_bindings": 27, + "bind": 142, + "phase_bind": 17, + "phase_settle": 6, + "phase_place_bindings": 490, "phase_facet_requests": 0, - "materialise": 124, + "materialise": 115, "phase_materialise": 1, - "answer": 25, - "phase_outcome": 636 + "answer": 243, + "phase_outcome": 5435 } }, "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", @@ -284,6 +284,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -806,7 +814,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2340,7 +2348,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2639,7 +2647,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "8122d1bf0e034c8b833ac2f202e2a9c0" + "x-dfo-trace-id": "bb50ec0b45244567bf259cee9e6de857" }, "json": { "schema_version": 1, @@ -2648,11 +2656,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "8122d1bf0e034c8b833ac2f202e2a9c0", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "bb50ec0b45244567bf259cee9e6de857", "warnings": [], "timing_ms": { - "total": 637, + "total": 486, "by_step": { "coverage": 0 } @@ -2665,21 +2673,22 @@ "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 590, + "total": 436, "by_step": { - "validate": 0, - "walk": 215, + "validate": 1, + "walk": 182, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 257, - "bind": 0, + "shape": 158, + "bind": 1, "where_places": 0, - "materialise": 116, + "materialise": 93, "answer": 1, - "options": 1 + "options": 0 } }, + "entity_refs": [], "operations": [], "departures": [], "assumptions": [ @@ -3204,7 +3213,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-by-label.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-by-label.json index 15fafc5..6219a29 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-by-label.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-by-label.json @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "2fefffc9aac84b4fae2eb1888a1d3b74" + "x-dfo-trace-id": "21bb19c92c824a70b2eb378e85a9cfd0" }, "json": { "schema_version": 1, @@ -45,15 +45,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "2fefffc9aac84b4fae2eb1888a1d3b74", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "21bb19c92c824a70b2eb378e85a9cfd0", "warnings": [], "timing_ms": { - "total": 2300, + "total": 8287, "by_step": { "coverage": 0, - "extract": 1022, - "cache_lookup": 0 + "extract": 1330, + "cache_lookup": 2 } }, "llm_usage": { @@ -71,28 +71,28 @@ "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 1274, + "total": 6951, "by_step": { - "recall": 0, + "recall": 261, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 4, - "shape_probe": 112, - "shape_groups": 5, + "shape_arcs": 7, + "shape_probe": 122, + "shape_groups": 6, "shape_labels": 1, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 237, + "shape": 241, "phase_prune_and_rank": 0, - "bind": 214, - "phase_bind": 3, - "phase_settle": 7, - "phase_place_bindings": 27, + "bind": 142, + "phase_bind": 17, + "phase_settle": 6, + "phase_place_bindings": 490, "phase_facet_requests": 0, - "materialise": 124, + "materialise": 115, "phase_materialise": 1, - "answer": 25, - "phase_outcome": 636 + "answer": 243, + "phase_outcome": 5435 } }, "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", @@ -284,6 +284,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -806,7 +814,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2340,7 +2348,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2621,7 +2629,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "8122d1bf0e034c8b833ac2f202e2a9c0" + "x-dfo-trace-id": "bb50ec0b45244567bf259cee9e6de857" }, "json": { "schema_version": 1, @@ -2630,11 +2638,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "8122d1bf0e034c8b833ac2f202e2a9c0", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "bb50ec0b45244567bf259cee9e6de857", "warnings": [], "timing_ms": { - "total": 637, + "total": 486, "by_step": { "coverage": 0 } @@ -2647,21 +2655,22 @@ "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 590, + "total": 436, "by_step": { - "validate": 0, - "walk": 215, + "validate": 1, + "walk": 182, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 257, - "bind": 0, + "shape": 158, + "bind": 1, "where_places": 0, - "materialise": 116, + "materialise": 93, "answer": 1, - "options": 1 + "options": 0 } }, + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -3177,7 +3186,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-echoes-assumptions.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-echoes-assumptions.json index eb1315d..c0a28da 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-echoes-assumptions.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-echoes-assumptions.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:39:43Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:32:01Z" }, "call": [ { @@ -36,7 +36,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "25c71c81e1ca452e8b685116e6be540e" + "x-dfo-trace-id": "fef53a976b3e4e1cb64f3bc36f96f076" }, "json": { "schema_version": 1, @@ -47,14 +47,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "25c71c81e1ca452e8b685116e6be540e", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "fef53a976b3e4e1cb64f3bc36f96f076", "warnings": [], "timing_ms": { - "total": 3941, + "total": 3026, "by_step": { "coverage": 0, - "extract": 1292, + "extract": 1213, "cache_lookup": 0 } }, @@ -79,28 +79,28 @@ } ], "timing_ms": { - "total": 2646, + "total": 1634, "by_step": { "recall": 1, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 4, - "shape_probe": 106, + "shape_arcs": 3, + "shape_probe": 138, "shape_groups": 5, "shape_labels": 1, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 250, + "shape": 249, "phase_prune_and_rank": 0, - "bind": 805, - "phase_bind": 4, - "phase_settle": 8, - "phase_place_bindings": 110, + "bind": 135, + "phase_bind": 11, + "phase_settle": 7, + "phase_place_bindings": 28, "phase_facet_requests": 0, - "materialise": 167, + "materialise": 116, "phase_materialise": 0, - "answer": 26, - "phase_outcome": 1275 + "answer": 57, + "phase_outcome": 1030 } }, "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", @@ -307,6 +307,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [ { @@ -836,7 +844,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2370,7 +2378,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2406,30 +2414,30 @@ } ], "timing_ms": { - "total": 1430, + "total": 1809, "by_step": { - "recall": 0, + "recall": 452, "phase_resolve_places": 0, "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe_coverage": 6, - "shape_probe": 111, - "shape_groups": 50, + "shape_probe_coverage": 10, + "shape_probe": 142, + "shape_groups": 40, "shape_labels": 0, - "shape_admission": 1, + "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 565, + "shape": 666, "phase_prune_and_rank": 0, - "bind": 135, - "phase_bind": 368, - "phase_settle": 11, - "phase_place_bindings": 91, + "bind": 129, + "phase_bind": 297, + "phase_settle": 13, + "phase_place_bindings": 76, "phase_facet_requests": 0, - "materialise": 38, + "materialise": 16, "phase_materialise": 0, - "answer": 25, - "options": 7, - "phase_outcome": 190 + "answer": 8, + "options": 33, + "phase_outcome": 119 } }, "restatement": { @@ -2444,6 +2452,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [ { @@ -2455,7 +2471,7 @@ { "code": "whole_total_read", "binding_ref": "origin:", - "text": "No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, search again with open_roles ['donor']." + "text": "No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, add \"for each donor\" to the question." } ], "assumptions": [ @@ -2848,7 +2864,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -3296,7 +3312,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -5419,7 +5435,7 @@ } } ], - "rendered_sentence": "Answered 1 of 2 parts. Mortality has 2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself. Gross disbursements to Kenya from official donors (DAC) for official development assistance, 2013 to 2022. Current US dollars · OECD DAC2a. You asked for aid flows. This shows gross disbursements, the closest measure the data holds. No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, search again with open_roles ['donor']. Assumed: official development assistance.", + "rendered_sentence": "Answered 1 of 2 parts. Mortality has 2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself. Gross disbursements to Kenya from official donors (DAC) for official development assistance, 2013 to 2022. Current US dollars · OECD DAC2a. You asked for aid flows. This shows gross disbursements, the closest measure the data holds. No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, add \"for each donor\" to the question. Assumed: official development assistance.", "sentence_plan": [ { "kind": "text", @@ -5882,7 +5898,7 @@ }, { "kind": "text", - "text": "No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, search again with open_roles ['donor'].", + "text": "No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, add \"for each donor\" to the question.", "segment": "departure", "entity_refs": [], "states": [], @@ -6057,7 +6073,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "bdcd09adc5d149ef9430710a445cb8ca" + "x-dfo-trace-id": "6255e04219bd4208bca0a6f26fbe89b2" }, "json": { "schema_version": 1, @@ -6066,11 +6082,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "bdcd09adc5d149ef9430710a445cb8ca", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "6255e04219bd4208bca0a6f26fbe89b2", "warnings": [], "timing_ms": { - "total": 1780, + "total": 1746, "by_step": { "coverage": 0 } @@ -6083,21 +6099,22 @@ "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 303, + "total": 262, "by_step": { - "validate": 1, + "validate": 0, "walk": 0, - "reread_arcs": 0, + "reread_arcs": 1, "detect_edits": 0, "resolve_survivors": 0, - "shape": 209, + "shape": 169, "bind": 0, "where_places": 0, - "materialise": 92, + "materialise": 91, "answer": 1, "options": 0 } }, + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -6613,7 +6630,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -6662,21 +6679,22 @@ "variable_text": "aid flows", "warnings": [], "timing_ms": { - "total": 1732, + "total": 1695, "by_step": { "validate": 0, "walk": 10, - "reread_arcs": 0, + "reread_arcs": 1, "detect_edits": 0, "resolve_survivors": 0, - "shape": 1699, + "shape": 1660, "bind": 0, "where_places": 0, - "materialise": 14, + "materialise": 15, "answer": 7, "options": 2 } }, + "entity_refs": [], "operations": [], "departures": [ { @@ -7074,7 +7092,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -7522,7 +7540,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -10018,7 +10036,7 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "Answered 1 of 2 parts. Mortality has 2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself. Gross disbursements to Kenya from official donors (DAC) for official development assistance, 2013 to 2022. Current US dollars · OECD DAC2a. You asked for aid flows. This shows gross disbursements, the closest measure the data holds. No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, search again with open_roles ['donor']. Assumed: official development assistance.", + "sentence": "Answered 1 of 2 parts. Mortality has 2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself. Gross disbursements to Kenya from official donors (DAC) for official development assistance, 2013 to 2022. Current US dollars · OECD DAC2a. You asked for aid flows. This shows gross disbursements, the closest measure the data holds. No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, add \"for each donor\" to the question. Assumed: official development assistance.", "complete": false, "specs": [ "spec_f24e46ae9854884308fc0f33d154361e" diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json index 7bbd5e0..cbcd88d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-candidate-two-parts.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:39:21Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:31:37Z" }, "call": [ { @@ -39,7 +39,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "fac5b4aa15d145e6b20db91a1cd7a24b" + "x-dfo-trace-id": "542dac0d7c43477cb66c1841c20e169d" }, "json": { "schema_version": 1, @@ -50,14 +50,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "fac5b4aa15d145e6b20db91a1cd7a24b", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "542dac0d7c43477cb66c1841c20e169d", "warnings": [], "timing_ms": { - "total": 9120, + "total": 8962, "by_step": { "coverage": 0, - "extract": 979, + "extract": 1389, "cache_lookup": 0 } }, @@ -65,8 +65,8 @@ "input_tokens": 2245, "output_tokens": 202, "cached_tokens": 844, - "jev_input_tokens": 26433, - "jev_output_tokens": 5561 + "jev_input_tokens": 26840, + "jev_output_tokens": 5603 }, "timed_out": false }, @@ -76,28 +76,28 @@ "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 8137, + "total": 7499, "by_step": { - "recall": 0, - "phase_resolve_places": 1, + "recall": 1, + "phase_resolve_places": 83, "phase_check_entities": 0, - "shape_arcs": 3, - "shape_probe": 102, + "shape_arcs": 4, + "shape_probe": 98, "shape_groups": 5, "shape_labels": 1, - "shape_admission": 1, + "shape_admission": 75, "phase_derive_shapes": 0, - "shape": 362, + "shape": 417, "phase_prune_and_rank": 0, - "bind": 146, - "phase_bind": 4, - "phase_settle": 11, - "phase_place_bindings": 27, + "bind": 125, + "phase_bind": 17, + "phase_settle": 7, + "phase_place_bindings": 23, "phase_facet_requests": 0, - "materialise": 896, + "materialise": 285, "phase_materialise": 0, - "answer": 45, - "phase_outcome": 6645 + "answer": 46, + "phase_outcome": 6495 } }, "rendered_sentence": "3 readings. Deaths rate per capita in the 48 countries in Sub-Saharan Africa. World Development Indicators · 2013 to 2022. Number of deaths in the 48 countries in Sub-Saharan Africa. Kenya Census · 2018 to 2022. Count of mortality event (as fraction of count birth event live birth) in the 48 countries in Sub-Saharan Africa. Nigeria Statistics · 2014.", @@ -348,6 +348,68 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + }, + { + "text": "Sub-Saharan Africa", + "refs": [ + "SubSaharanAfrica", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -1915,7 +1977,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -4485,7 +4547,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -6074,7 +6136,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -6100,30 +6162,30 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 1889, + "total": 1683, "by_step": { - "recall": 1, - "phase_resolve_places": 0, + "recall": 0, + "phase_resolve_places": 103, "phase_check_entities": 0, - "shape_arcs": 4, - "shape_probe_coverage": 8, - "shape_probe": 10, - "shape_groups": 46, + "shape_arcs": 3, + "shape_probe_coverage": 3, + "shape_probe": 5, + "shape_groups": 48, "shape_labels": 10, - "shape_admission": 1, + "shape_admission": 112, "phase_derive_shapes": 0, - "shape": 327, + "shape": 447, "phase_prune_and_rank": 0, - "bind": 843, - "phase_bind": 4, - "phase_settle": 16, + "bind": 143, + "phase_bind": 12, + "phase_settle": 36, "phase_place_bindings": 7, "phase_facet_requests": 0, - "materialise": 377, + "materialise": 337, "phase_materialise": 0, - "answer": 32, - "options": 146, - "phase_outcome": 136 + "answer": 33, + "options": 426, + "phase_outcome": 139 } }, "restatement": { @@ -6140,6 +6202,68 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + }, + { + "text": "Sub-Saharan Africa", + "refs": [ + "SubSaharanAfrica", + "country/AGO", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BWA", + "country/CAF", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COM", + "country/CPV", + "country/DJI", + "country/ERI", + "country/ETH", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/KEN", + "country/LBR", + "country/LSO", + "country/MDG", + "country/MLI", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/NAM", + "country/NER", + "country/NGA", + "country/RWA", + "country/SEN", + "country/SLE", + "country/SOM", + "country/SSD", + "country/STP", + "country/SWZ", + "country/SYC", + "country/TCD", + "country/TGO", + "country/TZA", + "country/UGA", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + } + ], "operations": [], "departures": [ { @@ -8563,7 +8687,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -10132,7 +10256,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -10887,7 +11011,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a307928119964968b55057dbf481949e" + "x-dfo-trace-id": "fed0402857db4d198957a2377d91a266" }, "json": { "schema_version": 1, @@ -10896,11 +11020,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "a307928119964968b55057dbf481949e", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "fed0402857db4d198957a2377d91a266", "warnings": [], "timing_ms": { - "total": 1587, + "total": 1060, "by_step": { "coverage": 0 } @@ -10913,21 +11037,22 @@ "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 1115, + "total": 548, "by_step": { "validate": 1, "walk": 0, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 192, + "shape": 157, "bind": 0, - "where_places": 1, - "materialise": 780, - "answer": 17, - "options": 124 + "where_places": 0, + "materialise": 256, + "answer": 8, + "options": 126 } }, + "entity_refs": [], "operations": [], "departures": [ { @@ -12494,7 +12619,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -12508,21 +12633,22 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 1463, + "total": 937, "by_step": { "validate": 0, "walk": 0, - "reread_arcs": 1, + "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 980, + "shape": 657, "bind": 0, - "where_places": 0, - "materialise": 197, - "answer": 8, - "options": 277 + "where_places": 1, + "materialise": 181, + "answer": 7, + "options": 91 } }, + "entity_refs": [], "operations": [], "departures": [ { @@ -14651,7 +14777,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -15091,7 +15217,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "56077c07b2ac447282af326922be9262" + "x-dfo-trace-id": "4afea2b786664a9fa9659b020e0016d6" }, "json": { "schema_version": 1, @@ -15352,7 +15478,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "head", - "confirmed_at": "2026-10-23T18:39:33.191814+00:00" + "confirmed_at": "2026-10-24T16:31:48.627461+00:00" }, "warnings": [], "diagnostics": [ @@ -15550,7 +15676,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-22T17:40:52.293692Z" @@ -15568,7 +15694,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A0652c59a04403a740ed0a4a75360cc04900bbcce57dfc4d7f7b7d2b21a9404dd?X-Goog-Signature=redacted", - "x-dfo-trace-id": "cd6b8ede11cf4b3cbf3b5aef915f8d14" + "x-dfo-trace-id": "4035ed942dbd417b883890979c32af7b" } } }, @@ -15709,7 +15835,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "42d04700ff8e49ab9a21a3f778594017" + "x-dfo-trace-id": "0dd46708d45b47a39b91408cc8700637" }, "json": { "schema_version": 1, @@ -15934,7 +16060,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "head", - "confirmed_at": "2026-10-23T18:39:34.359134+00:00" + "confirmed_at": "2026-10-24T16:31:49.948810+00:00" }, "warnings": [ { @@ -16138,7 +16264,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-22T17:40:54.208730Z" @@ -16156,7 +16282,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A18a2e84a4829808841c3967941a92c555ac6c8c30856fe2113ba38d89e121cf7?X-Goog-Signature=redacted", - "x-dfo-trace-id": "8c9d245aa46c4b6e89b1cf2c79657eb3" + "x-dfo-trace-id": "7646f48ce8414ae8aefdf014523b025c" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-echo-drops-malformed-items.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-echo-drops-malformed-items.json index 2e5100d..8e13000 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-echo-drops-malformed-items.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-echo-drops-malformed-items.json @@ -35,7 +35,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "25c71c81e1ca452e8b685116e6be540e" + "x-dfo-trace-id": "fef53a976b3e4e1cb64f3bc36f96f076" }, "json": { "schema_version": 1, @@ -46,14 +46,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "25c71c81e1ca452e8b685116e6be540e", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "fef53a976b3e4e1cb64f3bc36f96f076", "warnings": [], "timing_ms": { - "total": 3941, + "total": 3026, "by_step": { "coverage": 0, - "extract": 1292, + "extract": 1213, "cache_lookup": 0 } }, @@ -78,28 +78,28 @@ } ], "timing_ms": { - "total": 2646, + "total": 1634, "by_step": { "recall": 1, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 4, - "shape_probe": 106, + "shape_arcs": 3, + "shape_probe": 138, "shape_groups": 5, "shape_labels": 1, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 250, + "shape": 249, "phase_prune_and_rank": 0, - "bind": 805, - "phase_bind": 4, - "phase_settle": 8, - "phase_place_bindings": 110, + "bind": 135, + "phase_bind": 11, + "phase_settle": 7, + "phase_place_bindings": 28, "phase_facet_requests": 0, - "materialise": 167, + "materialise": 116, "phase_materialise": 0, - "answer": 26, - "phase_outcome": 1275 + "answer": 57, + "phase_outcome": 1030 } }, "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself.", @@ -306,6 +306,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [ { @@ -835,7 +843,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2369,7 +2377,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2412,30 +2420,30 @@ } ], "timing_ms": { - "total": 1430, + "total": 1809, "by_step": { - "recall": 0, + "recall": 452, "phase_resolve_places": 0, "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe_coverage": 6, - "shape_probe": 111, - "shape_groups": 50, + "shape_probe_coverage": 10, + "shape_probe": 142, + "shape_groups": 40, "shape_labels": 0, - "shape_admission": 1, + "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 565, + "shape": 666, "phase_prune_and_rank": 0, - "bind": 135, - "phase_bind": 368, - "phase_settle": 11, - "phase_place_bindings": 91, + "bind": 129, + "phase_bind": 297, + "phase_settle": 13, + "phase_place_bindings": 76, "phase_facet_requests": 0, - "materialise": 38, + "materialise": 16, "phase_materialise": 0, - "answer": 25, - "options": 7, - "phase_outcome": 190 + "answer": 8, + "options": 33, + "phase_outcome": 119 } }, "restatement": { @@ -2450,6 +2458,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [ 42, { @@ -2478,7 +2494,7 @@ { "code": "whole_total_read", "binding_ref": "origin:", - "text": "No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, search again with open_roles ['donor']." + "text": "No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, add \"for each donor\" to the question." } ], "assumptions": [ @@ -2887,7 +2903,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -3335,7 +3351,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -5458,7 +5474,7 @@ } } ], - "rendered_sentence": "Answered 1 of 2 parts. Mortality has 2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself. Gross disbursements to Kenya from official donors (DAC) for official development assistance, 2013 to 2022. Current US dollars · OECD DAC2a. You asked for aid flows. This shows gross disbursements, the closest measure the data holds. No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, search again with open_roles ['donor']. Assumed: official development assistance.", + "rendered_sentence": "Answered 1 of 2 parts. Mortality has 2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself. Gross disbursements to Kenya from official donors (DAC) for official development assistance, 2013 to 2022. Current US dollars · OECD DAC2a. You asked for aid flows. This shows gross disbursements, the closest measure the data holds. No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, add \"for each donor\" to the question. Assumed: official development assistance.", "sentence_plan": [ { "kind": "text", @@ -5921,7 +5937,7 @@ }, { "kind": "text", - "text": "No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, search again with open_roles ['donor'].", + "text": "No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, add \"for each donor\" to the question.", "segment": "departure", "entity_refs": [], "states": [], @@ -6115,7 +6131,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "bdcd09adc5d149ef9430710a445cb8ca" + "x-dfo-trace-id": "6255e04219bd4208bca0a6f26fbe89b2" }, "json": { "schema_version": 1, @@ -6124,11 +6140,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "bdcd09adc5d149ef9430710a445cb8ca", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "6255e04219bd4208bca0a6f26fbe89b2", "warnings": [], "timing_ms": { - "total": 1780, + "total": 1746, "by_step": { "coverage": 0 } @@ -6141,21 +6157,22 @@ "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 303, + "total": 262, "by_step": { - "validate": 1, + "validate": 0, "walk": 0, - "reread_arcs": 0, + "reread_arcs": 1, "detect_edits": 0, "resolve_survivors": 0, - "shape": 209, + "shape": 169, "bind": 0, "where_places": 0, - "materialise": 92, + "materialise": 91, "answer": 1, "options": 0 } }, + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -6671,7 +6688,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -6720,21 +6737,22 @@ "variable_text": "aid flows", "warnings": [], "timing_ms": { - "total": 1732, + "total": 1695, "by_step": { "validate": 0, "walk": 10, - "reread_arcs": 0, + "reread_arcs": 1, "detect_edits": 0, "resolve_survivors": 0, - "shape": 1699, + "shape": 1660, "bind": 0, "where_places": 0, - "materialise": 14, + "materialise": 15, "answer": 7, "options": 2 } }, + "entity_refs": [], "operations": [], "departures": [ { @@ -7132,7 +7150,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -7580,7 +7598,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -10076,7 +10094,7 @@ "answer": { "kind": "resolution", "status": "mixed", - "sentence": "Answered 1 of 2 parts. Mortality has 2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself. Gross disbursements to Kenya from official donors (DAC) for official development assistance, 2013 to 2022. Current US dollars · OECD DAC2a. You asked for aid flows. This shows gross disbursements, the closest measure the data holds. No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, search again with open_roles ['donor']. Assumed: official development assistance.", + "sentence": "Answered 1 of 2 parts. Mortality has 2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022. You named Kenya as a recipient. This measure has no recipients, so this shows the place itself. Gross disbursements to Kenya from official donors (DAC) for official development assistance, 2013 to 2022. Current US dollars · OECD DAC2a. You asked for aid flows. This shows gross disbursements, the closest measure the data holds. No donor was named, so this shows official donors (DAC), the source's total for every official donor. Private donors are outside it. To list each donor, add \"for each donor\" to the question. Assumed: official development assistance.", "complete": false, "specs": [ "spec_f24e46ae9854884308fc0f33d154361e" diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-echoes-separate-and-operations.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-echoes-separate-and-operations.json index b91bae3..0799c24 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-echoes-separate-and-operations.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-echoes-separate-and-operations.json @@ -35,7 +35,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4b32dbe3eadc46e5b1815c1408980fef" + "x-dfo-trace-id": "009afd1dc09e44299c2004e111d17991" }, "json": { "schema_version": 1, @@ -46,14 +46,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "4b32dbe3eadc46e5b1815c1408980fef", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "009afd1dc09e44299c2004e111d17991", "warnings": [], "timing_ms": { - "total": 2102, + "total": 2627, "by_step": { "coverage": 0, - "extract": 990, + "extract": 1263, "cache_lookup": 0 } }, @@ -61,8 +61,8 @@ "input_tokens": 2239, "output_tokens": 164, "cached_tokens": 842, - "jev_input_tokens": 16995, - "jev_output_tokens": 3458 + "jev_input_tokens": 17402, + "jev_output_tokens": 3500 }, "timed_out": false }, @@ -72,30 +72,30 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 1107, + "total": 1129, "by_step": { "recall": 2, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 3, - "shape_probe_coverage": 6, - "shape_probe": 103, + "shape_arcs": 4, + "shape_probe_coverage": 4, + "shape_probe": 151, "shape_groups": 45, "shape_labels": 10, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 439, + "shape": 407, "phase_prune_and_rank": 0, - "bind": 149, - "phase_bind": 7, - "phase_settle": 14, + "bind": 127, + "phase_bind": 10, + "phase_settle": 24, "phase_place_bindings": 8, "phase_facet_requests": 0, - "materialise": 135, + "materialise": 144, "phase_materialise": 0, - "answer": 33, - "options": 161, - "phase_outcome": 159 + "answer": 185, + "options": 98, + "phase_outcome": 124 } }, "restatement": { @@ -115,6 +115,45 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "G20", + "refs": [ + "groups/G20", + "country/ARG", + "country/AUS", + "country/BRA", + "country/CAN", + "country/CHN", + "country/DEU", + "country/FRA", + "country/GBR", + "country/IDN", + "country/IND", + "country/ITA", + "country/JPN", + "country/KOR", + "country/MEX", + "country/RUS", + "country/SAU", + "country/TUR", + "country/USA", + "country/ZAF" + ] + }, + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "India", + "refs": [ + "country/IND" + ] + } + ], "operations": [ { "verb": "growth", @@ -1926,7 +1965,7 @@ "start_year": 2015, "end_year": 2015 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -2845,7 +2884,7 @@ "start_year": 2015, "end_year": 2015 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -2949,24 +2988,24 @@ "variable_text": "ODA", "warnings": [], "timing_ms": { - "total": 828, + "total": 619, "by_step": { - "recall": 417, + "recall": 315, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 2, + "shape_arcs": 1, "shape_probe_coverage": 5, - "shape_probe": 213, - "shape_groups": 2, + "shape_probe": 107, + "shape_groups": 3, "shape_labels": 0, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 298, + "shape": 196, "phase_prune_and_rank": 0, - "bind": 104, - "phase_bind": 1, - "phase_settle": 7, - "phase_place_bindings": 1 + "bind": 97, + "phase_bind": 2, + "phase_settle": 9, + "phase_place_bindings": 0 } }, "rendered_sentence": "Could not tell who is giving and who is receiving among \"G20\", \"Germany\", and \"India\". Put \"from\" or \"to\" before a name.", @@ -2979,6 +3018,7 @@ "states": [] } ], + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -3535,7 +3575,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "d9e0eb5cd99248bc851045e80fcfef32" + "x-dfo-trace-id": "6a837108e9cb4b74b197a33c82a6e92f" }, "json": { "schema_version": 1, @@ -3544,11 +3584,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "d9e0eb5cd99248bc851045e80fcfef32", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "6a837108e9cb4b74b197a33c82a6e92f", "warnings": [], "timing_ms": { - "total": 960, + "total": 953, "by_step": { "coverage": 0 } @@ -3568,21 +3608,22 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 841, + "total": 847, "by_step": { "validate": 0, "walk": 1, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 599, + "shape": 638, "bind": 0, "where_places": 0, - "materialise": 132, - "answer": 3, - "options": 106 + "materialise": 110, + "answer": 4, + "options": 94 } }, + "entity_refs": [], "operations": [], "departures": [ { @@ -5094,7 +5135,7 @@ "start_year": 2015, "end_year": 2015 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -5169,30 +5210,30 @@ "variable_text": "ODA", "warnings": [], "timing_ms": { - "total": 390, + "total": 339, "by_step": { - "recall": 2, - "phase_resolve_places": 0, + "recall": 1, + "phase_resolve_places": 1, "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe_coverage": 5, - "shape_probe": 106, - "shape_groups": 2, + "shape_probe_coverage": 6, + "shape_probe": 95, + "shape_groups": 3, "shape_labels": 0, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 198, + "shape": 169, "phase_prune_and_rank": 0, - "bind": 88, + "bind": 84, "phase_bind": 9, "phase_settle": 8, "phase_place_bindings": 1, "phase_facet_requests": 0, - "materialise": 18, + "materialise": 17, "phase_materialise": 0, - "answer": 10, + "answer": 9, "options": 6, - "phase_outcome": 50 + "phase_outcome": 34 } }, "restatement": { @@ -5215,6 +5256,45 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "G20", + "refs": [ + "groups/G20", + "country/ARG", + "country/AUS", + "country/BRA", + "country/CAN", + "country/CHN", + "country/DEU", + "country/FRA", + "country/GBR", + "country/IDN", + "country/IND", + "country/ITA", + "country/JPN", + "country/KOR", + "country/MEX", + "country/RUS", + "country/SAU", + "country/TUR", + "country/USA", + "country/ZAF" + ] + }, + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "India", + "refs": [ + "country/IND" + ] + } + ], "operations": [], "departures": [ { @@ -5729,7 +5809,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -6267,7 +6347,7 @@ "start_year": 2015, "end_year": 2015 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-option-beside-definite.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-beside-definite.json index 78c3836..45ca40c 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-option-beside-definite.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-beside-definite.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:39:39Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:31:56Z" }, "call": [ { @@ -36,7 +36,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4b32dbe3eadc46e5b1815c1408980fef" + "x-dfo-trace-id": "009afd1dc09e44299c2004e111d17991" }, "json": { "schema_version": 1, @@ -47,14 +47,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "4b32dbe3eadc46e5b1815c1408980fef", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "009afd1dc09e44299c2004e111d17991", "warnings": [], "timing_ms": { - "total": 2102, + "total": 2627, "by_step": { "coverage": 0, - "extract": 990, + "extract": 1263, "cache_lookup": 0 } }, @@ -62,8 +62,8 @@ "input_tokens": 2239, "output_tokens": 164, "cached_tokens": 842, - "jev_input_tokens": 16995, - "jev_output_tokens": 3458 + "jev_input_tokens": 17402, + "jev_output_tokens": 3500 }, "timed_out": false }, @@ -73,30 +73,30 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 1107, + "total": 1129, "by_step": { "recall": 2, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 3, - "shape_probe_coverage": 6, - "shape_probe": 103, + "shape_arcs": 4, + "shape_probe_coverage": 4, + "shape_probe": 151, "shape_groups": 45, "shape_labels": 10, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 439, + "shape": 407, "phase_prune_and_rank": 0, - "bind": 149, - "phase_bind": 7, - "phase_settle": 14, + "bind": 127, + "phase_bind": 10, + "phase_settle": 24, "phase_place_bindings": 8, "phase_facet_requests": 0, - "materialise": 135, + "materialise": 144, "phase_materialise": 0, - "answer": 33, - "options": 161, - "phase_outcome": 159 + "answer": 185, + "options": 98, + "phase_outcome": 124 } }, "restatement": { @@ -116,6 +116,45 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "G20", + "refs": [ + "groups/G20", + "country/ARG", + "country/AUS", + "country/BRA", + "country/CAN", + "country/CHN", + "country/DEU", + "country/FRA", + "country/GBR", + "country/IDN", + "country/IND", + "country/ITA", + "country/JPN", + "country/KOR", + "country/MEX", + "country/RUS", + "country/SAU", + "country/TUR", + "country/USA", + "country/ZAF" + ] + }, + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "India", + "refs": [ + "country/IND" + ] + } + ], "operations": [], "departures": [ { @@ -1921,7 +1960,7 @@ "start_year": 2015, "end_year": 2015 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -2840,7 +2879,7 @@ "start_year": 2015, "end_year": 2015 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -2943,24 +2982,24 @@ "variable_text": "ODA", "warnings": [], "timing_ms": { - "total": 828, + "total": 619, "by_step": { - "recall": 417, + "recall": 315, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 2, + "shape_arcs": 1, "shape_probe_coverage": 5, - "shape_probe": 213, - "shape_groups": 2, + "shape_probe": 107, + "shape_groups": 3, "shape_labels": 0, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 298, + "shape": 196, "phase_prune_and_rank": 0, - "bind": 104, - "phase_bind": 1, - "phase_settle": 7, - "phase_place_bindings": 1 + "bind": 97, + "phase_bind": 2, + "phase_settle": 9, + "phase_place_bindings": 0 } }, "rendered_sentence": "Could not tell who is giving and who is receiving among \"G20\", \"Germany\", and \"India\". Put \"from\" or \"to\" before a name.", @@ -2973,6 +3012,7 @@ "states": [] } ], + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -3521,7 +3561,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "d9e0eb5cd99248bc851045e80fcfef32" + "x-dfo-trace-id": "6a837108e9cb4b74b197a33c82a6e92f" }, "json": { "schema_version": 1, @@ -3530,11 +3570,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "d9e0eb5cd99248bc851045e80fcfef32", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "6a837108e9cb4b74b197a33c82a6e92f", "warnings": [], "timing_ms": { - "total": 960, + "total": 953, "by_step": { "coverage": 0 } @@ -3554,21 +3594,22 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 841, + "total": 847, "by_step": { "validate": 0, "walk": 1, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 599, + "shape": 638, "bind": 0, "where_places": 0, - "materialise": 132, - "answer": 3, - "options": 106 + "materialise": 110, + "answer": 4, + "options": 94 } }, + "entity_refs": [], "operations": [], "departures": [ { @@ -5080,7 +5121,7 @@ "start_year": 2015, "end_year": 2015 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -5155,30 +5196,30 @@ "variable_text": "ODA", "warnings": [], "timing_ms": { - "total": 390, + "total": 339, "by_step": { - "recall": 2, - "phase_resolve_places": 0, + "recall": 1, + "phase_resolve_places": 1, "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe_coverage": 5, - "shape_probe": 106, - "shape_groups": 2, + "shape_probe_coverage": 6, + "shape_probe": 95, + "shape_groups": 3, "shape_labels": 0, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 198, + "shape": 169, "phase_prune_and_rank": 0, - "bind": 88, + "bind": 84, "phase_bind": 9, "phase_settle": 8, "phase_place_bindings": 1, "phase_facet_requests": 0, - "materialise": 18, + "materialise": 17, "phase_materialise": 0, - "answer": 10, + "answer": 9, "options": 6, - "phase_outcome": 50 + "phase_outcome": 34 } }, "restatement": { @@ -5201,6 +5242,45 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "G20", + "refs": [ + "groups/G20", + "country/ARG", + "country/AUS", + "country/BRA", + "country/CAN", + "country/CHN", + "country/DEU", + "country/FRA", + "country/GBR", + "country/IDN", + "country/IND", + "country/ITA", + "country/JPN", + "country/KOR", + "country/MEX", + "country/RUS", + "country/SAU", + "country/TUR", + "country/USA", + "country/ZAF" + ] + }, + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "India", + "refs": [ + "country/IND" + ] + } + ], "operations": [], "departures": [ { @@ -5715,7 +5795,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -6253,7 +6333,7 @@ "start_year": 2015, "end_year": 2015 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-option-two-part-query.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-two-part-query.json index 3df58c7..61d4757 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-option-two-part-query.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-two-part-query.json @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "febf95d73157448f9ad342fe31a897d4" + "x-dfo-trace-id": "6c90259bc5dc43649740c2e47cb555bc" }, "json": { "schema_version": 1, @@ -45,8 +45,8 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "febf95d73157448f9ad342fe31a897d4", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "6c90259bc5dc43649740c2e47cb555bc", "warnings": [], "timing_ms": { "total": 1, @@ -68,9 +68,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -117,6 +117,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -284,7 +294,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "febf95d73157448f9ad342fe31a897d4" + "trace_id": "6c90259bc5dc43649740c2e47cb555bc" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-option-without-data-query.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-without-data-query.json index 0862a4e..f2c90c7 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-option-without-data-query.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-option-without-data-query.json @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "febf95d73157448f9ad342fe31a897d4" + "x-dfo-trace-id": "6c90259bc5dc43649740c2e47cb555bc" }, "json": { "schema_version": 1, @@ -45,8 +45,8 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "febf95d73157448f9ad342fe31a897d4", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "6c90259bc5dc43649740c2e47cb555bc", "warnings": [], "timing_ms": { "total": 1, @@ -68,9 +68,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -117,6 +117,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -243,7 +253,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "febf95d73157448f9ad342fe31a897d4" + "trace_id": "6c90259bc5dc43649740c2e47cb555bc" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-part-by-mention.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-part-by-mention.json index b62c0fd..926c0bb 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-part-by-mention.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-part-by-mention.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:39:15Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:31:31Z" }, "call": [ { @@ -36,7 +36,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "7c9c9bea4a59447ba7b6412c645456e1" + "x-dfo-trace-id": "79f55e76540244d18a4543d497614a89" }, "json": { "schema_version": 1, @@ -47,8 +47,8 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "7c9c9bea4a59447ba7b6412c645456e1", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "79f55e76540244d18a4543d497614a89", "warnings": [], "timing_ms": { "total": 1, @@ -70,9 +70,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -119,6 +119,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -281,7 +291,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "3fe50c68d204497f8418531c936b8a81" + "x-dfo-trace-id": "0a622ff00fe449c19cedbae4fd61f52b" }, "json": { "schema_version": 1, @@ -290,14 +300,14 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "3fe50c68d204497f8418531c936b8a81", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "0a622ff00fe449c19cedbae4fd61f52b", "warnings": [], "timing_ms": { - "total": 2, + "total": 3, "by_step": { "coverage": 0, - "response_cache_layer2": 0 + "response_cache_layer2": 1 } }, "llm_usage": { @@ -319,30 +329,30 @@ } ], "timing_ms": { - "total": 1070, + "total": 907, "by_step": { - "recall": 1, + "recall": 0, "phase_resolve_places": 0, "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe_coverage": 7, - "shape_probe": 131, - "shape_groups": 44, + "shape_probe_coverage": 6, + "shape_probe": 109, + "shape_groups": 41, "shape_labels": 1, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 524, + "shape": 387, "phase_prune_and_rank": 0, - "bind": 104, - "phase_bind": 177, - "phase_settle": 8, - "phase_place_bindings": 73, + "bind": 111, + "phase_bind": 175, + "phase_settle": 9, + "phase_place_bindings": 67, "phase_facet_requests": 0, "materialise": 15, "phase_materialise": 0, - "answer": 7, - "options": 6, - "phase_outcome": 155 + "answer": 10, + "options": 13, + "phase_outcome": 120 } }, "restatement": { @@ -363,6 +373,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Congo", + "refs": [ + "country/COD" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -732,7 +756,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1186,7 +1210,7 @@ "start_year": 2018, "end_year": 2018 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-place-one-part.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-place-one-part.json index 534b76f..81ed866 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-place-one-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-place-one-part.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:39:14Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:31:30Z" }, "call": [ { @@ -35,7 +35,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "febf95d73157448f9ad342fe31a897d4" + "x-dfo-trace-id": "6c90259bc5dc43649740c2e47cb555bc" }, "json": { "schema_version": 1, @@ -46,8 +46,8 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "febf95d73157448f9ad342fe31a897d4", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "6c90259bc5dc43649740c2e47cb555bc", "warnings": [], "timing_ms": { "total": 1, @@ -69,9 +69,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -118,6 +118,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -280,7 +290,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "9254a776588b49739881b71f3257f9b7" + "x-dfo-trace-id": "67793b9246794fc18d48484eb317d58f" }, "json": { "schema_version": 1, @@ -289,11 +299,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "9254a776588b49739881b71f3257f9b7", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "67793b9246794fc18d48484eb317d58f", "warnings": [], "timing_ms": { - "total": 1072, + "total": 932, "by_step": { "coverage": 0 } @@ -319,30 +329,30 @@ } ], "timing_ms": { - "total": 1070, + "total": 907, "by_step": { - "recall": 1, + "recall": 0, "phase_resolve_places": 0, "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe_coverage": 7, - "shape_probe": 131, - "shape_groups": 44, + "shape_probe_coverage": 6, + "shape_probe": 109, + "shape_groups": 41, "shape_labels": 1, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 524, + "shape": 387, "phase_prune_and_rank": 0, - "bind": 104, - "phase_bind": 177, - "phase_settle": 8, - "phase_place_bindings": 73, + "bind": 111, + "phase_bind": 175, + "phase_settle": 9, + "phase_place_bindings": 67, "phase_facet_requests": 0, "materialise": 15, "phase_materialise": 0, - "answer": 7, - "options": 6, - "phase_outcome": 155 + "answer": 10, + "options": 13, + "phase_outcome": 120 } }, "restatement": { @@ -363,6 +373,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Congo", + "refs": [ + "country/COD" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -732,7 +756,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1186,7 +1210,7 @@ "start_year": 2018, "end_year": 2018 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-place-two-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-place-two-parts.json index ffb88fc..4ba7c6a 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-place-two-parts.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-place-two-parts.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:39:16Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:31:32Z" }, "call": [ { @@ -36,7 +36,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "54bfcfb9a52b47bab15cedbc04e2cb8e" + "x-dfo-trace-id": "a49188b7f477461e9942a92b389f8671" }, "json": { "schema_version": 1, @@ -47,8 +47,8 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "54bfcfb9a52b47bab15cedbc04e2cb8e", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "a49188b7f477461e9942a92b389f8671", "warnings": [], "timing_ms": { "total": 1, @@ -122,6 +122,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [] + }, + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -227,9 +241,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 2, + "total": 1, "by_step": { - "recall": 2, + "recall": 1, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -279,6 +293,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [] + }, + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -475,7 +503,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "c58a661a7d274384aa44d978ba85987e" + "x-dfo-trace-id": "e4482a207d27410a9a03cb6f915ae3df" }, "json": { "schema_version": 1, @@ -484,11 +512,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "c58a661a7d274384aa44d978ba85987e", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "e4482a207d27410a9a03cb6f915ae3df", "warnings": [], "timing_ms": { - "total": 1053, + "total": 984, "by_step": { "coverage": 0 } @@ -566,6 +594,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [] + }, + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -682,30 +724,30 @@ } ], "timing_ms": { - "total": 1049, + "total": 980, "by_step": { "recall": 1, "phase_resolve_places": 0, "phase_check_entities": 0, "shape_arcs": 1, "shape_probe_coverage": 6, - "shape_probe": 113, - "shape_groups": 53, + "shape_probe": 84, + "shape_groups": 40, "shape_labels": 1, "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 455, + "shape": 402, "phase_prune_and_rank": 0, - "bind": 139, - "phase_bind": 226, + "bind": 106, + "phase_bind": 230, "phase_settle": 9, - "phase_place_bindings": 68, + "phase_place_bindings": 83, "phase_facet_requests": 0, "materialise": 13, "phase_materialise": 0, - "answer": 8, - "options": 5, - "phase_outcome": 125 + "answer": 7, + "options": 6, + "phase_outcome": 123 } }, "restatement": { @@ -730,6 +772,26 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + }, + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Congo", + "refs": [ + "country/COD" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -1098,7 +1160,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1571,7 +1633,7 @@ "selected": [] } ], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-posts-unsupported-placeholder.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-posts-unsupported-placeholder.json index 81096f5..0c8ad89 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-posts-unsupported-placeholder.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-posts-unsupported-placeholder.json @@ -35,7 +35,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4b32dbe3eadc46e5b1815c1408980fef" + "x-dfo-trace-id": "009afd1dc09e44299c2004e111d17991" }, "json": { "schema_version": 1, @@ -46,14 +46,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "4b32dbe3eadc46e5b1815c1408980fef", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "009afd1dc09e44299c2004e111d17991", "warnings": [], "timing_ms": { - "total": 2102, + "total": 2627, "by_step": { "coverage": 0, - "extract": 990, + "extract": 1263, "cache_lookup": 0 } }, @@ -61,8 +61,8 @@ "input_tokens": 2239, "output_tokens": 164, "cached_tokens": 842, - "jev_input_tokens": 16995, - "jev_output_tokens": 3458 + "jev_input_tokens": 17402, + "jev_output_tokens": 3500 }, "timed_out": false }, @@ -72,32 +72,71 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 1107, + "total": 1129, "by_step": { "recall": 2, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 3, - "shape_probe_coverage": 6, - "shape_probe": 103, + "shape_arcs": 4, + "shape_probe_coverage": 4, + "shape_probe": 151, "shape_groups": 45, "shape_labels": 10, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 439, + "shape": 407, "phase_prune_and_rank": 0, - "bind": 149, - "phase_bind": 7, - "phase_settle": 14, + "bind": 127, + "phase_bind": 10, + "phase_settle": 24, "phase_place_bindings": 8, "phase_facet_requests": 0, - "materialise": 135, + "materialise": 144, "phase_materialise": 0, - "answer": 33, - "options": 161, - "phase_outcome": 159 + "answer": 185, + "options": 98, + "phase_outcome": 124 } }, + "entity_refs": [ + { + "text": "G20", + "refs": [ + "groups/G20", + "country/ARG", + "country/AUS", + "country/BRA", + "country/CAN", + "country/CHN", + "country/DEU", + "country/FRA", + "country/GBR", + "country/IDN", + "country/IND", + "country/ITA", + "country/JPN", + "country/KOR", + "country/MEX", + "country/RUS", + "country/SAU", + "country/TUR", + "country/USA", + "country/ZAF" + ] + }, + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "India", + "refs": [ + "country/IND" + ] + } + ], "operations": [], "departures": [ { @@ -118,24 +157,24 @@ "variable_text": "ODA", "warnings": [], "timing_ms": { - "total": 828, + "total": 619, "by_step": { - "recall": 417, + "recall": 315, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 2, + "shape_arcs": 1, "shape_probe_coverage": 5, - "shape_probe": 213, - "shape_groups": 2, + "shape_probe": 107, + "shape_groups": 3, "shape_labels": 0, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 298, + "shape": 196, "phase_prune_and_rank": 0, - "bind": 104, - "phase_bind": 1, - "phase_settle": 7, - "phase_place_bindings": 1 + "bind": 97, + "phase_bind": 2, + "phase_settle": 9, + "phase_place_bindings": 0 } }, "rendered_sentence": "Could not tell who is giving and who is receiving among \"G20\", \"Germany\", and \"India\". Put \"from\" or \"to\" before a name.", @@ -148,6 +187,7 @@ "states": [] } ], + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -620,7 +660,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "d9e0eb5cd99248bc851045e80fcfef32" + "x-dfo-trace-id": "6a837108e9cb4b74b197a33c82a6e92f" }, "json": { "schema_version": 1, @@ -629,11 +669,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "d9e0eb5cd99248bc851045e80fcfef32", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "6a837108e9cb4b74b197a33c82a6e92f", "warnings": [], "timing_ms": { - "total": 960, + "total": 953, "by_step": { "coverage": 0 } @@ -653,21 +693,22 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 841, + "total": 847, "by_step": { "validate": 0, "walk": 1, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 599, + "shape": 638, "bind": 0, "where_places": 0, - "materialise": 132, - "answer": 3, - "options": 106 + "materialise": 110, + "answer": 4, + "options": 94 } }, + "entity_refs": [], "operations": [], "departures": [ { @@ -2179,7 +2220,7 @@ "start_year": 2015, "end_year": 2015 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -2254,30 +2295,30 @@ "variable_text": "ODA", "warnings": [], "timing_ms": { - "total": 390, + "total": 339, "by_step": { - "recall": 2, - "phase_resolve_places": 0, + "recall": 1, + "phase_resolve_places": 1, "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe_coverage": 5, - "shape_probe": 106, - "shape_groups": 2, + "shape_probe_coverage": 6, + "shape_probe": 95, + "shape_groups": 3, "shape_labels": 0, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 198, + "shape": 169, "phase_prune_and_rank": 0, - "bind": 88, + "bind": 84, "phase_bind": 9, "phase_settle": 8, "phase_place_bindings": 1, "phase_facet_requests": 0, - "materialise": 18, + "materialise": 17, "phase_materialise": 0, - "answer": 10, + "answer": 9, "options": 6, - "phase_outcome": 50 + "phase_outcome": 34 } }, "restatement": { @@ -2300,6 +2341,45 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "G20", + "refs": [ + "groups/G20", + "country/ARG", + "country/AUS", + "country/BRA", + "country/CAN", + "country/CHN", + "country/DEU", + "country/FRA", + "country/GBR", + "country/IDN", + "country/IND", + "country/ITA", + "country/JPN", + "country/KOR", + "country/MEX", + "country/RUS", + "country/SAU", + "country/TUR", + "country/USA", + "country/ZAF" + ] + }, + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "India", + "refs": [ + "country/IND" + ] + } + ], "operations": [], "departures": [ { @@ -2814,7 +2894,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -3352,7 +3432,7 @@ "start_year": 2015, "end_year": 2015 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json index d8ca5fd..17760cf 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-answered-part.json @@ -35,7 +35,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4d9323abf43e4fccadfbd64caf2b371c" + "x-dfo-trace-id": "1e95940d311043d0b63bd27a87996439" }, "json": { "schema_version": 1, @@ -46,14 +46,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "4d9323abf43e4fccadfbd64caf2b371c", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "1e95940d311043d0b63bd27a87996439", "warnings": [], "timing_ms": { - "total": 1772, + "total": 2200, "by_step": { "coverage": 0, - "extract": 876, + "extract": 1432, "cache_lookup": 0 } }, @@ -72,30 +72,30 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 892, + "total": 757, "by_step": { - "recall": 414, + "recall": 316, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 3, - "shape_probe_coverage": 6, - "shape_probe": 93, + "shape_arcs": 2, + "shape_probe_coverage": 8, + "shape_probe": 72, "shape_groups": 5, "shape_labels": 10, "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 205, + "shape": 179, "phase_prune_and_rank": 0, - "bind": 101, + "bind": 89, "phase_bind": 10, - "phase_settle": 12, - "phase_place_bindings": 11, + "phase_settle": 13, + "phase_place_bindings": 12, "phase_facet_requests": 0, "materialise": 9, "phase_materialise": 0, - "answer": 2, - "options": 81, - "phase_outcome": 47 + "answer": 1, + "options": 79, + "phase_outcome": 49 } }, "restatement": { @@ -108,6 +108,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [ @@ -562,7 +570,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1280,7 +1288,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3265,18 +3273,18 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 466, + "total": 330, "by_step": { - "recall": 339, + "recall": 216, "phase_resolve_places": 1, "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe": 122, - "shape_groups": 1, + "shape_probe": 108, + "shape_groups": 2, "shape_labels": 0, "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 126, + "shape": 113, "phase_prune_and_rank": 0 } }, @@ -3290,6 +3298,7 @@ "states": [] } ], + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json index 21918dc..e8343b6 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-mention-names-two-parts.json @@ -35,7 +35,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "88156a0c48754c7fb0d5c5a544daed09" + "x-dfo-trace-id": "4b576ea3cd364ddeb664b3b219dffb19" }, "json": { "schema_version": 1, @@ -46,14 +46,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "88156a0c48754c7fb0d5c5a544daed09", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "4b576ea3cd364ddeb664b3b219dffb19", "warnings": [], "timing_ms": { - "total": 1686, + "total": 1260, "by_step": { "coverage": 0, - "extract": 1680, + "extract": 1255, "cache_lookup": 0 } }, @@ -122,6 +122,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [] + }, + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -227,9 +241,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 2, + "total": 1, "by_step": { - "recall": 2, + "recall": 1, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -279,6 +293,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [] + }, + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json index e3d62bb..f77a9d9 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-choice.json @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "8ff5daac36fe403ab946f5b02785cb0d" + "x-dfo-trace-id": "bf6613bf82be4bddb4d60879aaf907d9" }, "json": { "schema_version": 1, @@ -45,21 +45,23 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "8ff5daac36fe403ab946f5b02785cb0d", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "bf6613bf82be4bddb4d60879aaf907d9", "warnings": [], "timing_ms": { - "total": 4716, + "total": 2620, "by_step": { "coverage": 0, - "extract": 1242, + "extract": 1068, "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 6216, - "output_tokens": 423, - "cached_tokens": 841 + "input_tokens": 2231, + "output_tokens": 102, + "cached_tokens": 841, + "jev_input_tokens": 6586, + "jev_output_tokens": 2060 }, "timed_out": false }, @@ -69,30 +71,30 @@ "variable_text": "ODA disbursements for basic health care", "warnings": [], "timing_ms": { - "total": 3468, + "total": 1548, "by_step": { - "recall": 547, + "recall": 437, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 1, - "shape_probe_coverage": 6, - "shape_probe": 136, - "shape_groups": 43, + "shape_arcs": 2, + "shape_probe_coverage": 4, + "shape_probe": 161, + "shape_groups": 45, "shape_labels": 1, - "shape_admission": 0, + "shape_admission": 3, "phase_derive_shapes": 0, - "shape": 1190, + "shape": 326, "phase_prune_and_rank": 0, - "bind": 1278, - "phase_bind": 149, - "phase_settle": 50, - "phase_place_bindings": 19, + "bind": 225, + "phase_bind": 158, + "phase_settle": 56, + "phase_place_bindings": 18, "phase_facet_requests": 0, - "materialise": 30, + "materialise": 41, "phase_materialise": 0, - "answer": 110, - "options": 38, - "phase_outcome": 57 + "answer": 186, + "options": 40, + "phase_outcome": 61 } }, "restatement": { @@ -110,6 +112,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Nigeria", + "refs": [ + "country/NGA" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -525,7 +541,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1178,7 +1194,7 @@ "selected": [] } ], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json index 0d16e6e..1ec2f9f 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-no-options.json @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f" + "x-dfo-trace-id": "304fe92b998b45849ff11a547aadc3e8" }, "json": { "schema_version": 1, @@ -45,15 +45,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "a321fb82bfba461b9dc922634789650f", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "304fe92b998b45849ff11a547aadc3e8", "warnings": [], "timing_ms": { - "total": 1126, + "total": 1416, "by_step": { "coverage": 0, - "extract": 1119, - "cache_lookup": 1 + "extract": 1297, + "cache_lookup": 0 } }, "llm_usage": { @@ -69,9 +69,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -118,6 +118,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json index a0d1250..ac800b2 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-option-out-of-range.json @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "2fefffc9aac84b4fae2eb1888a1d3b74" + "x-dfo-trace-id": "21bb19c92c824a70b2eb378e85a9cfd0" }, "json": { "schema_version": 1, @@ -45,15 +45,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "2fefffc9aac84b4fae2eb1888a1d3b74", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "21bb19c92c824a70b2eb378e85a9cfd0", "warnings": [], "timing_ms": { - "total": 2300, + "total": 8287, "by_step": { "coverage": 0, - "extract": 1022, - "cache_lookup": 0 + "extract": 1330, + "cache_lookup": 2 } }, "llm_usage": { @@ -71,28 +71,28 @@ "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 1274, + "total": 6951, "by_step": { - "recall": 0, + "recall": 261, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 4, - "shape_probe": 112, - "shape_groups": 5, + "shape_arcs": 7, + "shape_probe": 122, + "shape_groups": 6, "shape_labels": 1, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 237, + "shape": 241, "phase_prune_and_rank": 0, - "bind": 214, - "phase_bind": 3, - "phase_settle": 7, - "phase_place_bindings": 27, + "bind": 142, + "phase_bind": 17, + "phase_settle": 6, + "phase_place_bindings": 490, "phase_facet_requests": 0, - "materialise": 124, + "materialise": 115, "phase_materialise": 1, - "answer": 25, - "phase_outcome": 636 + "answer": 243, + "phase_outcome": 5435 } }, "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", @@ -284,6 +284,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -806,7 +814,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2340,7 +2348,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-part-without-variable-text.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-part-without-variable-text.json index a006d18..07027a2 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-part-without-variable-text.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-part-without-variable-text.json @@ -35,7 +35,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4b32dbe3eadc46e5b1815c1408980fef" + "x-dfo-trace-id": "009afd1dc09e44299c2004e111d17991" }, "json": { "schema_version": 1, @@ -46,14 +46,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "4b32dbe3eadc46e5b1815c1408980fef", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "009afd1dc09e44299c2004e111d17991", "warnings": [], "timing_ms": { - "total": 2102, + "total": 2627, "by_step": { "coverage": 0, - "extract": 990, + "extract": 1263, "cache_lookup": 0 } }, @@ -61,8 +61,8 @@ "input_tokens": 2239, "output_tokens": 164, "cached_tokens": 842, - "jev_input_tokens": 16995, - "jev_output_tokens": 3458 + "jev_input_tokens": 17402, + "jev_output_tokens": 3500 }, "timed_out": false }, @@ -71,30 +71,30 @@ { "warnings": [], "timing_ms": { - "total": 1107, + "total": 1129, "by_step": { "recall": 2, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 3, - "shape_probe_coverage": 6, - "shape_probe": 103, + "shape_arcs": 4, + "shape_probe_coverage": 4, + "shape_probe": 151, "shape_groups": 45, "shape_labels": 10, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 439, + "shape": 407, "phase_prune_and_rank": 0, - "bind": 149, - "phase_bind": 7, - "phase_settle": 14, + "bind": 127, + "phase_bind": 10, + "phase_settle": 24, "phase_place_bindings": 8, "phase_facet_requests": 0, - "materialise": 135, + "materialise": 144, "phase_materialise": 0, - "answer": 33, - "options": 161, - "phase_outcome": 159 + "answer": 185, + "options": 98, + "phase_outcome": 124 } }, "restatement": { @@ -114,6 +114,45 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "G20", + "refs": [ + "groups/G20", + "country/ARG", + "country/AUS", + "country/BRA", + "country/CAN", + "country/CHN", + "country/DEU", + "country/FRA", + "country/GBR", + "country/IDN", + "country/IND", + "country/ITA", + "country/JPN", + "country/KOR", + "country/MEX", + "country/RUS", + "country/SAU", + "country/TUR", + "country/USA", + "country/ZAF" + ] + }, + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "India", + "refs": [ + "country/IND" + ] + } + ], "operations": [], "departures": [ { @@ -1919,7 +1958,7 @@ "start_year": 2015, "end_year": 2015 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -2838,7 +2877,7 @@ "start_year": 2015, "end_year": 2015 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -2941,24 +2980,24 @@ "variable_text": "ODA", "warnings": [], "timing_ms": { - "total": 828, + "total": 619, "by_step": { - "recall": 417, + "recall": 315, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 2, + "shape_arcs": 1, "shape_probe_coverage": 5, - "shape_probe": 213, - "shape_groups": 2, + "shape_probe": 107, + "shape_groups": 3, "shape_labels": 0, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 298, + "shape": 196, "phase_prune_and_rank": 0, - "bind": 104, - "phase_bind": 1, - "phase_settle": 7, - "phase_place_bindings": 1 + "bind": 97, + "phase_bind": 2, + "phase_settle": 9, + "phase_place_bindings": 0 } }, "rendered_sentence": "Could not tell who is giving and who is receiving among \"G20\", \"Germany\", and \"India\". Put \"from\" or \"to\" before a name.", @@ -2971,6 +3010,7 @@ "states": [] } ], + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-candidate-label.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-candidate-label.json index b87dfa5..91e3f40 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-candidate-label.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-candidate-label.json @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "2fefffc9aac84b4fae2eb1888a1d3b74" + "x-dfo-trace-id": "21bb19c92c824a70b2eb378e85a9cfd0" }, "json": { "schema_version": 1, @@ -45,15 +45,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "2fefffc9aac84b4fae2eb1888a1d3b74", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "21bb19c92c824a70b2eb378e85a9cfd0", "warnings": [], "timing_ms": { - "total": 2300, + "total": 8287, "by_step": { "coverage": 0, - "extract": 1022, - "cache_lookup": 0 + "extract": 1330, + "cache_lookup": 2 } }, "llm_usage": { @@ -71,28 +71,28 @@ "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 1274, + "total": 6951, "by_step": { - "recall": 0, + "recall": 261, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 4, - "shape_probe": 112, - "shape_groups": 5, + "shape_arcs": 7, + "shape_probe": 122, + "shape_groups": 6, "shape_labels": 1, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 237, + "shape": 241, "phase_prune_and_rank": 0, - "bind": 214, - "phase_bind": 3, - "phase_settle": 7, - "phase_place_bindings": 27, + "bind": 142, + "phase_bind": 17, + "phase_settle": 6, + "phase_place_bindings": 490, "phase_facet_requests": 0, - "materialise": 124, + "materialise": 115, "phase_materialise": 1, - "answer": 25, - "phase_outcome": 636 + "answer": 243, + "phase_outcome": 5435 } }, "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", @@ -284,6 +284,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -806,7 +814,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2285,7 +2293,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-label.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-label.json index 166cb0e..fad67ba 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-label.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-shared-label.json @@ -45,8 +45,8 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "febf95d73157448f9ad342fe31a897d4", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "6c90259bc5dc43649740c2e47cb555bc", "warnings": [], "timing_ms": { "total": 1, @@ -68,9 +68,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -117,6 +117,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json index f4df983..ae28288 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-two-choices.json @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "88156a0c48754c7fb0d5c5a544daed09" + "x-dfo-trace-id": "4b576ea3cd364ddeb664b3b219dffb19" }, "json": { "schema_version": 1, @@ -45,14 +45,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "88156a0c48754c7fb0d5c5a544daed09", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "4b576ea3cd364ddeb664b3b219dffb19", "warnings": [], "timing_ms": { - "total": 1686, + "total": 1260, "by_step": { "coverage": 0, - "extract": 1680, + "extract": 1255, "cache_lookup": 0 } }, @@ -121,6 +121,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [] + }, + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -226,9 +240,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 2, + "total": 1, "by_step": { - "recall": 2, + "recall": 1, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -278,6 +292,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [] + }, + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-candidate-label.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-candidate-label.json index 5076e2c..8a9eadc 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-candidate-label.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-candidate-label.json @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "2fefffc9aac84b4fae2eb1888a1d3b74" + "x-dfo-trace-id": "21bb19c92c824a70b2eb378e85a9cfd0" }, "json": { "schema_version": 1, @@ -45,15 +45,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "2fefffc9aac84b4fae2eb1888a1d3b74", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "21bb19c92c824a70b2eb378e85a9cfd0", "warnings": [], "timing_ms": { - "total": 2300, + "total": 8287, "by_step": { "coverage": 0, - "extract": 1022, - "cache_lookup": 0 + "extract": 1330, + "cache_lookup": 2 } }, "llm_usage": { @@ -71,28 +71,28 @@ "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 1274, + "total": 6951, "by_step": { - "recall": 0, + "recall": 261, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 4, - "shape_probe": 112, - "shape_groups": 5, + "shape_arcs": 7, + "shape_probe": 122, + "shape_groups": 6, "shape_labels": 1, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 237, + "shape": 241, "phase_prune_and_rank": 0, - "bind": 214, - "phase_bind": 3, - "phase_settle": 7, - "phase_place_bindings": 27, + "bind": 142, + "phase_bind": 17, + "phase_settle": 6, + "phase_place_bindings": 490, "phase_facet_requests": 0, - "materialise": 124, + "materialise": 115, "phase_materialise": 1, - "answer": 25, - "phase_outcome": 636 + "answer": 243, + "phase_outcome": 5435 } }, "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", @@ -284,6 +284,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -806,7 +814,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2340,7 +2348,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json index 5d348bd..e99807c 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-label.json @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f" + "x-dfo-trace-id": "304fe92b998b45849ff11a547aadc3e8" }, "json": { "schema_version": 1, @@ -45,15 +45,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "a321fb82bfba461b9dc922634789650f", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "304fe92b998b45849ff11a547aadc3e8", "warnings": [], "timing_ms": { - "total": 1126, + "total": 1416, "by_step": { "coverage": 0, - "extract": 1119, - "cache_lookup": 1 + "extract": 1297, + "cache_lookup": 0 } }, "llm_usage": { @@ -69,9 +69,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -118,6 +118,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json index c6262fd..8442bcc 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-part.json @@ -35,7 +35,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4d9323abf43e4fccadfbd64caf2b371c" + "x-dfo-trace-id": "1e95940d311043d0b63bd27a87996439" }, "json": { "schema_version": 1, @@ -46,14 +46,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "4d9323abf43e4fccadfbd64caf2b371c", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "1e95940d311043d0b63bd27a87996439", "warnings": [], "timing_ms": { - "total": 1772, + "total": 2200, "by_step": { "coverage": 0, - "extract": 876, + "extract": 1432, "cache_lookup": 0 } }, @@ -72,30 +72,30 @@ "variable_text": "debt service", "warnings": [], "timing_ms": { - "total": 892, + "total": 757, "by_step": { - "recall": 414, + "recall": 316, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 3, - "shape_probe_coverage": 6, - "shape_probe": 93, + "shape_arcs": 2, + "shape_probe_coverage": 8, + "shape_probe": 72, "shape_groups": 5, "shape_labels": 10, "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 205, + "shape": 179, "phase_prune_and_rank": 0, - "bind": 101, + "bind": 89, "phase_bind": 10, - "phase_settle": 12, - "phase_place_bindings": 11, + "phase_settle": 13, + "phase_place_bindings": 12, "phase_facet_requests": 0, "materialise": 9, "phase_materialise": 0, - "answer": 2, - "options": 81, - "phase_outcome": 47 + "answer": 1, + "options": 79, + "phase_outcome": 49 } }, "restatement": { @@ -108,6 +108,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [ @@ -562,7 +570,7 @@ "label": "Creative Commons Attribution License" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1280,7 +1288,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3265,18 +3273,18 @@ "variable_text": "price of tea", "warnings": [], "timing_ms": { - "total": 466, + "total": 330, "by_step": { - "recall": 339, + "recall": 216, "phase_resolve_places": 1, "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe": 122, - "shape_groups": 1, + "shape_probe": 108, + "shape_groups": 2, "shape_labels": 0, "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 126, + "shape": 113, "phase_prune_and_rank": 0 } }, @@ -3290,6 +3298,7 @@ "states": [] } ], + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-status.json b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-status.json index 187b0e2..f6404bf 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-status.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/choose-refused-unknown-status.json @@ -35,7 +35,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4b32dbe3eadc46e5b1815c1408980fef" + "x-dfo-trace-id": "009afd1dc09e44299c2004e111d17991" }, "json": { "schema_version": 1, @@ -46,14 +46,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "4b32dbe3eadc46e5b1815c1408980fef", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "009afd1dc09e44299c2004e111d17991", "warnings": [], "timing_ms": { - "total": 2102, + "total": 2627, "by_step": { "coverage": 0, - "extract": 990, + "extract": 1263, "cache_lookup": 0 } }, @@ -61,8 +61,8 @@ "input_tokens": 2239, "output_tokens": 164, "cached_tokens": 842, - "jev_input_tokens": 16995, - "jev_output_tokens": 3458 + "jev_input_tokens": 17402, + "jev_output_tokens": 3500 }, "timed_out": false }, @@ -72,32 +72,71 @@ "variable_text": "GDP", "warnings": [], "timing_ms": { - "total": 1107, + "total": 1129, "by_step": { "recall": 2, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 3, - "shape_probe_coverage": 6, - "shape_probe": 103, + "shape_arcs": 4, + "shape_probe_coverage": 4, + "shape_probe": 151, "shape_groups": 45, "shape_labels": 10, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 439, + "shape": 407, "phase_prune_and_rank": 0, - "bind": 149, - "phase_bind": 7, - "phase_settle": 14, + "bind": 127, + "phase_bind": 10, + "phase_settle": 24, "phase_place_bindings": 8, "phase_facet_requests": 0, - "materialise": 135, + "materialise": 144, "phase_materialise": 0, - "answer": 33, - "options": 161, - "phase_outcome": 159 + "answer": 185, + "options": 98, + "phase_outcome": 124 } }, + "entity_refs": [ + { + "text": "G20", + "refs": [ + "groups/G20", + "country/ARG", + "country/AUS", + "country/BRA", + "country/CAN", + "country/CHN", + "country/DEU", + "country/FRA", + "country/GBR", + "country/IDN", + "country/IND", + "country/ITA", + "country/JPN", + "country/KOR", + "country/MEX", + "country/RUS", + "country/SAU", + "country/TUR", + "country/USA", + "country/ZAF" + ] + }, + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "India", + "refs": [ + "country/IND" + ] + } + ], "operations": [], "departures": [ { @@ -1903,7 +1942,7 @@ "start_year": 2015, "end_year": 2015 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -2822,7 +2861,7 @@ "start_year": 2015, "end_year": 2015 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -2925,24 +2964,24 @@ "variable_text": "ODA", "warnings": [], "timing_ms": { - "total": 828, + "total": 619, "by_step": { - "recall": 417, + "recall": 315, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 2, + "shape_arcs": 1, "shape_probe_coverage": 5, - "shape_probe": 213, - "shape_groups": 2, + "shape_probe": 107, + "shape_groups": 3, "shape_labels": 0, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 298, + "shape": 196, "phase_prune_and_rank": 0, - "bind": 104, - "phase_bind": 1, - "phase_settle": 7, - "phase_place_bindings": 1 + "bind": 97, + "phase_bind": 2, + "phase_settle": 9, + "phase_place_bindings": 0 } }, "rendered_sentence": "Could not tell who is giving and who is receiving among \"G20\", \"Germany\", and \"India\". Put \"from\" or \"to\" before a name.", @@ -2955,6 +2994,7 @@ "states": [] } ], + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json index 6c4ac7f..a526083 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-frame-several-readings.json @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "6d68317966c44c48a0701ff661a5e655" + "x-dfo-trace-id": "74e9acc99aff40f7a653093976c55e3b" }, "json": { "schema_version": 1, @@ -45,14 +45,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "6d68317966c44c48a0701ff661a5e655", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "74e9acc99aff40f7a653093976c55e3b", "warnings": [], "timing_ms": { - "total": 4868, + "total": 4632, "by_step": { "coverage": 0, - "extract": 1143, + "extract": 1209, "cache_lookup": 0 } }, @@ -60,8 +60,8 @@ "input_tokens": 2237, "output_tokens": 215, "cached_tokens": 842, - "jev_input_tokens": 25205, - "jev_output_tokens": 5698 + "jev_input_tokens": 25612, + "jev_output_tokens": 5740 }, "timed_out": false }, @@ -71,30 +71,30 @@ "variable_text": "health ODA disbursements", "warnings": [], "timing_ms": { - "total": 3437, + "total": 3118, "by_step": { - "recall": 538, + "recall": 753, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 85, + "shape_arcs": 75, "shape_probe_coverage": 3, - "shape_probe": 426, - "shape_groups": 43, + "shape_probe": 164, + "shape_groups": 44, "shape_labels": 9, - "shape_admission": 1, + "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 1403, + "shape": 695, "phase_prune_and_rank": 0, - "bind": 228, - "phase_bind": 458, - "phase_settle": 103, - "phase_place_bindings": 23, + "bind": 275, + "phase_bind": 190, + "phase_settle": 91, + "phase_place_bindings": 19, "phase_facet_requests": 0, - "materialise": 385, - "phase_materialise": 1, - "answer": 18, - "options": 174, - "phase_outcome": 106 + "materialise": 616, + "phase_materialise": 0, + "answer": 20, + "options": 307, + "phase_outcome": 152 } }, "restatement": { @@ -112,6 +112,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -579,12 +593,6 @@ ] }, "facets": { - "unit": { - "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" - }, "provenance": { "basis": "fallback", "ref": "provenance/OECDCreditorReportingSystem", @@ -599,6 +607,12 @@ }, "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" } }, "slot_options": [ @@ -1424,7 +1438,7 @@ "selected": [] } ], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3752,30 +3766,30 @@ } ], "timing_ms": { - "total": 3091, + "total": 3017, "by_step": { - "recall": 450, - "phase_resolve_places": 0, + "recall": 704, + "phase_resolve_places": 1, "phase_check_entities": 0, - "shape_arcs": 93, + "shape_arcs": 82, "shape_probe_coverage": 2, - "shape_probe": 98, - "shape_groups": 44, - "shape_labels": 9, + "shape_probe": 99, + "shape_groups": 47, + "shape_labels": 10, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 374, + "shape": 365, "phase_prune_and_rank": 0, - "bind": 223, - "phase_bind": 160, - "phase_settle": 51, - "phase_place_bindings": 27, + "bind": 402, + "phase_bind": 196, + "phase_settle": 88, + "phase_place_bindings": 44, "phase_facet_requests": 0, - "materialise": 1197, + "materialise": 512, "phase_materialise": 0, - "answer": 20, - "options": 455, - "phase_outcome": 134 + "answer": 58, + "options": 511, + "phase_outcome": 136 } }, "restatement": { @@ -3793,6 +3807,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -4260,12 +4288,6 @@ ] }, "facets": { - "unit": { - "basis": "fallback", - "ref": "CurrencyUSD", - "label": "US Dollar", - "currency": "USD" - }, "provenance": { "basis": "fallback", "ref": "provenance/OECDCreditorReportingSystem", @@ -4280,6 +4302,12 @@ }, "documentation": "/api/graph/documentation/provenance/OECDCreditorReportingSystem", "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" } }, "slot_options": [ @@ -5105,7 +5133,7 @@ "selected": [] } ], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -7438,30 +7466,30 @@ } ], "timing_ms": { - "total": 707, + "total": 1849, "by_step": { - "recall": 3, + "recall": 391, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 3, - "shape_probe_coverage": 6, - "shape_probe": 146, - "shape_groups": 48, - "shape_labels": 9, + "shape_arcs": 4, + "shape_probe_coverage": 2, + "shape_probe": 126, + "shape_groups": 55, + "shape_labels": 10, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 316, + "shape": 311, "phase_prune_and_rank": 0, - "bind": 143, - "phase_bind": 4, - "phase_settle": 16, - "phase_place_bindings": 7, + "bind": 139, + "phase_bind": 15, + "phase_settle": 27, + "phase_place_bindings": 426, "phase_facet_requests": 0, - "materialise": 98, - "phase_materialise": 1, - "answer": 6, - "options": 108, - "phase_outcome": 5 + "materialise": 93, + "phase_materialise": 0, + "answer": 244, + "options": 193, + "phase_outcome": 10 } }, "restatement": { @@ -7479,6 +7507,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [ { @@ -8884,7 +8926,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [ @@ -9417,7 +9459,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [ diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json index dd1f3e0..e1916ab 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-null-member.json @@ -33,7 +33,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "8ff5daac36fe403ab946f5b02785cb0d" + "x-dfo-trace-id": "bf6613bf82be4bddb4d60879aaf907d9" }, "json": { "schema_version": 1, @@ -44,21 +44,23 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "8ff5daac36fe403ab946f5b02785cb0d", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "bf6613bf82be4bddb4d60879aaf907d9", "warnings": [], "timing_ms": { - "total": 4716, + "total": 2620, "by_step": { "coverage": 0, - "extract": 1242, + "extract": 1068, "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 6216, - "output_tokens": 423, - "cached_tokens": 841 + "input_tokens": 2231, + "output_tokens": 102, + "cached_tokens": 841, + "jev_input_tokens": 6586, + "jev_output_tokens": 2060 }, "timed_out": false }, @@ -68,30 +70,30 @@ "variable_text": "ODA disbursements for basic health care", "warnings": [], "timing_ms": { - "total": 3468, + "total": 1548, "by_step": { - "recall": 547, + "recall": 437, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 1, - "shape_probe_coverage": 6, - "shape_probe": 136, - "shape_groups": 43, + "shape_arcs": 2, + "shape_probe_coverage": 4, + "shape_probe": 161, + "shape_groups": 45, "shape_labels": 1, - "shape_admission": 0, + "shape_admission": 3, "phase_derive_shapes": 0, - "shape": 1190, + "shape": 326, "phase_prune_and_rank": 0, - "bind": 1278, - "phase_bind": 149, - "phase_settle": 50, - "phase_place_bindings": 19, + "bind": 225, + "phase_bind": 158, + "phase_settle": 56, + "phase_place_bindings": 18, "phase_facet_requests": 0, - "materialise": 30, + "materialise": 41, "phase_materialise": 0, - "answer": 110, - "options": 38, - "phase_outcome": 57 + "answer": 186, + "options": 40, + "phase_outcome": 61 } }, "restatement": { @@ -109,6 +111,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Nigeria", + "refs": [ + "country/NGA" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -524,7 +540,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1177,7 +1193,7 @@ "selected": [] } ], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3775,7 +3791,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "c1f0030e84b5418d89553827b503d006" + "x-dfo-trace-id": "42460c90e7274dd19ecba24a6a0377e9" }, "json": { "schema_version": 1, @@ -4176,7 +4192,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261011T194155Z-80081f08", "served_from": "head", - "confirmed_at": "2026-10-23T18:36:51.837863+00:00" + "confirmed_at": "2026-10-24T16:30:05.017544+00:00" }, "warnings": [ { @@ -4205,7 +4221,7 @@ "created_at": "2026-10-23T16:56:32.058938+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", @@ -4505,7 +4521,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": true } @@ -4522,7 +4538,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db?X-Goog-Signature=redacted", - "x-dfo-trace-id": "b2396d674b5848e7b1828fca235d84a1" + "x-dfo-trace-id": "b9b4b3a90d6546e09cc738a29bbbb1d6" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json index 9888ea9..86968a3 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-partial-nothing-answered.json @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f" + "x-dfo-trace-id": "304fe92b998b45849ff11a547aadc3e8" }, "json": { "schema_version": 1, @@ -45,15 +45,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "a321fb82bfba461b9dc922634789650f", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "304fe92b998b45849ff11a547aadc3e8", "warnings": [], "timing_ms": { - "total": 1126, + "total": 1416, "by_step": { "coverage": 0, - "extract": 1119, - "cache_lookup": 1 + "extract": 1297, + "cache_lookup": 0 } }, "llm_usage": { @@ -69,9 +69,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -118,6 +118,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -267,7 +277,7 @@ "error": { "class": "IncompleteAnswerError", "code": "answer_incomplete", - "trace_id": "a321fb82bfba461b9dc922634789650f" + "trace_id": "304fe92b998b45849ff11a547aadc3e8" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-artifact-unlisted.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-artifact-unlisted.json index 95bbba3..44e3548 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-artifact-unlisted.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-artifact-unlisted.json @@ -111,7 +111,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "f8dc4c6d0e4d4ce9882d862d2ed5b3ef" + "x-dfo-trace-id": "6a9a38fa39014e7282da94b82d6ba3ee" }, "json": { "schema_version": 1, @@ -943,7 +943,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db?X-Goog-Signature=redacted", - "x-dfo-trace-id": "6bdc7a9de08e4bceb3e1e8eab34d4ad1" + "x-dfo-trace-id": "7e3ff4f01985498db43aebbf83d13839" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-file-selector.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-file-selector.json index 3898c8f..dff0cc7 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-file-selector.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-file-selector.json @@ -111,7 +111,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "f8dc4c6d0e4d4ce9882d862d2ed5b3ef" + "x-dfo-trace-id": "6a9a38fa39014e7282da94b82d6ba3ee" }, "json": { "schema_version": 1, @@ -539,7 +539,7 @@ "created_at": "2026-10-23T16:56:32.058938+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:f4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104", @@ -979,7 +979,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db?X-Goog-Signature=redacted", - "x-dfo-trace-id": "6bdc7a9de08e4bceb3e1e8eab34d4ad1" + "x-dfo-trace-id": "7e3ff4f01985498db43aebbf83d13839" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json index 556ecbb..35c65cb 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-newer-version.json @@ -211,7 +211,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "c1f0030e84b5418d89553827b503d006" + "x-dfo-trace-id": "42460c90e7274dd19ecba24a6a0377e9" }, "json": { "schema_version": 1, @@ -612,7 +612,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261011T194155Z-80081f08", "served_from": "head", - "confirmed_at": "2026-10-23T18:36:51.837863+00:00" + "confirmed_at": "2026-10-24T16:30:05.017544+00:00" }, "warnings": [ { @@ -641,7 +641,7 @@ "created_at": "2026-10-23T16:56:32.058938+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", @@ -940,7 +940,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": true } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json index a90a960..517e8c4 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-not-reproducible.json @@ -231,12 +231,12 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "bff64c2e088f43959abac4151c6a78e4" + "x-dfo-trace-id": "6f93d15300c8413191296f90fbc4b8b0" }, "json": { "schema_version": 1, "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0", + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8", "versions": [ { "content_version": "cv_25fa336da15247db708dd220b2d933a2", @@ -248,28 +248,28 @@ ], "op": "sum" }, - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", "base_content_version": null, "rendering": "plain", "groupby": null, - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "content_version": "cv_9417c96e4e09dd36053fc395c5b0f92c", "base_content_version": null, "rendering": "plain", "groupby": null, - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "content_version": "cv_e7f6ed9ddc5ca69902f92a8866f93ef7", "base_content_version": null, "rendering": "plain", "groupby": null, - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" } ], "next_cursor": null, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-other-spec.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-other-spec.json index 898c35a..d8e8c73 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-other-spec.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-other-spec.json @@ -211,7 +211,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "c1f0030e84b5418d89553827b503d006" + "x-dfo-trace-id": "42460c90e7274dd19ecba24a6a0377e9" }, "json": { "schema_version": 1, @@ -612,7 +612,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261011T194155Z-80081f08", "served_from": "head", - "confirmed_at": "2026-10-23T18:36:51.837863+00:00" + "confirmed_at": "2026-10-24T16:30:05.017544+00:00" }, "warnings": [ { @@ -641,7 +641,7 @@ "created_at": "2026-10-23T16:56:32.058938+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", @@ -940,7 +940,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": true } @@ -953,7 +953,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "c1f0030e84b5418d89553827b503d006" + "trace_id": "42460c90e7274dd19ecba24a6a0377e9" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-same-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-same-version.json index f56d10d..87efd88 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-same-version.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-expired-rebuild-same-version.json @@ -211,7 +211,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "c1f0030e84b5418d89553827b503d006" + "x-dfo-trace-id": "42460c90e7274dd19ecba24a6a0377e9" }, "json": { "schema_version": 1, @@ -612,7 +612,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261011T194155Z-80081f08", "served_from": "head", - "confirmed_at": "2026-10-23T18:36:51.837863+00:00" + "confirmed_at": "2026-10-24T16:30:05.017544+00:00" }, "warnings": [ { @@ -641,7 +641,7 @@ "created_at": "2026-10-23T16:56:32.058938+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", @@ -940,7 +940,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": true } @@ -957,7 +957,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db?X-Goog-Signature=redacted", - "x-dfo-trace-id": "b2396d674b5848e7b1828fca235d84a1" + "x-dfo-trace-id": "b9b4b3a90d6546e09cc738a29bbbb1d6" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-newest-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-newest-version.json index c15112c..8916674 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-newest-version.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-newest-version.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:39:42Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:32:01Z" }, "call": [ { @@ -94,12 +94,12 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "bff64c2e088f43959abac4151c6a78e4" + "x-dfo-trace-id": "6f93d15300c8413191296f90fbc4b8b0" }, "json": { "schema_version": 1, "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0", + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8", "versions": [ { "content_version": "cv_25fa336da15247db708dd220b2d933a2", @@ -111,28 +111,28 @@ ], "op": "sum" }, - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", "base_content_version": null, "rendering": "plain", "groupby": null, - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "content_version": "cv_9417c96e4e09dd36053fc395c5b0f92c", "base_content_version": null, "rendering": "plain", "groupby": null, - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "content_version": "cv_e7f6ed9ddc5ca69902f92a8866f93ef7", "base_content_version": null, "rendering": "plain", "groupby": null, - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" } ], "next_cursor": null, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused-twice.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused-twice.json index bcf05da..85a980e 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused-twice.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused-twice.json @@ -111,7 +111,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "f8dc4c6d0e4d4ce9882d862d2ed5b3ef" + "x-dfo-trace-id": "6a9a38fa39014e7282da94b82d6ba3ee" }, "json": { "schema_version": 1, @@ -539,7 +539,7 @@ "created_at": "2026-10-23T16:56:32.058938+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:f4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104", @@ -957,7 +957,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db?X-Goog-Signature=redacted", - "x-dfo-trace-id": "6bdc7a9de08e4bceb3e1e8eab34d4ad1" + "x-dfo-trace-id": "7e3ff4f01985498db43aebbf83d13839" } } }, @@ -983,7 +983,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db?X-Goog-Signature=redacted", - "x-dfo-trace-id": "6bdc7a9de08e4bceb3e1e8eab34d4ad1" + "x-dfo-trace-id": "7e3ff4f01985498db43aebbf83d13839" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused.json index e1e5248..23646db 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-signed-url-refused.json @@ -111,7 +111,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "f8dc4c6d0e4d4ce9882d862d2ed5b3ef" + "x-dfo-trace-id": "6a9a38fa39014e7282da94b82d6ba3ee" }, "json": { "schema_version": 1, @@ -539,7 +539,7 @@ "created_at": "2026-10-23T16:56:32.058938+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:f4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104", @@ -957,7 +957,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db?X-Goog-Signature=redacted", - "x-dfo-trace-id": "6bdc7a9de08e4bceb3e1e8eab34d4ad1" + "x-dfo-trace-id": "7e3ff4f01985498db43aebbf83d13839" } } }, @@ -983,7 +983,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db?X-Goog-Signature=redacted", - "x-dfo-trace-id": "6bdc7a9de08e4bceb3e1e8eab34d4ad1" + "x-dfo-trace-id": "7e3ff4f01985498db43aebbf83d13839" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-unknown-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-unknown-version.json index 33d49d7..50d58fe 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-unknown-version.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref-unknown-version.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:37:31Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:30:53Z" }, "call": [ { @@ -112,7 +112,7 @@ "status": 404, "headers": { "content-type": "application/problem+json", - "x-dfo-trace-id": "02a3a5e50f21446ea06f9f064086059b" + "x-dfo-trace-id": "5228b20a07a147e9861e20170e7363f1" }, "json": { "type": "/codes/snapshot_not_found", @@ -120,7 +120,7 @@ "status": 404, "detail": "'spec_774d6c001a6250aa67ca676ab067895e' has no version at content_version 'cv_00000000000000000000000000000000'", "code": "snapshot_not_found", - "trace_id": "02a3a5e50f21446ea06f9f064086059b", + "trace_id": "5228b20a07a147e9861e20170e7363f1", "capability_version": "dset_cc753cefa9199881", "retryable": false } @@ -132,7 +132,7 @@ "error": { "class": "NotFoundError", "code": "snapshot_not_found", - "trace_id": "02a3a5e50f21446ea06f9f064086059b" + "trace_id": "5228b20a07a147e9861e20170e7363f1" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref.json index 58009b1..856d5c5 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-ref.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:37:29Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:30:51Z" }, "call": [ { @@ -112,7 +112,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "f8dc4c6d0e4d4ce9882d862d2ed5b3ef" + "x-dfo-trace-id": "6a9a38fa39014e7282da94b82d6ba3ee" }, "json": { "schema_version": 1, @@ -540,7 +540,7 @@ "created_at": "2026-10-23T16:56:32.058938+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:f4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104", @@ -958,7 +958,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db?X-Goog-Signature=redacted", - "x-dfo-trace-id": "6bdc7a9de08e4bceb3e1e8eab34d4ad1" + "x-dfo-trace-id": "7e3ff4f01985498db43aebbf83d13839" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json index b838bb6..5e6acb1 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-renamed-strict-field.json @@ -33,7 +33,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "8ff5daac36fe403ab946f5b02785cb0d" + "x-dfo-trace-id": "bf6613bf82be4bddb4d60879aaf907d9" }, "json": { "schema_version": 1, @@ -44,21 +44,23 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "8ff5daac36fe403ab946f5b02785cb0d", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "bf6613bf82be4bddb4d60879aaf907d9", "warnings": [], "timing_ms": { - "total": 4716, + "total": 2620, "by_step": { "coverage": 0, - "extract": 1242, + "extract": 1068, "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 6216, - "output_tokens": 423, - "cached_tokens": 841 + "input_tokens": 2231, + "output_tokens": 102, + "cached_tokens": 841, + "jev_input_tokens": 6586, + "jev_output_tokens": 2060 }, "timed_out": false }, @@ -68,30 +70,30 @@ "variable_text": "ODA disbursements for basic health care", "warnings": [], "timing_ms": { - "total": 3468, + "total": 1548, "by_step": { - "recall": 547, + "recall": 437, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 1, - "shape_probe_coverage": 6, - "shape_probe": 136, - "shape_groups": 43, + "shape_arcs": 2, + "shape_probe_coverage": 4, + "shape_probe": 161, + "shape_groups": 45, "shape_labels": 1, - "shape_admission": 0, + "shape_admission": 3, "phase_derive_shapes": 0, - "shape": 1190, + "shape": 326, "phase_prune_and_rank": 0, - "bind": 1278, - "phase_bind": 149, - "phase_settle": 50, - "phase_place_bindings": 19, + "bind": 225, + "phase_bind": 158, + "phase_settle": 56, + "phase_place_bindings": 18, "phase_facet_requests": 0, - "materialise": 30, + "materialise": 41, "phase_materialise": 0, - "answer": 110, - "options": 38, - "phase_outcome": 57 + "answer": 186, + "options": 40, + "phase_outcome": 61 } }, "restatement": { @@ -109,6 +111,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Nigeria", + "refs": [ + "country/NGA" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -524,7 +540,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1177,7 +1193,7 @@ "selected": [] } ], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3775,7 +3791,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "c1f0030e84b5418d89553827b503d006" + "x-dfo-trace-id": "42460c90e7274dd19ecba24a6a0377e9" }, "json": { "schema_version": 1, @@ -4175,7 +4191,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261011T194155Z-80081f08", "served_from": "head", - "confirmed_at": "2026-10-23T18:36:51.837863+00:00" + "confirmed_at": "2026-10-24T16:30:05.017544+00:00" }, "warnings": [ { @@ -4204,7 +4220,7 @@ "created_at": "2026-10-23T16:56:32.058938+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", @@ -4503,7 +4519,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": true }, @@ -4529,7 +4545,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "c1f0030e84b5418d89553827b503d006" + "trace_id": "42460c90e7274dd19ecba24a6a0377e9" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json index 53d3564..6e10641 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-retry-after-504.json @@ -33,7 +33,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "8ff5daac36fe403ab946f5b02785cb0d" + "x-dfo-trace-id": "bf6613bf82be4bddb4d60879aaf907d9" }, "json": { "schema_version": 1, @@ -44,21 +44,23 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "8ff5daac36fe403ab946f5b02785cb0d", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "bf6613bf82be4bddb4d60879aaf907d9", "warnings": [], "timing_ms": { - "total": 4716, + "total": 2620, "by_step": { "coverage": 0, - "extract": 1242, + "extract": 1068, "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 6216, - "output_tokens": 423, - "cached_tokens": 841 + "input_tokens": 2231, + "output_tokens": 102, + "cached_tokens": 841, + "jev_input_tokens": 6586, + "jev_output_tokens": 2060 }, "timed_out": false }, @@ -68,30 +70,30 @@ "variable_text": "ODA disbursements for basic health care", "warnings": [], "timing_ms": { - "total": 3468, + "total": 1548, "by_step": { - "recall": 547, + "recall": 437, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 1, - "shape_probe_coverage": 6, - "shape_probe": 136, - "shape_groups": 43, + "shape_arcs": 2, + "shape_probe_coverage": 4, + "shape_probe": 161, + "shape_groups": 45, "shape_labels": 1, - "shape_admission": 0, + "shape_admission": 3, "phase_derive_shapes": 0, - "shape": 1190, + "shape": 326, "phase_prune_and_rank": 0, - "bind": 1278, - "phase_bind": 149, - "phase_settle": 50, - "phase_place_bindings": 19, + "bind": 225, + "phase_bind": 158, + "phase_settle": 56, + "phase_place_bindings": 18, "phase_facet_requests": 0, - "materialise": 30, + "materialise": 41, "phase_materialise": 0, - "answer": 110, - "options": 38, - "phase_outcome": 57 + "answer": 186, + "options": 40, + "phase_outcome": 61 } }, "restatement": { @@ -109,6 +111,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Nigeria", + "refs": [ + "country/NGA" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -524,7 +540,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1177,7 +1193,7 @@ "selected": [] } ], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3875,7 +3891,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "c1f0030e84b5418d89553827b503d006" + "x-dfo-trace-id": "42460c90e7274dd19ecba24a6a0377e9" }, "json": { "schema_version": 1, @@ -4276,7 +4292,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261011T194155Z-80081f08", "served_from": "head", - "confirmed_at": "2026-10-23T18:36:51.837863+00:00" + "confirmed_at": "2026-10-24T16:30:05.017544+00:00" }, "warnings": [ { @@ -4305,7 +4321,7 @@ "created_at": "2026-10-23T16:56:32.058938+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", @@ -4604,7 +4620,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": true } @@ -4621,7 +4637,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db?X-Goog-Signature=redacted", - "x-dfo-trace-id": "b2396d674b5848e7b1828fca235d84a1" + "x-dfo-trace-id": "b9b4b3a90d6546e09cc738a29bbbb1d6" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-503-then-504.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-503-then-504.json index ed95d0e..b3db0e5 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-503-then-504.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-503-then-504.json @@ -379,7 +379,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "x-dfo-trace-id": "bfc5cc090c4347f489fffcc62fc3d2bf" }, "json": { "schema_version": 1, @@ -786,7 +786,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:10.942106+00:00" + "confirmed_at": "2026-10-24T16:30:31.570035+00:00" }, "warnings": [ { @@ -815,7 +815,7 @@ "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -1099,7 +1099,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T13:59:18.051742Z" @@ -1117,7 +1117,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", - "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" + "x-dfo-trace-id": "8261c9be5a7c406a80692fac6b28ee05" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-retry-after.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-retry-after.json index 00ce7f5..05c7be4 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-retry-after.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-504-retry-after.json @@ -278,7 +278,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "x-dfo-trace-id": "bfc5cc090c4347f489fffcc62fc3d2bf" }, "json": { "schema_version": 1, @@ -685,7 +685,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:10.942106+00:00" + "confirmed_at": "2026-10-24T16:30:31.570035+00:00" }, "warnings": [ { @@ -714,7 +714,7 @@ "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -998,7 +998,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T13:59:18.051742Z" @@ -1016,7 +1016,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", - "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" + "x-dfo-trace-id": "8261c9be5a7c406a80692fac6b28ee05" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-accepted-running.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-accepted-running.json new file mode 100644 index 0000000..8f0d10e --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-accepted-running.json @@ -0,0 +1,1474 @@ +{ + "format_version": 1, + "name": "fetch-spec-accepted-running", + "description": "A 202 reads pending or running: the client polls either as an operation still under way, with the same pacing, and downloads the done manifest's file.", + "origin": { + "kind": "synthetic", + "derived_from": "mint-async-build", + "edit": "As fetch-spec-async-build, with the 202 reading running where it read pending." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "definition": { + "schema_version": 1, + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 1963, + "end_year": 2024 + } + } + }, + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a.", + "entity_groups": { + "destination": { + "label": "G77 countries", + "group_id": "groups/G77" + }, + "origin": { + "label": "DAC countries", + "group_id": "groups/OECD.DAC" + } + } + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "definition": { + "schema_version": 1, + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 1963, + "end_year": 2024 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 202, + "headers": { + "content-type": "application/json", + "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry-after": "2", + "x-dfo-trace-id": "a6d5bb2eff5a48578dce7fbf91715755" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "running", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 1500 + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2", + "x-dfo-trace-id": "71ecc596c6034e27b8ba5dd0a5d2c744" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "running", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2", + "x-dfo-trace-id": "760a3bb2de5e430fb316b3f6a4059c67" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "running", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2", + "x-dfo-trace-id": "15f9386c84484af983d33c6d183e5349" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "running", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "2cc73cd4fbaa4a28a350025111f70a79" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "done" + }, + "manifest": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "ref": "DAC2aAidType206", + "state": "value" + }, + "property": "dac2aAidType" + }, + { + "binding": { + "state": "unbound" + }, + "property": "dacTypeOfFinance" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ], + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2024, + "start_year": 1963 + } + } + }, + "content_version": "cv_3d58d26a874dc30b1bba7d5ad6dd90ee", + "prepared_at": "2026-10-23T18:38:28Z", + "coverage": { + "rows": 109318, + "dimensions": [ + { + "label": "financingProvider", + "count": 32, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 133, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 62 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 1963 + } + }, + "citation": { + "text": "OECD DAC2A (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=dac2a&pg=0&snb=1&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_DAC2%40DF_DAC2A&df[ag]=OECD.DCD.FSD&df[vs]=1.6&dq=.DPGC.206.USD.Q&lom=LASTNPERIODS&lo=5&to[TIME_PERIOD]=false&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "DAC2A is the OECD Development Assistance Committee's table of ODA disbursements by donor and recipient country or region. It covers bilateral donors and multilateral agencies reporting their own outflows, and includes the OECD's estimate of each donor's core multilateral contributions attributed to recipients.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip", + "attribution": "OECD (2026), OECD DAC2A, OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip (accessed on 2026-10-12)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1960-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The OECD publishes DAC2A in April, June, September and December. The complete table is downloaded from the OECD each time it is republished, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets. The totals DAC2A reports for groups of providers, such as all DAC countries, and for groups of recipients, such as regions and income groups, are included as providers and recipients of their own. Where two provider codes name the same organisation and report the same figures, the figures are counted once. Where two recipient codes name the same organisation, such as IDA and IDA's Multilateral Debt Relief Initiative, their flows are added." + }, + { + "transformation": "Select figures", + "description": "Only figures in current US dollars are included, not constant US dollars. Only flows to recipients on Part I of the DAC List are included: the developing countries, and the multilateral organisations DAC2A reports as recipients, such as development banks and UN agencies. Flows to Part II recipients, the countries in transition, are excluded." + }, + { + "transformation": "Convert to whole units", + "description": "DAC2A reports amounts in millions, which are converted to whole units. ODA per person and ODA as a share of GNI are kept as reported." + }, + { + "transformation": "Select dimensions", + "description": "Each figure is reported by year, provider, recipient and type of aid, such as grants, repayments, interest received, or debt forgiven or rescheduled. DAC2A is a table of disbursements, so every figure, repayments and interest included, is recorded as a disbursement. Figures are marked as gross or net, except where DAC2A does not say which, and as grants or non-grants where the type of aid is wholly one or the other. Imputed multilateral ODA, the OECD's estimate of each provider's share of multilateral organisations' ODA, is marked as modelled. ODA as a share of GNI records the recipient's GNI as its denominator, and ODA per person records the recipient's population." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "ODA disbursements by donor and recipient country or region, including the OECD's imputed multilateral contributions, and ODA per person and as a share of recipient GNI." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDDAC2A", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + }, + { + "ref": null, + "axis": "measurementMethod", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 1963 + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00264-2s9", + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-23T18:14:12Z", + "content_hash": "29eb81d7b6c88641b1d4e8eb5e850ca36de66b99d6e9e09680aac020507a6392", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDDAC2A", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_cc753cefa9199881", + "materialiser_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 109318 + } + ], + "family_member_count": 1, + "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", + "served_from": "materialise", + "confirmed_at": "2026-10-24T16:30:59.952146+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 4 + }, + "bytes": 473679, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-23T18:38:31.580044+00:00", + "tier": "working", + "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" + }, + { + "artifact_digest": "sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39", + "rendering": { + "statistics": "series" + }, + "bytes": 144274, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-23T18:38:31.580044+00:00", + "tier": "working", + "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39" + } + ], + "series_count": 3656, + "output_options": { + "capability_version": "dset_cc753cefa9199881", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 32 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 133 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 62 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 133, + "covered": 132 + }, + "missing": [ + { + "ref": "country/SSD", + "label": "South Sudan" + } + ], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_kind", + "financingRecipient_label", + "financingRecipient_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "financingProvider", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 62 + } + ] + }, + { + "index": "financingProvider", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 133 + } + ] + }, + { + "index": "financingRecipient", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 62 + } + ] + }, + { + "index": "financingRecipient", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 32 + } + ] + }, + { + "index": "time_period", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 133 + } + ] + }, + { + "index": "time_period", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 32 + } + ] + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "retention": { + "pinned": false, + "held_until": "2026-11-22T18:38:31.579178Z" + } + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65" + }, + "response": { + "status": 302, + "headers": { + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted", + "x-dfo-trace-id": "fb09161c837d4874970eaf5a188845da" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "mint-async-build.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 109318, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_kind", + "dac2aAidType", + "dac2aAidType_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "content_version": "cv_3d58d26a874dc30b1bba7d5ad6dd90ee", + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a." + } + ], + "missing": [], + "long_builds": [ + { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "poll_waits": [ + 1.5, + 1.5, + 1.5, + 1.5 + ], + "resubmissions": 0 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-async-build.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-async-build.json index b1e43b7..ecdf113 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-async-build.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-async-build.json @@ -487,7 +487,7 @@ "content-type": "application/json", "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry-after": "2", - "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" + "x-dfo-trace-id": "a6d5bb2eff5a48578dce7fbf91715755" }, "json": { "operation": { @@ -509,12 +509,12 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "043386d87ba247048aa921704d3ff030" + "x-dfo-trace-id": "71ecc596c6034e27b8ba5dd0a5d2c744" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { @@ -535,12 +535,12 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "c7ef77e57a864be6a4617b1aeae7c11d" + "x-dfo-trace-id": "760a3bb2de5e430fb316b3f6a4059c67" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { @@ -561,12 +561,12 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "cea2df9c98f94601a5e9976e76842f12" + "x-dfo-trace-id": "15f9386c84484af983d33c6d183e5349" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { @@ -586,267 +586,7 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2", - "x-dfo-trace-id": "7a800f2714b94a8482dc5fb553c669f5" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 1804, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "f911f5f7ca244733b2da3d5ce6913f6d" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 2292, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "07d32bbe980e419eb9f8461492ff4c62" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 2903, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "4", - "x-dfo-trace-id": "dd33ade549434abf82b662ab5251b0c1" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 3686, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "5", - "x-dfo-trace-id": "51d3664ad3e84fed8da1d94ce250d5de" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 4645, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "6", - "x-dfo-trace-id": "6a3b79b90c29464ca15c35d8eafecb96" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 5865, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "d7de7e24059f4d75ae14bd1778b984de" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 7391, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "cd1a9f894cbe4b6a9c1a7ee78315aff0" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 8000, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "e1c46fecd652459380163afea4dc35b7" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "running", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 8000, - "progress": { - "rows_written": 105253, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "3b9df177b0a94b069b47c8b441c6f232" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "running", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 8000, - "progress": { - "rows_written": 109318, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "x-dfo-trace-id": "cd6f7d2857a44f9c947573b696793564" + "x-dfo-trace-id": "2cc73cd4fbaa4a28a350025111f70a79" }, "json": { "operation": { @@ -1257,7 +997,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "materialise", - "confirmed_at": "2026-10-23T18:38:31.738121+00:00" + "confirmed_at": "2026-10-24T16:30:59.952146+00:00" }, "warnings": [], "diagnostics": [ @@ -1280,7 +1020,7 @@ "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39", @@ -1662,7 +1402,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted", - "x-dfo-trace-id": "b0cef6f918794d048a8a5056022de7cc" + "x-dfo-trace-id": "fb09161c837d4874970eaf5a188845da" } } }, @@ -1723,17 +1463,7 @@ 1.5, 1.5, 1.5, - 1.5, - 1.804, - 2.292, - 2.903, - 3.686, - 4.645, - 5.865, - 7.391, - 8.0, - 8.0, - 8.0 + 1.5 ], "resubmissions": 0 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json index c69fc38..ab4e913 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-digest-mismatch.json @@ -175,7 +175,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "x-dfo-trace-id": "bfc5cc090c4347f489fffcc62fc3d2bf" }, "json": { "schema_version": 1, @@ -582,7 +582,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:10.942106+00:00" + "confirmed_at": "2026-10-24T16:30:31.570035+00:00" }, "warnings": [ { @@ -611,7 +611,7 @@ "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -895,7 +895,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T13:59:18.051742Z" @@ -913,7 +913,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", - "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" + "x-dfo-trace-id": "8261c9be5a7c406a80692fac6b28ee05" } } }, @@ -940,7 +940,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", - "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" + "x-dfo-trace-id": "8261c9be5a7c406a80692fac6b28ee05" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-empty-narrowing.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-empty-narrowing.json index 23e0622..38256c0 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-empty-narrowing.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-empty-narrowing.json @@ -177,7 +177,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "x-dfo-trace-id": "bfc5cc090c4347f489fffcc62fc3d2bf" }, "json": { "schema_version": 1, @@ -584,7 +584,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:10.942106+00:00" + "confirmed_at": "2026-10-24T16:30:31.570035+00:00" }, "warnings": [ { @@ -613,7 +613,7 @@ "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -897,7 +897,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T13:59:18.051742Z" @@ -915,7 +915,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", - "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" + "x-dfo-trace-id": "8261c9be5a7c406a80692fac6b28ee05" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json index bea5f54..6d1c279 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-dropped.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:37:14Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:30:35Z" }, "call": [ { @@ -182,7 +182,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "5de76faaaff84624ac1026e8e9beb150" + "x-dfo-trace-id": "1855a065f7494cd6ba7eecd9fd790858" }, "json": { "schema_version": 1, @@ -584,7 +584,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261020T170016Z-691bf0da", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:15.216372+00:00" + "confirmed_at": "2026-10-24T16:30:35.784659+00:00" }, "warnings": [], "diagnostics": [ @@ -607,7 +607,7 @@ "created_at": "2026-10-23T16:58:55.692876+00:00", "tier": "working", "url": "/api/datasets/spec_4c228c73be6c18efd0939eabb3b3c456/cv_1868d697e8e7d56da6a83740a940c2e5/files/sha256:582f586bcb05d6807c91e6b5d88779c13c5c0962cd42e793184e8c6c8c90d2d9", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:ffd0e9eaabfc35d3113188c82648ce0bf809307a01a024b52b0baa133ef63d18", @@ -1024,7 +1024,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-20T06:50:59.874372Z" @@ -1113,7 +1113,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "fb2aa42a24b34e7eb4ceda53dd1ba402" + "x-dfo-trace-id": "37247e5873b241a7aee7ac321de35814" }, "json": { "schema_version": 1, @@ -1122,11 +1122,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "fb2aa42a24b34e7eb4ceda53dd1ba402", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "37247e5873b241a7aee7ac321de35814", "warnings": [], "timing_ms": { - "total": 400, + "total": 442, "by_step": { "coverage": 0 } @@ -1145,21 +1145,22 @@ } ], "timing_ms": { - "total": 258, + "total": 321, "by_step": { - "validate": 7, - "walk": 190, - "reread_arcs": 2, + "validate": 3, + "walk": 227, + "reread_arcs": 1, "detect_edits": 0, "resolve_survivors": 0, - "shape": 3, + "shape": 4, "bind": 0, "where_places": 0, - "materialise": 31, - "answer": 15, - "options": 10 + "materialise": 33, + "answer": 42, + "options": 11 } }, + "entity_refs": [], "operations": [], "departures": [], "assumptions": [ @@ -1571,7 +1572,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -2300,7 +2301,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -4932,7 +4933,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A582f586bcb05d6807c91e6b5d88779c13c5c0962cd42e793184e8c6c8c90d2d9?X-Goog-Signature=redacted", - "x-dfo-trace-id": "cee12ff09673464d98d98632db4244b1" + "x-dfo-trace-id": "c76ebbf49c774bb7acee93d8877f450d" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json index 4703609..9cf73b6 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-entity-rebound.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:37:12Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:30:33Z" }, "call": [ { @@ -187,7 +187,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "58ed6d83ebac443ab3da3ef0a085c7f5" + "x-dfo-trace-id": "102dc8c602004615becaa7905509e259" }, "json": { "schema_version": 1, @@ -592,7 +592,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261020T170016Z-691bf0da", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:13.103333+00:00" + "confirmed_at": "2026-10-24T16:30:33.522693+00:00" }, "warnings": [], "diagnostics": [ @@ -615,7 +615,7 @@ "created_at": "2026-10-23T16:58:51.358637+00:00", "tier": "working", "url": "/api/datasets/spec_1ee5f6648c9e46ddcc806fa0034bb6a8/cv_7947f7ed828c0b23b8df4c601d463c09/files/sha256:13a775f3b4811a104717ac226f173d614d685e533def09482b83c55e06505c4c", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:36616ef68df33904cc9dfa37fb145d8fd1563b1b3701710dcd8d9e04ed50d79a", @@ -914,7 +914,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-20T06:50:59.083841Z" @@ -1006,7 +1006,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "3ea2202f586b47b48906c83b42b9a4fe" + "x-dfo-trace-id": "c379d5c730dc4f85b1a5630c2a8b85f8" }, "json": { "schema_version": 1, @@ -1015,11 +1015,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "3ea2202f586b47b48906c83b42b9a4fe", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "c379d5c730dc4f85b1a5630c2a8b85f8", "warnings": [], "timing_ms": { - "total": 340, + "total": 461, "by_step": { "coverage": 0 } @@ -1032,21 +1032,22 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 288, + "total": 405, "by_step": { - "validate": 3, - "walk": 225, + "validate": 4, + "walk": 190, "reread_arcs": 2, "detect_edits": 0, "resolve_survivors": 0, - "shape": 3, + "shape": 4, "bind": 0, - "where_places": 0, - "materialise": 12, - "answer": 41, - "options": 2 + "where_places": 93, + "materialise": 14, + "answer": 95, + "options": 3 } }, + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -1457,7 +1458,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -2056,7 +2057,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -4663,7 +4664,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A13a775f3b4811a104717ac226f173d614d685e533def09482b83c55e06505c4c?X-Goog-Signature=redacted", - "x-dfo-trace-id": "037ba569f0d64fd7a230db5c74978c3f" + "x-dfo-trace-id": "9e24d0570f8f4988a32209d5670538c9" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-no-content.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-no-content.json index 504f1f0..4130d61 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-no-content.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-no-content.json @@ -175,7 +175,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "x-dfo-trace-id": "bfc5cc090c4347f489fffcc62fc3d2bf" }, "json": { "schema_version": 1, @@ -582,7 +582,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:10.942106+00:00" + "confirmed_at": "2026-10-24T16:30:31.570035+00:00" }, "warnings": [ { @@ -611,7 +611,7 @@ "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -895,7 +895,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T13:59:18.051742Z" @@ -911,7 +911,7 @@ "response": { "status": 204, "headers": { - "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" + "x-dfo-trace-id": "8261c9be5a7c406a80692fac6b28ee05" } } } @@ -921,7 +921,7 @@ "error": { "class": "ContractError", "code": "unexpected_response", - "trace_id": "07a61fadcaa94c9eafa158ddc41c07f3" + "trace_id": "8261c9be5a7c406a80692fac6b28ee05" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-serves-file.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-serves-file.json index 1f68551..818ed05 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-serves-file.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-serves-file.json @@ -175,7 +175,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "x-dfo-trace-id": "bfc5cc090c4347f489fffcc62fc3d2bf" }, "json": { "schema_version": 1, @@ -582,7 +582,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:10.942106+00:00" + "confirmed_at": "2026-10-24T16:30:31.570035+00:00" }, "warnings": [ { @@ -611,7 +611,7 @@ "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -895,7 +895,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T13:59:18.051742Z" @@ -912,7 +912,7 @@ "status": 200, "headers": { "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" + "x-dfo-trace-id": "8261c9be5a7c406a80692fac6b28ee05" }, "body_file": "fetch-spec-known-sentence.parquet" } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-temporary-redirect.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-temporary-redirect.json index 93fd488..c24d0d2 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-temporary-redirect.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-files-route-temporary-redirect.json @@ -175,7 +175,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "x-dfo-trace-id": "bfc5cc090c4347f489fffcc62fc3d2bf" }, "json": { "schema_version": 1, @@ -582,7 +582,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:10.942106+00:00" + "confirmed_at": "2026-10-24T16:30:31.570035+00:00" }, "warnings": [ { @@ -611,7 +611,7 @@ "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -895,7 +895,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T13:59:18.051742Z" @@ -912,7 +912,7 @@ "status": 307, "headers": { "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", - "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" + "x-dfo-trace-id": "8261c9be5a7c406a80692fac6b28ee05" } } } @@ -922,7 +922,7 @@ "error": { "class": "ContractError", "code": "unexpected_response", - "trace_id": "07a61fadcaa94c9eafa158ddc41c07f3" + "trace_id": "8261c9be5a7c406a80692fac6b28ee05" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-foreign-artifact-url.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-foreign-artifact-url.json index dded642..6e83998 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-foreign-artifact-url.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-foreign-artifact-url.json @@ -175,7 +175,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "x-dfo-trace-id": "bfc5cc090c4347f489fffcc62fc3d2bf" }, "json": { "schema_version": 1, @@ -582,7 +582,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:10.942106+00:00" + "confirmed_at": "2026-10-24T16:30:31.570035+00:00" }, "warnings": [ { @@ -611,7 +611,7 @@ "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", "url": "https://downloads.example.com/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -895,7 +895,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T13:59:18.051742Z" @@ -909,7 +909,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "trace_id": "bfc5cc090c4347f489fffcc62fc3d2bf" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.json index b1837ee..728a173 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-frame-layout.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:39:07Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:31:23Z" }, "call": [ { @@ -174,7 +174,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "f1a36f3b4730463a8de70a4aa9cc0f85" + "x-dfo-trace-id": "bb332867f3894a6291e202e0b4666901" }, "json": { "schema_version": 1, @@ -575,7 +575,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261011T194155Z-80081f08", "served_from": "head", - "confirmed_at": "2026-10-23T18:36:51.837863+00:00" + "confirmed_at": "2026-10-24T16:30:05.017544+00:00" }, "warnings": [ { @@ -902,7 +902,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": true } @@ -919,7 +919,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Af4026e80af4b8683d3bb86645ab3aca83dff75cd03fdd4c73ec54ba638922104?X-Goog-Signature=redacted", - "x-dfo-trace-id": "726df05bf2494e12a8a64e1291a60c57" + "x-dfo-trace-id": "1621b753678947a1ab313a52be193785" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.json index bea8c4c..9a5b59c 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-narrowed.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:37:17Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:30:37Z" }, "call": [ { @@ -249,7 +249,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "8f11970eb98c4d8e9a4e79dacba133b9" + "x-dfo-trace-id": "031e93c3d83b4ef9bbead5c617599dee" }, "json": { "schema_version": 1, @@ -535,7 +535,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:19.976783+00:00" + "confirmed_at": "2026-10-24T16:30:41.604527+00:00" }, "warnings": [ { @@ -564,7 +564,7 @@ "created_at": "2026-10-23T16:59:04.339940+00:00", "tier": "working", "url": "/api/datasets/spec_f04936b8378cde70bc6289ac1e45ee9b/cv_daec84e443d4e1b37291242d90fc8fa8/files/sha256:a5198249a7b16b895b1b7e8127605c644edaf2cda240201e391fc377aaf4dafd", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:78ad78b09dcc0d40e50f5804d66f3399fa6b851ae4b4ac48b27ce5a6f2124ef0", @@ -869,7 +869,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-20T07:08:48.808348Z" @@ -999,7 +999,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "4a5fe9dbf7364316b01946567ba1ab18" + "x-dfo-trace-id": "11177bfa56c249feaec154d376c0e318" }, "json": { "schema_version": 1, @@ -1008,11 +1008,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "4a5fe9dbf7364316b01946567ba1ab18", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "11177bfa56c249feaec154d376c0e318", "warnings": [], "timing_ms": { - "total": 2064, + "total": 1198, "by_step": { "coverage": 0 } @@ -1025,21 +1025,22 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 2000, + "total": 1118, "by_step": { - "validate": 1, + "validate": 0, "walk": 11, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 1949, - "bind": 1, - "where_places": 0, + "shape": 1069, + "bind": 0, + "where_places": 1, "materialise": 24, "answer": 11, - "options": 3 + "options": 2 } }, + "entity_refs": [], "operations": [], "departures": [ { @@ -2029,7 +2030,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -2871,7 +2872,7 @@ "start_year": 2020, "end_year": 2023 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -5311,7 +5312,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Aa5198249a7b16b895b1b7e8127605c644edaf2cda240201e391fc377aaf4dafd?X-Goog-Signature=redacted", - "x-dfo-trace-id": "e675f244eda341d28e917266242db362" + "x-dfo-trace-id": "f34686e7f0454a87b31b8f3a23ee43a4" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json index dd8a271..e961827 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-group-origin-rebound.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:37:23Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:30:44Z" }, "call": [ { @@ -296,7 +296,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "c13351d375404401a8266f1009cb72a5" + "x-dfo-trace-id": "be9bb0e6abf54384a9226f44f6f09902" }, "json": { "schema_version": 1, @@ -580,7 +580,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261021T070020Z-7262111e", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:23.648030+00:00" + "confirmed_at": "2026-10-24T16:30:44.568363+00:00" }, "warnings": [], "diagnostics": [ @@ -603,7 +603,7 @@ "created_at": "2026-10-23T16:59:11.517434+00:00", "tier": "working", "url": "/api/datasets/spec_c2f21170dfa9f31705e47ed60c8fa305/cv_66a0a4a0331d59b519aa1629dade3d99/files/sha256:a382b8f9e3ba634c150c6588e21f79413722d53f7bcdcb9dfd4e929aa4f80993", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:b1f80f2d3df16b6cda3831730ee4749b13e1eb3fff82cdf2f479e71f087bfe2b", @@ -908,7 +908,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-20T07:08:52.858156Z" @@ -1036,7 +1036,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "94e2938030144075b73ca71182f9377a" + "x-dfo-trace-id": "de81189cf3d441c69f9bc70f4786a3d4" }, "json": { "schema_version": 1, @@ -1045,11 +1045,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "94e2938030144075b73ca71182f9377a", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "de81189cf3d441c69f9bc70f4786a3d4", "warnings": [], "timing_ms": { - "total": 1785, + "total": 2566, "by_step": { "coverage": 0 } @@ -1062,21 +1062,22 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 1737, + "total": 2493, "by_step": { - "validate": 0, + "validate": 1, "walk": 10, - "reread_arcs": 0, + "reread_arcs": 1, "detect_edits": 0, "resolve_survivors": 0, - "shape": 1700, - "bind": 0, - "where_places": 1, - "materialise": 16, - "answer": 8, + "shape": 1756, + "bind": 1, + "where_places": 0, + "materialise": 20, + "answer": 702, "options": 2 } }, + "entity_refs": [], "operations": [], "departures": [ { @@ -2044,7 +2045,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -2882,7 +2883,7 @@ } ], "query_qualifiers": [], - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -5310,7 +5311,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Aa382b8f9e3ba634c150c6588e21f79413722d53f7bcdcb9dfd4e929aa4f80993?X-Goog-Signature=redacted", - "x-dfo-trace-id": "40d3efef54434905ad56dd99d8835067" + "x-dfo-trace-id": "d62572e0146a43f89d89c138493238e1" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json index 076139d..f58acdc 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-known-sentence.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:37:26Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:30:48Z" }, "call": [ { @@ -176,7 +176,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "x-dfo-trace-id": "bfc5cc090c4347f489fffcc62fc3d2bf" }, "json": { "schema_version": 1, @@ -583,7 +583,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:10.942106+00:00" + "confirmed_at": "2026-10-24T16:30:31.570035+00:00" }, "warnings": [ { @@ -612,7 +612,7 @@ "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -896,7 +896,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T13:59:18.051742Z" @@ -914,7 +914,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", - "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" + "x-dfo-trace-id": "8261c9be5a7c406a80692fac6b28ee05" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json index c0149d5..5f174b5 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-identity.json @@ -175,7 +175,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "x-dfo-trace-id": "bfc5cc090c4347f489fffcc62fc3d2bf" }, "json": { "schema_version": 1, @@ -517,7 +517,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:10.942106+00:00" + "confirmed_at": "2026-10-24T16:30:31.570035+00:00" }, "warnings": [ { @@ -546,7 +546,7 @@ "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -830,7 +830,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T13:59:18.051742Z" @@ -844,7 +844,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "trace_id": "bfc5cc090c4347f489fffcc62fc3d2bf" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-schema-version.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-schema-version.json index 55f8856..40803a3 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-schema-version.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-manifest-without-schema-version.json @@ -175,7 +175,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "x-dfo-trace-id": "bfc5cc090c4347f489fffcc62fc3d2bf" }, "json": { "schema_version": 1, @@ -581,7 +581,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:10.942106+00:00" + "confirmed_at": "2026-10-24T16:30:31.570035+00:00" }, "warnings": [ { @@ -610,7 +610,7 @@ "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -894,7 +894,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T13:59:18.051742Z" @@ -908,7 +908,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "trace_id": "bfc5cc090c4347f489fffcc62fc3d2bf" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.json index 5144675..3e6c833 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-narrowed.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:37:10Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:30:30Z" }, "call": [ { @@ -183,7 +183,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "52642a89ff44404fb61540fe78b1ca94" + "x-dfo-trace-id": "a1fe53d87b784d23bcc55926b9530dec" }, "json": { "schema_version": 1, @@ -590,7 +590,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:10.942106+00:00" + "confirmed_at": "2026-10-24T16:30:31.570035+00:00" }, "warnings": [ { @@ -619,7 +619,7 @@ "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -903,7 +903,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T13:59:18.051742Z" @@ -997,7 +997,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "0d356c6a142c45b5a4e8ea173623cc40" + "x-dfo-trace-id": "c4313642ac68484fb1d13d6f7b206d66" }, "json": { "schema_version": 1, @@ -1006,11 +1006,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "0d356c6a142c45b5a4e8ea173623cc40", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "c4313642ac68484fb1d13d6f7b206d66", "warnings": [], "timing_ms": { - "total": 341, + "total": 340, "by_step": { "coverage": 0 } @@ -1023,21 +1023,22 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 269, + "total": 256, "by_step": { "validate": 4, - "walk": 217, + "walk": 219, "reread_arcs": 1, "detect_edits": 0, "resolve_survivors": 0, - "shape": 4, - "bind": 0, + "shape": 3, + "bind": 1, "where_places": 0, - "materialise": 13, - "answer": 29, - "options": 1 + "materialise": 12, + "answer": 14, + "options": 2 } }, + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -1468,7 +1469,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -2031,7 +2032,7 @@ "start_year": 2020, "end_year": 2023 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -4639,7 +4640,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", - "x-dfo-trace-id": "577ae3aa962c474cadcd801c357ba73e" + "x-dfo-trace-id": "2f0c6beb58394dd390dc7e490b5e6c00" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-operation-failed-resubmitted.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-operation-failed-resubmitted.json index 84c9646..1fec5d0 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-operation-failed-resubmitted.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-operation-failed-resubmitted.json @@ -487,7 +487,7 @@ "content-type": "application/json", "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry-after": "2", - "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" + "x-dfo-trace-id": "a6d5bb2eff5a48578dce7fbf91715755" }, "json": { "operation": { @@ -509,7 +509,7 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "043386d87ba247048aa921704d3ff030" + "x-dfo-trace-id": "71ecc596c6034e27b8ba5dd0a5d2c744" }, "json": { "operation": { @@ -772,7 +772,7 @@ "content-type": "application/json", "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry-after": "2", - "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" + "x-dfo-trace-id": "a6d5bb2eff5a48578dce7fbf91715755" }, "json": { "operation": { @@ -794,12 +794,12 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "043386d87ba247048aa921704d3ff030" + "x-dfo-trace-id": "71ecc596c6034e27b8ba5dd0a5d2c744" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { @@ -820,12 +820,12 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "c7ef77e57a864be6a4617b1aeae7c11d" + "x-dfo-trace-id": "760a3bb2de5e430fb316b3f6a4059c67" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { @@ -846,12 +846,12 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "cea2df9c98f94601a5e9976e76842f12" + "x-dfo-trace-id": "15f9386c84484af983d33c6d183e5349" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { @@ -871,267 +871,7 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2", - "x-dfo-trace-id": "7a800f2714b94a8482dc5fb553c669f5" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 1804, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "f911f5f7ca244733b2da3d5ce6913f6d" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 2292, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "07d32bbe980e419eb9f8461492ff4c62" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 2903, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "4", - "x-dfo-trace-id": "dd33ade549434abf82b662ab5251b0c1" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 3686, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "5", - "x-dfo-trace-id": "51d3664ad3e84fed8da1d94ce250d5de" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 4645, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "6", - "x-dfo-trace-id": "6a3b79b90c29464ca15c35d8eafecb96" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 5865, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "d7de7e24059f4d75ae14bd1778b984de" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 7391, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "cd1a9f894cbe4b6a9c1a7ee78315aff0" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 8000, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "e1c46fecd652459380163afea4dc35b7" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "running", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 8000, - "progress": { - "rows_written": 105253, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "3b9df177b0a94b069b47c8b441c6f232" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "running", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 8000, - "progress": { - "rows_written": 109318, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "x-dfo-trace-id": "cd6f7d2857a44f9c947573b696793564" + "x-dfo-trace-id": "2cc73cd4fbaa4a28a350025111f70a79" }, "json": { "operation": { @@ -1542,7 +1282,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "materialise", - "confirmed_at": "2026-10-23T18:38:31.738121+00:00" + "confirmed_at": "2026-10-24T16:30:59.952146+00:00" }, "warnings": [], "diagnostics": [ @@ -1565,7 +1305,7 @@ "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39", @@ -1947,7 +1687,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted", - "x-dfo-trace-id": "b0cef6f918794d048a8a5056022de7cc" + "x-dfo-trace-id": "fb09161c837d4874970eaf5a188845da" } } }, @@ -2009,17 +1749,7 @@ 1.5, 1.5, 1.5, - 1.5, - 1.804, - 2.292, - 2.903, - 3.686, - 4.645, - 5.865, - 7.391, - 8.0, - 8.0, - 8.0 + 1.5 ], "resubmissions": 1 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json index a414d60..96921e6 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-not-found.json @@ -487,7 +487,7 @@ "content-type": "application/json", "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry-after": "2", - "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" + "x-dfo-trace-id": "a6d5bb2eff5a48578dce7fbf91715755" }, "json": { "operation": { diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-pacing-changes.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-pacing-changes.json new file mode 100644 index 0000000..099416b --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-pacing-changes.json @@ -0,0 +1,1474 @@ +{ + "format_version": 1, + "name": "fetch-spec-poll-pacing-changes", + "description": "Before each poll the client waits the retry_after_ms of the last operation resource it read: 1.5 seconds from the 202, then 2.5, 4 and 1 from the polls. A client that keeps the 202's value, or reads the Retry-After header in its place, waits otherwise.", + "origin": { + "kind": "synthetic", + "derived_from": "mint-async-build", + "edit": "As fetch-spec-async-build, with the polls that find the build running reading retry_after_ms 2500, 4000 and 1000 where the recording reads 1500." + }, + "call": [ + { + "op": "fetch", + "spec": { + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "definition": { + "schema_version": 1, + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 1963, + "end_year": 2024 + } + } + }, + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a.", + "entity_groups": { + "destination": { + "label": "G77 countries", + "group_id": "groups/G77" + }, + "origin": { + "label": "DAC countries", + "group_id": "groups/OECD.DAC" + } + } + } + } + ], + "exchanges": [ + { + "request": { + "method": "POST", + "path": "/datasets", + "json": { + "schema_version": 1, + "input": { + "kind": "spec_id", + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "definition": { + "schema_version": 1, + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ] + }, + "requested_window": { + "kind": "range", + "start_year": 1963, + "end_year": 2024 + } + } + } + }, + "options": { + "format": "parquet", + "bundle": false + } + } + }, + "response": { + "status": 202, + "headers": { + "content-type": "application/json", + "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry-after": "2", + "x-dfo-trace-id": "a6d5bb2eff5a48578dce7fbf91715755" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "pending", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 1500 + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2", + "x-dfo-trace-id": "71ecc596c6034e27b8ba5dd0a5d2c744" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "running", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 2500, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2", + "x-dfo-trace-id": "760a3bb2de5e430fb316b3f6a4059c67" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "running", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 4000, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2", + "x-dfo-trace-id": "15f9386c84484af983d33c6d183e5349" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "running", + "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "retry_after_ms": 1000, + "progress": { + "rows_written": 0, + "estimate_rows": 109318 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-dfo-trace-id": "2cc73cd4fbaa4a28a350025111f70a79" + }, + "json": { + "operation": { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "status": "done" + }, + "manifest": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "ref": "DAC2aAidType206", + "state": "value" + }, + "property": "dac2aAidType" + }, + { + "binding": { + "state": "unbound" + }, + "property": "dacTypeOfFinance" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "entities": { + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/USA" + ], + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] + }, + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2024, + "start_year": 1963 + } + } + }, + "content_version": "cv_3d58d26a874dc30b1bba7d5ad6dd90ee", + "prepared_at": "2026-10-23T18:38:28Z", + "coverage": { + "rows": 109318, + "dimensions": [ + { + "label": "financingProvider", + "count": 32, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 133, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 62 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 1963 + } + }, + "citation": { + "text": "OECD DAC2A (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=dac2a&pg=0&snb=1&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_DAC2%40DF_DAC2A&df[ag]=OECD.DCD.FSD&df[vs]=1.6&dq=.DPGC.206.USD.Q&lom=LASTNPERIODS&lo=5&to[TIME_PERIOD]=false&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "DAC2A is the OECD Development Assistance Committee's table of ODA disbursements by donor and recipient country or region. It covers bilateral donors and multilateral agencies reporting their own outflows, and includes the OECD's estimate of each donor's core multilateral contributions attributed to recipients.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip", + "attribution": "OECD (2026), OECD DAC2A, OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip (accessed on 2026-10-12)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1960-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The OECD publishes DAC2A in April, June, September and December. The complete table is downloaded from the OECD each time it is republished, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets. The totals DAC2A reports for groups of providers, such as all DAC countries, and for groups of recipients, such as regions and income groups, are included as providers and recipients of their own. Where two provider codes name the same organisation and report the same figures, the figures are counted once. Where two recipient codes name the same organisation, such as IDA and IDA's Multilateral Debt Relief Initiative, their flows are added." + }, + { + "transformation": "Select figures", + "description": "Only figures in current US dollars are included, not constant US dollars. Only flows to recipients on Part I of the DAC List are included: the developing countries, and the multilateral organisations DAC2A reports as recipients, such as development banks and UN agencies. Flows to Part II recipients, the countries in transition, are excluded." + }, + { + "transformation": "Convert to whole units", + "description": "DAC2A reports amounts in millions, which are converted to whole units. ODA per person and ODA as a share of GNI are kept as reported." + }, + { + "transformation": "Select dimensions", + "description": "Each figure is reported by year, provider, recipient and type of aid, such as grants, repayments, interest received, or debt forgiven or rescheduled. DAC2A is a table of disbursements, so every figure, repayments and interest included, is recorded as a disbursement. Figures are marked as gross or net, except where DAC2A does not say which, and as grants or non-grants where the type of aid is wholly one or the other. Imputed multilateral ODA, the OECD's estimate of each provider's share of multilateral organisations' ODA, is marked as modelled. ODA as a share of GNI records the recipient's GNI as its denominator, and ODA per person records the recipient's population." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "ODA disbursements by donor and recipient country or region, including the OECD's imputed multilateral contributions, and ODA per person and as a share of recipient GNI." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDDAC2A", + "axis": "provenance", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + }, + { + "ref": null, + "axis": "measurementMethod", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 1963 + }, + "graph_revision": "dfo-dev-dc-datacommons-service-00264-2s9", + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-23T18:14:12Z", + "content_hash": "29eb81d7b6c88641b1d4e8eb5e850ca36de66b99d6e9e09680aac020507a6392", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDDAC2A", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_cc753cefa9199881", + "materialiser_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 109318 + } + ], + "family_member_count": 1, + "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", + "served_from": "materialise", + "confirmed_at": "2026-10-24T16:30:59.952146+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 4 + }, + "bytes": 473679, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-23T18:38:31.580044+00:00", + "tier": "working", + "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" + }, + { + "artifact_digest": "sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39", + "rendering": { + "statistics": "series" + }, + "bytes": 144274, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-23T18:38:31.580044+00:00", + "tier": "working", + "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39" + } + ], + "series_count": 3656, + "output_options": { + "capability_version": "dset_cc753cefa9199881", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 32 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 133 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 62 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 32, + "covered": 32 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 133, + "covered": 132 + }, + "missing": [ + { + "ref": "country/SSD", + "label": "South Sudan" + } + ], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_kind", + "financingRecipient_label", + "financingRecipient_kind" + ], + "long_layout_totals": [], + "pivots": [ + { + "index": "financingProvider", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 62 + } + ] + }, + { + "index": "financingProvider", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 133 + } + ] + }, + { + "index": "financingRecipient", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 62 + } + ] + }, + { + "index": "financingRecipient", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 32 + } + ] + }, + { + "index": "time_period", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 133 + } + ] + }, + { + "index": "time_period", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 32 + } + ] + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "retention": { + "pinned": false, + "held_until": "2026-11-22T18:38:31.579178Z" + } + } + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65" + }, + "response": { + "status": 302, + "headers": { + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted", + "x-dfo-trace-id": "fb09161c837d4874970eaf5a188845da" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "mint-async-build.parquet" + } + } + ], + "expect": [ + { + "dataset": { + "rows": 109318, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_kind", + "dac2aAidType", + "dac2aAidType_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_fbca0f29755230d84729c1243b1d9b45", + "content_version": "cv_3d58d26a874dc30b1bba7d5ad6dd90ee", + "sentence": "Gross disbursements to the 133 G77 countries from the 32 DAC countries for official development assistance, 1963 to 2024. Current US dollars · OECD DAC2a." + } + ], + "missing": [], + "long_builds": [ + { + "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", + "poll_waits": [ + 1.5, + 2.5, + 4.0, + 1.0 + ], + "resubmissions": 0 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited-not-retryable.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited-not-retryable.json index ee97d16..eb3fdc5 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited-not-retryable.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited-not-retryable.json @@ -487,7 +487,7 @@ "content-type": "application/json", "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry-after": "2", - "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" + "x-dfo-trace-id": "a6d5bb2eff5a48578dce7fbf91715755" }, "json": { "operation": { diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited.json index 7929226..5dc6d95 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-rate-limited.json @@ -487,7 +487,7 @@ "content-type": "application/json", "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry-after": "2", - "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" + "x-dfo-trace-id": "a6d5bb2eff5a48578dce7fbf91715755" }, "json": { "operation": { @@ -521,12 +521,12 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "043386d87ba247048aa921704d3ff030" + "x-dfo-trace-id": "71ecc596c6034e27b8ba5dd0a5d2c744" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { @@ -547,12 +547,12 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "c7ef77e57a864be6a4617b1aeae7c11d" + "x-dfo-trace-id": "760a3bb2de5e430fb316b3f6a4059c67" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { @@ -573,12 +573,12 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "cea2df9c98f94601a5e9976e76842f12" + "x-dfo-trace-id": "15f9386c84484af983d33c6d183e5349" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { @@ -598,267 +598,7 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2", - "x-dfo-trace-id": "7a800f2714b94a8482dc5fb553c669f5" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 1804, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "f911f5f7ca244733b2da3d5ce6913f6d" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 2292, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "07d32bbe980e419eb9f8461492ff4c62" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 2903, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "4", - "x-dfo-trace-id": "dd33ade549434abf82b662ab5251b0c1" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 3686, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "5", - "x-dfo-trace-id": "51d3664ad3e84fed8da1d94ce250d5de" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 4645, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "6", - "x-dfo-trace-id": "6a3b79b90c29464ca15c35d8eafecb96" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 5865, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "d7de7e24059f4d75ae14bd1778b984de" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 7391, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "cd1a9f894cbe4b6a9c1a7ee78315aff0" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 8000, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "e1c46fecd652459380163afea4dc35b7" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "running", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 8000, - "progress": { - "rows_written": 105253, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "3b9df177b0a94b069b47c8b441c6f232" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "running", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 8000, - "progress": { - "rows_written": 109318, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "x-dfo-trace-id": "cd6f7d2857a44f9c947573b696793564" + "x-dfo-trace-id": "2cc73cd4fbaa4a28a350025111f70a79" }, "json": { "operation": { @@ -1269,7 +1009,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "materialise", - "confirmed_at": "2026-10-23T18:38:31.738121+00:00" + "confirmed_at": "2026-10-24T16:30:59.952146+00:00" }, "warnings": [], "diagnostics": [ @@ -1292,7 +1032,7 @@ "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39", @@ -1674,7 +1414,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted", - "x-dfo-trace-id": "b0cef6f918794d048a8a5056022de7cc" + "x-dfo-trace-id": "fb09161c837d4874970eaf5a188845da" } } }, @@ -1736,17 +1476,7 @@ 3.0, 1.5, 1.5, - 1.5, - 1.804, - 2.292, - 2.903, - 3.686, - 4.645, - 5.865, - 7.391, - 8.0, - 8.0, - 8.0 + 1.5 ], "resubmissions": 0 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-backoff.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-backoff.json index 7c36fd8..ed5514f 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-backoff.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-backoff.json @@ -486,7 +486,7 @@ "headers": { "content-type": "application/json", "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" + "x-dfo-trace-id": "a6d5bb2eff5a48578dce7fbf91715755" }, "json": { "operation": { @@ -506,12 +506,12 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "043386d87ba247048aa921704d3ff030" + "x-dfo-trace-id": "71ecc596c6034e27b8ba5dd0a5d2c744" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "progress": { "rows_written": 0, @@ -552,247 +552,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "c7ef77e57a864be6a4617b1aeae7c11d" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "x-dfo-trace-id": "cea2df9c98f94601a5e9976e76842f12" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "x-dfo-trace-id": "7a800f2714b94a8482dc5fb553c669f5" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "x-dfo-trace-id": "f911f5f7ca244733b2da3d5ce6913f6d" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "x-dfo-trace-id": "07d32bbe980e419eb9f8461492ff4c62" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "x-dfo-trace-id": "dd33ade549434abf82b662ab5251b0c1" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "x-dfo-trace-id": "51d3664ad3e84fed8da1d94ce250d5de" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "x-dfo-trace-id": "6a3b79b90c29464ca15c35d8eafecb96" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "x-dfo-trace-id": "d7de7e24059f4d75ae14bd1778b984de" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "x-dfo-trace-id": "cd1a9f894cbe4b6a9c1a7ee78315aff0" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "x-dfo-trace-id": "e1c46fecd652459380163afea4dc35b7" + "x-dfo-trace-id": "760a3bb2de5e430fb316b3f6a4059c67" }, "json": { "operation": { @@ -800,7 +560,7 @@ "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "progress": { - "rows_written": 105253, + "rows_written": 0, "estimate_rows": 109318 } } @@ -816,7 +576,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "3b9df177b0a94b069b47c8b441c6f232" + "x-dfo-trace-id": "15f9386c84484af983d33c6d183e5349" }, "json": { "operation": { @@ -824,7 +584,7 @@ "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "progress": { - "rows_written": 109318, + "rows_written": 0, "estimate_rows": 109318 } } @@ -840,7 +600,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "cd6f7d2857a44f9c947573b696793564" + "x-dfo-trace-id": "2cc73cd4fbaa4a28a350025111f70a79" }, "json": { "operation": { @@ -1251,7 +1011,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "materialise", - "confirmed_at": "2026-10-23T18:38:31.738121+00:00" + "confirmed_at": "2026-10-24T16:30:59.952146+00:00" }, "warnings": [], "diagnostics": [ @@ -1274,7 +1034,7 @@ "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39", @@ -1656,7 +1416,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted", - "x-dfo-trace-id": "b0cef6f918794d048a8a5056022de7cc" + "x-dfo-trace-id": "fb09161c837d4874970eaf5a188845da" } } }, @@ -1718,16 +1478,6 @@ 2.0, 4.0, 8.0, - 8.0, - 8.0, - 8.0, - 8.0, - 8.0, - 8.0, - 8.0, - 8.0, - 8.0, - 8.0, 8.0 ], "resubmissions": 0 diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-retry-after.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-retry-after.json index 94cf7d7..02becd9 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-retry-after.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused-retry-after.json @@ -487,7 +487,7 @@ "content-type": "application/json", "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry-after": "2", - "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" + "x-dfo-trace-id": "a6d5bb2eff5a48578dce7fbf91715755" }, "json": { "operation": { @@ -532,12 +532,12 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "043386d87ba247048aa921704d3ff030" + "x-dfo-trace-id": "71ecc596c6034e27b8ba5dd0a5d2c744" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { @@ -558,12 +558,12 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "c7ef77e57a864be6a4617b1aeae7c11d" + "x-dfo-trace-id": "760a3bb2de5e430fb316b3f6a4059c67" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { @@ -584,12 +584,12 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "cea2df9c98f94601a5e9976e76842f12" + "x-dfo-trace-id": "15f9386c84484af983d33c6d183e5349" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { @@ -609,267 +609,7 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2", - "x-dfo-trace-id": "7a800f2714b94a8482dc5fb553c669f5" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 1804, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "f911f5f7ca244733b2da3d5ce6913f6d" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 2292, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "07d32bbe980e419eb9f8461492ff4c62" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 2903, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "4", - "x-dfo-trace-id": "dd33ade549434abf82b662ab5251b0c1" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 3686, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "5", - "x-dfo-trace-id": "51d3664ad3e84fed8da1d94ce250d5de" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 4645, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "6", - "x-dfo-trace-id": "6a3b79b90c29464ca15c35d8eafecb96" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 5865, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "d7de7e24059f4d75ae14bd1778b984de" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 7391, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "cd1a9f894cbe4b6a9c1a7ee78315aff0" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 8000, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "e1c46fecd652459380163afea4dc35b7" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "running", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 8000, - "progress": { - "rows_written": 105253, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "3b9df177b0a94b069b47c8b441c6f232" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "running", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 8000, - "progress": { - "rows_written": 109318, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "x-dfo-trace-id": "cd6f7d2857a44f9c947573b696793564" + "x-dfo-trace-id": "2cc73cd4fbaa4a28a350025111f70a79" }, "json": { "operation": { @@ -1280,7 +1020,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "materialise", - "confirmed_at": "2026-10-23T18:38:31.738121+00:00" + "confirmed_at": "2026-10-24T16:30:59.952146+00:00" }, "warnings": [], "diagnostics": [ @@ -1303,7 +1043,7 @@ "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39", @@ -1685,7 +1425,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted", - "x-dfo-trace-id": "b0cef6f918794d048a8a5056022de7cc" + "x-dfo-trace-id": "fb09161c837d4874970eaf5a188845da" } } }, @@ -1747,17 +1487,7 @@ 5.0, 1.5, 1.5, - 1.5, - 1.804, - 2.292, - 2.903, - 3.686, - 4.645, - 5.865, - 7.391, - 8.0, - 8.0, - 8.0 + 1.5 ], "resubmissions": 0 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused.json index 8110b3d..b1f3dcf 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-poll-refused.json @@ -487,7 +487,7 @@ "content-type": "application/json", "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry-after": "2", - "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" + "x-dfo-trace-id": "a6d5bb2eff5a48578dce7fbf91715755" }, "json": { "operation": { @@ -531,12 +531,12 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "043386d87ba247048aa921704d3ff030" + "x-dfo-trace-id": "71ecc596c6034e27b8ba5dd0a5d2c744" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { @@ -557,12 +557,12 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "c7ef77e57a864be6a4617b1aeae7c11d" + "x-dfo-trace-id": "760a3bb2de5e430fb316b3f6a4059c67" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { @@ -627,12 +627,12 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "cea2df9c98f94601a5e9976e76842f12" + "x-dfo-trace-id": "15f9386c84484af983d33c6d183e5349" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { @@ -652,267 +652,7 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2", - "x-dfo-trace-id": "7a800f2714b94a8482dc5fb553c669f5" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 1804, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "f911f5f7ca244733b2da3d5ce6913f6d" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 2292, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "07d32bbe980e419eb9f8461492ff4c62" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 2903, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "4", - "x-dfo-trace-id": "dd33ade549434abf82b662ab5251b0c1" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 3686, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "5", - "x-dfo-trace-id": "51d3664ad3e84fed8da1d94ce250d5de" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 4645, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "6", - "x-dfo-trace-id": "6a3b79b90c29464ca15c35d8eafecb96" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 5865, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "d7de7e24059f4d75ae14bd1778b984de" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 7391, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "cd1a9f894cbe4b6a9c1a7ee78315aff0" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 8000, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "e1c46fecd652459380163afea4dc35b7" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "running", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 8000, - "progress": { - "rows_written": 105253, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "3b9df177b0a94b069b47c8b441c6f232" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "running", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 8000, - "progress": { - "rows_written": 109318, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "x-dfo-trace-id": "cd6f7d2857a44f9c947573b696793564" + "x-dfo-trace-id": "2cc73cd4fbaa4a28a350025111f70a79" }, "json": { "operation": { @@ -1323,7 +1063,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "materialise", - "confirmed_at": "2026-10-23T18:38:31.738121+00:00" + "confirmed_at": "2026-10-24T16:30:59.952146+00:00" }, "warnings": [], "diagnostics": [ @@ -1346,7 +1086,7 @@ "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39", @@ -1728,7 +1468,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted", - "x-dfo-trace-id": "b0cef6f918794d048a8a5056022de7cc" + "x-dfo-trace-id": "fb09161c837d4874970eaf5a188845da" } } }, @@ -1792,17 +1532,7 @@ 1.5, 1.5, 1.5, - 1.5, - 1.804, - 2.292, - 2.903, - 3.686, - 4.645, - 5.865, - 7.391, - 8.0, - 8.0, - 8.0 + 1.5 ], "resubmissions": 0 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-relative-location.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-relative-location.json index c28f441..1b2da24 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-relative-location.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-relative-location.json @@ -175,7 +175,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "x-dfo-trace-id": "bfc5cc090c4347f489fffcc62fc3d2bf" }, "json": { "schema_version": 1, @@ -582,7 +582,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:10.942106+00:00" + "confirmed_at": "2026-10-24T16:30:31.570035+00:00" }, "warnings": [ { @@ -611,7 +611,7 @@ "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -895,7 +895,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T13:59:18.051742Z" @@ -913,7 +913,7 @@ "headers": { "content-type": "text/html", "location": "bytes", - "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" + "x-dfo-trace-id": "8261c9be5a7c406a80692fac6b28ee05" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json index c89f183..29a3f26 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-request-invalid.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:37:29Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:30:51Z" }, "call": [ { @@ -182,7 +182,7 @@ "status": 400, "headers": { "content-type": "application/problem+json", - "x-dfo-trace-id": "060bc9edc00f4aeb8550070e8c9b2632" + "x-dfo-trace-id": "e229106e38d04e07af32b2895e017913" }, "json": { "type": "/codes/request_invalid", @@ -191,7 +191,7 @@ "detail": "Value error, unknown facet axis/axes: colour", "code": "request_invalid", "pointer": "/input/scope", - "trace_id": "060bc9edc00f4aeb8550070e8c9b2632", + "trace_id": "e229106e38d04e07af32b2895e017913", "capability_version": "dset_cc753cefa9199881", "retryable": false } @@ -203,7 +203,7 @@ "error": { "class": "InvalidRequestError", "code": "request_invalid", - "trace_id": "060bc9edc00f4aeb8550070e8c9b2632" + "trace_id": "e229106e38d04e07af32b2895e017913" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json index a4d3743..e3b2dfb 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-resubmit-other-spec.json @@ -182,7 +182,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "52642a89ff44404fb61540fe78b1ca94" + "x-dfo-trace-id": "a1fe53d87b784d23bcc55926b9530dec" }, "json": { "schema_version": 1, @@ -589,7 +589,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:10.942106+00:00" + "confirmed_at": "2026-10-24T16:30:31.570035+00:00" }, "warnings": [ { @@ -618,7 +618,7 @@ "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -902,7 +902,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T13:59:18.051742Z" @@ -996,7 +996,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "0d356c6a142c45b5a4e8ea173623cc40" + "x-dfo-trace-id": "c4313642ac68484fb1d13d6f7b206d66" }, "json": { "schema_version": 1, @@ -1005,11 +1005,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "0d356c6a142c45b5a4e8ea173623cc40", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "c4313642ac68484fb1d13d6f7b206d66", "warnings": [], "timing_ms": { - "total": 341, + "total": 340, "by_step": { "coverage": 0 } @@ -1022,21 +1022,22 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 269, + "total": 256, "by_step": { "validate": 4, - "walk": 217, + "walk": 219, "reread_arcs": 1, "detect_edits": 0, "resolve_survivors": 0, - "shape": 4, - "bind": 0, + "shape": 3, + "bind": 1, "where_places": 0, - "materialise": 13, - "answer": 29, - "options": 1 + "materialise": 12, + "answer": 14, + "options": 2 } }, + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -1467,7 +1468,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -2030,7 +2031,7 @@ "start_year": 2020, "end_year": 2023 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -4634,7 +4635,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "0d356c6a142c45b5a4e8ea173623cc40" + "trace_id": "c4313642ac68484fb1d13d6f7b206d66" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-same-origin-artifact-url.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-same-origin-artifact-url.json index 43923a4..2878965 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-same-origin-artifact-url.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-same-origin-artifact-url.json @@ -175,7 +175,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "x-dfo-trace-id": "bfc5cc090c4347f489fffcc62fc3d2bf" }, "json": { "schema_version": 1, @@ -582,7 +582,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:10.942106+00:00" + "confirmed_at": "2026-10-24T16:30:31.570035+00:00" }, "warnings": [ { @@ -611,7 +611,7 @@ "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", "url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -895,7 +895,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T13:59:18.051742Z" @@ -913,7 +913,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", - "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" + "x-dfo-trace-id": "8261c9be5a7c406a80692fac6b28ee05" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-signed-fetch-partial.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-signed-fetch-partial.json index 7ffadd3..dc97e7e 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-signed-fetch-partial.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-signed-fetch-partial.json @@ -175,7 +175,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "x-dfo-trace-id": "bfc5cc090c4347f489fffcc62fc3d2bf" }, "json": { "schema_version": 1, @@ -582,7 +582,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:10.942106+00:00" + "confirmed_at": "2026-10-24T16:30:31.570035+00:00" }, "warnings": [ { @@ -611,7 +611,7 @@ "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -895,7 +895,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T13:59:18.051742Z" @@ -913,7 +913,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", - "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" + "x-dfo-trace-id": "8261c9be5a7c406a80692fac6b28ee05" } } }, @@ -940,7 +940,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Ac44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170?X-Goog-Signature=redacted", - "x-dfo-trace-id": "07a61fadcaa94c9eafa158ddc41c07f3" + "x-dfo-trace-id": "8261c9be5a7c406a80692fac6b28ee05" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json index cfc71b4..29d6a08 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-storage-artifact-url.json @@ -175,7 +175,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "x-dfo-trace-id": "bfc5cc090c4347f489fffcc62fc3d2bf" }, "json": { "schema_version": 1, @@ -582,7 +582,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:10.942106+00:00" + "confirmed_at": "2026-10-24T16:30:31.570035+00:00" }, "warnings": [ { @@ -611,7 +611,7 @@ "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", "url": "https://storage.googleapis.com/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -895,7 +895,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T13:59:18.051742Z" @@ -909,7 +909,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "e1bfd7e1ab67428e9dc923e28d07d4f9" + "trace_id": "bfc5cc090c4347f489fffcc62fc3d2bf" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json index 96dc34e..f5755d2 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-spec-strict-warning.json @@ -583,7 +583,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:37:10.942106+00:00" + "confirmed_at": "2026-10-24T16:30:31.570035+00:00" }, "warnings": [ { @@ -612,7 +612,7 @@ "created_at": "2026-10-23T16:58:47.734759+00:00", "tier": "working", "url": "/api/datasets/spec_cb5baa4161de718f18583060674dbca6/cv_bf242138f8d0a892c97da9373d1626f4/files/sha256:c44200969f19d73104d1bc24ebca905e59f749c2939234cdde10ba6f5a131170", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:d3a506bc9b95188583b5764592d2f1897c0665add660106b7f77c3e501000bb4", @@ -896,7 +896,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T13:59:18.051742Z" diff --git a/python/client-contract/src/dfo_client_contract/scenarios/fetch-strict-info-notice.json b/python/client-contract/src/dfo_client_contract/scenarios/fetch-strict-info-notice.json index 34d3e52..1463a62 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/fetch-strict-info-notice.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/fetch-strict-info-notice.json @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "8ff5daac36fe403ab946f5b02785cb0d" + "x-dfo-trace-id": "bf6613bf82be4bddb4d60879aaf907d9" }, "json": { "schema_version": 1, @@ -45,21 +45,23 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "8ff5daac36fe403ab946f5b02785cb0d", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "bf6613bf82be4bddb4d60879aaf907d9", "warnings": [], "timing_ms": { - "total": 4716, + "total": 2620, "by_step": { "coverage": 0, - "extract": 1242, + "extract": 1068, "cache_lookup": 0 } }, "llm_usage": { - "input_tokens": 6216, - "output_tokens": 423, - "cached_tokens": 841 + "input_tokens": 2231, + "output_tokens": 102, + "cached_tokens": 841, + "jev_input_tokens": 6586, + "jev_output_tokens": 2060 }, "timed_out": false }, @@ -75,30 +77,30 @@ } ], "timing_ms": { - "total": 3468, + "total": 1548, "by_step": { - "recall": 547, + "recall": 437, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 1, - "shape_probe_coverage": 6, - "shape_probe": 136, - "shape_groups": 43, + "shape_arcs": 2, + "shape_probe_coverage": 4, + "shape_probe": 161, + "shape_groups": 45, "shape_labels": 1, - "shape_admission": 0, + "shape_admission": 3, "phase_derive_shapes": 0, - "shape": 1190, + "shape": 326, "phase_prune_and_rank": 0, - "bind": 1278, - "phase_bind": 149, - "phase_settle": 50, - "phase_place_bindings": 19, + "bind": 225, + "phase_bind": 158, + "phase_settle": 56, + "phase_place_bindings": 18, "phase_facet_requests": 0, - "materialise": 30, + "materialise": 41, "phase_materialise": 0, - "answer": 110, - "options": 38, - "phase_outcome": 57 + "answer": 186, + "options": 40, + "phase_outcome": 61 } }, "restatement": { @@ -116,6 +118,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [ + "country/DEU" + ] + }, + { + "text": "Nigeria", + "refs": [ + "country/NGA" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -531,7 +547,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -1184,7 +1200,7 @@ "selected": [] } ], - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3782,7 +3798,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "c1f0030e84b5418d89553827b503d006" + "x-dfo-trace-id": "42460c90e7274dd19ecba24a6a0377e9" }, "json": { "schema_version": 1, @@ -4183,7 +4199,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261011T194155Z-80081f08", "served_from": "head", - "confirmed_at": "2026-10-23T18:36:51.837863+00:00" + "confirmed_at": "2026-10-24T16:30:05.017544+00:00" }, "warnings": [ { @@ -4212,7 +4228,7 @@ "created_at": "2026-10-23T16:56:32.058938+00:00", "tier": "working", "url": "/api/datasets/spec_774d6c001a6250aa67ca676ab067895e/cv_b92d94774702c7f05f2075d0b03dd756/files/sha256:421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:07984a96eaf8ee637fe15bf13f2b0d9160a6378d3fa1efae2e71cf0e20115dff", @@ -4511,7 +4527,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": true } @@ -4528,7 +4544,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A421efacc2dc010af38112a087b0b49ff5539f61d2afd12a88272b27e99b5f5db?X-Goog-Signature=redacted", - "x-dfo-trace-id": "b2396d674b5848e7b1828fca235d84a1" + "x-dfo-trace-id": "b9b4b3a90d6546e09cc738a29bbbb1d6" } } }, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.json b/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.json index 3d1995e..8fc7eea 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/mint-async-build.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:37:32Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:30:53Z" }, "call": [ { @@ -491,7 +491,7 @@ "content-type": "application/json", "location": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry-after": "2", - "x-dfo-trace-id": "fb72515bdace4ea592ff15b4e5b410fc" + "x-dfo-trace-id": "a6d5bb2eff5a48578dce7fbf91715755" }, "json": { "operation": { @@ -513,12 +513,12 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "043386d87ba247048aa921704d3ff030" + "x-dfo-trace-id": "71ecc596c6034e27b8ba5dd0a5d2c744" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { @@ -539,12 +539,12 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "c7ef77e57a864be6a4617b1aeae7c11d" + "x-dfo-trace-id": "760a3bb2de5e430fb316b3f6a4059c67" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { @@ -565,12 +565,12 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "cea2df9c98f94601a5e9976e76842f12" + "x-dfo-trace-id": "15f9386c84484af983d33c6d183e5349" }, "json": { "operation": { "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", + "status": "running", "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", "retry_after_ms": 1500, "progress": { @@ -590,267 +590,7 @@ "status": 200, "headers": { "content-type": "application/json", - "retry-after": "2", - "x-dfo-trace-id": "7a800f2714b94a8482dc5fb553c669f5" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 1804, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "f911f5f7ca244733b2da3d5ce6913f6d" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 2292, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "07d32bbe980e419eb9f8461492ff4c62" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 2903, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "4", - "x-dfo-trace-id": "dd33ade549434abf82b662ab5251b0c1" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 3686, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "5", - "x-dfo-trace-id": "51d3664ad3e84fed8da1d94ce250d5de" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 4645, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "6", - "x-dfo-trace-id": "6a3b79b90c29464ca15c35d8eafecb96" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 5865, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "d7de7e24059f4d75ae14bd1778b984de" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 7391, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "cd1a9f894cbe4b6a9c1a7ee78315aff0" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "pending", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 8000, - "progress": { - "rows_written": 0, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "e1c46fecd652459380163afea4dc35b7" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "running", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 8000, - "progress": { - "rows_written": 105253, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "8", - "x-dfo-trace-id": "3b9df177b0a94b069b47c8b441c6f232" - }, - "json": { - "operation": { - "operation_id": "op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "status": "running", - "poll": "/api/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e", - "retry_after_ms": 8000, - "progress": { - "rows_written": 109318, - "estimate_rows": 109318 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_cc325e96d3ac6fdb6721c2468fd261f221bc87ee5eb9d8e82cf4d1f3720bdf6e" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "x-dfo-trace-id": "cd6f7d2857a44f9c947573b696793564" + "x-dfo-trace-id": "2cc73cd4fbaa4a28a350025111f70a79" }, "json": { "operation": { @@ -1261,7 +1001,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "materialise", - "confirmed_at": "2026-10-23T18:38:31.738121+00:00" + "confirmed_at": "2026-10-24T16:30:59.952146+00:00" }, "warnings": [], "diagnostics": [ @@ -1284,7 +1024,7 @@ "created_at": "2026-10-23T18:38:31.580044+00:00", "tier": "working", "url": "/api/datasets/spec_fbca0f29755230d84729c1243b1d9b45/cv_3d58d26a874dc30b1bba7d5ad6dd90ee/files/sha256:9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:099d1ce36b440868b72174fb9cdff503cc4c7a0f0ef902e66484c5bfbd270f39", @@ -1666,7 +1406,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A9242d69bedb460996f21f782b1a85ee5cd7eb967174e3b64a4ec5ade5bebab65?X-Goog-Signature=redacted", - "x-dfo-trace-id": "b0cef6f918794d048a8a5056022de7cc" + "x-dfo-trace-id": "fb09161c837d4874970eaf5a188845da" } } }, @@ -1733,17 +1473,7 @@ 1.5, 1.5, 1.5, - 1.5, - 1.804, - 2.292, - 2.903, - 3.686, - 4.645, - 5.865, - 7.391, - 8.0, - 8.0, - 8.0 + 1.5 ], "resubmissions": 0 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json b/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json index 72fa553..7226186 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json @@ -93,12 +93,12 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "bff64c2e088f43959abac4151c6a78e4" + "x-dfo-trace-id": "6f93d15300c8413191296f90fbc4b8b0" }, "json": { "schema_version": 1, "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0", + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8", "next_cursor": null, "complete": true, "items": [ @@ -112,28 +112,28 @@ ], "op": "sum" }, - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", "base_content_version": null, "rendering": "plain", "groupby": null, - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "content_version": "cv_9417c96e4e09dd36053fc395c5b0f92c", "base_content_version": null, "rendering": "plain", "groupby": null, - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "content_version": "cv_e7f6ed9ddc5ca69902f92a8866f93ef7", "base_content_version": null, "rendering": "plain", "groupby": null, - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" } ] } @@ -145,7 +145,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "bff64c2e088f43959abac4151c6a78e4" + "trace_id": "6f93d15300c8413191296f90fbc4b8b0" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json b/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json index decf121..b716c5c 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json @@ -27,7 +27,7 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "a54948450bc0460c9ed02ae930ce385a" + "x-dfo-trace-id": "7a8fcbad75fa4232a0fd7b55729da907" }, "json": { "operation": { @@ -53,7 +53,7 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "7ad3c071f95943deb4d9804df43d9c8f" + "x-dfo-trace-id": "09873539d7e1412baa820fb5f7421322" }, "json": { "operation": { @@ -77,7 +77,7 @@ "error": { "class": "ServerError", "code": "operation_failed", - "trace_id": "7ad3c071f95943deb4d9804df43d9c8f", + "trace_id": "09873539d7e1412baa820fb5f7421322", "long_builds": [ { "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", diff --git a/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.json b/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.json index 7d9f4a8..b34c17c 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:38:40Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:31:08Z" }, "call": [ { @@ -28,7 +28,7 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "a54948450bc0460c9ed02ae930ce385a" + "x-dfo-trace-id": "7a8fcbad75fa4232a0fd7b55729da907" }, "json": { "operation": { @@ -54,7 +54,7 @@ "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "7ad3c071f95943deb4d9804df43d9c8f" + "x-dfo-trace-id": "09873539d7e1412baa820fb5f7421322" }, "json": { "operation": { @@ -63,137 +63,7 @@ "poll": "/api/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", "retry_after_ms": 1500, "progress": { - "rows_written": 20644, - "estimate_rows": 112203 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "2", - "x-dfo-trace-id": "82bcbf5ea88a470f8efc4982ca9da566" - }, - "json": { - "operation": { - "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", - "status": "running", - "poll": "/api/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", - "retry_after_ms": 1500, - "progress": { - "rows_written": 57823, - "estimate_rows": 112203 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "2", - "x-dfo-trace-id": "c73d60d488e04687ab17f9b0e571b7d4" - }, - "json": { - "operation": { - "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", - "status": "running", - "poll": "/api/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", - "retry_after_ms": 1500, - "progress": { - "rows_written": 94473, - "estimate_rows": 112203 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "2", - "x-dfo-trace-id": "a164edf73d6248fe9d741ea324305510" - }, - "json": { - "operation": { - "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", - "status": "running", - "poll": "/api/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", - "retry_after_ms": 1881, - "progress": { - "rows_written": 112203, - "estimate_rows": 112203 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "36531c091ceb429b95918024f5490371" - }, - "json": { - "operation": { - "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", - "status": "running", - "poll": "/api/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", - "retry_after_ms": 2386, - "progress": { - "rows_written": 112203, - "estimate_rows": 112203 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "4", - "x-dfo-trace-id": "51746ee3252343fabb47578db0ab7fdf" - }, - "json": { - "operation": { - "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", - "status": "running", - "poll": "/api/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", - "retry_after_ms": 3058, - "progress": { - "rows_written": 112203, + "rows_written": 0, "estimate_rows": 112203 } } @@ -209,7 +79,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "399bb2532fb74b8381ec3d2dee8a99e8" + "x-dfo-trace-id": "c5978ef07c5340e0ae21c8881deb8130" }, "json": { "operation": { @@ -626,7 +496,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "materialise", - "confirmed_at": "2026-10-23T18:39:02.862675+00:00" + "confirmed_at": "2026-10-24T16:31:14.752129+00:00" }, "warnings": [ { @@ -655,7 +525,7 @@ "created_at": "2026-10-23T18:39:02.714887+00:00", "tier": "working", "url": "/api/datasets/spec_8150d26a25222b2043e8c12b250b764d/cv_fe2e676a79899730eac6110f58213472/files/sha256:55f95f11ffe010e99407d279d159e956d4dfa6a6ba89f6d73aa32fb952fccd1d", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:39345f0fc420a15e6262bf58781d46ebda6e7e9a0f11fc0c7540826b151a1d0e", @@ -1269,7 +1139,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "957a2fdf109b4617a383ffd39e6b95ca" + "x-dfo-trace-id": "0a02312a9fba4338a5c67e61e4f0c8fd" }, "json": { "schema_version": 1, @@ -1278,11 +1148,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "957a2fdf109b4617a383ffd39e6b95ca", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "0a02312a9fba4338a5c67e61e4f0c8fd", "warnings": [], "timing_ms": { - "total": 1972, + "total": 2806, "by_step": { "coverage": 0 } @@ -1295,21 +1165,22 @@ "variable_text": "dataset", "warnings": [], "timing_ms": { - "total": 1780, + "total": 2075, "by_step": { - "validate": 0, - "walk": 11, + "validate": 1, + "walk": 10, "reread_arcs": 0, "detect_edits": 0, - "resolve_survivors": 1, - "shape": 1694, - "bind": 1, + "resolve_survivors": 0, + "shape": 1995, + "bind": 0, "where_places": 1, "materialise": 24, - "answer": 12, - "options": 36 + "answer": 11, + "options": 33 } }, + "entity_refs": [], "operations": [], "departures": [ { @@ -3793,7 +3664,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -5614,7 +5485,7 @@ "start_year": 1966, "end_year": 2024 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -8286,7 +8157,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A55f95f11ffe010e99407d279d159e956d4dfa6a6ba89f6d73aa32fb952fccd1d?X-Goog-Signature=redacted", - "x-dfo-trace-id": "99174adf5a674fefa2eb760afac524d3" + "x-dfo-trace-id": "51314836477547c6aff574e07f6b19ab" } } }, @@ -8351,12 +8222,7 @@ "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", "poll_waits": [ 1.5, - 1.5, - 1.5, - 1.5, - 1.881, - 2.386, - 3.058 + 1.5 ], "resubmissions": 0 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/resubmit-candidates-sibling.json b/python/client-contract/src/dfo_client_contract/scenarios/resubmit-candidates-sibling.json index 37dacc3..7854333 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/resubmit-candidates-sibling.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/resubmit-candidates-sibling.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:39:35Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:31:50Z" }, "call": [ { @@ -36,7 +36,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "dc9cc6e5c1a34ab295ff44b26137f6a1" + "x-dfo-trace-id": "a42078d26ea943a488b4cb642719e808" }, "json": { "schema_version": 1, @@ -47,14 +47,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "dc9cc6e5c1a34ab295ff44b26137f6a1", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "a42078d26ea943a488b4cb642719e808", "warnings": [], "timing_ms": { - "total": 2566, + "total": 4608, "by_step": { "coverage": 0, - "extract": 1061, + "extract": 1312, "cache_lookup": 0 } }, @@ -73,28 +73,28 @@ "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 1502, + "total": 2048, "by_step": { "recall": 1, "phase_resolve_places": 0, "phase_check_entities": 0, "shape_arcs": 4, - "shape_probe": 101, + "shape_probe": 96, "shape_groups": 5, "shape_labels": 1, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 230, + "shape": 246, "phase_prune_and_rank": 0, - "bind": 192, - "phase_bind": 3, - "phase_settle": 6, - "phase_place_bindings": 27, + "bind": 131, + "phase_bind": 11, + "phase_settle": 7, + "phase_place_bindings": 29, "phase_facet_requests": 0, - "materialise": 250, + "materialise": 113, "phase_materialise": 0, - "answer": 25, - "phase_outcome": 768 + "answer": 106, + "phase_outcome": 1404 } }, "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", @@ -286,6 +286,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -808,7 +816,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2342,7 +2350,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2380,29 +2388,29 @@ } ], "timing_ms": { - "total": 1199, + "total": 3238, "by_step": { - "recall": 1, + "recall": 321, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 3, - "shape_probe_coverage": 8, - "shape_probe": 237, + "shape_arcs": 86, + "shape_probe_coverage": 32, + "shape_probe": 102, "shape_groups": 22, "shape_labels": 1, - "shape_admission": 0, + "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 350, + "shape": 316, "phase_prune_and_rank": 0, - "bind": 150, - "phase_bind": 8, - "phase_settle": 27, - "phase_place_bindings": 167, + "bind": 125, + "phase_bind": 26, + "phase_settle": 56, + "phase_place_bindings": 1829, "phase_facet_requests": 0, - "materialise": 218, + "materialise": 162, "phase_materialise": 0, - "answer": 11, - "phase_outcome": 267 + "answer": 104, + "phase_outcome": 299 } }, "rendered_sentence": "2 readings. Kenya's annual amount of emissions: carbon dioxide. Air and GHG emissions · 2013 to 2020. Kenya's annual amount of emissions: carbon dioxide. Air and GHG emissions · 2013 to 2020.", @@ -2580,6 +2588,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -3273,7 +3289,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -3772,7 +3788,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -4359,7 +4375,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "f80a912e90f9426b91d135271778cff7" + "x-dfo-trace-id": "775b92aeffce4d859d3170a45daccd25" }, "json": { "schema_version": 1, @@ -4368,11 +4384,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "f80a912e90f9426b91d135271778cff7", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "775b92aeffce4d859d3170a45daccd25", "warnings": [], "timing_ms": { - "total": 854, + "total": 811, "by_step": { "coverage": 0 } @@ -4385,21 +4401,22 @@ "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 382, + "total": 397, "by_step": { "validate": 0, "walk": 0, - "reread_arcs": 0, + "reread_arcs": 1, "detect_edits": 0, "resolve_survivors": 0, - "shape": 226, - "bind": 1, + "shape": 274, + "bind": 0, "where_places": 0, - "materialise": 152, - "answer": 2, - "options": 1 + "materialise": 121, + "answer": 1, + "options": 0 } }, + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -4915,7 +4932,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -4977,19 +4994,19 @@ } ], "timing_ms": { - "total": 1494, + "total": 1120, "by_step": { "validate": 0, - "walk": 1093, + "walk": 797, "reread_arcs": 2, "detect_edits": 0, "resolve_survivors": 0, "shape": 9, "bind": 0, "where_places": 0, - "materialise": 273, + "materialise": 168, "answer": 8, - "options": 109 + "options": 136 } }, "rendered_sentence": "2 readings. Kenya's annual amount of emissions: carbon dioxide. Air and GHG emissions · 2013 to 2020. Kenya's annual amount of emissions: carbon dioxide. Air and GHG emissions · 2013 to 2020.", @@ -5156,6 +5173,7 @@ "states": [] } ], + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -5827,7 +5845,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -6471,7 +6489,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, diff --git a/python/client-contract/src/dfo_client_contract/scenarios/resubmit-placeholder-without-restatement.json b/python/client-contract/src/dfo_client_contract/scenarios/resubmit-placeholder-without-restatement.json index ba20654..eb14cf3 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/resubmit-placeholder-without-restatement.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/resubmit-placeholder-without-restatement.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:39:49Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:32:06Z" }, "call": [ { @@ -36,7 +36,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "392e75ae92374ca4b32bda343566ed60" + "x-dfo-trace-id": "8419a37e166c4f1c99132fe35dbe31ce" }, "json": { "schema_version": 1, @@ -47,23 +47,23 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "392e75ae92374ca4b32bda343566ed60", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "8419a37e166c4f1c99132fe35dbe31ce", "warnings": [], "timing_ms": { - "total": 2549, + "total": 3120, "by_step": { "coverage": 0, - "extract": 1164, - "cache_lookup": 1 + "extract": 1374, + "cache_lookup": 0 } }, "llm_usage": { "input_tokens": 2241, "output_tokens": 196, "cached_tokens": 843, - "jev_input_tokens": 15830, - "jev_output_tokens": 3276 + "jev_input_tokens": 20184, + "jev_output_tokens": 4309 }, "timed_out": false }, @@ -73,28 +73,28 @@ "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 1381, + "total": 1744, "by_step": { - "recall": 1, + "recall": 2, "phase_resolve_places": 0, "phase_check_entities": 0, - "shape_arcs": 6, - "shape_probe": 223, + "shape_arcs": 3, + "shape_probe": 80, "shape_groups": 5, "shape_labels": 1, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 339, + "shape": 178, "phase_prune_and_rank": 0, - "bind": 125, - "phase_bind": 4, - "phase_settle": 8, - "phase_place_bindings": 25, + "bind": 126, + "phase_bind": 11, + "phase_settle": 7, + "phase_place_bindings": 17, "phase_facet_requests": 0, - "materialise": 14, + "materialise": 26, "phase_materialise": 0, - "answer": 25, - "phase_outcome": 840 + "answer": 30, + "phase_outcome": 1347 } }, "rendered_sentence": "2 readings. Kenya's deaths rate per capita. World Development Indicators · 2013 to 2022. Kenya's number of deaths. Kenya Census · 2018 to 2022.", @@ -286,6 +286,14 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [ + "country/KEN" + ] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -808,7 +816,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2342,7 +2350,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -2367,21 +2375,22 @@ "variable_text": "savings", "warnings": [], "timing_ms": { - "total": 356, + "total": 1383, "by_step": { - "recall": 1, + "recall": 222, "phase_resolve_places": 0, "phase_check_entities": 0, "shape_arcs": 1, - "shape_probe": 110, - "shape_groups": 3, + "shape_probe_coverage": 1, + "shape_probe": 181, + "shape_groups": 41, "shape_labels": 1, "shape_admission": 0, "phase_derive_shapes": 0, - "shape": 264, + "shape": 1000, "phase_prune_and_rank": 0, - "bind": 88, - "phase_bind": 3 + "bind": 103, + "phase_bind": 58 } }, "rendered_sentence": "Could not match \"savings\" to a supported indicator. Try a different wording or a related indicator.", @@ -2394,6 +2403,7 @@ "states": [] } ], + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -2717,7 +2727,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "f61373c01c6c48ac82fb99f413a0f978" + "x-dfo-trace-id": "00de3c0cb919474893de7c4eb875f9be" }, "json": { "schema_version": 1, @@ -2726,11 +2736,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "f61373c01c6c48ac82fb99f413a0f978", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "00de3c0cb919474893de7c4eb875f9be", "warnings": [], "timing_ms": { - "total": 380, + "total": 293, "by_step": { "coverage": 0 } @@ -2743,21 +2753,22 @@ "variable_text": "mortality", "warnings": [], "timing_ms": { - "total": 323, + "total": 242, "by_step": { "validate": 0, "walk": 0, "reread_arcs": 0, "detect_edits": 0, "resolve_survivors": 0, - "shape": 204, + "shape": 149, "bind": 0, - "where_places": 0, - "materialise": 117, - "answer": 2, - "options": 0 + "where_places": 1, + "materialise": 90, + "answer": 1, + "options": 1 } }, + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], @@ -3273,7 +3284,7 @@ "start_year": 2013, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c" + "capability_version": "cap_9deef72763b45f40" }, "confidence": "high", "available_at_place": true, @@ -3340,6 +3351,7 @@ "states": [] } ], + "entity_refs": [], "operations": [], "departures": [], "assumptions": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json b/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json index ddc05c0..54acd79 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-body-not-an-object.json @@ -30,7 +30,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f" + "x-dfo-trace-id": "304fe92b998b45849ff11a547aadc3e8" }, "json": [ { @@ -42,15 +42,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "a321fb82bfba461b9dc922634789650f", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "304fe92b998b45849ff11a547aadc3e8", "warnings": [], "timing_ms": { - "total": 1126, + "total": 1416, "by_step": { "coverage": 0, - "extract": 1119, - "cache_lookup": 1 + "extract": 1297, + "cache_lookup": 0 } }, "llm_usage": { @@ -66,9 +66,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -115,6 +115,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -249,7 +259,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "a321fb82bfba461b9dc922634789650f" + "trace_id": "304fe92b998b45849ff11a547aadc3e8" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json b/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json index e1bbc3c..7763a30 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-place-ambiguous.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:39:11Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:31:27Z" }, "call": [ { @@ -31,7 +31,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f" + "x-dfo-trace-id": "304fe92b998b45849ff11a547aadc3e8" }, "json": { "schema_version": 1, @@ -42,15 +42,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "a321fb82bfba461b9dc922634789650f", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "304fe92b998b45849ff11a547aadc3e8", "warnings": [], "timing_ms": { - "total": 1126, + "total": 1416, "by_step": { "coverage": 0, - "extract": 1119, - "cache_lookup": 1 + "extract": 1297, + "cache_lookup": 0 } }, "llm_usage": { @@ -66,9 +66,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -115,6 +115,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json index cbd9c6c..f930fba 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-rate-limited.json @@ -1,11 +1,11 @@ { "format_version": 1, "name": "search-proxy-rate-limited", - "description": "The proxy's 429 body carries no code or retryable: error is the code and retry \"retry_after_delay\" makes it retryable, so the client waits the Retry-After seconds, retries, and reaches the same answer.", + "description": "The proxy's 429 is a problem document like any other refusal: rate_limited has no row in actions.json, so it is a RateLimitError by its status, and retryable true makes the client wait the Retry-After seconds, retry, and reach the same answer.", "origin": { "kind": "synthetic", "derived_from": "search-place-ambiguous", - "edit": "The website proxy's own 429 {error, retry, detail} with Retry-After 2 answers the first search." + "edit": "The website proxy's own 429 rate_limited problem document with Retry-After 2 answers the first search." }, "call": [ { @@ -29,13 +29,19 @@ "response": { "status": 429, "headers": { - "content-type": "application/json", + "content-type": "application/problem+json", + "cache-control": "no-cache", + "x-dfo-trace-id": "77777777777777777777777777777777", "retry-after": "2" }, "json": { - "error": "rate_limited", - "retry": "retry_after_delay", - "detail": "Too many requests from this address. Try again shortly." + "type": "/codes/rate_limited", + "title": "Too Many Requests", + "status": 429, + "detail": "Too many requests: 120 per window per address. Try again in 2s.", + "code": "rate_limited", + "trace_id": "77777777777777777777777777777777", + "retryable": true } } }, @@ -55,7 +61,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f" + "x-dfo-trace-id": "304fe92b998b45849ff11a547aadc3e8" }, "json": { "schema_version": 1, @@ -66,15 +72,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "a321fb82bfba461b9dc922634789650f", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "304fe92b998b45849ff11a547aadc3e8", "warnings": [], "timing_ms": { - "total": 1126, + "total": 1416, "by_step": { "coverage": 0, - "extract": 1119, - "cache_lookup": 1 + "extract": 1297, + "cache_lookup": 0 } }, "llm_usage": { @@ -90,9 +96,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -139,6 +145,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json index db4e3ad..76ed394 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-proxy-unavailable.json @@ -1,11 +1,11 @@ { "format_version": 1, "name": "search-proxy-unavailable", - "description": "The proxy's 502 body is retryable through its retry member and has no Retry-After, so the client backs off and retries twice, then raises ServerError with the error member, transient_unavailable, as its code.", + "description": "The proxy's 502 problem document says retryable true and has no Retry-After, so the client backs off and retries twice, then raises ServerError, the class of its status, with its code, transient_unavailable, and its trace id.", "origin": { "kind": "synthetic", "derived_from": "search-place-ambiguous", - "edit": "The website proxy's own 502 {error, retry, detail} answers the search and both retries." + "edit": "The website proxy's own 502 transient_unavailable problem document answers the search and both retries." }, "call": [ { @@ -29,12 +29,18 @@ "response": { "status": 502, "headers": { - "content-type": "application/json" + "content-type": "application/problem+json", + "cache-control": "no-cache", + "x-dfo-trace-id": "77777777777777777777777777777777" }, "json": { - "error": "transient_unavailable", - "retry": "retry_after_delay", - "detail": "The Search API is unreachable." + "type": "/codes/transient_unavailable", + "title": "Bad Gateway", + "status": 502, + "detail": "The Search API is unreachable.", + "code": "transient_unavailable", + "trace_id": "77777777777777777777777777777777", + "retryable": true } } }, @@ -53,12 +59,18 @@ "response": { "status": 502, "headers": { - "content-type": "application/json" + "content-type": "application/problem+json", + "cache-control": "no-cache", + "x-dfo-trace-id": "77777777777777777777777777777777" }, "json": { - "error": "transient_unavailable", - "retry": "retry_after_delay", - "detail": "The Search API is unreachable." + "type": "/codes/transient_unavailable", + "title": "Bad Gateway", + "status": 502, + "detail": "The Search API is unreachable.", + "code": "transient_unavailable", + "trace_id": "77777777777777777777777777777777", + "retryable": true } } }, @@ -77,12 +89,18 @@ "response": { "status": 502, "headers": { - "content-type": "application/json" + "content-type": "application/problem+json", + "cache-control": "no-cache", + "x-dfo-trace-id": "77777777777777777777777777777777" }, "json": { - "error": "transient_unavailable", - "retry": "retry_after_delay", - "detail": "The Search API is unreachable." + "type": "/codes/transient_unavailable", + "title": "Bad Gateway", + "status": 502, + "detail": "The Search API is unreachable.", + "code": "transient_unavailable", + "trace_id": "77777777777777777777777777777777", + "retryable": true } } } @@ -92,7 +110,7 @@ "error": { "class": "ServerError", "code": "transient_unavailable", - "trace_id": null, + "trace_id": "77777777777777777777777777777777", "retry_waits": [ 0.5, 1.0 diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json b/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json index 97da3dc..9603c79 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-retry-after-503.json @@ -60,7 +60,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f" + "x-dfo-trace-id": "304fe92b998b45849ff11a547aadc3e8" }, "json": { "schema_version": 1, @@ -71,15 +71,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "a321fb82bfba461b9dc922634789650f", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "304fe92b998b45849ff11a547aadc3e8", "warnings": [], "timing_ms": { - "total": 1126, + "total": 1416, "by_step": { "coverage": 0, - "extract": 1119, - "cache_lookup": 1 + "extract": 1297, + "cache_lookup": 0 } }, "llm_usage": { @@ -95,9 +95,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -144,6 +144,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-server-warning.json b/python/client-contract/src/dfo_client_contract/scenarios/search-server-warning.json index b540d6f..6424a89 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-server-warning.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-server-warning.json @@ -38,7 +38,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f", + "x-dfo-trace-id": "304fe92b998b45849ff11a547aadc3e8", "x-dfo-warning": "Search runs on a reduced index while it is rebuilt." }, "json": { @@ -50,15 +50,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "a321fb82bfba461b9dc922634789650f", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "304fe92b998b45849ff11a547aadc3e8", "warnings": [], "timing_ms": { - "total": 1126, + "total": 1416, "by_step": { "coverage": 0, - "extract": 1119, - "cache_lookup": 1 + "extract": 1297, + "cache_lookup": 0 } }, "llm_usage": { @@ -74,9 +74,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -123,6 +123,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -266,7 +276,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f", + "x-dfo-trace-id": "304fe92b998b45849ff11a547aadc3e8", "x-dfo-warning": "Search runs on a reduced index while it is rebuilt.", "sunset": "Sat, 01 May 2027 00:00:00 GMT" }, @@ -279,15 +289,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "a321fb82bfba461b9dc922634789650f", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "304fe92b998b45849ff11a547aadc3e8", "warnings": [], "timing_ms": { - "total": 1126, + "total": 1416, "by_step": { "coverage": 0, - "extract": 1119, - "cache_lookup": 1 + "extract": 1297, + "cache_lookup": 0 } }, "llm_usage": { @@ -303,9 +313,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -352,6 +362,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -495,7 +515,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f", + "x-dfo-trace-id": "304fe92b998b45849ff11a547aadc3e8", "x-dfo-warning": "Search answers from a cached release.", "deprecation": "@1777593600", "sunset": "Sat, 01 May 2027 00:00:00 GMT" @@ -509,15 +529,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "a321fb82bfba461b9dc922634789650f", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "304fe92b998b45849ff11a547aadc3e8", "warnings": [], "timing_ms": { - "total": 1126, + "total": 1416, "by_step": { "coverage": 0, - "extract": 1119, - "cache_lookup": 1 + "extract": 1297, + "cache_lookup": 0 } }, "llm_usage": { @@ -533,9 +553,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -582,6 +602,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-sunset-warning.json b/python/client-contract/src/dfo_client_contract/scenarios/search-sunset-warning.json index f3915bc..8c3b97e 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-sunset-warning.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-sunset-warning.json @@ -34,7 +34,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f", + "x-dfo-trace-id": "304fe92b998b45849ff11a547aadc3e8", "sunset": "Sat, 01 May 2027 00:00:00 GMT" }, "json": { @@ -46,15 +46,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "a321fb82bfba461b9dc922634789650f", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "304fe92b998b45849ff11a547aadc3e8", "warnings": [], "timing_ms": { - "total": 1126, + "total": 1416, "by_step": { "coverage": 0, - "extract": 1119, - "cache_lookup": 1 + "extract": 1297, + "cache_lookup": 0 } }, "llm_usage": { @@ -70,9 +70,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -119,6 +119,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -262,7 +272,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "a321fb82bfba461b9dc922634789650f", + "x-dfo-trace-id": "304fe92b998b45849ff11a547aadc3e8", "sunset": "Sat, 01 May 2027 00:00:00 GMT" }, "json": { @@ -274,15 +284,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "a321fb82bfba461b9dc922634789650f", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "304fe92b998b45849ff11a547aadc3e8", "warnings": [], "timing_ms": { - "total": 1126, + "total": 1416, "by_step": { "coverage": 0, - "extract": 1119, - "cache_lookup": 1 + "extract": 1297, + "cache_lookup": 0 } }, "llm_usage": { @@ -298,9 +308,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 1, + "total": 115, "by_step": { - "recall": 1, + "recall": 115, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -347,6 +357,16 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json b/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json index 329f75d..36a4e81 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-two-parts-place-ambiguous.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:39:12Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:31:28Z" }, "call": [ { @@ -31,7 +31,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "88156a0c48754c7fb0d5c5a544daed09" + "x-dfo-trace-id": "4b576ea3cd364ddeb664b3b219dffb19" }, "json": { "schema_version": 1, @@ -42,14 +42,14 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "88156a0c48754c7fb0d5c5a544daed09", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "4b576ea3cd364ddeb664b3b219dffb19", "warnings": [], "timing_ms": { - "total": 1686, + "total": 1260, "by_step": { "coverage": 0, - "extract": 1680, + "extract": 1255, "cache_lookup": 0 } }, @@ -118,6 +118,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [] + }, + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], @@ -223,9 +237,9 @@ "variable_text": "ODA disbursements", "warnings": [], "timing_ms": { - "total": 2, + "total": 1, "by_step": { - "recall": 2, + "recall": 1, "phase_resolve_places": 0, "phase_check_entities": 0 } @@ -275,6 +289,20 @@ "sources": [], "operations": [] }, + "entity_refs": [ + { + "text": "Kenya", + "refs": [] + }, + { + "text": "Germany", + "refs": [] + }, + { + "text": "Congo", + "refs": [] + } + ], "operations": [], "departures": [], "assumptions": [], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json b/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json index f32ec45..e612f0d 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/search-warning-top5.json @@ -5,8 +5,8 @@ "origin": { "kind": "recorded", "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", - "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "recorded_at": "2026-10-23T18:39:17Z" + "dfo_commit": "0ba344270784ae9929a369da8acd00b399dfced8", + "recorded_at": "2026-10-24T16:31:33Z" }, "call": [ { @@ -38,7 +38,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "9574dd6f16974328a119e8d83e6e7818" + "x-dfo-trace-id": "50172d3089cd486e929895f6865985bb" }, "json": { "schema_version": 1, @@ -49,15 +49,15 @@ "extract_skipped": false }, "diagnostics": { - "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", - "trace_id": "9574dd6f16974328a119e8d83e6e7818", + "engine_build": "0ba344270784ae9929a369da8acd00b399dfced8", + "trace_id": "50172d3089cd486e929895f6865985bb", "warnings": [], "timing_ms": { - "total": 2030, + "total": 1979, "by_step": { "coverage": 0, - "extract": 1077, - "cache_lookup": 0 + "extract": 1147, + "cache_lookup": 1 } }, "llm_usage": { @@ -97,30 +97,30 @@ } ], "timing_ms": { - "total": 947, + "total": 829, "by_step": { - "recall": 391, + "recall": 300, "phase_resolve_places": 0, "phase_check_entities": 0, "shape_arcs": 3, "shape_probe_coverage": 5, - "shape_probe": 154, + "shape_probe": 152, "shape_groups": 4, "shape_labels": 0, "shape_admission": 1, "phase_derive_shapes": 0, - "shape": 309, + "shape": 264, "phase_prune_and_rank": 0, - "bind": 112, + "bind": 97, "phase_bind": 14, - "phase_settle": 7, + "phase_settle": 9, "phase_place_bindings": 1, "phase_facet_requests": 0, - "materialise": 31, + "materialise": 34, "phase_materialise": 0, - "answer": 14, - "options": 8, - "phase_outcome": 60 + "answer": 16, + "options": 36, + "phase_outcome": 58 } }, "restatement": { @@ -141,6 +141,14 @@ } ] }, + "entity_refs": [ + { + "text": "Ethiopia", + "refs": [ + "country/ETH" + ] + } + ], "operations": [ { "verb": "rank", @@ -525,7 +533,7 @@ "label": "OECD Terms and Conditions" } }, - "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "facets": { "provenance": { "basis": "fallback", @@ -674,7 +682,7 @@ "source": "observed" } ], - "rendered_sentence": "Gross disbursements to Ethiopia from 137 providers for official development assistance in 2022. Current US dollars · OECD DAC2a.", + "rendered_sentence": "Gross disbursements to Ethiopia from 110 providers for official development assistance in 2022. Current US dollars · OECD DAC2a.", "sentence_plan": [ { "kind": "slot", @@ -719,7 +727,7 @@ }, { "kind": "slot", - "text": "137 providers", + "text": "110 providers", "segment": "heading", "role": "origin", "binding_ref": "origin:", @@ -974,7 +982,7 @@ "start_year": 2022, "end_year": 2022 }, - "capability_version": "cap_94e25737d859392c", + "capability_version": "cap_9deef72763b45f40", "default_reading": { "applied": true, "removed_stat_vars": [] @@ -1128,7 +1136,7 @@ "role_axis_facts": [ { "role": "origin", - "member_count": 137, + "member_count": 110, "members_available": true } ], @@ -3083,7 +3091,7 @@ } } ], - "rendered_sentence": "Gross disbursements to Ethiopia from 137 providers for official development assistance in 2022. Current US dollars · OECD DAC2a. You asked for a ranking. This shows the amounts behind it, because Search does not compute rankings. Assumed: official development assistance.", + "rendered_sentence": "Gross disbursements to Ethiopia from 110 providers for official development assistance in 2022. Current US dollars · OECD DAC2a. You asked for a ranking. This shows the amounts behind it, because Search does not compute rankings. Assumed: official development assistance.", "sentence_plan": [ { "kind": "slot", @@ -3132,7 +3140,7 @@ }, { "kind": "slot", - "text": "137 providers", + "text": "110 providers", "segment": "heading", "role": "origin", "binding_ref": "origin:", @@ -3393,7 +3401,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "204cdb090cb6492b829defbe74a5dfbf" + "x-dfo-trace-id": "66eb538f1f7943f8a03a5c3500185e5a" }, "json": { "schema_version": 1, @@ -3636,7 +3644,7 @@ "frame_grammar_version": "1.1.0", "origin_catalogue_build_id": "20261019T174519Z-2e5e8cfd", "served_from": "head", - "confirmed_at": "2026-10-23T18:39:20.385608+00:00" + "confirmed_at": "2026-10-24T16:31:36.102594+00:00" }, "warnings": [], "diagnostics": [ @@ -3659,7 +3667,7 @@ "created_at": "2026-10-23T16:59:51.176407+00:00", "tier": "working", "url": "/api/datasets/spec_7778beed72f8433bb7fde4293acfd175/cv_534dd4c2bf9bdafc837d51a3ba4bcf3e/files/sha256:f0ac1a058c4addb59b1974b73706b12ddc112b409aac006d6a561279f61f0c6a", - "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + "enrichment_stamp": "08ed6c734fc69ea2204a21f4e1dd8b963f14dd1e03a2484c618049ac2e2d93d8" }, { "artifact_digest": "sha256:5b508be6b46ce8e01315f9c89a1837e17ed7b49d7d2554011cfdba9f32203084", @@ -4029,7 +4037,7 @@ ] } }, - "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", + "series_coverage_stamp": "45bdd65f2fd33ac77a897180047080d33ed9db812afe0cbb887bf22e2ac52690", "retention": { "pinned": false, "held_until": "2026-11-19T16:52:44.112184Z" @@ -4047,7 +4055,7 @@ "headers": { "content-type": "text/html", "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3Af0ac1a058c4addb59b1974b73706b12ddc112b409aac006d6a561279f61f0c6a?X-Goog-Signature=redacted", - "x-dfo-trace-id": "6ea497e67fff4becbcee2656441d0dac" + "x-dfo-trace-id": "cf517ecd99ac4157ab7d54003b5771a5" } } }, @@ -4070,7 +4078,7 @@ "answer": { "kind": "resolution", "status": "definite", - "sentence": "Gross disbursements to Ethiopia from 137 providers for official development assistance in 2022. Current US dollars · OECD DAC2a. You asked for a ranking. This shows the amounts behind it, because Search does not compute rankings. Assumed: official development assistance.", + "sentence": "Gross disbursements to Ethiopia from 110 providers for official development assistance in 2022. Current US dollars · OECD DAC2a. You asked for a ranking. This shows the amounts behind it, because Search does not compute rankings. Assumed: official development assistance.", "complete": true, "specs": [ "spec_7778beed72f8433bb7fde4293acfd175" @@ -4082,7 +4090,7 @@ "error": { "class": "SearchWarning", "code": null, - "trace_id": "9574dd6f16974328a119e8d83e6e7818" + "trace_id": "50172d3089cd486e929895f6865985bb" } }, { @@ -4118,7 +4126,7 @@ ], "spec_id": "spec_7778beed72f8433bb7fde4293acfd175", "content_version": "cv_534dd4c2bf9bdafc837d51a3ba4bcf3e", - "sentence": "Gross disbursements to Ethiopia from 137 providers for official development assistance in 2022. Current US dollars · OECD DAC2a." + "sentence": "Gross disbursements to Ethiopia from 110 providers for official development assistance in 2022. Current US dollars · OECD DAC2a." } ], "missing": [], diff --git a/python/client-contract/src/dfo_client_contract/served/SOURCE.json b/python/client-contract/src/dfo_client_contract/served/SOURCE.json index 8aa6966..4e6aeef 100644 --- a/python/client-contract/src/dfo_client_contract/served/SOURCE.json +++ b/python/client-contract/src/dfo_client_contract/served/SOURCE.json @@ -1,6 +1,6 @@ { "format_version": 1, "repository": "DevelopmentFinanceObservatory/apis", - "commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "commit": "0ba344270784ae9929a369da8acd00b399dfced8", "captured_from": "dfo_apis.app.create_app() in process" } diff --git a/python/client-contract/src/dfo_client_contract/served/openapi.json b/python/client-contract/src/dfo_client_contract/served/openapi.json index c7112d7..e3ca7a2 100644 --- a/python/client-contract/src/dfo_client_contract/served/openapi.json +++ b/python/client-contract/src/dfo_client_contract/served/openapi.json @@ -1756,7 +1756,7 @@ "Datasets" ], "summary": "Post Pin", - "description": "Pin an artifact of a version, and the frame its files render from: the version's own frame and, for a derived version, its base version's frame, servable or aged, so every format stays fetchable and the version reports `retention.pinned`. A frame whose bytes are gone stays unpinned: the named artifact still pins, and `retention` keeps that frame's `held_until`. Only the named artifact's copy waits on the daily pin budget; the frame copies skip it and count toward later calls, so one pin can add up to three copies to the count.", + "description": "Pin an artifact of a version, and the first frame its files can render from that survives, servable or aged: the version's own frame, else, for a derived version, its base version's frame. Every format then stays fetchable and the version reports `retention.pinned`. When no such frame's bytes survive, the named artifact still pins, and `retention` keeps the frames' `held_until`. Only the named artifact's copy waits on the daily pin budget; the frame copy skips it and counts toward later calls, so one pin can add up to two copies to the count.", "operationId": "datasets_post_pin", "parameters": [ { @@ -4295,6 +4295,14 @@ ], "description": "the ParsedPart that reproduces this part's own resolution inputs -- the same entities, resolved time window, unit text, and source text the engine actually used to resolve this one leg -- so a client holding this part alone can copy it straight into a fresh ParsedInput.parts entry and re-resolve it faithfully, without flattening it into the whole query's variable_text the way variable_text alone would. Canonical, not verbatim: for a raw_text part, time_text is the equivalent phrase this door's own time grammar recognises (e.g. '2015 to 2020'), not the user's original words, since the engine's date extraction keeps only the structured window and discards the phrasing. Null whenever this part has no faithful echo to give. On a dataset_resubmit entry's identity/candidates/placeholder kinds, which post an identity or stub rather than a phrase and have no per-part resolution inputs to echo -- a dataset_resubmit parsed entry, genuinely re-resolved from its own posted ParsedPart, carries a real one like any parsed-door part. Also null when this leg's entity was bound to a directional role axis (origin/destination) and no door-supplied role named that axis, since an echo without the axis would resubmit the request with that entity reversed. Also null when one of this leg's own inputs does not fit ParsedPart's own field caps, since a truncated echo would misrepresent what was actually resolved." }, + "entity_refs": { + "items": { + "$ref": "#/components/schemas/EntityRefs" + }, + "type": "array", + "title": "Entity Refs", + "description": "the binding of each entity text of `restatement`, once per text in restatement order, so a client can tell which node a text such as 'G7' bound. A response field kept off `restatement`, which posts back unchanged. The binding is the one the answer reads: for a candidates part, the elected reading's; for a part folded into an earlier part's spec, its own. [] when `restatement` is null or names no entity" + }, "operations": { "items": { "$ref": "#/components/schemas/Operation" @@ -7267,6 +7275,14 @@ ], "description": "the ParsedPart that reproduces this part's own resolution inputs -- the same entities, resolved time window, unit text, and source text the engine actually used to resolve this one leg -- so a client holding this part alone can copy it straight into a fresh ParsedInput.parts entry and re-resolve it faithfully, without flattening it into the whole query's variable_text the way variable_text alone would. Canonical, not verbatim: for a raw_text part, time_text is the equivalent phrase this door's own time grammar recognises (e.g. '2015 to 2020'), not the user's original words, since the engine's date extraction keeps only the structured window and discards the phrasing. Null whenever this part has no faithful echo to give. On a dataset_resubmit entry's identity/candidates/placeholder kinds, which post an identity or stub rather than a phrase and have no per-part resolution inputs to echo -- a dataset_resubmit parsed entry, genuinely re-resolved from its own posted ParsedPart, carries a real one like any parsed-door part. Also null when this leg's entity was bound to a directional role axis (origin/destination) and no door-supplied role named that axis, since an echo without the axis would resubmit the request with that entity reversed. Also null when one of this leg's own inputs does not fit ParsedPart's own field caps, since a truncated echo would misrepresent what was actually resolved." }, + "entity_refs": { + "items": { + "$ref": "#/components/schemas/EntityRefs" + }, + "type": "array", + "title": "Entity Refs", + "description": "the binding of each entity text of `restatement`, once per text in restatement order, so a client can tell which node a text such as 'G7' bound. A response field kept off `restatement`, which posts back unchanged. The binding is the one the answer reads: for a candidates part, the elected reading's; for a part folded into an earlier part's spec, its own. [] when `restatement` is null or names no entity" + }, "operations": { "items": { "$ref": "#/components/schemas/Operation" @@ -7441,7 +7457,7 @@ "scope_limited" ], "title": "Code", - "description": "what kind of departure this is. 'closest_match': the answer shows the nearest measure the graph holds, not the one asked; a client draws a muted 'Closest match:' lead before the heading, and on a candidates part, whose readings stand in for a measure with no data, once before the first reading. 'measure_not_applied': a named measure qualifier was not applied. 'operation_not_applied': an operation the request named (a share, a ranking) was not run, so the amounts behind it are shown. 'breakdown_not_applied': a breakdown the request named was not applied, so the total is shown. 'entity_unavailable': an entity the request named holds no values in the series the answer reads, one departure per role; for a role the request named as a group, asked is the request's words for the group and the text counts the members without values; the text names any source holding values there that Search does not read. 'year_unavailable': a named year or range falls outside the years served. 'modelled_values': the served values are modelled or estimated. 'group_read_as_members': a named group was read as its member entities; on a flow role the text names the amounts the group's published total counts that no member holds, and, for a group whose published total is not its members' sum, says the source publishes its own figure for the group. 'whole_total_read': a flow side is read as its whole population, the total its source publishes for every party of that side (official donors (DAC) for 'official donors' or a donor side the request named nothing on or summed over; official and private donors (DAC) for 'all donors'); the text says what the total holds and how to list the side's members with open_roles. 'whole_total_unpublished': the request named a whole population ('all donors', 'all recipients') on a side whose dataset publishes no total of it and holds no party outside it, so the side is left unnamed and the answer covers every party the dataset holds there; asked is the request's words, and the text names the dataset. 'direction_discarded': a flow direction the request's own words named was not applied. 'direction_inferred': a place the request named without a direction is read on the one direction that holds data, which over names. 'scope_limited': a no_data answer's check covered only values the engine chose, which the request did not name; its text names only what the check covered ('This check covered only ODA.')" + "description": "what kind of departure this is. 'closest_match': the answer shows the nearest measure the graph holds, not the one asked; a client draws a muted 'Closest match:' lead before the heading, and on a candidates part, whose readings stand in for a measure with no data, once before the first reading. 'measure_not_applied': a named measure qualifier was not applied. 'operation_not_applied': an operation the request named (a share, a ranking) was not run, so the amounts behind it are shown. 'breakdown_not_applied': a breakdown the request named was not applied, so the total is shown. 'entity_unavailable': an entity the request named holds no values in the series the answer reads, one departure per role; for a role the request named as a group, asked is the request's words for the group and the text counts the members without values; the text names any source holding values there that Search does not read. 'year_unavailable': a named year or range falls outside the years served. 'modelled_values': the served values are modelled or estimated. 'group_read_as_members': a named group was read as its member entities; on a flow role the text names the amounts the group's published total counts that no member holds, and, for a group whose published total is not its members' sum, says the source publishes its own figure for the group. 'whole_total_read': a flow side is read as its whole population, the total its source publishes for every party of that side (official donors (DAC) for 'official donors' or a donor side the request named nothing on or summed over; official and private donors (DAC) for 'all donors'); the text says what the total holds and how to list the side's members: in the question's words ('by donor') on the raw_text door, with open_roles on the others. 'whole_total_unpublished': the request named a whole population ('all donors', 'all recipients') on a side whose dataset publishes no total of it and holds no party outside it, so the side is left unnamed and the answer covers every party the dataset holds there; asked is the request's words, and the text names the dataset. 'direction_discarded': a flow direction the request's own words named was not applied. 'direction_inferred': a place the request named without a direction is read on the one direction that holds data, which over names. 'scope_limited': a no_data answer's check covered only values the engine chose, which the request did not name; its text names only what the check covered ('This check covered only ODA.')" }, "binding_ref": { "anyOf": [ @@ -8223,6 +8239,31 @@ "title": "GraphResolveEntity", "description": "A reference with its kind. `kind` is `null` only for a `not_held` entity, which the\ngraph holds no node to classify." }, + "EntityRefs": { + "properties": { + "text": { + "type": "string", + "title": "Text", + "description": "the entity text, equal to some restatement.entities[i].text" + }, + "refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Refs", + "description": "the refs the part's answer binds for `text`: a place gives its node; a group, continent or subregion bound as itself gives its own node, or the total its dataset publishes for it (G7 bound as GroupOfSeven); one bound as its members gives the set's own ref first (its node, else that total, else its registry id) and then the members, sorted. [] for an ambiguous text, one that resolved to no node or a node the answer does not bind, and every text of a part refused before its places were bound" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "refs" + ], + "title": "EntityRefs", + "description": "The graph nodes one entity text of a part's restatement binds in the answer." + }, "Exclusion": { "properties": { "ref": { @@ -10522,10 +10563,11 @@ "facet_not_available", "role_incompatible", "role_signature_incompatible", - "qualifier_not_bound" + "qualifier_not_bound", + "timed_out" ], "title": "Reason", - "description": "why nothing could be returned, in contract resolution order. \"entity_not_resolved\" means a named entity could not be resolved to a graph node; \"entity_ambiguous\" means a named entity matched more than one graph candidate and none could be preferred over the others, distinct from \"entity_not_resolved\", where no node matched at all; \"entity_role_not_admitted\" means a named entity resolved to exactly one graph node, but no role any candidate shape declares admits that node's graph type -- the entity is real, just not the kind of thing this query's data is reported for; \"entity_set_too_large\" means every named entity resolved, but the places the request names, counting the members of each group or region among them and summed over the roles they sit on, exceed what the engine binds in one request -- distinct from every other entity_* reason, where one entity, not the size of the set, is what failed; \"variable_not_resolved\" means no StatVar matched the variable text (e.g. an absent posted stat_var_dcid or entity, or no measure match at all); \"role_not_resolved\" means the query names a role the engine could not resolve; \"unit_not_resolved\" means the unit binder could not classify a token in the requested unit phrase against its lexicons; \"no_matching_slice\" means the measure matched fine, but the requested combination has no corresponding data series -- the constructed/derived variable does not exist in the graph at all. Covers an identity resubmit refine edit with no confirmable sibling StatVar for the edited slice, and a dev-finance scheme x purpose x recipient combination that was never published as a series, on raw-text and resubmit alike; \"binding_mismatch\" means the variable resolved and graph-confirmed StatVars exist, but none satisfies the requested slot bindings, either because a resolved value on a bound property mismatched or because the StatVar's value on a bound property is present but could not be read (an unresolvable dcid); distinct from \"no_matching_slice\" (the combination was never published at all) and \"variable_not_resolved\" (no StatVar matched at all); \"denominator_not_available\" means the query asks for a normalised form (per person, per area, a rate or a share) or names a denominator, and the matched series is not in that form or divides by another base; \"no_observations\" means a StatVar WAS confirmed to exist but has no observation at the resolved entity (it exists, but not data here); \"facet_not_available\" means observations exist at the entity, none under the requested facet values; \"role_incompatible\" means the role is real, and the StatVar does not declare it; \"role_signature_incompatible\" means the resolved StatVars carry incompatible role signatures and no partition into candidates was possible; \"source_code_not_held\" means no variable held under the part's source_code by a source search serves can answer the part: no served source holds the code, the part's sources exclude every source that does, or the code's variables cannot answer the part as asked; \"source_code_ambiguous\" means two of the part's sources hold its source_code; \"source_code_shares_variable\" means the source_code's variables answer other codes of its source too, so search cannot serve the code alone; \"qualifier_not_bound\" means the variable resolved to a series family, but a narrowing term the request's text named bound no constraint slot: no code system in the packaged index carries it, or its registered rows landed in no binding" + "description": "why nothing could be returned, in contract resolution order. \"entity_not_resolved\" means a named entity could not be resolved to a graph node; \"entity_ambiguous\" means a named entity matched more than one graph candidate and none could be preferred over the others, distinct from \"entity_not_resolved\", where no node matched at all; \"entity_role_not_admitted\" means a named entity resolved to exactly one graph node, but no role any candidate shape declares admits that node's graph type -- the entity is real, just not the kind of thing this query's data is reported for; \"entity_set_too_large\" means every named entity resolved, but the places the request names, counting the members of each group or region among them and summed over the roles they sit on, exceed what the engine binds in one request -- distinct from every other entity_* reason, where one entity, not the size of the set, is what failed; \"variable_not_resolved\" means no StatVar matched the variable text (e.g. an absent posted stat_var_dcid or entity, or no measure match at all); \"role_not_resolved\" means the query names a role the engine could not resolve; \"unit_not_resolved\" means the unit binder could not classify a token in the requested unit phrase against its lexicons; \"no_matching_slice\" means the measure matched fine, but the requested combination has no corresponding data series -- the constructed/derived variable does not exist in the graph at all. Covers an identity resubmit refine edit with no confirmable sibling StatVar for the edited slice, and a dev-finance scheme x purpose x recipient combination that was never published as a series, on raw-text and resubmit alike; \"binding_mismatch\" means the variable resolved and graph-confirmed StatVars exist, but none satisfies the requested slot bindings, either because a resolved value on a bound property mismatched or because the StatVar's value on a bound property is present but could not be read (an unresolvable dcid); distinct from \"no_matching_slice\" (the combination was never published at all) and \"variable_not_resolved\" (no StatVar matched at all); \"denominator_not_available\" means the query asks for a normalised form (per person, per area, a rate or a share) or names a denominator, and the matched series is not in that form or divides by another base; \"no_observations\" means a StatVar WAS confirmed to exist but has no observation at the resolved entity (it exists, but not data here); \"facet_not_available\" means observations exist at the entity, none under the requested facet values; \"role_incompatible\" means the role is real, and the StatVar does not declare it; \"role_signature_incompatible\" means the resolved StatVars carry incompatible role signatures and no partition into candidates was possible; \"source_code_not_held\" means no variable held under the part's source_code by a source search serves can answer the part: no served source holds the code, the part's sources exclude every source that does, or the code's variables cannot answer the part as asked; \"source_code_ambiguous\" means two of the part's sources hold its source_code; \"source_code_shares_variable\" means the source_code's variables answer other codes of its source too, so search cannot serve the code alone; \"qualifier_not_bound\" means the variable resolved to a series family, but a narrowing term the request's text named bound no constraint slot: no code system in the packaged index carries it, or its registered rows landed in no binding; \"timed_out\" means the request reached its time limit before this part was answered (diagnostics.timed_out is true); the question may hold data, so asking it again, alone or narrower, can answer it" }, "cause": { "anyOf": [ @@ -10545,7 +10587,7 @@ "absent" ], "title": "Category", - "description": "derived from reason, never independently settable: \"entity_not_resolved\", \"entity_ambiguous\", \"entity_set_too_large\", \"entity_role_not_admitted\", \"variable_not_resolved\", \"role_not_resolved\", \"source_not_resolved\", \"source_ambiguous\", \"source_code_not_held\", \"source_code_ambiguous\", \"source_code_shares_variable\", and \"unit_not_resolved\" are \"unresolved\" (the request could not be read into the graph); every other code is \"absent\" (the read request names a place holding nothing)", + "description": "derived from reason, never independently settable: \"entity_not_resolved\", \"entity_ambiguous\", \"entity_set_too_large\", \"entity_role_not_admitted\", \"variable_not_resolved\", \"role_not_resolved\", \"source_not_resolved\", \"source_ambiguous\", \"source_code_not_held\", \"source_code_ambiguous\", \"source_code_shares_variable\", \"unit_not_resolved\", and \"timed_out\" are \"unresolved\" (the request could not be read into the graph); every other code is \"absent\" (the read request names a place holding nothing)", "default": "absent" }, "message": { @@ -10846,6 +10888,14 @@ ], "description": "the ParsedPart that reproduces this part's own resolution inputs -- the same entities, resolved time window, unit text, and source text the engine actually used to resolve this one leg -- so a client holding this part alone can copy it straight into a fresh ParsedInput.parts entry and re-resolve it faithfully, without flattening it into the whole query's variable_text the way variable_text alone would. Canonical, not verbatim: for a raw_text part, time_text is the equivalent phrase this door's own time grammar recognises (e.g. '2015 to 2020'), not the user's original words, since the engine's date extraction keeps only the structured window and discards the phrasing. Null whenever this part has no faithful echo to give. On a dataset_resubmit entry's identity/candidates/placeholder kinds, which post an identity or stub rather than a phrase and have no per-part resolution inputs to echo -- a dataset_resubmit parsed entry, genuinely re-resolved from its own posted ParsedPart, carries a real one like any parsed-door part. Also null when this leg's entity was bound to a directional role axis (origin/destination) and no door-supplied role named that axis, since an echo without the axis would resubmit the request with that entity reversed. Also null when one of this leg's own inputs does not fit ParsedPart's own field caps, since a truncated echo would misrepresent what was actually resolved." }, + "entity_refs": { + "items": { + "$ref": "#/components/schemas/EntityRefs" + }, + "type": "array", + "title": "Entity Refs", + "description": "the binding of each entity text of `restatement`, once per text in restatement order, so a client can tell which node a text such as 'G7' bound. A response field kept off `restatement`, which posts back unchanged. The binding is the one the answer reads: for a candidates part, the elected reading's; for a part folded into an earlier part's spec, its own. [] when `restatement` is null or names no entity" + }, "operations": { "items": { "$ref": "#/components/schemas/Operation" @@ -15233,7 +15283,8 @@ "facet_not_available", "role_incompatible", "role_signature_incompatible", - "qualifier_not_bound" + "qualifier_not_bound", + "timed_out" ] }, { @@ -18845,6 +18896,14 @@ ], "description": "the ParsedPart that reproduces this part's own resolution inputs -- the same entities, resolved time window, unit text, and source text the engine actually used to resolve this one leg -- so a client holding this part alone can copy it straight into a fresh ParsedInput.parts entry and re-resolve it faithfully, without flattening it into the whole query's variable_text the way variable_text alone would. Canonical, not verbatim: for a raw_text part, time_text is the equivalent phrase this door's own time grammar recognises (e.g. '2015 to 2020'), not the user's original words, since the engine's date extraction keeps only the structured window and discards the phrasing. Null whenever this part has no faithful echo to give. On a dataset_resubmit entry's identity/candidates/placeholder kinds, which post an identity or stub rather than a phrase and have no per-part resolution inputs to echo -- a dataset_resubmit parsed entry, genuinely re-resolved from its own posted ParsedPart, carries a real one like any parsed-door part. Also null when this leg's entity was bound to a directional role axis (origin/destination) and no door-supplied role named that axis, since an echo without the axis would resubmit the request with that entity reversed. Also null when one of this leg's own inputs does not fit ParsedPart's own field caps, since a truncated echo would misrepresent what was actually resolved." }, + "entity_refs": { + "items": { + "$ref": "#/components/schemas/EntityRefs" + }, + "type": "array", + "title": "Entity Refs", + "description": "the binding of each entity text of `restatement`, once per text in restatement order, so a client can tell which node a text such as 'G7' bound. A response field kept off `restatement`, which posts back unchanged. The binding is the one the answer reads: for a candidates part, the elected reading's; for a part folded into an earlier part's spec, its own. [] when `restatement` is null or names no entity" + }, "operations": { "items": { "$ref": "#/components/schemas/Operation" diff --git a/tools/README.md b/tools/README.md index 6fe2b93..6e4fb59 100644 --- a/tools/README.md +++ b/tools/README.md @@ -38,7 +38,7 @@ uv run tools/validate_provenance_docs_vectors.py uv run tools/validate_descriptions_vectors.py ``` -`validate_client_contract.py` validates the client contract under `python/client-contract/src/dfo_client_contract/` against its schemas, then checks what they cannot express: every `strict-fields.json` pointer resolves in `served/openapi.json` and stays required and non-nullable, or keeps its enum values; `actions.json` holds one row, in code order, for each active refusal code in `registries/codes.json` that reaches a problem document or a no_data reason, with a gap kind exactly for the no_data reasons; `client-codes.json` lists each code a client raises itself once, in code order, none of them a code in `actions.json` or the registry, each with a class a scenario names and a retryable flag; `proxy-codes.json` and `warning-codes.json` list their codes once, in code order, apart from every other table, and the warning codes are those the client rules issue; `served/openapi.json` holds the Search, Datasets, Graph and Presentation surfaces and nothing outside them but the platform's `/codes` route; each recorded scenario's requests match a served route and its JSON bodies validate against that route's schemas, where a required member stays required when it admits null; every problem document in a scenario, synthetic ones and failed operations' errors included, carries an active code registered at its status, and every website proxy body a code `proxy-codes.json` lists at its status; each recorded scenario names `served/SOURCE.json`'s commit; each scenario's `expect` equals the outcomes its steps reach over its exchanges, with refusals' error classes and gap kinds from `actions.json`, each error the client raises itself carrying its code and class from `client-codes.json`, a repeated refused request counted a retry only where the retry rules allow one, a record that stops retrying while a retry remains refused, and the waits before retries and the warnings response headers issue derived; each POST carries its body, each build posts the body its spec, narrowing and layout give, each Search request posts the whole body its steps derive, each poll names the operation the client holds, and each signed download is the URL its redirect names; each body file a record names is a bare file name in `scenarios/` and no symlink; every absolute URL a record holds is a signed URL on the storage host with the redacted query, or a `location` under the base URL; and each `DatasetRef` example gets the verdict it states. It does not import `dfo_client_contract`, whose `tests/test_rules.py` replays the rule vectors. Also a PEP 723 script: +`validate_client_contract.py` validates the client contract under `python/client-contract/src/dfo_client_contract/` against its schemas, then checks what they cannot express: every `strict-fields.json` pointer resolves in `served/openapi.json` and stays required and non-nullable, or keeps its enum values; `actions.json` holds one row, in code order, for each active refusal code in `registries/codes.json` that reaches a problem document or a no_data reason, with a gap kind exactly for the no_data reasons; `client-codes.json` lists each code a client raises itself once, in code order, none of them a code in `actions.json` or the registry, each with a class a scenario names and a retryable flag; `proxy-codes.json` and `warning-codes.json` list their codes once, in code order, apart from every other table, and the warning codes are those the client rules issue; `served/openapi.json` holds the Search, Datasets, Graph and Presentation surfaces and nothing outside them but the platform's `/codes` route; each recorded scenario's requests match a served route and its JSON bodies validate against that route's schemas, where a required member stays required when it admits null; every problem document in a scenario, synthetic ones and failed operations' errors included, carries an active code registered at its status or a code `proxy-codes.json` lists at its status, and one with a proxy code is `application/problem+json` with the common members, its own status and `retryable` true; no 202 in a scenario reads `done`; each recorded scenario names `served/SOURCE.json`'s commit; each scenario's `expect` equals the outcomes its steps reach over its exchanges, with refusals' error classes and gap kinds from `actions.json`, each error the client raises itself carrying its code and class from `client-codes.json`, a repeated refused request counted a retry only where the retry rules allow one, a record that stops retrying while a retry remains refused, and the waits before retries and the warnings response headers issue derived; each POST carries its body, each build posts the body its spec, narrowing and layout give, each Search request posts the whole body its steps derive, each poll names the operation the client holds, and each signed download is the URL its redirect names; each body file a record names is a bare file name in `scenarios/` and no symlink; every absolute URL a record holds is a signed URL on the storage host with the redacted query, or a `location` under the base URL; and each `DatasetRef` example gets the verdict it states. It does not import `dfo_client_contract`, whose `tests/test_rules.py` replays the rule vectors. Also a PEP 723 script: ```bash uv run tools/validate_client_contract.py diff --git a/tools/capture_client_contract.py b/tools/capture_client_contract.py index c7da7e9..b232ab8 100644 --- a/tools/capture_client_contract.py +++ b/tools/capture_client_contract.py @@ -1872,29 +1872,47 @@ def _refusal( body: dict[str, Any], headers: Mapping[str, str] | None = None, ) -> dict[str, Any]: - """An exchange answering `request` with a refusal: a problem document, or - the website proxy's own `{error, retry, detail}` JSON.""" - media = "application/json" if "error" in body else "application/problem+json" + """An exchange answering `request` with the problem document `body`.""" return { "request": copy.deepcopy(request), "response": { "status": status, - "headers": {"content-type": media, **(headers or {})}, + "headers": {"content-type": "application/problem+json", **(headers or {})}, "json": body, }, } -_PROXY_RATE_LIMITED = { - "error": "rate_limited", - "retry": "retry_after_delay", - "detail": "Too many requests from this address. Try again shortly.", -} -_PROXY_UNAVAILABLE = { - "error": "transient_unavailable", - "retry": "retry_after_delay", - "detail": "The Search API is unreachable.", -} +# The trace id of the website proxy's own refusals, which it also sends in +# the x-dfo-trace-id header. +_PROXY_TRACE_ID = "7" * 32 + + +def _proxy_problem(code: str, status: int, title: str, detail: str) -> dict[str, Any]: + """A problem document the website proxy answers itself. It has the common + members with `retryable` true, and no `capability_version`, which only + dfo-apis sends.""" + return { + "type": f"/codes/{code}", + "title": title, + "status": status, + "detail": detail, + "code": code, + "trace_id": _PROXY_TRACE_ID, + "retryable": True, + } + + +_PROXY_HEADERS = {"cache-control": "no-cache", "x-dfo-trace-id": _PROXY_TRACE_ID} +_PROXY_RATE_LIMITED = _proxy_problem( + "rate_limited", + 429, + "Too Many Requests", + "Too many requests: 120 per window per address. Try again in 2s.", +) +_PROXY_UNAVAILABLE = _proxy_problem( + "transient_unavailable", 502, "Bad Gateway", "The Search API is unreachable." +) @dataclass(frozen=True) @@ -1963,7 +1981,10 @@ def _retry_after_503(parent: dict[str, Any], ctx: Context) -> Derived: def _proxy_429(parent: dict[str, Any], ctx: Context) -> Derived: first = parent["exchanges"][0] refused = _refusal( - first["request"], 429, dict(_PROXY_RATE_LIMITED), {"retry-after": "2"} + first["request"], + 429, + dict(_PROXY_RATE_LIMITED), + {**_PROXY_HEADERS, "retry-after": "2"}, ) return _refused_first(parent, 0, refused) @@ -1971,9 +1992,10 @@ def _proxy_429(parent: dict[str, Any], ctx: Context) -> Derived: def _proxy_502(parent: dict[str, Any], ctx: Context) -> Derived: first = parent["exchanges"][0] refused = [ - _refusal(first["request"], 502, dict(_PROXY_UNAVAILABLE)) for _ in range(3) + _refusal(first["request"], 502, dict(_PROXY_UNAVAILABLE), _PROXY_HEADERS) + for _ in range(3) ] - error = refusal_error(502, _PROXY_UNAVAILABLE, ctx.actions).outcome( + error = refusal_error(502, _PROXY_UNAVAILABLE, ctx.actions, _PROXY_HEADERS).outcome( ctx.client_codes ) return Derived( @@ -2371,6 +2393,36 @@ def _poll_rate_limited(exchanges: list[dict[str, Any]], build: dict[str, Any]) - build["poll_waits"].insert(1, 3.0) +def _accepted_running(exchanges: list[dict[str, Any]], build: dict[str, Any]) -> None: + """The 202 reads running where the recording reads pending. The polls and + the outcome are the recording's.""" + exchanges[0]["response"]["json"]["operation"]["status"] = "running" + + +# The retry_after_ms each poll that finds the build running reads in +# fetch-spec-poll-pacing-changes. The values go up, up again, then down. +_CHANGING_PACING_MS = (2500, 4000, 1000) + + +def _pacing_changes(exchanges: list[dict[str, Any]], build: dict[str, Any]) -> None: + """Each poll that finds the build running reads its own retry_after_ms + from _CHANGING_PACING_MS, and the wait before the next poll is that + poll's value.""" + running = [ + e["response"]["json"]["operation"] + for e in exchanges[_poll_index(exchanges) :] + if e["request"].get("path", "").startswith("/datasets/operations/") + and e["response"]["json"]["operation"]["status"] == "running" + ] + require( + len(running) == len(_CHANGING_PACING_MS), + f"{len(_CHANGING_PACING_MS)} polls find the build running", + ) + for operation, ms in zip(running, _CHANGING_PACING_MS, strict=True): + operation["retry_after_ms"] = ms + build["poll_waits"][1:] = [ms / 1000 for ms in _CHANGING_PACING_MS] + + def _operation_failed(exchanges: list[dict[str, Any]], build: dict[str, Any]) -> None: """The first poll answers the operation failed with a retryable operation_failed, and the build is posted again and runs as recorded. The @@ -3415,19 +3467,21 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: Synthetic( "search-proxy-rate-limited", "search-place-ambiguous", - "The website proxy's own 429 {error, retry, detail} with Retry-After 2 answers the first search.", - "The proxy's 429 body carries no code or retryable: error is the code and retry " - '"retry_after_delay" makes it retryable, so the client waits the Retry-After seconds, ' - "retries, and reaches the same answer.", + "The website proxy's own 429 rate_limited problem document with Retry-After 2 answers " + "the first search.", + "The proxy's 429 is a problem document like any other refusal: rate_limited has no " + "row in actions.json, so it is a RateLimitError by its status, and retryable true makes " + "the client wait the Retry-After seconds, retry, and reach the same answer.", _proxy_429, ), Synthetic( "search-proxy-unavailable", "search-place-ambiguous", - "The website proxy's own 502 {error, retry, detail} answers the search and both retries.", - "The proxy's 502 body is retryable through its retry member and has no Retry-After, so " - "the client backs off and retries twice, then raises ServerError with the error member, " - "transient_unavailable, as its code.", + "The website proxy's own 502 transient_unavailable problem document answers the search " + "and both retries.", + "The proxy's 502 problem document says retryable true and has no Retry-After, so the " + "client backs off and retries twice, then raises ServerError, the class of its status, " + "with its code, transient_unavailable, and its trace id.", _proxy_502, ), Synthetic( @@ -3591,6 +3645,25 @@ def _empty_narrowing(parent: dict[str, Any], ctx: Context) -> Derived: "none, and downloads the done manifest's file.", _async_fetch(), ), + Synthetic( + "fetch-spec-accepted-running", + "mint-async-build", + "As fetch-spec-async-build, with the 202 reading running where it read pending.", + "A 202 reads pending or running: the client polls either as an operation still " + "under way, with the same pacing, and downloads the done manifest's file.", + _async_fetch(_accepted_running), + ), + Synthetic( + "fetch-spec-poll-pacing-changes", + "mint-async-build", + "As fetch-spec-async-build, with the polls that find the build running reading " + "retry_after_ms 2500, 4000 and 1000 where the recording reads 1500.", + "Before each poll the client waits the retry_after_ms of the last operation " + "resource it read: 1.5 seconds from the 202, then 2.5, 4 and 1 from the polls. A " + "client that keeps the 202's value, or reads the Retry-After header in its place, " + "waits otherwise.", + _async_fetch(_pacing_changes), + ), Synthetic( "fetch-spec-poll-rate-limited", "mint-async-build", diff --git a/tools/tests/test_validate_client_contract.py b/tools/tests/test_validate_client_contract.py index fd00276..89a9859 100644 --- a/tools/tests/test_validate_client_contract.py +++ b/tools/tests/test_validate_client_contract.py @@ -309,12 +309,37 @@ def _never_retried(doc: Any) -> None: def _proxy_code(code: str) -> Callable[[Any], None]: def change(doc: Any) -> None: for exchange in doc["exchanges"]: - exchange["response"]["json"]["error"] = code + exchange["response"]["json"]["code"] = code doc["expect"][0]["error"]["code"] = code return change +def _proxy_responses(change: Callable[[Any], None]) -> Callable[[Any], None]: + """`change` edits every response of a proxy scenario.""" + + def edit(doc: Any) -> None: + for exchange in doc["exchanges"]: + change(exchange["response"]) + + return edit + + +def _proxy_old_body(doc: Any) -> None: + """The proxy's 502s carry the `{error, retry, detail}` JSON body it sent + before its refusals became problem documents, with no trace id, and the + step expects `error` read as the code. A client reads that body as one + without a code.""" + for exchange in doc["exchanges"]: + exchange["response"]["headers"] = {"content-type": "application/json"} + exchange["response"]["json"] = { + "error": "transient_unavailable", + "retry": "retry_after_delay", + "detail": "The Search API is unreachable.", + } + doc["expect"][0]["error"]["trace_id"] = None + + def _search_posts(change: Callable[[Any], None]) -> Callable[[Any], None]: return lambda doc: change(doc["exchanges"][0]["request"]["json"]) @@ -1173,13 +1198,37 @@ def change(doc: Any) -> None: ( "scenarios/search-proxy-unavailable.json", _proxy_code("made_up_code"), - "proxy code 'made_up_code' is not a code proxy-codes.json lists", + "problem code 'made_up_code' is not in the registry", + ), + ( + "scenarios/search-proxy-unavailable.json", + _proxy_old_body, + "step 0 expects", ), ( "scenarios/search-proxy-unavailable.json", _proxy_code("rate_limited"), "lists with status 502", ), + ( + "scenarios/search-proxy-unavailable.json", + _proxy_responses(lambda response: response["json"].pop("retryable")), + "a proxy problem document is not retryable: true", + ), + ( + "scenarios/search-proxy-rate-limited.json", + _proxy_responses( + lambda response: response["headers"].update( + {"content-type": "application/json"} + ) + ), + "a proxy problem document is not application/problem+json", + ), + ( + "scenarios/fetch-spec-accepted-running.json", + _set_body(0, lambda body: body["operation"].update(status="done")), + "exchange 0: a 202's operation reads done", + ), ( "proxy-codes.json", _add_action({"code": "spec_not_found", "status": 404, "condition": "x"}), @@ -1438,9 +1487,9 @@ def change(doc: Any) -> None: ( "scenarios/search-proxy-unavailable.json", lambda doc: doc["exchanges"][0]["response"]["json"].update( - error=["transient_unavailable"] + code=["transient_unavailable"] ), - "proxy code ['transient_unavailable'] is not a code", + "problem code ['transient_unavailable'] is not in the registry", ), ( _FETCH, @@ -1622,7 +1671,7 @@ def change(doc: Any) -> None: "strict-enum-value-gone", "strict-pointer-repeated", "action-row-missing", - "action-row-timed-out-missing", + "action-row-no-data-reason-missing", "action-row-for-a-warning", "action-row-for-an-unknown-code", "actions-unsorted", @@ -1747,7 +1796,11 @@ def change(doc: Any) -> None: "search-without-schema-version", "step-timeout", "proxy-code-unlisted", + "proxy-old-body-reads-without-code", "proxy-code-wrong-status", + "proxy-problem-without-retryable", + "proxy-problem-in-plain-json", + "accepted-operation-reads-done", "proxy-code-is-a-registry-code", "warning-code-ref-digest-changed-missing", "warning-code-missing", diff --git a/tools/validate_client_contract.py b/tools/validate_client_contract.py index 44ac99f..604ba3b 100644 --- a/tools/validate_client_contract.py +++ b/tools/validate_client_contract.py @@ -35,7 +35,8 @@ - `proxy-codes.json` and `warning-codes.json` list codes in order, each once, none of them a code another table or `registries/codes.json` holds, and the warning codes are those the client rules issue: `ref_digest_changed`, - `route_deprecated`, `server_warning`, and one `key_` per key-format reason. + `route_deprecated`, `server_warning`, and one `key_` per key-format + reason. - Each scenario's file name matches its `name`, names are unique, `expect` holds one outcome per step, a step that acts on an earlier result follows one, a synthetic scenario derives from a recorded one, and every body file @@ -46,8 +47,10 @@ route's schema for its status, a required member included when it admits null, and its `origin.dfo_commit` is `served/SOURCE.json`'s commit. In every scenario a problem document's `code`, a failed operation's error - included, is an active code registered with its status, and the website - proxy's `error` a code `proxy-codes.json` lists with its status. + included, is an active code registered with its status or a code + `proxy-codes.json` lists with its status. A document with a proxy code is + `application/problem+json` and carries PROXY_PROBLEM_MEMBERS, its own + status and `retryable` true, and no 202's operation reads `done`. - Each error a scenario expects, other than a `SearchWarning` or `DataWarning`, carries a refusal's code from its exchanges, a failed operation's included, or a client code of its class. @@ -668,25 +671,23 @@ def _check_problem_code( registry: dict[str, Any], proxy_codes: Mapping[str, Mapping[str, Any]], ) -> list[str]: - """A refusal's code: a problem document's is an active registry code - registered with its status, and the website proxy's `error` is a code - `proxy-codes.json` lists with its status.""" + """A problem document's code: an active registry code registered with its + status, or a code of the website proxy's own refusals that + `proxy-codes.json` lists with its status, in a proxy problem document.""" body = response.get("json") - if response["status"] < 400 or not isinstance(body, dict): + if response["status"] < 400 or not isinstance(body, dict) or "code" not in body: return [] - if "code" not in body: - if "error" not in body: - return [] - error = body["error"] - row = proxy_codes.get(error) if isinstance(error, str) else None - if row is None or row["status"] != response["status"]: + code = body["code"] + proxy_row = proxy_codes.get(code) if isinstance(code, str) else None + if proxy_row is not None: + if proxy_row["status"] != response["status"]: return [ ( - f"{label}: proxy code {body['error']!r} is not a code " + f"{label}: proxy code {code!r} is not a code " f"proxy-codes.json lists with status {response['status']}" ) ] - return [] + return _check_proxy_problem(label, response) for entry in registry["entries"]: if entry["code"] != body["code"]: continue @@ -706,6 +707,43 @@ def _check_problem_code( return [f"{label}: problem code {body['code']!r} is not in the registry"] +def _check_accepted(label: str, response: Mapping[str, Any]) -> list[str]: + """A 202's operation does not read `done`, because a submission that finds a + done operation builds it again.""" + body = response.get("json") + operation = body.get("operation") if isinstance(body, dict) else None + if response["status"] != 202 or not isinstance(operation, dict): + return [] + if operation.get("status") == "done": + return [f"{label}: a 202's operation reads done"] + return [] + + +# The members every problem document the website proxy answers itself carries. +PROXY_PROBLEM_MEMBERS = ("type", "title", "status", "detail", "code", "trace_id") +PROXY_PROBLEM_MEDIA = "application/problem+json" + + +def _check_proxy_problem(label: str, response: Mapping[str, Any]) -> list[str]: + """A proxy problem document is `application/problem+json`, has the common + members, carries the response's status, and has `retryable` true.""" + body = response["json"] + problems = [] + content_type = response.get("headers", {}).get("content-type", "") + if content_type.split(";", maxsplit=1)[0].strip().lower() != PROXY_PROBLEM_MEDIA: + problems.append( + f"{label}: a proxy problem document is not {PROXY_PROBLEM_MEDIA}" + ) + missing = [m for m in PROXY_PROBLEM_MEMBERS if m not in body] + if missing: + problems.append(f"{label}: a proxy problem document lacks {missing}") + if "status" in body and body["status"] != response["status"]: + problems.append(f"{label}: a proxy problem document's status is not its own") + if body.get("retryable") is not True: + problems.append(f"{label}: a proxy problem document is not retryable: true") + return problems + + # --- outcomes --------------------------------------------------------------- # # A client's outcome for each step follows from the exchanges and from @@ -741,8 +779,6 @@ def _check_problem_code( } # The statuses a refusal is retried on when its body does not say. RETRYABLE_STATUSES = frozenset({408, 429, 500, 502, 503, 504}) -# The website proxy's `retry` value that makes its refusal retryable. -_PROXY_RETRY = "retry_after_delay" # The retries a client makes by default after a retryable refusal. MAX_RETRIES = 2 # The status that cuts a synchronous build off at the server's limit. @@ -768,8 +804,7 @@ def may_retry( return not (build and any(r["status"] == BUILD_CUT_OFF for r in earlier)) -# The content types a client reads a refusal's body as a problem document, or -# the website proxy's own body, in. +# The content types a client reads a refusal's body as a problem document in. PROBLEM_MEDIA = ("application/problem+json", "application/json") @@ -787,11 +822,10 @@ def gap_kinds(actions: Mapping[str, Mapping[str, Any]]) -> dict[str, str]: def refusal_code(body: Any) -> str | None: - """A refusal's code: a problem document's `code`, or the `error` member - of the website proxy's own `{error, retry, detail}` body.""" + """A refusal's code: its problem document's `code`.""" if not isinstance(body, dict): return None - code = body.get("code", body.get("error")) + code = body.get("code") return code if isinstance(code, str) else None @@ -808,13 +842,10 @@ def error_class( def retryable(status: int, body: Any) -> bool: - """Whether a client retries a refusal: as a problem document's `retryable` - says, or the website proxy's `retry`, and otherwise by its status.""" - if isinstance(body, dict): - if "code" not in body and "error" in body: - return body.get("retry") == _PROXY_RETRY - if isinstance(body.get("retryable"), bool): - return body["retryable"] + """Whether a client retries a refusal: as its problem document's + `retryable` says, and otherwise by its status.""" + if isinstance(body, dict) and isinstance(body.get("retryable"), bool): + return body["retryable"] return status in RETRYABLE_STATUSES @@ -3085,6 +3116,7 @@ def _check_scenarios( label, exchange["response"], registry, proxy_codes ) ) + problems.extend(_check_accepted(label, exchange["response"])) for resource in _failed_operations(record): error = resource.get("error") status = error.get("status") if isinstance(error, dict) else None

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≠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

5y!iV*My#eA! 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 X&C>0VS-=Td^eUUznKC_mUpaxU;SmJJcSJU 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 literal 1031059 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�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

TV6U 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 AEdT%j diff --git a/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json b/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json index 587d844..72fa553 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/newest-version-unreadable-page.json @@ -87,25 +87,53 @@ { "request": { "method": "GET", - "path": "/datasets/spec_774d6c001a6250aa67ca676ab067895e/versions?limit=1" + "path": "/datasets/spec_774d6c001a6250aa67ca676ab067895e/versions?limit=100" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "e5ff992e18a94c18866838012ff15862" + "x-dfo-trace-id": "bff64c2e088f43959abac4151c6a78e4" }, "json": { "schema_version": 1, "spec_id": "spec_774d6c001a6250aa67ca676ab067895e", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0", "next_cursor": null, "complete": true, "items": [ + { + "content_version": "cv_25fa336da15247db708dd220b2d933a2", + "base_content_version": "cv_b92d94774702c7f05f2075d0b03dd756", + "rendering": "groupby", + "groupby": { + "by": [ + "crsTypeOfFlow" + ], + "op": "sum" + }, + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + }, { "content_version": "cv_b92d94774702c7f05f2075d0b03dd756", "base_content_version": null, "rendering": "plain", - "groupby": null + "groupby": null, + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + }, + { + "content_version": "cv_9417c96e4e09dd36053fc395c5b0f92c", + "base_content_version": null, + "rendering": "plain", + "groupby": null, + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" + }, + { + "content_version": "cv_e7f6ed9ddc5ca69902f92a8866f93ef7", + "base_content_version": null, + "rendering": "plain", + "groupby": null, + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" } ] } @@ -117,7 +145,7 @@ "error": { "class": "ContractError", "code": "contract_violation", - "trace_id": "e5ff992e18a94c18866838012ff15862" + "trace_id": "bff64c2e088f43959abac4151c6a78e4" } } ] diff --git a/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json b/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json index e4ed5f8..decf121 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/operation-failed-without-error.json @@ -10,7 +10,7 @@ "call": [ { "op": "operation", - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5" }, { "op": "result" @@ -20,24 +20,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + "path": "/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "05701162424340a4826f3babe8623497" + "x-dfo-trace-id": "a54948450bc0460c9ed02ae930ce385a" }, "json": { "operation": { - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", - "status": "pending", - "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", + "status": "running", + "poll": "/api/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 123015 + "estimate_rows": 112203 } } } @@ -46,20 +46,20 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + "path": "/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "330e5223958b4f9bb2832079fa1a1bf7" + "x-dfo-trace-id": "7ad3c071f95943deb4d9804df43d9c8f" }, "json": { "operation": { - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", "status": "failed", - "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "poll": "/api/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", "retry_after_ms": 1500 } } @@ -69,18 +69,18 @@ "expect": [ { "operation": { - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", - "status": "pending" + "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", + "status": "running" } }, { "error": { "class": "ServerError", "code": "operation_failed", - "trace_id": "330e5223958b4f9bb2832079fa1a1bf7", + "trace_id": "7ad3c071f95943deb4d9804df43d9c8f", "long_builds": [ { - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", "poll_waits": [ 1.5 ], diff --git a/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.json b/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.json index 6c9afa4..7d9f4a8 100644 --- a/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.json +++ b/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.json @@ -4,14 +4,14 @@ "description": "Resuming a long build another process started reads its operation by id, and the operation is pending or running. Waiting polls it at the server's pacing until done; the client holds no spec, so it takes the sentence from Search by posting the built identity with variable_text \"dataset\", then downloads the file. A resumed build holds no request, so a failed operation is not posted again.", "origin": { "kind": "recorded", - "base_url": "http://127.0.0.1:19493/api", - "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", - "recorded_at": "2026-10-21T13:06:13Z" + "base_url": "https://dfo-dev-apis-zms5lj4zhq-nn.a.run.app/api", + "dfo_commit": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "recorded_at": "2026-10-23T18:38:40Z" }, "call": [ { "op": "operation", - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5" }, { "op": "result" @@ -21,50 +21,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + "path": "/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "05701162424340a4826f3babe8623497" + "x-dfo-trace-id": "a54948450bc0460c9ed02ae930ce385a" }, "json": { "operation": { - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", - "status": "pending", - "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", - "retry_after_ms": 1500, - "progress": { - "rows_written": 0, - "estimate_rows": 123015 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "2", - "x-dfo-trace-id": "330e5223958b4f9bb2832079fa1a1bf7" - }, - "json": { - "operation": { - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", "status": "running", - "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "poll": "/api/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", "retry_after_ms": 1500, "progress": { "rows_written": 0, - "estimate_rows": 123015 + "estimate_rows": 112203 } } } @@ -73,24 +47,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + "path": "/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "0e7e7a314c4e4eb3a93b781968cc2026" + "x-dfo-trace-id": "7ad3c071f95943deb4d9804df43d9c8f" }, "json": { "operation": { - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", "status": "running", - "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "poll": "/api/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", "retry_after_ms": 1500, "progress": { - "rows_written": 0, - "estimate_rows": 123015 + "rows_written": 20644, + "estimate_rows": 112203 } } } @@ -99,24 +73,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + "path": "/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "d0b0a6aa8f59442bbc225bb043881fbc" + "x-dfo-trace-id": "82bcbf5ea88a470f8efc4982ca9da566" }, "json": { "operation": { - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", "status": "running", - "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "poll": "/api/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", "retry_after_ms": 1500, "progress": { - "rows_written": 0, - "estimate_rows": 123015 + "rows_written": 57823, + "estimate_rows": 112203 } } } @@ -125,24 +99,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + "path": "/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "a6e1921e93944058a3083758a470bb80" + "x-dfo-trace-id": "c73d60d488e04687ab17f9b0e571b7d4" }, "json": { "operation": { - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", "status": "running", - "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", - "retry_after_ms": 1518, + "poll": "/api/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", + "retry_after_ms": 1500, "progress": { - "rows_written": 1876, - "estimate_rows": 123015 + "rows_written": 94473, + "estimate_rows": 112203 } } } @@ -151,50 +125,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + "path": "/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "2", - "x-dfo-trace-id": "29c3f42fcb2442d49636e30e36584ced" - }, - "json": { - "operation": { - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", - "status": "running", - "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", - "retry_after_ms": 1901, - "progress": { - "rows_written": 16634, - "estimate_rows": 123015 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "3", - "x-dfo-trace-id": "5ae05887ed9e4f10b5771d5af03b45ab" + "x-dfo-trace-id": "a164edf73d6248fe9d741ea324305510" }, "json": { "operation": { - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", "status": "running", - "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", - "retry_after_ms": 2381, + "poll": "/api/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", + "retry_after_ms": 1881, "progress": { - "rows_written": 34372, - "estimate_rows": 123015 + "rows_written": 112203, + "estimate_rows": 112203 } } } @@ -203,24 +151,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + "path": "/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "3", - "x-dfo-trace-id": "0bdf8274baba4a90911a519ebcb0a316" + "x-dfo-trace-id": "36531c091ceb429b95918024f5490371" }, "json": { "operation": { - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", "status": "running", - "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", - "retry_after_ms": 2979, + "poll": "/api/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", + "retry_after_ms": 2386, "progress": { - "rows_written": 64989, - "estimate_rows": 123015 + "rows_written": 112203, + "estimate_rows": 112203 } } } @@ -229,50 +177,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + "path": "/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5" }, "response": { "status": 200, "headers": { "content-type": "application/json", "retry-after": "4", - "x-dfo-trace-id": "e219ac63111f485a82f419a4257bb933" - }, - "json": { - "operation": { - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", - "status": "running", - "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", - "retry_after_ms": 3729, - "progress": { - "rows_written": 88009, - "estimate_rows": 123015 - } - } - } - } - }, - { - "request": { - "method": "GET", - "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" - }, - "response": { - "status": 200, - "headers": { - "content-type": "application/json", - "retry-after": "5", - "x-dfo-trace-id": "d81a3a69c6184e75a73cc40c1076576c" + "x-dfo-trace-id": "51746ee3252343fabb47578db0ab7fdf" }, "json": { "operation": { - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", "status": "running", - "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", - "retry_after_ms": 4696, + "poll": "/api/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", + "retry_after_ms": 3058, "progress": { - "rows_written": 123015, - "estimate_rows": 123015 + "rows_written": 112203, + "estimate_rows": 112203 } } } @@ -281,24 +203,24 @@ { "request": { "method": "GET", - "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + "path": "/datasets/operations/op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5" }, "response": { "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "babd0944d30042f89412ae971f1e748c" + "x-dfo-trace-id": "399bb2532fb74b8381ec3d2dee8a99e8" }, "json": { "operation": { - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", "status": "done" }, "manifest": { "schema_version": 1, "definition": { "schema_version": 1, - "spec_id": "spec_8a4676c4abdf43d105aeff9d4ba9299b", + "spec_id": "spec_8150d26a25222b2043e8c12b250b764d", "identity": { "shape": { "kind": "statvar_schema", @@ -336,32 +258,199 @@ "property": "nettingBasis" } ], - "facets": { - "provenance": { - "ref": "provenance/OECDDAC2A", - "state": "value" - } + "entities": { + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CHL", + "country/COL", + "country/CRI", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ISR", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/MEX", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/TUR", + "country/USA" + ], + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] }, - "entities": {}, - "open_roles": [ - "destination" - ], "identity_version": "spec1", "requested_window": { "kind": "range", "end_year": 2024, - "start_year": 2017 + "start_year": 1966 } } }, - "content_version": "cv_50e17ab9c2e732f13c48cf2028ac5928", - "prepared_at": "2026-10-21T13:06:37Z", + "content_version": "cv_fe2e676a79899730eac6110f58213472", + "prepared_at": "2026-10-23T18:38:59Z", "coverage": { - "rows": 123015, + "rows": 112203, "dimensions": [ { "label": "financingProvider", - "count": 172, + "count": 34, "axis": "origin", "noun": { "singular": "provider", @@ -370,7 +459,7 @@ }, { "label": "financingRecipient", - "count": 241, + "count": 133, "axis": "destination", "noun": { "singular": "recipient", @@ -379,14 +468,14 @@ }, { "label": "years", - "count": 8 + "count": 59 } ], "window": { "kind": "range", "origin": "query", "end_year": 2024, - "start_year": 2017 + "start_year": 1966 } }, "citation": { @@ -476,11 +565,11 @@ { "ref": "provenance/OECDDAC2A", "axis": "provenance", - "basis": "bound", - "default_policy": null, - "selection_reason": null, + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", "dispatch_facet_id": "1962969911839422253", - "default_policy_version": null + "default_policy_version": "1" }, { "ref": null, @@ -505,13 +594,13 @@ "kind": "range", "origin": "query", "end_year": 2024, - "start_year": 2017 + "start_year": 1966 }, - "graph_revision": null, + "graph_revision": "dfo-dev-dc-datacommons-service-00264-2s9", "normalisations": [], "code_index_stamp": { - "exported_at": "2026-10-20T19:50:14Z", - "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "exported_at": "2026-10-23T18:14:12Z", + "content_hash": "29eb81d7b6c88641b1d4e8eb5e850ca36de66b99d6e9e09680aac020507a6392", "graph_endpoint": "graph_release" }, "source_revisions": [ @@ -520,8 +609,8 @@ "revision": "2026-10-15" } ], - "capability_version": "dset_88fecfec3c5b89d1", - "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "capability_version": "dset_cc753cefa9199881", + "materialiser_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", "resolved_stat_vars": [ { "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", @@ -529,17 +618,23 @@ "financingProvider", "financingRecipient" ], - "observation_count": 123015 + "observation_count": 112203 } ], "family_member_count": 1, "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", "frame_grammar_version": "1.1.0", - "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "origin_catalogue_build_id": "20261023T061534Z-06fa7b89", "served_from": "materialise", - "confirmed_at": "2026-10-21T13:06:38.298569+00:00" + "confirmed_at": "2026-10-23T18:39:02.862675+00:00" }, - "warnings": [], + "warnings": [ + { + "code": "coverage_below_scope", + "severity": "warn", + "message": "The served coverage falls short of the requested scope. No observations were served for country/CHL, country/COL, country/CRI, country/MEX." + } + ], "diagnostics": [ { "code": "processing_level_undeclared", @@ -549,33 +644,34 @@ ], "artifacts": [ { - "artifact_digest": "sha256:cf2a4a97cc0fdfeb74ce021502e58c70d87ae4d67dc061a46fa62bb4f106a192", + "artifact_digest": "sha256:55f95f11ffe010e99407d279d159e956d4dfa6a6ba89f6d73aa32fb952fccd1d", "rendering": { "bundle": false, "format": "parquet", - "layout": 3 + "layout": 4 }, - "bytes": 1031059, + "bytes": 489647, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:06:38.266212+00:00", + "created_at": "2026-10-23T18:39:02.714887+00:00", "tier": "working", - "url": "/api/datasets/spec_8a4676c4abdf43d105aeff9d4ba9299b/cv_50e17ab9c2e732f13c48cf2028ac5928/files/sha256:cf2a4a97cc0fdfeb74ce021502e58c70d87ae4d67dc061a46fa62bb4f106a192" + "url": "/api/datasets/spec_8150d26a25222b2043e8c12b250b764d/cv_fe2e676a79899730eac6110f58213472/files/sha256:55f95f11ffe010e99407d279d159e956d4dfa6a6ba89f6d73aa32fb952fccd1d", + "enrichment_stamp": "5821dc7ce2050dff29f86570ff50f0adfb78c3ed7c7596e4f24a024892583cb0" }, { - "artifact_digest": "sha256:1a9852b1499a841264af878b70b999a25b104804e6ae1825dcfaabd5eab989bd", + "artifact_digest": "sha256:39345f0fc420a15e6262bf58781d46ebda6e7e9a0f11fc0c7540826b151a1d0e", "rendering": { "statistics": "series" }, - "bytes": 984263, + "bytes": 153622, "media_type": "application/vnd.apache.parquet", - "created_at": "2026-10-21T13:06:38.266212+00:00", + "created_at": "2026-10-23T18:39:02.714887+00:00", "tier": "working", - "url": "/api/datasets/spec_8a4676c4abdf43d105aeff9d4ba9299b/cv_50e17ab9c2e732f13c48cf2028ac5928/files/sha256:1a9852b1499a841264af878b70b999a25b104804e6ae1825dcfaabd5eab989bd" + "url": "/api/datasets/spec_8150d26a25222b2043e8c12b250b764d/cv_fe2e676a79899730eac6110f58213472/files/sha256:39345f0fc420a15e6262bf58781d46ebda6e7e9a0f11fc0c7540826b151a1d0e" } ], - "series_count": 21438, + "series_count": 3907, "output_options": { - "capability_version": "dset_88fecfec3c5b89d1", + "capability_version": "dset_cc753cefa9199881", "columns": [ { "name": "stat_var", @@ -587,19 +683,19 @@ "name": "financingProvider", "kind": "role", "droppable": false, - "distinct": 172 + "distinct": 34 }, { "name": "financingRecipient", "kind": "role", "droppable": false, - "distinct": 241 + "distinct": 133 }, { "name": "time_period", "kind": "grain", "droppable": false, - "distinct": 8 + "distinct": 59 }, { "name": "value", @@ -652,109 +748,25 @@ "column": "financingProvider", "field": "iso3", "token": "financingProvider_iso3", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 172, - "covered": 50 + "entities": 34, + "covered": 34 }, - "missing": [ - { - "ref": "AdaptationFund", - "label": "Adaptation Fund" - }, - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentBankGroup", - "label": "African Development Bank Group" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AndrewCarnegieFoundation", - "label": "Andrew Carnegie Foundation" - }, - { - "ref": "ArabFundForEconomicAndSocialDevelopment", - "label": "Arab Fund for Economic and Social Development" - }, - { - "ref": "Arcadia", - "label": "Arcadia" - }, - { - "ref": "ArcusFoundation", - "label": "Arcus Foundation" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianInfrastructureInvestmentBank", - "label": "Asian Infrastructure Investment Bank" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingProvider", "field": "iso2", "token": "financingProvider_iso2", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 172, - "covered": 50 + "entities": 34, + "covered": 34 }, - "missing": [ - { - "ref": "AdaptationFund", - "label": "Adaptation Fund" - }, - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentBankGroup", - "label": "African Development Bank Group" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AndrewCarnegieFoundation", - "label": "Andrew Carnegie Foundation" - }, - { - "ref": "ArabFundForEconomicAndSocialDevelopment", - "label": "Arab Fund for Economic and Social Development" - }, - { - "ref": "Arcadia", - "label": "Arcadia" - }, - { - "ref": "ArcusFoundation", - "label": "Arcus Foundation" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianInfrastructureInvestmentBank", - "label": "Asian Infrastructure Investment Bank" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingProvider", @@ -762,8 +774,8 @@ "token": "financingProvider_label", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 34, + "covered": 34 }, "missing": [], "truncated": false @@ -774,8 +786,8 @@ "token": "financingProvider_type", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 34, + "covered": 34 }, "missing": [], "truncated": false @@ -786,8 +798,32 @@ "token": "financingProvider_party_kind", "state": "available", "coverage": { - "entities": 172, - "covered": 172 + "entities": 34, + "covered": 34 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_class", + "token": "financingProvider_party_class", + "state": "available", + "coverage": { + "entities": 34, + "covered": 34 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_whole", + "token": "financingProvider_party_whole", + "state": "available", + "coverage": { + "entities": 34, + "covered": 34 }, "missing": [], "truncated": false @@ -796,55 +832,13 @@ "column": "financingRecipient", "field": "iso3", "token": "financingRecipient_iso3", - "state": "partial", - "reason": "enrichment_unavailable", + "state": "available", "coverage": { - "entities": 241, - "covered": 146 + "entities": 133, + "covered": 133 }, - "missing": [ - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianDevelopmentBankSpecialFunds", - "label": "Asian Development Bank Special Funds" - }, - { - "ref": "CaribbeanDevelopmentBank", - "label": "Caribbean Development Bank" - }, - { - "ref": "CentralAmericanBankForEconomicIntegration", - "label": "Central American Bank for Economic Integration" - }, - { - "ref": "DACACPCountries", - "label": "ACP countries (DAC)" - }, - { - "ref": "DACAfrica", - "label": "Africa (DAC)" - }, - { - "ref": "DACAfricaUnallocated", - "label": "Africa, unallocated by country (DAC)" - }, - { - "ref": "DACAllMultilateralRecipients", - "label": "all multilateral recipients (DAC)" - } - ], - "truncated": true + "missing": [], + "truncated": false }, { "column": "financingRecipient", @@ -853,52 +847,16 @@ "state": "partial", "reason": "enrichment_unavailable", "coverage": { - "entities": 241, - "covered": 144 + "entities": 133, + "covered": 132 }, "missing": [ { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank" - }, - { - "ref": "AsianDevelopmentBankSpecialFunds", - "label": "Asian Development Bank Special Funds" - }, - { - "ref": "CaribbeanDevelopmentBank", - "label": "Caribbean Development Bank" - }, - { - "ref": "CentralAmericanBankForEconomicIntegration", - "label": "Central American Bank for Economic Integration" - }, - { - "ref": "DACACPCountries", - "label": "ACP countries (DAC)" - }, - { - "ref": "DACAfrica", - "label": "Africa (DAC)" - }, - { - "ref": "DACAfricaUnallocated", - "label": "Africa, unallocated by country (DAC)" - }, - { - "ref": "DACAllMultilateralRecipients", - "label": "all multilateral recipients (DAC)" + "ref": "country/SSD", + "label": "South Sudan" } ], - "truncated": true + "truncated": false }, { "column": "financingRecipient", @@ -906,8 +864,8 @@ "token": "financingRecipient_label", "state": "available", "coverage": { - "entities": 241, - "covered": 241 + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -918,8 +876,8 @@ "token": "financingRecipient_type", "state": "available", "coverage": { - "entities": 241, - "covered": 241 + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -930,8 +888,32 @@ "token": "financingRecipient_party_kind", "state": "available", "coverage": { - "entities": 241, - "covered": 241 + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_class", + "token": "financingRecipient_party_class", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_whole", + "token": "financingRecipient_party_whole", + "state": "available", + "coverage": { + "entities": 133, + "covered": 133 }, "missing": [], "truncated": false @@ -939,13 +921,11 @@ ], "long_layout_defaults": [ "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient_label", - "financingRecipient_party_kind" - ], - "long_layout_totals": [ - "financingRecipient" + "financingRecipient_kind" ], + "long_layout_totals": [], "pivots": [ { "index": "financingProvider", @@ -955,7 +935,7 @@ "varying": [ { "column": "time_period", - "distinct": 8 + "distinct": 59 } ] }, @@ -967,7 +947,7 @@ "varying": [ { "column": "financingRecipient", - "distinct": 241 + "distinct": 133 } ] }, @@ -979,7 +959,7 @@ "varying": [ { "column": "time_period", - "distinct": 8 + "distinct": 59 } ] }, @@ -991,7 +971,7 @@ "varying": [ { "column": "financingProvider", - "distinct": 172 + "distinct": 34 } ] }, @@ -1003,7 +983,7 @@ "varying": [ { "column": "financingRecipient", - "distinct": 241 + "distinct": 133 } ] }, @@ -1015,7 +995,7 @@ "varying": [ { "column": "financingProvider", - "distinct": 172 + "distinct": 34 } ] } @@ -1038,10 +1018,10 @@ ] } }, - "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "series_coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "retention": { "pinned": false, - "held_until": "2026-11-20T13:06:38.266048Z" + "held_until": "2026-11-22T18:39:02.713360Z" } } } @@ -1096,21 +1076,188 @@ "property": "nettingBasis" } ], - "facets": { - "provenance": { - "ref": "provenance/OECDDAC2A", - "state": "value" - } + "entities": { + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CHL", + "country/COL", + "country/CRI", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ISR", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/MEX", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/TUR", + "country/USA" + ], + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ] }, - "entities": {}, - "open_roles": [ - "destination" - ], "identity_version": "spec1", "requested_window": { "kind": "range", "end_year": 2024, - "start_year": 2017 + "start_year": 1966 } } } @@ -1122,7 +1269,7 @@ "status": 200, "headers": { "content-type": "application/json", - "x-dfo-trace-id": "7a2237593d79419a816a8040aee2a734" + "x-dfo-trace-id": "957a2fdf109b4617a383ffd39e6b95ca" }, "json": { "schema_version": 1, @@ -1131,11 +1278,11 @@ "extract_skipped": true }, "diagnostics": { - "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", - "trace_id": "7a2237593d79419a816a8040aee2a734", + "engine_build": "035d29cd05fb31d7cb47cfb33197d4002f773df6", + "trace_id": "957a2fdf109b4617a383ffd39e6b95ca", "warnings": [], "timing_ms": { - "total": 1680, + "total": 1972, "by_step": { "coverage": 0 } @@ -1146,50 +1293,38 @@ "parts": [ { "variable_text": "dataset", - "warnings": [ - { - "code": "role_scope_defaulted", - "severity": "warn", - "message": "no recipient was named; the answer was resolved across the 241 recipients with data." - }, - { - "code": "role_scope_defaulted", - "severity": "warn", - "message": "no provider was named; the answer was resolved across every provider with data." - } - ], + "warnings": [], "timing_ms": { - "total": 1217, + "total": 1780, "by_step": { "validate": 0, - "walk": 7, + "walk": 11, "reread_arcs": 0, "detect_edits": 0, - "resolve_survivors": 0, - "shape": 1003, - "bind": 0, - "where_places": 0, - "materialise": 188, - "answer": 5, - "options": 14 + "resolve_survivors": 1, + "shape": 1694, + "bind": 1, + "where_places": 1, + "materialise": 24, + "answer": 12, + "options": 36 } }, "operations": [], - "departures": [], - "assumptions": [ + "departures": [ { - "kind": "open_role", + "code": "entity_unavailable", "binding_ref": "origin:", - "text": "every provider", - "refs": [] + "text": "You asked for Chile, Colombia, Costa Rica, and Mexico. The data holds no values for them." } ], + "assumptions": [], "status": "definite", "spec": { - "spec_id": "spec_8a4676c4abdf43d105aeff9d4ba9299b", + "spec_id": "spec_8150d26a25222b2043e8c12b250b764d", "definition": { "schema_version": 1, - "spec_id": "spec_8a4676c4abdf43d105aeff9d4ba9299b", + "spec_id": "spec_8150d26a25222b2043e8c12b250b764d", "identity": { "identity_version": "spec1", "shape": { @@ -1228,21 +1363,188 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CHL", + "country/COL", + "country/CRI", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ISR", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/MEX", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/TUR", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2017, + "start_year": 1966, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } - }, - "open_roles": [ - "destination" - ] + } } }, "resolved": { @@ -1406,1591 +1708,2095 @@ "label": "place" }, "binding": { - "kind": "unbound" - }, - "summable": false - }, - { - "key": { - "axis": "when", - "label": "time window" - }, - "binding": { - "kind": "value", - "value": { - "value_kind": "time_window", - "time_window": { - "start_year": 2017, - "end_year": 2024 - } - } - }, - "summable": false - }, - { - "key": { - "axis": "source", - "label": "data source" - }, - "binding": { - "kind": "value", - "value": { - "ref": { - "ref": "provenance/OECDDAC2A", - "label": "OECD DAC2A" - }, - "value_kind": "source" - } - }, - "summable": false - } - ], - "inapplicable_slots": [ - "dacTypeOfFinance" - ], - "unresolved_slots": [], - "stat_vars": { - "member_count": 1, - "member_count_exact": true, - "served_count": 1, - "data_date_range": { - "start": "2017", - "end": "2024" - } - }, - "entities": [], - "coverage": { - "kind": "breadth", - "has_data": true, - "dimensions": [ - { - "label": "recipients", - "count": 241 - }, - { - "label": "sources", - "count": 1 - }, - { - "label": "variables", - "count": 1 - } - ], - "window": { - "start_year": 2017, - "end_year": 2024 - } - }, - "headline": { - "year": 2024, - "year_named": true, - "named_window": { - "start_year": 2017, - "end_year": 2024 - }, - "observations": 15402, - "series": 15402, - "role_counts": { - "financingProvider": 148, - "financingRecipient": 234 - }, - "recent_years": [ - { - "year": 2024, - "observations": 15402, - "series": 15402, - "role_counts": { - "financingProvider": 148, - "financingRecipient": 234 - } - }, - { - "year": 2023, - "observations": 15579, - "series": 15579, - "role_counts": { - "financingProvider": 156, - "financingRecipient": 234 - } - }, - { - "year": 2022, - "observations": 16403, - "series": 16403, - "role_counts": { - "financingProvider": 162, - "financingRecipient": 235 - } - } - ] - }, - "download": { - "rows": 123015, - "rows_exact": true, - "series": 21438, - "window": { - "start_year": 2017, - "end_year": 2024 - }, - "licence": { - "label": "OECD Terms and Conditions" - } - }, - "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", - "scope": { - "axis": "destination", - "members": [ - { - "ref": "AfricanDevelopmentBank", - "label": "African Development Bank", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "AfricanDevelopmentFund", - "label": "African Development Fund", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "AsianDevelopmentBank", - "label": "Asian Development Bank", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "AsianDevelopmentBankSpecialFunds", - "label": "Asian Development Bank Special Funds", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "CaribbeanDevelopmentBank", - "label": "Caribbean Development Bank", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "CentralAmericanBankForEconomicIntegration", - "label": "Central American Bank for Economic Integration", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "DACACPCountries", - "label": "ACP countries (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACAfrica", - "label": "Africa (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACAfricaUnallocated", - "label": "Africa, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACAllMultilateralRecipients", - "label": "all multilateral recipients (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACAllRecipients", - "label": "all recipients (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACAmerica", - "label": "America (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACAmericaUnallocated", - "label": "America, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACAsia", - "label": "Asia (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACAsiaUnallocated", - "label": "Asia, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACBilateralUnallocated", - "label": "Bilateral, unallocated (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACCaribbean", - "label": "Caribbean (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACCaribbeanAndCentralAmerica", - "label": "Caribbean and Central America (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACCaribbeanAndCentralAmericaUnallocated", - "label": "Caribbean and Central America, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACCaribbeanUnallocated", - "label": "Caribbean, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACCentralAmerica", - "label": "Central America (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACCentralAmericaUnallocated", - "label": "Central America, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACCentralAndEasternEuropeanCountries", - "label": "Central and Eastern European countries (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACCentralAsiaUnallocated", - "label": "Central Asia, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACClubDuSahelCountries", - "label": "Club du Sahel countries (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACDevelopingCountries", - "label": "developing countries (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACEasternAfrica", - "label": "Eastern Africa (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACEasternAfricaUnallocated", - "label": "Eastern Africa, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACEurope", - "label": "Europe (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACEuropeUnallocated", - "label": "Europe, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACExYugoslaviaUnallocated", - "label": "States of the former Yugoslavia, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACFarEastAsia", - "label": "Far East Asia (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACFarEastAsiaUnallocated", - "label": "Far East Asia, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACFragileStates", - "label": "fragile states (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACLowerMiddleIncomeCountries", - "label": "lower middle-income countries (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACMelanesia", - "label": "Melanesia (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACMelanesiaUnallocated", - "label": "Melanesia, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACMicronesia", - "label": "Micronesia (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACMicronesiaUnallocated", - "label": "Micronesia, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACMiddleAfrica", - "label": "Middle Africa (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACMiddleAfricaUnallocated", - "label": "Middle Africa, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACMiddleEast", - "label": "Middle East (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACMiddleEastUnallocated", - "label": "Middle East, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACMoreAdvancedDevelopingCountriesAndTerritories", - "label": "more advanced developing countries and territories (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACNewIndependentStates", - "label": "New Independent States of the former Soviet Union (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACNorthOfSahara", - "label": "North of Sahara (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACNorthOfSaharaUnallocated", - "label": "North of Sahara, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACOceania", - "label": "Oceania (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACOceaniaUnallocated", - "label": "Oceania, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACOtherEUInstitutions", - "label": "other EU institutions (DAC)", - "entity_type": "DACUnspecifiedParty", - "role": "destination" - }, - { - "ref": "DACOtherLowIncomeCountries", - "label": "other low-income countries (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACOtherMultilateralRecipient", - "label": "other multilateral recipient (DAC)", - "entity_type": "DACUnspecifiedParty", - "role": "destination" - }, - { - "ref": "DACOtherRegionalDevelopmentBanks", - "label": "other regional development banks (DAC)", - "entity_type": "DACUnspecifiedParty", - "role": "destination" - }, - { - "ref": "DACOtherUnitedNations", - "label": "other United Nations entities (DAC)", - "entity_type": "DACUnspecifiedParty", - "role": "destination" - }, - { - "ref": "DACOtherWorldBank", - "label": "other World Bank (DAC)", - "entity_type": "DACUnspecifiedParty", - "role": "destination" - }, - { - "ref": "DACPolynesia", - "label": "Polynesia (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACPolynesiaUnallocated", - "label": "Polynesia, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACSmallIslandStates", - "label": "small island states (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACSouthAmerica", - "label": "South America (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACSouthAmericaUnallocated", - "label": "South America, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACSouthAndCentralAsia", - "label": "South and Central Asia (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACSouthAndCentralAsiaUnallocated", - "label": "South and Central Asia, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACSouthAsiaUnallocated", - "label": "South Asia, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACSouthOfSahara", - "label": "South of Sahara (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACSouthOfSaharaUnallocated", - "label": "South of Sahara, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACSouthernAfrica", - "label": "Southern Africa (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACSouthernAfricaUnallocated", - "label": "Southern Africa, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "DACUnallocatedByIncome", - "label": "unallocated by income (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACUpperMiddleIncomeCountries", - "label": "upper middle-income countries (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACWesternAfrica", - "label": "Western Africa (DAC)", - "entity_type": "DACGroup", - "role": "destination" - }, - { - "ref": "DACWesternAfricaUnallocated", - "label": "Western Africa, unallocated by country (DAC)", - "entity_type": "DACRecipientUnallocatedByCountry", - "role": "destination" - }, - { - "ref": "EuropeanCommission", - "label": "European Commission", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "EuropeanInvestmentBank", - "label": "European Investment Bank", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "EuropeanUnionInstitutions", - "label": "European Union institutions", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "HeavilyIndebtedPoorCountries", - "label": "heavily indebted poor countries (IMF and World Bank)", - "entity_type": "Grouping", - "role": "destination" - }, - { - "ref": "InterAmericanDevelopmentBank", - "label": "Inter-American Development Bank", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "InterAmericanDevelopmentBankFundForSpecialOperations", - "label": "Inter-American Development Bank Fund for Special Operations", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "InternationalBankForReconstructionAndDevelopment", - "label": "International Bank for Reconstruction and Development", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "InternationalDevelopmentAssociation", - "label": "International Development Association", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "InternationalFinanceCorporation", - "label": "International Finance Corporation", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "InternationalFundForAgriculturalDevelopment", - "label": "International Fund for Agricultural Development", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "InternationalMonetaryFund", - "label": "International Monetary Fund", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "UNLandlockedDevelopingCountries", - "label": "landlocked developing countries (UN)", - "entity_type": "UNCountryDevelopmentGroup", - "role": "destination" - }, - { - "ref": "UNLeastDevelopedCountries", - "label": "least developed countries (UN)", - "entity_type": "UNCountryDevelopmentGroup", - "role": "destination" - }, - { - "ref": "UNRWA", - "label": "United Nations Relief and Works Agency for Palestine Refugees in the Near East", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "UnitedNationsChildrensFund", - "label": "United Nations Children's Fund", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "UnitedNationsDevelopmentProgramme", - "label": "United Nations Development Programme", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "UnitedNationsHighCommissionerForRefugees", - "label": "Office of the United Nations High Commissioner for Refugees", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "UnitedNationsPopulationFund", - "label": "United Nations Population Fund", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "WorldBankHighIncome", - "label": "high income (World Bank)", - "entity_type": "WorldBankIncomeGroup", - "role": "destination" - }, - { - "ref": "WorldBankLowIncome", - "label": "low income (World Bank)", - "entity_type": "WorldBankIncomeGroup", - "role": "destination" - }, - { - "ref": "WorldBankLowerMiddleIncome", - "label": "lower middle income (World Bank)", - "entity_type": "WorldBankIncomeGroup", - "role": "destination" - }, - { - "ref": "WorldBankNotClassifiedByIncome", - "label": "not classified by income (World Bank)", - "entity_type": "WorldBankIncomeGroup", - "role": "destination" - }, - { - "ref": "WorldBankUpperMiddleIncome", - "label": "upper middle income (World Bank)", - "entity_type": "WorldBankIncomeGroup", - "role": "destination" - }, - { - "ref": "WorldFoodProgramme", - "label": "World Food Programme", - "entity_type": "Organization", - "role": "destination" - }, - { - "ref": "country/AFG", - "label": "Afghanistan", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/AGO", - "label": "Angola", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/ALB", - "label": "Albania", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/ARG", - "label": "Argentina", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/ARM", - "label": "Armenia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/ATG", - "label": "Antigua and Barbuda", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/AZE", - "label": "Azerbaijan", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BDI", - "label": "Burundi", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BEN", - "label": "Benin", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BFA", - "label": "Burkina Faso", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BGD", - "label": "Bangladesh", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BIH", - "label": "Bosnia and Herzegovina", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BLR", - "label": "Belarus", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BLZ", - "label": "Belize", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BOL", - "label": "Bolivia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BRA", - "label": "Brazil", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BTN", - "label": "Bhutan", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/BWA", - "label": "Botswana", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/CAF", - "label": "Central African Republic", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/CHL", - "label": "Chile", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/CHN", - "label": "People's Republic of China", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/CIV", - "label": "Ivory Coast", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/CMR", - "label": "Cameroon", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/COD", - "label": "Democratic Republic of the Congo", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/COG", - "label": "Republic of the Congo", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/COK", - "label": "Cook Islands", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/COL", - "label": "Colombia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/COM", - "label": "Comoros", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/CPV", - "label": "Cape Verde", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/CRI", - "label": "Costa Rica", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/CUB", - "label": "Cuba", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/DJI", - "label": "Djibouti", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/DMA", - "label": "Dominica", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/DOM", - "label": "Dominican Republic", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/DZA", - "label": "Algeria", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/ECU", - "label": "Ecuador", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/EGY", - "label": "Egypt", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/ERI", - "label": "Eritrea", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/ETH", - "label": "Ethiopia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/FJI", - "label": "Fiji", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/FSM", - "label": "Micronesia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GAB", - "label": "Gabon", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GEO", - "label": "Georgia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GHA", - "label": "Ghana", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GIN", - "label": "Guinea", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GMB", - "label": "The Gambia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GNB", - "label": "Guinea-Bissau", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GNQ", - "label": "Equatorial Guinea", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GRD", - "label": "Grenada", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GTM", - "label": "Guatemala", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/GUY", - "label": "Guyana", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/HND", - "label": "Honduras", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/HTI", - "label": "Haiti", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/IDN", - "label": "Indonesia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/IND", - "label": "India", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/IRN", - "label": "Iran", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/IRQ", - "label": "Iraq", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/JAM", - "label": "Jamaica", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/JOR", - "label": "Jordan", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/KAZ", - "label": "Kazakhstan", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/KEN", - "label": "Kenya", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/KGZ", - "label": "Kyrgyzstan", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/KHM", - "label": "Cambodia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/KIR", - "label": "Kiribati", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/LAO", - "label": "Laos", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/LBN", - "label": "Lebanon", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/LBR", - "label": "Liberia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/LBY", - "label": "Libya", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/LCA", - "label": "Saint Lucia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/LKA", - "label": "Sri Lanka", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/LSO", - "label": "Lesotho", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MAR", - "label": "Morocco", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MDA", - "label": "Moldova", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MDG", - "label": "Madagascar", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MDV", - "label": "Maldives", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MEX", - "label": "Mexico", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MHL", - "label": "Marshall Islands", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MKD", - "label": "North Macedonia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MLI", - "label": "Mali", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MMR", - "label": "Myanmar [Burma]", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MNE", - "label": "Montenegro", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MNG", - "label": "Mongolia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MOZ", - "label": "Mozambique", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MRT", - "label": "Mauritania", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MSR", - "label": "Montserrat", - "entity_type": "AdministrativeArea1", - "role": "destination" - }, - { - "ref": "country/MUS", - "label": "Mauritius", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MWI", - "label": "Malawi", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/MYS", - "label": "Malaysia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/NAM", - "label": "Namibia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/NER", - "label": "Niger", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/NGA", - "label": "Nigeria", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/NIC", - "label": "Nicaragua", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/NIU", - "label": "Niue", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/NPL", - "label": "Nepal", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/NRU", - "label": "Nauru", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/PAK", - "label": "Pakistan", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/PAN", - "label": "Panama", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/PER", - "label": "Peru", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/PHL", - "label": "Philippines", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/PLW", - "label": "Palau", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/PNG", - "label": "Papua New Guinea", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/PRK", - "label": "North Korea", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/PRY", - "label": "Paraguay", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/PSE", - "label": "State of Palestine", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/RWA", - "label": "Rwanda", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/SDN", - "label": "Sudan", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/SEN", - "label": "Senegal", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/SHN", - "label": "Saint Helena, Ascension and Tristan da Cunha", - "entity_type": "AdministrativeArea1", - "role": "destination" - }, - { - "ref": "country/SLB", - "label": "Solomon Islands", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/SLE", - "label": "Sierra Leone", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/SLV", - "label": "El Salvador", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/SOM", - "label": "Somalia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/SRB", - "label": "Serbia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/SSD", - "label": "South Sudan", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/STP", - "label": "São Tomé and Príncipe", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/SUR", - "label": "Suriname", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/SWZ", - "label": "Swaziland", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/SYC", - "label": "Seychelles", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/SYR", - "label": "Syria", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/TCD", - "label": "Chad", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/TGO", - "label": "Togo", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/THA", - "label": "Thailand", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/TJK", - "label": "Tajikistan", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/TKL", - "label": "Tokelau", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/TKM", - "label": "Turkmenistan", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/TLS", - "label": "Timor-Leste", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/TON", - "label": "Tonga", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/TUN", - "label": "Tunisia", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/TUR", - "label": "Turkey", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/TUV", - "label": "Tuvalu", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/TZA", - "label": "Tanzania", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/UGA", - "label": "Uganda", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/UKR", - "label": "Ukraine", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/URY", - "label": "Uruguay", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/UZB", - "label": "Uzbekistan", - "entity_type": "Country", - "role": "destination" - }, - { - "ref": "country/VCT", - "label": "Saint Vincent and the Grenadines", - "entity_type": "Country", - "role": "destination" + "kind": "set", + "values": [ + { + "ref": { + "ref": "country/AFG", + "label": "Afghanistan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/AGO", + "label": "Angola" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ARE", + "label": "United Arab Emirates" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ARG", + "label": "Argentina" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ATG", + "label": "Antigua and Barbuda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/AZE", + "label": "Azerbaijan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BDI", + "label": "Burundi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BEN", + "label": "Benin" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BGD", + "label": "Bangladesh" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BHR", + "label": "Bahrain" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BHS", + "label": "The Bahamas" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BLZ", + "label": "Belize" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BOL", + "label": "Bolivia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BRA", + "label": "Brazil" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BRB", + "label": "Barbados" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BRN", + "label": "Brunei" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BTN", + "label": "Bhutan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/BWA", + "label": "Botswana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CAF", + "label": "Central African Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CHL", + "label": "Chile" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CHN", + "label": "People's Republic of China" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CMR", + "label": "Cameroon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COL", + "label": "Colombia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/COM", + "label": "Comoros" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CPV", + "label": "Cape Verde" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CRI", + "label": "Costa Rica" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/CUB", + "label": "Cuba" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DJI", + "label": "Djibouti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DMA", + "label": "Dominica" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DOM", + "label": "Dominican Republic" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/DZA", + "label": "Algeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ECU", + "label": "Ecuador" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/EGY", + "label": "Egypt" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ERI", + "label": "Eritrea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ETH", + "label": "Ethiopia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/FJI", + "label": "Fiji" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/FSM", + "label": "Micronesia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GAB", + "label": "Gabon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GHA", + "label": "Ghana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GIN", + "label": "Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GMB", + "label": "The Gambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GRD", + "label": "Grenada" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GTM", + "label": "Guatemala" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/GUY", + "label": "Guyana" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/HND", + "label": "Honduras" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/HTI", + "label": "Haiti" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/IDN", + "label": "Indonesia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/IND", + "label": "India" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/IRN", + "label": "Iran" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/IRQ", + "label": "Iraq" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/JAM", + "label": "Jamaica" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/JOR", + "label": "Jordan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KEN", + "label": "Kenya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KHM", + "label": "Cambodia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KIR", + "label": "Kiribati" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KNA", + "label": "Saint Kitts and Nevis" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/KWT", + "label": "Kuwait" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LAO", + "label": "Laos" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBN", + "label": "Lebanon" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBR", + "label": "Liberia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LBY", + "label": "Libya" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LCA", + "label": "Saint Lucia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LKA", + "label": "Sri Lanka" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/LSO", + "label": "Lesotho" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MAR", + "label": "Morocco" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDG", + "label": "Madagascar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MDV", + "label": "Maldives" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MHL", + "label": "Marshall Islands" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MLI", + "label": "Mali" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MMR", + "label": "Myanmar [Burma]" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MNG", + "label": "Mongolia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MOZ", + "label": "Mozambique" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MRT", + "label": "Mauritania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MUS", + "label": "Mauritius" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MWI", + "label": "Malawi" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/MYS", + "label": "Malaysia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NAM", + "label": "Namibia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NER", + "label": "Niger" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NGA", + "label": "Nigeria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NIC", + "label": "Nicaragua" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NPL", + "label": "Nepal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/NRU", + "label": "Nauru" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/OMN", + "label": "Oman" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/PAK", + "label": "Pakistan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/PAN", + "label": "Panama" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/PER", + "label": "Peru" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/PHL", + "label": "Philippines" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/PNG", + "label": "Papua New Guinea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/PRK", + "label": "North Korea" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/PRY", + "label": "Paraguay" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/QAT", + "label": "Qatar" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/RWA", + "label": "Rwanda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SAU", + "label": "Saudi Arabia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SDN", + "label": "Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SEN", + "label": "Senegal" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SGP", + "label": "Singapore" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLB", + "label": "Solomon Islands" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SLV", + "label": "El Salvador" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SOM", + "label": "Somalia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SSD", + "label": "South Sudan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SUR", + "label": "Suriname" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SWZ", + "label": "Swaziland" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYC", + "label": "Seychelles" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/SYR", + "label": "Syria" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TCD", + "label": "Chad" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TGO", + "label": "Togo" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/THA", + "label": "Thailand" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TJK", + "label": "Tajikistan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TKM", + "label": "Turkmenistan" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TLS", + "label": "Timor-Leste" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TON", + "label": "Tonga" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TTO", + "label": "Trinidad and Tobago" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TUN", + "label": "Tunisia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/TZA", + "label": "Tanzania" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/UGA", + "label": "Uganda" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/URY", + "label": "Uruguay" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/VCT", + "label": "Saint Vincent and the Grenadines" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/VEN", + "label": "Venezuela" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/VNM", + "label": "Vietnam" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/VUT", + "label": "Vanuatu" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/WSM", + "label": "Samoa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/YEM", + "label": "Yemen" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZAF", + "label": "South Africa" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZMB", + "label": "Zambia" + }, + "value_kind": "entity" + }, + { + "ref": { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + "value_kind": "entity" + } + ] }, - { - "ref": "country/VEN", - "label": "Venezuela", - "entity_type": "Country", - "role": "destination" + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" }, - { - "ref": "country/VNM", - "label": "Vietnam", - "entity_type": "Country", - "role": "destination" + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 1966, + "end_year": 2024 + } + } }, - { - "ref": "country/VUT", - "label": "Vanuatu", - "entity_type": "Country", - "role": "destination" + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" }, - { - "ref": "country/WLF", - "label": "Wallis and Futuna", - "entity_type": "AdministrativeArea", - "role": "destination" + "binding": { + "kind": "unbound" }, + "summable": false + } + ], + "inapplicable_slots": [ + "dacTypeOfFinance" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "1966", + "end": "2024" + } + }, + "entities": [ + { + "ref": "country/AFG", + "label": "Afghanistan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ARE", + "label": "United Arab Emirates", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ARG", + "label": "Argentina", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ATG", + "label": "Antigua and Barbuda", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/AZE", + "label": "Azerbaijan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BGD", + "label": "Bangladesh", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BHR", + "label": "Bahrain", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BHS", + "label": "The Bahamas", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BLZ", + "label": "Belize", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BOL", + "label": "Bolivia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BRA", + "label": "Brazil", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BRB", + "label": "Barbados", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BRN", + "label": "Brunei", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BTN", + "label": "Bhutan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CHL", + "label": "Chile", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CHN", + "label": "People's Republic of China", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COL", + "label": "Colombia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CRI", + "label": "Costa Rica", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CUB", + "label": "Cuba", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DMA", + "label": "Dominica", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DOM", + "label": "Dominican Republic", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DZA", + "label": "Algeria", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ECU", + "label": "Ecuador", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/EGY", + "label": "Egypt", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/FJI", + "label": "Fiji", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/FSM", + "label": "Micronesia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GRD", + "label": "Grenada", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GTM", + "label": "Guatemala", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GUY", + "label": "Guyana", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/HND", + "label": "Honduras", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/HTI", + "label": "Haiti", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/IDN", + "label": "Indonesia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/IND", + "label": "India", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/IRN", + "label": "Iran", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/IRQ", + "label": "Iraq", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/JAM", + "label": "Jamaica", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/JOR", + "label": "Jordan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/KHM", + "label": "Cambodia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/KIR", + "label": "Kiribati", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/KNA", + "label": "Saint Kitts and Nevis", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/KWT", + "label": "Kuwait", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LAO", + "label": "Laos", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LBN", + "label": "Lebanon", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LBY", + "label": "Libya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LCA", + "label": "Saint Lucia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LKA", + "label": "Sri Lanka", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MAR", + "label": "Morocco", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MDV", + "label": "Maldives", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MHL", + "label": "Marshall Islands", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MMR", + "label": "Myanmar [Burma]", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MNG", + "label": "Mongolia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MYS", + "label": "Malaysia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NIC", + "label": "Nicaragua", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NPL", + "label": "Nepal", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NRU", + "label": "Nauru", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/OMN", + "label": "Oman", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/PAK", + "label": "Pakistan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/PAN", + "label": "Panama", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/PER", + "label": "Peru", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/PHL", + "label": "Philippines", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/PNG", + "label": "Papua New Guinea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/PRK", + "label": "North Korea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/PRY", + "label": "Paraguay", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/QAT", + "label": "Qatar", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SAU", + "label": "Saudi Arabia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SDN", + "label": "Sudan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SGP", + "label": "Singapore", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SLB", + "label": "Solomon Islands", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SLV", + "label": "El Salvador", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SUR", + "label": "Suriname", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SYR", + "label": "Syria", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/THA", + "label": "Thailand", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TJK", + "label": "Tajikistan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TKM", + "label": "Turkmenistan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TLS", + "label": "Timor-Leste", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TON", + "label": "Tonga", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TTO", + "label": "Trinidad and Tobago", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TUN", + "label": "Tunisia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/URY", + "label": "Uruguay", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/VCT", + "label": "Saint Vincent and the Grenadines", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/VEN", + "label": "Venezuela", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/VNM", + "label": "Vietnam", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/VUT", + "label": "Vanuatu", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/WSM", + "label": "Samoa", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/YEM", + "label": "Yemen", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/AUS", + "label": "Australia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/AUT", + "label": "Austria", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/BEL", + "label": "Belgium", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CAN", + "label": "Canada", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CHE", + "label": "Switzerland", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CHL", + "label": "Chile", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/COL", + "label": "Colombia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CRI", + "label": "Costa Rica", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/CZE", + "label": "Czech Republic", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/DEU", + "label": "Germany", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/DNK", + "label": "Denmark", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ESP", + "label": "Spain", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/EST", + "label": "Estonia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/FIN", + "label": "Finland", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/FRA", + "label": "France", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GBR", + "label": "United Kingdom", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/GRC", + "label": "Greece", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/HUN", + "label": "Hungary", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/IRL", + "label": "Ireland", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ISL", + "label": "Iceland", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ISR", + "label": "Israel", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/ITA", + "label": "Italy", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/JPN", + "label": "Japan", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/KOR", + "label": "South Korea", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/LTU", + "label": "Lithuania", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/LUX", + "label": "Luxembourg", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/LVA", + "label": "Latvia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/MEX", + "label": "Mexico", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/NLD", + "label": "Netherlands", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/NOR", + "label": "Norway", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/NZL", + "label": "New Zealand", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/POL", + "label": "Poland", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/PRT", + "label": "Portugal", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SVK", + "label": "Slovakia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SVN", + "label": "Slovenia", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/SWE", + "label": "Sweden", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/TUR", + "label": "Turkey", + "entity_type": "Country", + "role": "origin" + }, + { + "ref": "country/USA", + "label": "United States of America", + "entity_type": "Country", + "role": "origin" + } + ], + "coverage": { + "kind": "exact", + "has_data": true, + "observation_count": 112203, + "evidence": "facet_metadata", + "dimensions": [ { - "ref": "country/WSM", - "label": "Samoa", - "entity_type": "Country", - "role": "destination" + "label": "sources", + "count": 1 }, { - "ref": "country/XKS", - "label": "Kosovo", - "entity_type": "Country", - "role": "destination" + "label": "observations", + "count": 59 }, { - "ref": "country/YEM", - "label": "Yemen", - "entity_type": "Country", - "role": "destination" - }, + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 1966, + "end_year": 2024 + } + }, + "headline": { + "year": 2024, + "year_named": true, + "named_window": { + "start_year": 1966, + "end_year": 2024 + }, + "observations": 2629, + "series": 2629, + "role_counts": { + "financingProvider": 34, + "financingRecipient": 117 + }, + "recent_years": [ { - "ref": "country/ZAF", - "label": "South Africa", - "entity_type": "Country", - "role": "destination" + "year": 2024, + "observations": 2629, + "series": 2629, + "role_counts": { + "financingProvider": 34, + "financingRecipient": 117 + } }, { - "ref": "country/ZMB", - "label": "Zambia", - "entity_type": "Country", - "role": "destination" + "year": 2023, + "observations": 2588, + "series": 2588, + "role_counts": { + "financingProvider": 34, + "financingRecipient": 117 + } }, { - "ref": "country/ZWE", - "label": "Zimbabwe", - "entity_type": "Country", - "role": "destination" + "year": 2022, + "observations": 2628, + "series": 2628, + "role_counts": { + "financingProvider": 34, + "financingRecipient": 117 + } } ] }, + "download": { + "rows": 112203, + "rows_exact": true, + "series": 3907, + "window": { + "start_year": 1966, + "end_year": 2024 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "0b8c9a18fcc5af19013b21e865c64481503b6a6542f7d2e6628999e6559a47de", "facets": { "provenance": { - "basis": "bound", + "basis": "fallback", "ref": "provenance/OECDDAC2A", "label": "OECD DAC2A", "source": { @@ -3033,8 +3839,8 @@ "relation": "child", "parent": "DAC2aAidType206", "member_count": 2, - "served_rows": 26525, - "served_rows_exact": false + "served_rows": 18000, + "served_rows_exact": true }, { "value": { @@ -3047,8 +3853,8 @@ "relation": "child", "parent": "DAC2aAidType206", "member_count": 1, - "served_rows": 119269, - "served_rows_exact": false + "served_rows": 111362, + "served_rows_exact": true }, { "value": { @@ -3060,8 +3866,8 @@ }, "relation": "root", "member_count": 1, - "served_rows": 52151, - "served_rows_exact": false + "served_rows": 88283, + "served_rows_exact": true }, { "value": { @@ -3073,8 +3879,8 @@ }, "relation": "root", "member_count": 1, - "served_rows": 15005, - "served_rows_exact": false + "served_rows": 13512, + "served_rows_exact": true }, { "value": { @@ -3086,28 +3892,15 @@ }, "relation": "root", "member_count": 1, - "served_rows": 50159, - "served_rows_exact": false + "served_rows": 27720, + "served_rows_exact": true } ], "truncated": false, "source": "observed" } ], - "entity_options": [ - { - "role": "destination", - "options": [], - "truncated": true, - "source": "observed" - }, - { - "role": "origin", - "options": [], - "truncated": true, - "source": "observed" - } - ], + "entity_options": [], "facet_options": [ { "axis": "provenance", @@ -3142,7 +3935,7 @@ "source": "observed" } ], - "rendered_sentence": "Gross disbursements to 241 recipients from 172 providers for official development assistance, 2017 to 2024. Current US dollars · OECD DAC2A.", + "rendered_sentence": "Gross disbursements to 133 recipients from 38 providers for official development assistance, 1966 to 2024. Current US dollars · OECD DAC2a.", "sentence_plan": [ { "kind": "slot", @@ -3166,12 +3959,146 @@ }, { "kind": "slot", - "text": "241 recipients", + "text": "133 recipients", "axis": "where", "segment": "heading", "role": "destination", "binding_ref": "where:", - "entity_refs": [], + "entity_refs": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], "states": [ "where:" ] @@ -3185,11 +4112,50 @@ }, { "kind": "slot", - "text": "172 providers", + "text": "38 providers", "segment": "heading", "role": "origin", "binding_ref": "origin:", - "entity_refs": [], + "entity_refs": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CHL", + "country/COL", + "country/CRI", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ISR", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/MEX", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/TUR", + "country/USA" + ], "states": [ "origin:" ] @@ -3252,7 +4218,7 @@ }, { "kind": "slot", - "text": "2017 to 2024", + "text": "1966 to 2024", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -3296,10 +4262,9 @@ }, { "kind": "slot", - "text": "OECD DAC2A", + "text": "OECD DAC2a", "axis": "source", "segment": "byline", - "binding_ref": "source:", "entity_refs": [], "states": [ "source:" @@ -3314,7 +4279,692 @@ } ], "trace": { - "resolved_entities": [], + "resolved_entities": [ + { + "ref": "country/AFG", + "label": "Afghanistan" + }, + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/ARE", + "label": "United Arab Emirates" + }, + { + "ref": "country/ARG", + "label": "Argentina" + }, + { + "ref": "country/ATG", + "label": "Antigua and Barbuda" + }, + { + "ref": "country/AZE", + "label": "Azerbaijan" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BGD", + "label": "Bangladesh" + }, + { + "ref": "country/BHR", + "label": "Bahrain" + }, + { + "ref": "country/BHS", + "label": "The Bahamas" + }, + { + "ref": "country/BLZ", + "label": "Belize" + }, + { + "ref": "country/BOL", + "label": "Bolivia" + }, + { + "ref": "country/BRA", + "label": "Brazil" + }, + { + "ref": "country/BRB", + "label": "Barbados" + }, + { + "ref": "country/BRN", + "label": "Brunei" + }, + { + "ref": "country/BTN", + "label": "Bhutan" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CHL", + "label": "Chile" + }, + { + "ref": "country/CHN", + "label": "People's Republic of China" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COL", + "label": "Colombia" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/CRI", + "label": "Costa Rica" + }, + { + "ref": "country/CUB", + "label": "Cuba" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/DMA", + "label": "Dominica" + }, + { + "ref": "country/DOM", + "label": "Dominican Republic" + }, + { + "ref": "country/DZA", + "label": "Algeria" + }, + { + "ref": "country/ECU", + "label": "Ecuador" + }, + { + "ref": "country/EGY", + "label": "Egypt" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/FJI", + "label": "Fiji" + }, + { + "ref": "country/FSM", + "label": "Micronesia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/GRD", + "label": "Grenada" + }, + { + "ref": "country/GTM", + "label": "Guatemala" + }, + { + "ref": "country/GUY", + "label": "Guyana" + }, + { + "ref": "country/HND", + "label": "Honduras" + }, + { + "ref": "country/HTI", + "label": "Haiti" + }, + { + "ref": "country/IDN", + "label": "Indonesia" + }, + { + "ref": "country/IND", + "label": "India" + }, + { + "ref": "country/IRN", + "label": "Iran" + }, + { + "ref": "country/IRQ", + "label": "Iraq" + }, + { + "ref": "country/JAM", + "label": "Jamaica" + }, + { + "ref": "country/JOR", + "label": "Jordan" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/KHM", + "label": "Cambodia" + }, + { + "ref": "country/KIR", + "label": "Kiribati" + }, + { + "ref": "country/KNA", + "label": "Saint Kitts and Nevis" + }, + { + "ref": "country/KWT", + "label": "Kuwait" + }, + { + "ref": "country/LAO", + "label": "Laos" + }, + { + "ref": "country/LBN", + "label": "Lebanon" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LBY", + "label": "Libya" + }, + { + "ref": "country/LCA", + "label": "Saint Lucia" + }, + { + "ref": "country/LKA", + "label": "Sri Lanka" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MAR", + "label": "Morocco" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MDV", + "label": "Maldives" + }, + { + "ref": "country/MHL", + "label": "Marshall Islands" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MMR", + "label": "Myanmar [Burma]" + }, + { + "ref": "country/MNG", + "label": "Mongolia" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/MYS", + "label": "Malaysia" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/NIC", + "label": "Nicaragua" + }, + { + "ref": "country/NPL", + "label": "Nepal" + }, + { + "ref": "country/NRU", + "label": "Nauru" + }, + { + "ref": "country/OMN", + "label": "Oman" + }, + { + "ref": "country/PAK", + "label": "Pakistan" + }, + { + "ref": "country/PAN", + "label": "Panama" + }, + { + "ref": "country/PER", + "label": "Peru" + }, + { + "ref": "country/PHL", + "label": "Philippines" + }, + { + "ref": "country/PNG", + "label": "Papua New Guinea" + }, + { + "ref": "country/PRK", + "label": "North Korea" + }, + { + "ref": "country/PRY", + "label": "Paraguay" + }, + { + "ref": "country/QAT", + "label": "Qatar" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SAU", + "label": "Saudi Arabia" + }, + { + "ref": "country/SDN", + "label": "Sudan" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SGP", + "label": "Singapore" + }, + { + "ref": "country/SLB", + "label": "Solomon Islands" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SLV", + "label": "El Salvador" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SUR", + "label": "Suriname" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/SYR", + "label": "Syria" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/THA", + "label": "Thailand" + }, + { + "ref": "country/TJK", + "label": "Tajikistan" + }, + { + "ref": "country/TKM", + "label": "Turkmenistan" + }, + { + "ref": "country/TLS", + "label": "Timor-Leste" + }, + { + "ref": "country/TON", + "label": "Tonga" + }, + { + "ref": "country/TTO", + "label": "Trinidad and Tobago" + }, + { + "ref": "country/TUN", + "label": "Tunisia" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/URY", + "label": "Uruguay" + }, + { + "ref": "country/VCT", + "label": "Saint Vincent and the Grenadines" + }, + { + "ref": "country/VEN", + "label": "Venezuela" + }, + { + "ref": "country/VNM", + "label": "Vietnam" + }, + { + "ref": "country/VUT", + "label": "Vanuatu" + }, + { + "ref": "country/WSM", + "label": "Samoa" + }, + { + "ref": "country/YEM", + "label": "Yemen" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" + }, + { + "ref": "country/AUS", + "label": "Australia" + }, + { + "ref": "country/AUT", + "label": "Austria" + }, + { + "ref": "country/BEL", + "label": "Belgium" + }, + { + "ref": "country/CAN", + "label": "Canada" + }, + { + "ref": "country/CHE", + "label": "Switzerland" + }, + { + "ref": "country/CHL", + "label": "Chile" + }, + { + "ref": "country/COL", + "label": "Colombia" + }, + { + "ref": "country/CRI", + "label": "Costa Rica" + }, + { + "ref": "country/CZE", + "label": "Czech Republic" + }, + { + "ref": "country/DEU", + "label": "Germany" + }, + { + "ref": "country/DNK", + "label": "Denmark" + }, + { + "ref": "country/ESP", + "label": "Spain" + }, + { + "ref": "country/EST", + "label": "Estonia" + }, + { + "ref": "country/FIN", + "label": "Finland" + }, + { + "ref": "country/FRA", + "label": "France" + }, + { + "ref": "country/GBR", + "label": "United Kingdom" + }, + { + "ref": "country/GRC", + "label": "Greece" + }, + { + "ref": "country/HUN", + "label": "Hungary" + }, + { + "ref": "country/IRL", + "label": "Ireland" + }, + { + "ref": "country/ISL", + "label": "Iceland" + }, + { + "ref": "country/ISR", + "label": "Israel" + }, + { + "ref": "country/ITA", + "label": "Italy" + }, + { + "ref": "country/JPN", + "label": "Japan" + }, + { + "ref": "country/KOR", + "label": "South Korea" + }, + { + "ref": "country/LTU", + "label": "Lithuania" + }, + { + "ref": "country/LUX", + "label": "Luxembourg" + }, + { + "ref": "country/LVA", + "label": "Latvia" + }, + { + "ref": "country/MEX", + "label": "Mexico" + }, + { + "ref": "country/NLD", + "label": "Netherlands" + }, + { + "ref": "country/NOR", + "label": "Norway" + }, + { + "ref": "country/NZL", + "label": "New Zealand" + }, + { + "ref": "country/POL", + "label": "Poland" + }, + { + "ref": "country/PRT", + "label": "Portugal" + }, + { + "ref": "country/SVK", + "label": "Slovakia" + }, + { + "ref": "country/SVN", + "label": "Slovenia" + }, + { + "ref": "country/SWE", + "label": "Sweden" + }, + { + "ref": "country/TUR", + "label": "Turkey" + }, + { + "ref": "country/USA", + "label": "United States of America" + } + ], "resolved_sources": [ { "ref": "provenance/OECDDAC2A", @@ -3338,75 +4988,608 @@ "ref": "dac2aAidType", "label": "DAC 2a aid type" }, - "label": "aid type" - }, - "binding_kind": "value", - "refs": [ + "label": "aid type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "DAC2aAidType206", + "label": "official development assistance" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "set", + "refs": [ + { + "ref": "country/AFG", + "label": "Afghanistan" + }, + { + "ref": "country/AGO", + "label": "Angola" + }, + { + "ref": "country/ARE", + "label": "United Arab Emirates" + }, + { + "ref": "country/ARG", + "label": "Argentina" + }, + { + "ref": "country/ATG", + "label": "Antigua and Barbuda" + }, + { + "ref": "country/AZE", + "label": "Azerbaijan" + }, + { + "ref": "country/BDI", + "label": "Burundi" + }, + { + "ref": "country/BEN", + "label": "Benin" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso" + }, + { + "ref": "country/BGD", + "label": "Bangladesh" + }, + { + "ref": "country/BHR", + "label": "Bahrain" + }, + { + "ref": "country/BHS", + "label": "The Bahamas" + }, + { + "ref": "country/BLZ", + "label": "Belize" + }, + { + "ref": "country/BOL", + "label": "Bolivia" + }, + { + "ref": "country/BRA", + "label": "Brazil" + }, + { + "ref": "country/BRB", + "label": "Barbados" + }, + { + "ref": "country/BRN", + "label": "Brunei" + }, + { + "ref": "country/BTN", + "label": "Bhutan" + }, + { + "ref": "country/BWA", + "label": "Botswana" + }, + { + "ref": "country/CAF", + "label": "Central African Republic" + }, + { + "ref": "country/CHL", + "label": "Chile" + }, + { + "ref": "country/CHN", + "label": "People's Republic of China" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast" + }, + { + "ref": "country/CMR", + "label": "Cameroon" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo" + }, + { + "ref": "country/COL", + "label": "Colombia" + }, + { + "ref": "country/COM", + "label": "Comoros" + }, + { + "ref": "country/CPV", + "label": "Cape Verde" + }, + { + "ref": "country/CRI", + "label": "Costa Rica" + }, + { + "ref": "country/CUB", + "label": "Cuba" + }, + { + "ref": "country/DJI", + "label": "Djibouti" + }, + { + "ref": "country/DMA", + "label": "Dominica" + }, + { + "ref": "country/DOM", + "label": "Dominican Republic" + }, + { + "ref": "country/DZA", + "label": "Algeria" + }, + { + "ref": "country/ECU", + "label": "Ecuador" + }, + { + "ref": "country/EGY", + "label": "Egypt" + }, + { + "ref": "country/ERI", + "label": "Eritrea" + }, + { + "ref": "country/ETH", + "label": "Ethiopia" + }, + { + "ref": "country/FJI", + "label": "Fiji" + }, + { + "ref": "country/FSM", + "label": "Micronesia" + }, + { + "ref": "country/GAB", + "label": "Gabon" + }, + { + "ref": "country/GHA", + "label": "Ghana" + }, + { + "ref": "country/GIN", + "label": "Guinea" + }, + { + "ref": "country/GMB", + "label": "The Gambia" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea" + }, + { + "ref": "country/GRD", + "label": "Grenada" + }, + { + "ref": "country/GTM", + "label": "Guatemala" + }, + { + "ref": "country/GUY", + "label": "Guyana" + }, + { + "ref": "country/HND", + "label": "Honduras" + }, + { + "ref": "country/HTI", + "label": "Haiti" + }, + { + "ref": "country/IDN", + "label": "Indonesia" + }, + { + "ref": "country/IND", + "label": "India" + }, + { + "ref": "country/IRN", + "label": "Iran" + }, + { + "ref": "country/IRQ", + "label": "Iraq" + }, + { + "ref": "country/JAM", + "label": "Jamaica" + }, + { + "ref": "country/JOR", + "label": "Jordan" + }, + { + "ref": "country/KEN", + "label": "Kenya" + }, + { + "ref": "country/KHM", + "label": "Cambodia" + }, + { + "ref": "country/KIR", + "label": "Kiribati" + }, { - "ref": "DAC2aAidType206", - "label": "official development assistance" - } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "financialFlowType", - "label": "financial flow type" + "ref": "country/KNA", + "label": "Saint Kitts and Nevis" }, - "label": "financial flow type" - }, - "binding_kind": "value", - "refs": [ { - "ref": "Disbursement", - "label": "disbursement" - } - ], - "provenance": "binder" - }, - { - "key": { - "axis": "how", - "property": { - "ref": "nettingBasis", - "label": "netting basis" + "ref": "country/KWT", + "label": "Kuwait" }, - "label": "netting basis" - }, - "binding_kind": "value", - "refs": [ { - "ref": "Gross", - "label": "gross" + "ref": "country/LAO", + "label": "Laos" + }, + { + "ref": "country/LBN", + "label": "Lebanon" + }, + { + "ref": "country/LBR", + "label": "Liberia" + }, + { + "ref": "country/LBY", + "label": "Libya" + }, + { + "ref": "country/LCA", + "label": "Saint Lucia" + }, + { + "ref": "country/LKA", + "label": "Sri Lanka" + }, + { + "ref": "country/LSO", + "label": "Lesotho" + }, + { + "ref": "country/MAR", + "label": "Morocco" + }, + { + "ref": "country/MDG", + "label": "Madagascar" + }, + { + "ref": "country/MDV", + "label": "Maldives" + }, + { + "ref": "country/MHL", + "label": "Marshall Islands" + }, + { + "ref": "country/MLI", + "label": "Mali" + }, + { + "ref": "country/MMR", + "label": "Myanmar [Burma]" + }, + { + "ref": "country/MNG", + "label": "Mongolia" + }, + { + "ref": "country/MOZ", + "label": "Mozambique" + }, + { + "ref": "country/MRT", + "label": "Mauritania" + }, + { + "ref": "country/MUS", + "label": "Mauritius" + }, + { + "ref": "country/MWI", + "label": "Malawi" + }, + { + "ref": "country/MYS", + "label": "Malaysia" + }, + { + "ref": "country/NAM", + "label": "Namibia" + }, + { + "ref": "country/NER", + "label": "Niger" + }, + { + "ref": "country/NGA", + "label": "Nigeria" + }, + { + "ref": "country/NIC", + "label": "Nicaragua" + }, + { + "ref": "country/NPL", + "label": "Nepal" + }, + { + "ref": "country/NRU", + "label": "Nauru" + }, + { + "ref": "country/OMN", + "label": "Oman" + }, + { + "ref": "country/PAK", + "label": "Pakistan" + }, + { + "ref": "country/PAN", + "label": "Panama" + }, + { + "ref": "country/PER", + "label": "Peru" + }, + { + "ref": "country/PHL", + "label": "Philippines" + }, + { + "ref": "country/PNG", + "label": "Papua New Guinea" + }, + { + "ref": "country/PRK", + "label": "North Korea" + }, + { + "ref": "country/PRY", + "label": "Paraguay" + }, + { + "ref": "country/QAT", + "label": "Qatar" + }, + { + "ref": "country/RWA", + "label": "Rwanda" + }, + { + "ref": "country/SAU", + "label": "Saudi Arabia" + }, + { + "ref": "country/SDN", + "label": "Sudan" + }, + { + "ref": "country/SEN", + "label": "Senegal" + }, + { + "ref": "country/SGP", + "label": "Singapore" + }, + { + "ref": "country/SLB", + "label": "Solomon Islands" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone" + }, + { + "ref": "country/SLV", + "label": "El Salvador" + }, + { + "ref": "country/SOM", + "label": "Somalia" + }, + { + "ref": "country/SSD", + "label": "South Sudan" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe" + }, + { + "ref": "country/SUR", + "label": "Suriname" + }, + { + "ref": "country/SWZ", + "label": "Swaziland" + }, + { + "ref": "country/SYC", + "label": "Seychelles" + }, + { + "ref": "country/SYR", + "label": "Syria" + }, + { + "ref": "country/TCD", + "label": "Chad" + }, + { + "ref": "country/TGO", + "label": "Togo" + }, + { + "ref": "country/THA", + "label": "Thailand" + }, + { + "ref": "country/TJK", + "label": "Tajikistan" + }, + { + "ref": "country/TKM", + "label": "Turkmenistan" + }, + { + "ref": "country/TLS", + "label": "Timor-Leste" + }, + { + "ref": "country/TON", + "label": "Tonga" + }, + { + "ref": "country/TTO", + "label": "Trinidad and Tobago" + }, + { + "ref": "country/TUN", + "label": "Tunisia" + }, + { + "ref": "country/TZA", + "label": "Tanzania" + }, + { + "ref": "country/UGA", + "label": "Uganda" + }, + { + "ref": "country/URY", + "label": "Uruguay" + }, + { + "ref": "country/VCT", + "label": "Saint Vincent and the Grenadines" + }, + { + "ref": "country/VEN", + "label": "Venezuela" + }, + { + "ref": "country/VNM", + "label": "Vietnam" + }, + { + "ref": "country/VUT", + "label": "Vanuatu" + }, + { + "ref": "country/WSM", + "label": "Samoa" + }, + { + "ref": "country/YEM", + "label": "Yemen" + }, + { + "ref": "country/ZAF", + "label": "South Africa" + }, + { + "ref": "country/ZMB", + "label": "Zambia" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe" } ], "provenance": "binder" }, - { - "key": { - "axis": "how", - "property": { - "ref": "dacTypeOfFinance", - "label": "DAC type of finance" - }, - "label": "DAC type of finance" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, - { - "key": { - "axis": "where", - "label": "place" - }, - "binding_kind": "unbound", - "refs": [], - "provenance": "binder" - }, { "key": { "axis": "when", @@ -3421,29 +5604,25 @@ "axis": "source", "label": "data source" }, - "binding_kind": "value", - "refs": [ - { - "ref": "provenance/OECDDAC2A", - "label": "OECD DAC2A" - } - ], + "binding_kind": "unbound", + "refs": [], "provenance": "binder" } ], "query_qualifiers": [], "requested_window": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, - "capability_version": "cap_347a470e04c97eec" + "capability_version": "cap_94e25737d859392c" }, "confidence": "high", + "available_at_place": true, "alternative_measures": [ { "definition": { "schema_version": 1, - "spec_id": "spec_de034b2632a047bf6b7f6c8fdf1b172e", + "spec_id": "spec_52f77b1b2faab0669b4e550e53379c22", "identity": { "identity_version": "spec1", "shape": { @@ -3482,17 +5661,187 @@ } } ], - "entities": {}, + "entities": { + "destination": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], + "origin": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CHL", + "country/COL", + "country/CRI", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ISR", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/MEX", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/TUR", + "country/USA" + ] + }, "requested_window": { "kind": "range", - "start_year": 2017, + "start_year": 1966, "end_year": 2024 - }, - "facets": { - "provenance": { - "state": "value", - "ref": "provenance/OECDDAC2A" - } } } }, @@ -3535,8 +5884,8 @@ } } ], - "served_rows": 125252, - "served_rows_exact": false + "served_rows": 112830, + "served_rows_exact": true } ], "measure_label": "gross disbursements", @@ -3584,29 +5933,17 @@ } } ], - "role_axis_facts": [ - { - "role": "destination", - "member_count": 241, - "members_available": true - }, - { - "role": "origin", - "member_count": 172, - "members_available": true - } - ], "unit_conversion": { "currencies": [ { "code": "AED", "noun": "UAE dirhams", "current_years": { - "start_year": 2017, + "start_year": 1997, "end_year": 2021 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 2023, @@ -3616,11 +5953,11 @@ "code": "AFN", "noun": "Afghan afghanis", "current_years": { - "start_year": 2017, + "start_year": 2002, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 2002, @@ -3630,11 +5967,11 @@ "code": "ALL", "noun": "Albanian leks", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -3644,11 +5981,11 @@ "code": "AMD", "noun": "Armenian drams", "current_years": { - "start_year": 2017, + "start_year": 1992, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1992, @@ -3658,11 +5995,11 @@ "code": "AOA", "noun": "Angolan kwanzas", "current_years": { - "start_year": 2017, + "start_year": 1991, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1991, @@ -3672,11 +6009,11 @@ "code": "ARS", "noun": "Argentine pesos", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -3686,11 +6023,11 @@ "code": "AUD", "noun": "Australian dollars", "current_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1960, @@ -3700,11 +6037,11 @@ "code": "AWG", "noun": "Aruban florins", "current_years": { - "start_year": 2017, + "start_year": 1995, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1995, @@ -3714,11 +6051,11 @@ "code": "AZN", "noun": "Azerbaijani manats", "current_years": { - "start_year": 2017, + "start_year": 2014, "end_year": 2019 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 2023, @@ -3728,11 +6065,11 @@ "code": "BAM", "noun": "Bosnia-Herzegovina convertible marks", "current_years": { - "start_year": 2017, + "start_year": 1996, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1996, @@ -3742,11 +6079,11 @@ "code": "BBD", "noun": "Barbadian dollars", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -3756,11 +6093,11 @@ "code": "BDT", "noun": "Bangladeshi taka", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -3770,11 +6107,11 @@ "code": "BHD", "noun": "Bahraini dinars", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -3784,11 +6121,11 @@ "code": "BIF", "noun": "Burundian francs", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -3798,11 +6135,11 @@ "code": "BND", "noun": "Brunei dollars", "current_years": { - "start_year": 2017, + "start_year": 1985, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1985, @@ -3812,11 +6149,11 @@ "code": "BOB", "noun": "Bolivian bolivianos", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -3826,11 +6163,11 @@ "code": "BRL", "noun": "Brazilian reais", "current_years": { - "start_year": 2017, + "start_year": 1986, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1986, @@ -3840,11 +6177,11 @@ "code": "BSD", "noun": "Bahamian dollars", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -3854,11 +6191,11 @@ "code": "BTN", "noun": "Bhutanese ngultrums", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -3868,11 +6205,11 @@ "code": "BWP", "noun": "Botswana pula", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -3882,11 +6219,11 @@ "code": "BYN", "noun": "Belarusian rubles", "current_years": { - "start_year": 2017, + "start_year": 1992, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1992, @@ -3896,11 +6233,11 @@ "code": "BZD", "noun": "Belize dollars", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -3910,11 +6247,11 @@ "code": "CAD", "noun": "Canadian dollars", "current_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1960, @@ -3924,11 +6261,11 @@ "code": "CDF", "noun": "Congolese francs", "current_years": { - "start_year": 2017, + "start_year": 1991, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1991, @@ -3938,11 +6275,11 @@ "code": "CHF", "noun": "Swiss francs", "current_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1960, @@ -3952,11 +6289,11 @@ "code": "CLP", "noun": "Chilean pesos", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -3966,11 +6303,11 @@ "code": "CNY", "noun": "Chinese yuan", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -3980,11 +6317,11 @@ "code": "COP", "noun": "Colombian pesos", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -3994,11 +6331,11 @@ "code": "CRC", "noun": "Costa Rican colones", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4008,11 +6345,11 @@ "code": "CVE", "noun": "Cape Verdean escudos", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4022,11 +6359,11 @@ "code": "CZK", "noun": "Czech korunas", "current_years": { - "start_year": 2017, + "start_year": 1998, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1998, @@ -4036,11 +6373,11 @@ "code": "DJF", "noun": "Djiboutian francs", "current_years": { - "start_year": 2017, + "start_year": 1990, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1990, @@ -4050,11 +6387,11 @@ "code": "DKK", "noun": "Danish kroner", "current_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1960, @@ -4064,11 +6401,11 @@ "code": "DOP", "noun": "Dominican pesos", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4078,11 +6415,11 @@ "code": "DZD", "noun": "Algerian dinars", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4092,11 +6429,11 @@ "code": "EGP", "noun": "Egyptian pounds", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4106,11 +6443,11 @@ "code": "ERN", "noun": "Eritrean nakfas", "current_years": { - "start_year": 2017, + "start_year": 1992, "end_year": 2019 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1992, @@ -4120,11 +6457,11 @@ "code": "ETB", "noun": "Ethiopian birr", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4134,11 +6471,11 @@ "code": "EUR", "noun": "euros", "current_years": { - "start_year": 2017, + "start_year": 1973, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1973, @@ -4148,11 +6485,11 @@ "code": "FJD", "noun": "Fijian dollars", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4162,11 +6499,11 @@ "code": "GBP", "noun": "British pounds", "current_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1960, @@ -4176,11 +6513,11 @@ "code": "GEL", "noun": "Georgian lari", "current_years": { - "start_year": 2017, + "start_year": 1994, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1994, @@ -4190,11 +6527,11 @@ "code": "GHS", "noun": "Ghanaian cedis", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4204,11 +6541,11 @@ "code": "GMD", "noun": "Gambian dalasis", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4218,11 +6555,11 @@ "code": "GNF", "noun": "Guinean francs", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4232,11 +6569,11 @@ "code": "GTQ", "noun": "Guatemalan quetzales", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4246,11 +6583,11 @@ "code": "GYD", "noun": "Guyanese dollars", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4260,11 +6597,11 @@ "code": "HKD", "noun": "Hong Kong dollars", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4274,11 +6611,11 @@ "code": "HNL", "noun": "Honduran lempiras", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4288,11 +6625,11 @@ "code": "HTG", "noun": "Haitian gourdes", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4302,11 +6639,11 @@ "code": "HUF", "noun": "Hungarian forints", "current_years": { - "start_year": 2017, + "start_year": 2003, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 2003, @@ -4316,11 +6653,11 @@ "code": "IDR", "noun": "Indonesian rupiahs", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4330,11 +6667,11 @@ "code": "ILS", "noun": "Israeli new shekels", "current_years": { - "start_year": 2017, + "start_year": 1997, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1997, @@ -4344,11 +6681,11 @@ "code": "INR", "noun": "Indian rupees", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4358,11 +6695,11 @@ "code": "IQD", "noun": "Iraqi dinars", "current_years": { - "start_year": 2017, + "start_year": 2000, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 2000, @@ -4372,11 +6709,11 @@ "code": "IRR", "noun": "Iranian rials", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4386,11 +6723,11 @@ "code": "ISK", "noun": "Icelandic krónur", "current_years": { - "start_year": 2017, + "start_year": 1997, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1997, @@ -4400,11 +6737,11 @@ "code": "JMD", "noun": "Jamaican dollars", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4414,11 +6751,11 @@ "code": "JOD", "noun": "Jordanian dinars", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4428,11 +6765,11 @@ "code": "JPY", "noun": "Japanese yen", "current_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1960, @@ -4442,11 +6779,11 @@ "code": "KES", "noun": "Kenyan shillings", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4456,11 +6793,11 @@ "code": "KGS", "noun": "Kyrgyz soms", "current_years": { - "start_year": 2017, + "start_year": 1992, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1992, @@ -4470,11 +6807,11 @@ "code": "KHR", "noun": "Cambodian riels", "current_years": { - "start_year": 2017, + "start_year": 1986, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1986, @@ -4484,11 +6821,11 @@ "code": "KMF", "noun": "Comorian francs", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4498,11 +6835,11 @@ "code": "KRW", "noun": "South Korean won", "current_years": { - "start_year": 2017, + "start_year": 1987, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1987, @@ -4512,11 +6849,11 @@ "code": "KWD", "noun": "Kuwaiti dinars", "current_years": { - "start_year": 2017, + "start_year": 1995, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1995, @@ -4526,11 +6863,11 @@ "code": "KZT", "noun": "Kazakh tenge", "current_years": { - "start_year": 2017, + "start_year": 2013, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 2013, @@ -4540,11 +6877,11 @@ "code": "LAK", "noun": "Lao kip", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4554,11 +6891,11 @@ "code": "LBP", "noun": "Lebanese pounds", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4568,11 +6905,11 @@ "code": "LKR", "noun": "Sri Lankan rupees", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4582,11 +6919,11 @@ "code": "LSL", "noun": "Lesotho maloti", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4596,11 +6933,11 @@ "code": "LYD", "noun": "Libyan dinars", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4610,11 +6947,11 @@ "code": "MAD", "noun": "Moroccan dirhams", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4624,11 +6961,11 @@ "code": "MDL", "noun": "Moldovan lei", "current_years": { - "start_year": 2017, + "start_year": 1992, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1992, @@ -4638,11 +6975,11 @@ "code": "MGA", "noun": "Malagasy ariary", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4652,11 +6989,11 @@ "code": "MKD", "noun": "Macedonian denars", "current_years": { - "start_year": 2017, + "start_year": 1992, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1992, @@ -4666,11 +7003,11 @@ "code": "MMK", "noun": "Myanmar kyats", "current_years": { - "start_year": 2017, + "start_year": 1998, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1998, @@ -4680,11 +7017,11 @@ "code": "MNT", "noun": "Mongolian tugriks", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4694,11 +7031,11 @@ "code": "MOP", "noun": "Macanese patacas", "current_years": { - "start_year": 2017, + "start_year": 2001, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 2001, @@ -4708,11 +7045,11 @@ "code": "MRU", "noun": "Mauritanian ouguiyas", "current_years": { - "start_year": 2017, + "start_year": 1990, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1990, @@ -4722,11 +7059,11 @@ "code": "MUR", "noun": "Mauritian rupees", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4736,11 +7073,11 @@ "code": "MVR", "noun": "Maldivian rufiyaa", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4750,11 +7087,11 @@ "code": "MWK", "noun": "Malawian kwachas", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4764,11 +7101,11 @@ "code": "MXN", "noun": "Mexican pesos", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4778,11 +7115,11 @@ "code": "MYR", "noun": "Malaysian ringgits", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4792,11 +7129,11 @@ "code": "MZN", "noun": "Mozambican meticais", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4806,11 +7143,11 @@ "code": "NAD", "noun": "Namibian dollars", "current_years": { - "start_year": 2017, + "start_year": 1989, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1989, @@ -4820,11 +7157,11 @@ "code": "NGN", "noun": "Nigerian naira", "current_years": { - "start_year": 2017, + "start_year": 1990, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1990, @@ -4834,11 +7171,11 @@ "code": "NIO", "noun": "Nicaraguan córdobas", "current_years": { - "start_year": 2017, + "start_year": 1987, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1987, @@ -4848,11 +7185,11 @@ "code": "NOK", "noun": "Norwegian kroner", "current_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1960, @@ -4862,11 +7199,11 @@ "code": "NPR", "noun": "Nepalese rupees", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4876,11 +7213,11 @@ "code": "NZD", "noun": "New Zealand dollars", "current_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1961, @@ -4890,11 +7227,11 @@ "code": "OMR", "noun": "Omani rials", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4904,11 +7241,11 @@ "code": "PEN", "noun": "Peruvian soles", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4918,11 +7255,11 @@ "code": "PGK", "noun": "Papua New Guinean kina", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4932,11 +7269,11 @@ "code": "PHP", "noun": "Philippine pesos", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4946,11 +7283,11 @@ "code": "PKR", "noun": "Pakistani rupees", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4960,11 +7297,11 @@ "code": "PLN", "noun": "Polish zlotys", "current_years": { - "start_year": 2017, + "start_year": 1998, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1998, @@ -4974,11 +7311,11 @@ "code": "PYG", "noun": "Paraguayan guaranís", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -4988,11 +7325,11 @@ "code": "QAR", "noun": "Qatari riyals", "current_years": { - "start_year": 2023, - "end_year": 2023 + "start_year": 1985, + "end_year": 1990 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 2023, @@ -5002,11 +7339,11 @@ "code": "RON", "noun": "Romanian lei", "current_years": { - "start_year": 2017, + "start_year": 2013, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 2013, @@ -5016,11 +7353,11 @@ "code": "RSD", "noun": "Serbian dinars", "current_years": { - "start_year": 2017, + "start_year": 1997, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1997, @@ -5030,11 +7367,11 @@ "code": "RUB", "noun": "Russian rubles", "current_years": { - "start_year": 2017, + "start_year": 2010, "end_year": 2020 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 2010, @@ -5044,11 +7381,11 @@ "code": "RWF", "noun": "Rwandan francs", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5058,11 +7395,11 @@ "code": "SAR", "noun": "Saudi riyals", "current_years": { - "start_year": 2017, + "start_year": 2000, "end_year": 2023 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 2000, @@ -5072,11 +7409,11 @@ "code": "SBD", "noun": "Solomon Islands dollars", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5086,11 +7423,11 @@ "code": "SCR", "noun": "Seychellois rupees", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5100,11 +7437,11 @@ "code": "SDG", "noun": "Sudanese pounds", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5114,11 +7451,11 @@ "code": "SEK", "noun": "Swedish kronor", "current_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1960, @@ -5128,11 +7465,11 @@ "code": "SGD", "noun": "Singapore dollars", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5142,11 +7479,11 @@ "code": "SLE", "noun": "Sierra Leonean leones", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5156,11 +7493,11 @@ "code": "SRD", "noun": "Surinamese dollars", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5170,11 +7507,11 @@ "code": "SSP", "noun": "South Sudanese pounds", "current_years": { - "start_year": 2017, + "start_year": 2011, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 2011, @@ -5184,11 +7521,11 @@ "code": "STN", "noun": "São Tomé and Príncipe dobras", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5197,23 +7534,26 @@ { "code": "SYP", "noun": "Syrian pounds", + "current_years": { + "start_year": 1980, + "end_year": 2010 + }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, - "base_year_max": 2010, - "current_years": null + "base_year_max": 2010 }, { "code": "SZL", "noun": "Swazi emalangeni", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5223,11 +7563,11 @@ "code": "THB", "noun": "Thai baht", "current_years": { - "start_year": 2018, - "end_year": 2024 + "start_year": 2006, + "end_year": 2016 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 2018, @@ -5237,11 +7577,11 @@ "code": "TJS", "noun": "Tajikistani somonis", "current_years": { - "start_year": 2017, + "start_year": 1992, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1992, @@ -5251,11 +7591,11 @@ "code": "TMT", "noun": "Turkmenistani manat", "current_years": { - "start_year": 2017, + "start_year": 1992, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1992, @@ -5265,11 +7605,11 @@ "code": "TND", "noun": "Tunisian dinars", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5279,11 +7619,11 @@ "code": "TOP", "noun": "Tongan paʻanga", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5293,11 +7633,11 @@ "code": "TRY", "noun": "Turkish lira", "current_years": { - "start_year": 2017, + "start_year": 1990, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1990, @@ -5307,11 +7647,11 @@ "code": "TTD", "noun": "Trinidad and Tobago dollars", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5321,11 +7661,11 @@ "code": "TWD", "noun": "New Taiwan dollars", "current_years": { - "start_year": 2018, - "end_year": 2021 + "start_year": 2006, + "end_year": 2016 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 2023, @@ -5335,11 +7675,11 @@ "code": "TZS", "noun": "Tanzanian shillings", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5349,11 +7689,11 @@ "code": "UAH", "noun": "Ukrainian hryvnias", "current_years": { - "start_year": 2017, + "start_year": 1991, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1991, @@ -5363,11 +7703,11 @@ "code": "UGX", "noun": "Ugandan shillings", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5377,11 +7717,11 @@ "code": "USD", "noun": "US dollars", "current_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1960, @@ -5391,11 +7731,11 @@ "code": "UYU", "noun": "Uruguayan pesos", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5405,11 +7745,11 @@ "code": "UZS", "noun": "Uzbekistani soms", "current_years": { - "start_year": 2017, + "start_year": 1992, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1992, @@ -5423,7 +7763,7 @@ "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 2017, @@ -5433,11 +7773,11 @@ "code": "VND", "noun": "Vietnamese dong", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5447,11 +7787,11 @@ "code": "VUV", "noun": "Vanuatu vatu", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5461,11 +7801,11 @@ "code": "WST", "noun": "Samoan tala", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5475,11 +7815,11 @@ "code": "XAF", "noun": "Central African CFA francs", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5489,11 +7829,11 @@ "code": "XCD", "noun": "East Caribbean dollars", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5503,11 +7843,11 @@ "code": "XOF", "noun": "West African CFA francs", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5517,11 +7857,11 @@ "code": "YER", "noun": "Yemeni rials", "current_years": { - "start_year": 2017, + "start_year": 2014, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 2014, @@ -5531,11 +7871,11 @@ "code": "ZAR", "noun": "South African rand", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5545,11 +7885,11 @@ "code": "ZMW", "noun": "Zambian kwachas", "current_years": { - "start_year": 2017, + "start_year": 1980, "end_year": 2024 }, "constant_years": { - "start_year": 2017, + "start_year": 1966, "end_year": 2024 }, "base_year_min": 1980, @@ -5563,7 +7903,7 @@ } } ], - "rendered_sentence": "Gross disbursements to 241 recipients from 172 providers for official development assistance, 2017 to 2024. Current US dollars · OECD DAC2A. Assumed: every provider.", + "rendered_sentence": "Gross disbursements to 133 recipients from 38 providers for official development assistance, 1966 to 2024. Current US dollars · OECD DAC2a. You asked for Chile, Colombia, Costa Rica, and Mexico. The data holds no values for them.", "sentence_plan": [ { "kind": "slot", @@ -5589,12 +7929,146 @@ }, { "kind": "slot", - "text": "241 recipients", + "text": "133 recipients", "axis": "where", "segment": "heading", "role": "destination", "binding_ref": "where:", - "entity_refs": [], + "entity_refs": [ + "country/AFG", + "country/AGO", + "country/ARE", + "country/ARG", + "country/ATG", + "country/AZE", + "country/BDI", + "country/BEN", + "country/BFA", + "country/BGD", + "country/BHR", + "country/BHS", + "country/BLZ", + "country/BOL", + "country/BRA", + "country/BRB", + "country/BRN", + "country/BTN", + "country/BWA", + "country/CAF", + "country/CHL", + "country/CHN", + "country/CIV", + "country/CMR", + "country/COD", + "country/COG", + "country/COL", + "country/COM", + "country/CPV", + "country/CRI", + "country/CUB", + "country/DJI", + "country/DMA", + "country/DOM", + "country/DZA", + "country/ECU", + "country/EGY", + "country/ERI", + "country/ETH", + "country/FJI", + "country/FSM", + "country/GAB", + "country/GHA", + "country/GIN", + "country/GMB", + "country/GNB", + "country/GNQ", + "country/GRD", + "country/GTM", + "country/GUY", + "country/HND", + "country/HTI", + "country/IDN", + "country/IND", + "country/IRN", + "country/IRQ", + "country/JAM", + "country/JOR", + "country/KEN", + "country/KHM", + "country/KIR", + "country/KNA", + "country/KWT", + "country/LAO", + "country/LBN", + "country/LBR", + "country/LBY", + "country/LCA", + "country/LKA", + "country/LSO", + "country/MAR", + "country/MDG", + "country/MDV", + "country/MHL", + "country/MLI", + "country/MMR", + "country/MNG", + "country/MOZ", + "country/MRT", + "country/MUS", + "country/MWI", + "country/MYS", + "country/NAM", + "country/NER", + "country/NGA", + "country/NIC", + "country/NPL", + "country/NRU", + "country/OMN", + "country/PAK", + "country/PAN", + "country/PER", + "country/PHL", + "country/PNG", + "country/PRK", + "country/PRY", + "country/QAT", + "country/RWA", + "country/SAU", + "country/SDN", + "country/SEN", + "country/SGP", + "country/SLB", + "country/SLE", + "country/SLV", + "country/SOM", + "country/SSD", + "country/STP", + "country/SUR", + "country/SWZ", + "country/SYC", + "country/SYR", + "country/TCD", + "country/TGO", + "country/THA", + "country/TJK", + "country/TKM", + "country/TLS", + "country/TON", + "country/TTO", + "country/TUN", + "country/TZA", + "country/UGA", + "country/URY", + "country/VCT", + "country/VEN", + "country/VNM", + "country/VUT", + "country/WSM", + "country/YEM", + "country/ZAF", + "country/ZMB", + "country/ZWE" + ], "states": [ "where:" ], @@ -5610,11 +8084,50 @@ }, { "kind": "slot", - "text": "172 providers", + "text": "38 providers", "segment": "heading", "role": "origin", "binding_ref": "origin:", - "entity_refs": [], + "entity_refs": [ + "country/AUS", + "country/AUT", + "country/BEL", + "country/CAN", + "country/CHE", + "country/CHL", + "country/COL", + "country/CRI", + "country/CZE", + "country/DEU", + "country/DNK", + "country/ESP", + "country/EST", + "country/FIN", + "country/FRA", + "country/GBR", + "country/GRC", + "country/HUN", + "country/IRL", + "country/ISL", + "country/ISR", + "country/ITA", + "country/JPN", + "country/KOR", + "country/LTU", + "country/LUX", + "country/LVA", + "country/MEX", + "country/NLD", + "country/NOR", + "country/NZL", + "country/POL", + "country/PRT", + "country/SVK", + "country/SVN", + "country/SWE", + "country/TUR", + "country/USA" + ], "states": [ "origin:" ], @@ -5683,7 +8196,7 @@ }, { "kind": "slot", - "text": "2017 to 2024", + "text": "1966 to 2024", "axis": "when", "segment": "heading", "binding_ref": "when:", @@ -5727,10 +8240,9 @@ }, { "kind": "slot", - "text": "OECD DAC2A", + "text": "OECD DAC2a", "axis": "source", "segment": "byline", - "binding_ref": "source:", "entity_refs": [], "states": [ "source:" @@ -5746,31 +8258,15 @@ { "kind": "text", "text": " ", - "segment": "assumption", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "Assumed: ", - "segment": "assumption", - "entity_refs": [], - "states": [], - "part_index": 0 - }, - { - "kind": "text", - "text": "every provider", - "segment": "assumption", + "segment": "departure", "entity_refs": [], "states": [], "part_index": 0 }, { "kind": "text", - "text": ".", - "segment": "assumption", + "text": "You asked for Chile, Colombia, Costa Rica, and Mexico. The data holds no values for them.", + "segment": "departure", "entity_refs": [], "states": [], "part_index": 0 @@ -5783,26 +8279,26 @@ { "request": { "method": "GET", - "origin_path": "/api/datasets/spec_8a4676c4abdf43d105aeff9d4ba9299b/cv_50e17ab9c2e732f13c48cf2028ac5928/files/sha256:cf2a4a97cc0fdfeb74ce021502e58c70d87ae4d67dc061a46fa62bb4f106a192" + "origin_path": "/api/datasets/spec_8150d26a25222b2043e8c12b250b764d/cv_fe2e676a79899730eac6110f58213472/files/sha256:55f95f11ffe010e99407d279d159e956d4dfa6a6ba89f6d73aa32fb952fccd1d" }, "response": { "status": 302, "headers": { - "location": "https://storage.googleapis.com/e2e-working/sha256%3Acf2a4a97cc0fdfeb74ce021502e58c70d87ae4d67dc061a46fa62bb4f106a192?X-Goog-Signature=redacted", - "x-dfo-trace-id": "3bf6929fd74b42ca953c352829d86745" + "content-type": "text/html", + "location": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A55f95f11ffe010e99407d279d159e956d4dfa6a6ba89f6d73aa32fb952fccd1d?X-Goog-Signature=redacted", + "x-dfo-trace-id": "99174adf5a674fefa2eb760afac524d3" } } }, { "request": { "method": "GET", - "url": "https://storage.googleapis.com/e2e-working/sha256%3Acf2a4a97cc0fdfeb74ce021502e58c70d87ae4d67dc061a46fa62bb4f106a192?X-Goog-Signature=redacted" + "url": "https://storage.googleapis.com/dev-fin-observatory-datasets-working/sha256%3A55f95f11ffe010e99407d279d159e956d4dfa6a6ba89f6d73aa32fb952fccd1d?X-Goog-Signature=redacted" }, "response": { "status": 200, "headers": { - "content-type": "application/vnd.apache.parquet", - "x-dfo-trace-id": "e9f4912dd1e54c8491dd021b356724c3" + "content-type": "application/vnd.apache.parquet" }, "body_file": "operation-resume.parquet" } @@ -5811,21 +8307,21 @@ "expect": [ { "operation": { - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", - "status": "pending" + "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", + "status": "running" } }, { "dataset": { - "rows": 123015, + "rows": 112203, "columns": [ "stat_var", "financingProvider", "financingProvider_label", - "financingProvider_party_kind", + "financingProvider_kind", "financingRecipient", "financingRecipient_label", - "financingRecipient_party_kind", + "financingRecipient_kind", "dac2aAidType", "dac2aAidType_label", "time_period", @@ -5844,26 +8340,23 @@ "members": [ { "parts": [], - "spec_id": "spec_8a4676c4abdf43d105aeff9d4ba9299b", - "content_version": "cv_50e17ab9c2e732f13c48cf2028ac5928", - "sentence": "Gross disbursements to 241 recipients from 172 providers for official development assistance, 2017 to 2024. Current US dollars · OECD DAC2A." + "spec_id": "spec_8150d26a25222b2043e8c12b250b764d", + "content_version": "cv_fe2e676a79899730eac6110f58213472", + "sentence": "Gross disbursements to 133 recipients from 38 providers for official development assistance, 1966 to 2024. Current US dollars · OECD DAC2a." } ], "missing": [], "long_builds": [ { - "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "operation_id": "op_d3596ce124b0257af0dfded6707dc8179b5e046e67080dd6995f7e0de23f7fe5", "poll_waits": [ 1.5, 1.5, 1.5, 1.5, - 1.518, - 1.901, - 2.381, - 2.979, - 3.729, - 4.696 + 1.881, + 2.386, + 3.058 ], "resubmissions": 0 } diff --git a/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.parquet b/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.parquet index c7a5f317990a3f6ab81e56c418d9144c6288faf5..b39d4a808efefbe2833a8d52b65bbb36589e2224 100644 GIT binary patch literal 489647 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%0AGQbccZtf_6r8~{da^fYO3N8{OY8>t9i=1vI8Lz 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

@er zZ9y;MgXeIy;DG*OVw}=?CRhZW!$sL#N=b6p5_i{yn9+m`d301A${#yI--OM9I3=fp z<2@(p;K3%28Q3(0V#b<$BPm@EtbOgE-+>TyC{Rx4*2}(93aG)X!?N zXbuu)CtE$xf?Yf%;9J#kJA}<5&k`eNpIT+o%GfdyFS+qL+zpCstn`)OY4(96hIXh| z64w!rLc@gZtG+JR8i~DuX*Z<2RR{58xa?)4Wot{)s$lSXI>4e502r?&)D0IGbqlm%tn}uUiJ5Y>NKGi@NSmvp6IVVF#&gm)swi_`=8}znEk+m`k zUCM+gDl-4^j1_ebiy+ZYtq-6pzP-&#KQ0y7Q{F10!UvUun8WlB>>UQ<8HO{PKUzMHi?&B}#+KlF+ zLS4Q1RAqsyp0oI*>b6$~`KsG~tSs{N(?ne4%ssQ=669OhrE)#*5PP*6p|bZkfvdEW z8StJXJ`f(2^=S+Y(DRh&u*ZO7@tW!3t&K9q5b@nEc?WepGvIz9~1 ztiH4u#83k3EJiez{#j`NKBEJRQkq&xkkWA4UF?dhC(+w7V0Rd?;*InN!*+_Uf?u03uT`YOAyC>$^x!*x8vL2$ZBEARktV2UWQ+VMae;R=_w8e8)o~o=xanA`UZ9p0IHGERJR-%Is-R>_7KL5yISo*%l zZg&~>7TwhO`6Ws3+y z74L_lRZ+@oeZNxt1@7$SwM|Le~Jum+^S`= z!WTrjgeF~7NYfw$tAXXy77%X#J`2u^`&kPpYJN*}VugFkY7=rbcQT&)*a2>^ z?|`jUpDP1(6<*9@kSp=9;rk?eOY-%>xO(m>ToG*z=EHYONmx2JwyHpcI3UU})thYK z<0nkD&1lBcAguM@X8Htuak3%_oQ*MHpl}RX{RVVmuM}u{nlp2jQvR zCG=7Dzzp%b^pdUsFr5#?aenheH5NSNKM3N?T0frS_f7#-!aM2Ms8p+Yx0CAb(7E zyeQ|J(%3Unv<27tb`!bzsH+sZ(75AV4S*Y({9ysI=3jA3k(*aPFIvOo`cipA9^Z0V zXmHP0Eky5(y5gANqS+tU0fX^>RdB{miJPh0WOGN#o&Z5t&V}Kf90wucJL}FPuTt&B zIM`l#g(`20DD<>q$)V|MrkKyHPP_$zTpglHRtU(iL?u3}XOUwqsN>7kIDG@x!dhmb zPh@*T+CE4mS)=`hh0iV{sz>TEM00^&27ssNYB^*f!!2?QZ19t;StThZ#tqG^aVeI^j1r!>%2-6OhB*u#$p5VmU$^?rUq z1bs?qpRG^HCPF6`*1+^Cdqga}NpGnZyE3Un2(@$5uA}na4Q~`Nr7NNlRQc-BiUbN= zIDos^neoe?MO696Kb(2)d07A^yXJI)6b*h07BYu!K~%SBF9IpaIQQP?N*p}cd#=C0 zvjfgKi#+i^36e=Q$cYi?z+a@d(w9qd8`kAD0O*6K<^0G}rSH9yN?e?^d{WeY$Gby( zv0pD&n*m=`E=aClZGm(!{0t_=ST-E3zITZ78;yNz0VDsuvQhyeVYPrV%4KEL34~vg zQw?Z;T-51>-V#P=^b=4|)joq+GXD;6ts1)(EW^;7k6XQ8ZGpo6{XR>O(90RcZ65~g zaU*(fHe?}&^!lw_eYkhE5f0^!YEZb1Xk}q9JycPS29Na>xUl{mox;l#?@N$O*-F{x z<+-6HZ~+V@s88kAEevw4_PGW^$&T2kvvW_k1C|iacDu=+;K`YF5Uq~-Kua>P51l+Fhntgfj~r}5Y^&_;OWn@}qSXDcGlr5YLE`uj8xWFNf8fO^ z_uVLVcit>1hOwQi&&nwT_TH2n7^w8pI`C*T_^%kpXXrYolHrs$k*ots&0SmVY8xxH zKmF{U5^PNK{OcR=kv896QTDA`1!+T`&ZR8tR6{oyNXl1iv z$X$HYTY|ua&*Z3yw1rhE%6f5h6{i>>rMm9&hrsWsA4MV`Vr{y~HHJ341|u=u$qD;q z-RK&Krji9<1@%%$66K|zHIVGBxl%E^3NuXu*f6!rn|@qSlT~1oZ~aNC?Et;GvO?q0 zUx53w*M3Xuus19Eh;Z5p**p>BoE{d{@Me9L6y`wq z4Z{vp-PDPwpW$r~Nm}64FcR(-9jMB3Lc+vb>kIVPgIKysUdTW;YcIB2T{~Lv z+YgKJT$Xj$EybUAL2V31)Ct@Z;(-)x8}GJ5&TF?~z;OyS6~F6(xaeRxI28roa;_ic zpLTP~4HYr7>`YPgr0HPZ8lIJ1h`lYxEFFv*9c`&a5&c?Al-s}Ek4d3IiMU216oOf+ zWmF!Nl;&LBhLU6MyRk)OIk89O^e7(A47TNHqt9Q9rh#2f_`8#bgVU6k1K1~Db|rQQ zbJm?^Ze993p55`p7$*#vPuk*r@0*5dc(gzDbw(-mh~CVbewh~Gr9`)7P8_1UK6j>g z^yo4%V%Dc<;zGR)xVyRY23?M;ogRZ5!Oo7yqbgrxQqT|tJWdHPM)O`Yca*}Ss3-O* z)>|0osb09EYTpU@sebwzBJklXbkwnxSfkeEc`;u|{o9TRE^A(=aBcK`QW}cf9J1uO zcKe}<9E^!$;$o*VlA$y3wJu1gR9DxZ6n*_#levKMy7Ky{3Qm{5tX9#6Ik$!btl%C| zvt3jw&?@u!Cl(Jcz7xephWk8bwV=bgXGCE9$kk<{jTEI~Ci+)DYQaL)F zYh(Vy{n@w$Vo;qr9JU*>3mB2!6j;6E^)U*}6C-q4f2oMEpwnwAW5A&94&ljahlxrc zrJ0O8N%Au>!ZH5>jG*|pavUKGQEitW0V&F~hGHaR5NMoO=PRjr%t&eiorkgB2vcF%)NnI=QQ9JVf zFs!^zfh<)vh73xLMe8VEzRHGDv?JdLFj4JdHI#1hJA-IVVo!*1SmxQ6D&WnuPC?s5 z`|YU7ar4O={AP?n+-HfSV&ZjY5OKESQXbv#zwZ?-kLsPfoM|BIj}w0=&weI&>(?#V zRrQDHbufSqLLOZb!wD6sos`FiTJ;j=?!H>=XMD(fXDuLPPC-artuH_knB61(yLE*e zH_$UvAr`;SD;y4u>#g>62zMejVlO!J!jK!@CvPH&R2qG80xa^G^d>$ zlF8E+w#&((Vr8uLxM~LGIu2#3vgJB3+H18qG1{IZU~A=L4eu0^8$g@z=V%b&%9L7* zi}IaiFT$hSAFa^1{evE2_4yL2j&aXpogh-Q;?fE`g~D=f5;qQ80rNp=Aw%&c%P?#l zl7Us%nJKqKRJ~xBpg7zM8{mP|1!lJaSks~r#XU%L7j&NmTq5Rtf3d|*eRcjQ0FT>A zDMbIfn0(D?d&XaYnCa$LDfcqCV60svJJ~y8cJ%P>pv3kra_!9&oL%jOtBin4Lv}${ zr@`wsi^{xV^(;w*!y19P)u-y|<8<5YIxMBZUzG(?zn6V;V9?IiC3w(k6(8By3j~QK zzrn8No1UozS$erpR-SJod+vv~+YI*cg{Lb*Jb35zAyu^00+tAffhD;Kdn^cd{yAC) z#yd8}V#SmUKmN;{cSEFUSI*ngWQ;)wt2NsyIn0JLepSHxh*qpg_sPYk6o;>7rUN-- zlIDDG@<}2o(vXhFVa@ReWP?OMK7qtex6U}NY;bFAnHZxL#a3>w4soUaP+X7w+!K$h zEs#Z$*1S_rq3vecb@h4Xb0``%;YVE>paZX9rJA(4Dn~DDt4tu(zd|;e*u5rS51Lp4 zfua8IC>#e}Qc_Wp&}X9CL-pSmW0{{Tsl+`#-35N_vs0Atj-3tt-CHM~>OVhD3cIo% z^ivCq{5eEb4*AnuIlc+6YM-rOH?>>1g7M*YlzwvG?g{v$@zewOJ=gnAz)$h713@0z z_EUv}Z~tUu1-w1a9~I?1$A7~IwJQOv-+cE=$bnt@6>H()-G?F6^5@!%Fk$|W`8dqJ zBcd);v3HSND0062kfdOY+MY4^I=d?-l(hQm%<4R%Sx<^E-}*H|w<;$FT5xEmigJt_ z|G?K7>zQ%DzQRNagaX$hqMH9R<3goFtep6N88e0V2w%12XSbJHAF`FxExp_hTGK$b z+UQ|b7-fn5_>^`Dxm6Z70o3=vPJEQrnH)xTL@IBO`K4Y-MUiUNATg(urB=FKH0}(d z8?SD0VnLa8c-69f>uPCWjd1MLL)+^@^mq@EkyQKqDssc;e?my|z-BD&-Z6e3^m<0N z8!5NBDn#gPHN&i#7%VxuGG(*n^&lOGp zp8%PYzaO$#OSM0yPkqCI*--;6M$W$9kNx)LPKypxRT)y_;l6FRh@1!e_C;)D@)c8V zJgpW38QIp!)p+*RW|78ZRibUc{(+p3P_ybbQ*w8UfeIK8mG8f&<)%I)GOIw~b;j8M>!pSxwq?YQCD;k`@n zSS^P8z5M8uH4V-44C;$5Za-9F@GM?_KxCB#xadk&O-boYgJxA9eF- zoS)#2yCFz4OQw>zoj9|QPYTi@j`v}8po&yRet`L0 zA`+WzJg^2LM7~w_$+Yib$$&Yp?#a3s_x&_Vhmh%6KpGLsJmL=^y=9kt7)joEk@_pZZji%BNAH#GeM!0EPLh3s zkb5j8^9Dlm8_mquElj5#L8Krb6xGh=yYxO{jUz^CdPEE?Z}z3^>OyzT2;|udrc`e_ z-q?@FckYA3z?uymfPJi)gBVEPr(iI9E@R}3o*OMoYT(G8@YQ5_a_=yKQ|C`u@O%FX z$pyV&8X&gzyOEGt$_-f&P4G1=0|~YJo8jTS&Sf>I>NqCb+ks98us>s$RYW05D&??= zLZbyBz}Rax2O0LrQJGw0BN{tos_jWJE1*-@1QY8?Ycw0DLpro&u_JPR2*o#>64UAJ zmnt<(;#mndG5!$@B_3}73Y2oO@fS5Xe;q9%*=yL`wT1zrdG+&ct$g_KzWzK<{L@Jw zmRRq3Ml$GmxZV(ZJb61bS>R}tt=o3sC!AKh^+L<>W zbEB?eogZT0=YW*LbG;!%EIV*dwY^kbA0JwR=UW?JkBZ80sWSU)Bdi zGh+G%y^AGHiJqiHh0c$c$_4ONb5pVdyIGF)Kxgj?52_hCDvIRV?zC=JCP8~1MKGS| zlpHOk3m@US@$q<&1AoE6sXT~V_Yzt87cOK9w0T+u6zTt9aKOl2HO84ku6TfW#D1`1 zpfSeu!Napb$1Bs^yetp(fB!3$Va{HdT8U52z6Qh29vM;@<7~9E8u~BUJK&?%`(T}3 zTP+tGvz~HjDA&%M0&Bid7fI3Z%Xm4x5NAYLDQbY#hPUX=)MYD_8!D3}7b5>9Gu#IH zWO7}Qn$3czFzI$t_3c?CDm4#YsAeernusTio`HOr_Y-V|&CSqm^^+|`e$+2w;Y0et zgi>$qaVZko? z0iYEA9cx=PysZ>6^Pue?{BiC0d?C2K4~#@ntvu!}VRw0FQ z4P@St;sf+v^7Pa@$koq{%Jnk{MS12_DHQ8xvy$&LxTom=IKDVc4n#ZSrgRV5{ROCr zabJ4WmpzI7R-0v1GAzW#Xq^y$QO@H__D@99O+NccjmG11-xe4RT?b3Gw{qXEg2fC- z*9Q29a`m!^UTNNCHHt{#NeaNUmYsG&+uYVq(x4`16a_76Wx=PzjtVw%zu^Q2d4H)> z0L@Wj=hpc*NM`tmG#Qq72DpbE63zDA5x03iLxCga;u5L!|P;+7S~Q_Iu(id z5?I^Hh>!8Rk^}@gnYWtw1X|hxRvEkNZAdxx#y61=jlM5{DV;u>kHSmw+kzR$8T2#7 zPy@9lVx=C}^a_oBTaKZ(@Jr#!Y-e~B!`NG;B!uPUu1+t&V1)~=ymP<_N;C&jVRIh; z9v%kW+s1-bE?x=Q5Smk64v1cKr(sCiB_W`d6#{5Z#jtP>7V@8zZ^-lUrg+3C#$P0O z;g8n%a(3*S; zhxB#7DohLZu#lRpiB$;r+M$1nm`CvVV>&NtI0ixUv*Rsl;wWNviEDkh46i=_GfpJ2 z{~RS8f8SrDE0e%OA7cS0etW;DFjvM0ok5;|;yP5!uygRF*)UV?DT<82&DAZLjFIk{ zDd&4paZ-&BTRyNF8~ciYRaYDP^;Y_PH4ScqN7kDLHc_?j!zb-&J1J=iLm5J7%d|9*K!LDHfP&LP zAz{(52xT=a#RNgZqDDlRwiFW9uv!r@EX4#tBcetH94gh+2Q(^5Rn&l@t)fOn4T$<) zr@#NVmk*&$lbJc^-1~CfuK*@vX9ObA@k!h0EB^!op6j1{7KTi8I|FL+KO!68JC)r` zbK_D4c*jw&%^-6!x1d}G3iXOKsN55~m@6#qa=Dsm5ko8q)YL5CaSzE80VocvJ0MPKpH+t zmL7+;By7$RBAywy!KgQP!U0ii{mZSGE3#c}CiQ~U7wnX2ljs*~Tm5w4zH+06Ja%EU zsu`s=ommBBngUaG&3EvYEM5@u^D?jKIHf$*5Tj&;5FE|<7i+H9apre_fT$veX|0aa zy)_2R>O^TD$3@@iRc_&&rl0vbWHJx?*VJzY##}P=V zIZN=pIDbE=NNOHb>E#?#j~ehi&wpEvV+_A)h+-bqW*n)!wZwpIF)t`MK;KSSCGwq0 z5CQq|W0y#`yljHP|D5;Z(B*wXFc+Xk5S^bFGH#eU1SBbc+rk3Y69?1>k%M^ux*M}w ztiB-qwaowzuks$C3mh#OJdThnjOxi=UGeGcWVVm*U3FXF?!U* zB>0iyP?8d)eROo{a44Tu62tIwk7*6i*z2uzD3Xs1#k8qbVB7!0v_Whyjy3Y5(2~RO zPhgYS?}Kd{R~nND4|GN}?)W@tZR1>Ir4UdL(nv0nmGsTW@p$$JSc9x)wJA=YnFVt& zaG|U+LgP1t=3;;#-U3s|1D5g45Fj6$vEuk;2|%fi_7(FAB+MvTghd3#8u2P^YrvtB zyOzKVDlxMkr9P~Ij`dl#>hMSR3a8&mT;4aPH%c z>~)H}o^alRm6e1`N-Htu}xH zoxyk~_B_v5VCd~bgpIP@-H!FX7xxz`a##nUk!l4#2)B0h6Mf<&iamGMGN2ve$L`&@ zZL`oT4?vjR94<6x(%oMP655TXKy=9yKdl5Q8Fw)-I;ni|b(td<%-3x~DYH{ADT*Vb`L#(uD*wsZlE1@lixw{iZVThpun zSw4Y1v0i3lP080U`YO;1h`H5Nxf@FGUlx*cKQHLIVZ5l6twY_pe+4{7>YRu_h%dL{ zYdz$|ZAmFWw7@+E6M7ZitOslL28uPeCUutq#W0rFc&CBWZ75A^L6mJB96$Tk6!3=e zf;J7-#yYsK?k8{KwA}yIK->k*hwxp`n2u>tt|HBVCv$AP2<1Z}FNBQbKRqUzOf3|` zSv0c76h|FU-DsMlMv)O`j{b2yLH%esM>*c18ENoRXCce?#gNGgJYR2gB;6EYrGRy}Rg(lOi0 zF}QH1rxK5I6e^rZBCp&-0> z2=3Du5B|h}`m|G4)mk{R;8kd>&sjJ|zLO3@_U9d}1<^14h82Lw$JQ7kT-@}JK}Mf{ zFJ@;tR&_?uMzxH0fFEl4jznX$bJkGiP4)OK8ou5-i2+^2Ea?twARsve+^iUw>r(wN%r3xy_lNu zAr>BwkHk}oL)PMaly&#y1VR(qQ(jox&&NVgD zH$O38_3DRM>6~F6^5CRONRCBi+8#a%(X{lePyw$H&bgX?4_`Z*p1CH}b)?6>1U(j8 z!B%5Fas}wbC!vQsZEuax6csej6Hno1Q8eC*|cgLS`Bq zq4v`eItc%gY#1dU&BKei7hW!{z!%RAKoDo@5Fy6X)0fnM?^p~%30JZ#hr`OMXL=uo zD|dYvOyB1^LZ3Y3V(qQN#`^56AZI#NUU4B7Ab9RURa!@IoILq2P@s&_mu^J0ZZo&k z{x(x`i#U`Kl9vU`MAXh5W#$_heFyv@Vj@+MXnsl+2|U%*T7FCI9EG9X~KQQ4yR z%%a-Y8bOMUC>Dd|-K124eN$E$JRJFct0_tE1Z`;UyM|{X&$7L2Ie9&2Vdwb1hn<$psZYYCg3fivWvfI2_j%nt5gD?$##*nUsF zCB$`PjV}ql=m^v9uanpnZDsH4e$0W)#Nxf$`;kYgom}q#Z`Sf~N6e|8;r-?U*4EYh zau=|X)-=4ng0rZ|^(41sS6?u2VE2l09b(>R@bjsAHzOdH_(@1S#FZTVnvZL_cq+>V z(#U+g?!V*0g_5Oxc`b(QM%-ZeOa1SLu{Yr_6tr-=pZ^MXAUEsrA@@4D4H<21+n9n5 zf>uvYue2c`azyaXr`~y{I{Ny(rXW3QHc7NvZ}0+GwpWu(Zs_G&C4dM|_?h$m|O5L`q1BA;ZYCiDq^jiaB*%sWda zA1DDr%S7C5OsOqN2Q`CdJMDrky|PE6l~ZP_D`nWvW8k&1ZUhfdvkY+aIQaR&<5hI0XU$>)YM3B6Q zFFjFjM2h_0Mu{WA8*0GsrGkd{9kf~K@c>?qEHPD}^v(?!(BKG@ohBX@!o6rXqqbQi zmwY}J>v_2!B0fbfh^Q|5G%xbC5BR*)`#CetlQ#u(d;0mvMjc%Gx6$c7ScpQht$4E% zvgUy-R!<;5uOQT`A?Gpb9Ez~+8uSvzzLldQ=oh_X2pv8f-Zu}lp%Zsl{CFma2M^!zwjhtxhkuQUZsq=%Uin^^n@A4Ny>sY(<+puVAoMYf1( zIdsV$1DnKfZrYSm3&3d?vLUZTyB}vS{rqK`1Chv2nf;BS^+>~$-Fq8BW_bq~kNq%( z_uvFmpJkmh^5)&hlOd%lK*A_{Up5%g@uFhR%5Uv?KThlQ1RFMBK25OM=Hxzuh0{Kp z&x{&JA$SJ&%(|TxtU$nzRcTUgdKV(4eH|`rXSFRWDrrZP*4evuk{->IurwG zag>!!WnfkZ2I6SR@r4E_C%-fWx{rMOu;A}VN6%?Pp<1`A9NaYdD|}ZRj)q^#Z5Fuw zoLm1?T9AuL^O<^zFGsioTUfCJ&`eZHLmeomRK3bWJSvVYd<+2pyY{om#L}0e7+lTk zAAxq{O>1k7TwJX(z!A?KRVi!4haO*50H-nMp9}UFksGRZUOm2KtNmh3K9stg7E$1XN0JYS;_WpELgdi+V2QS zxP%tLGXMa3*I~?UxR1qM2Qc)+wx>4!2KA1y3f#iuCVa=$KXQ4{tE=UmK^&;GPeoK=bAScepsXVd|M`j70 zBC1@#Zb(!}4um;-2_3s@PP2BiDC$K!(d3dQR8~KUkOY1IW)r}}zQl{?$40Oa8epBU zs=nc)aE=|H3T`y(wO1?XLl(jaNj~L6prOHpm}=fcLgw&x2w{6R^qu&rDUOZjb-Oi0 zo^cL0bd=)>{3U_~IFWxq&1q`|2MnVfjewSvO<4|fFOq(g=&^KnFB4n3yMWp^Ko*mT z4K_>`uk^x+-+_deoz zV+~N4o*_b`)vSV0eyB63k(gK%FkC&PEpLso;g&93plU77BJjwNMmO9hRV8ze3Lv_a zcQPttaEd?VjVR*Se^7`4wd`J#Lao~Y)PU-g+Xf^FjY4t|9o1K8=BV>D8snitBipHU ziQwVr4L@rF_cPc&saOc})cQx0o7#!ZP6M}HFyKBip&o8Rp9GayB~#pgjgiABQ-Eq$ zxvbPN3IrzZ1^Ft!;k__}Ep(j4dy?G-zxGu~W2x^%IDvMG-p(LRT!tp~&r;iIE=r=* zoFB8f!A=*#pvb^`7QO=U+F<+I1dzO&>#dx)^Ps_vi4d3Sljy>lC2-l)_$YjwSgoKN zL}#MyyB(Dipu?F_Z1e5GZS~Dhb!>#RxY7}U7^3{nIth(>y}2DZ zb=x5{$mkF7=Rf}k>ovJvh~(glY>w2;ZRJe0t!pG2`Dps=a~4jy?;0<0FueVc0%SDg zBhGv89adYUj6VQP<;c&jcXIJF!$5?KmlzzJecU02#}}A9q76f->LR`vYh8KWi|E2@ ze2}9+(y>25$v=9nkvlPTvI@4u*4~CNCm-b0M()FpXR34zNGUi4byuqx_L}E36bdmS zfuX0-B`A-MUBh$hdNMFjGOav7$y%YpK(AbI>8MqYzuyG*nuccIW(Y{XrW;xSot+YL z(|azvJXHL_7DR?M!mM;u;gR_RwI7f4!Nj*_cKq{C*a0I#_45RFV zXC%FbU*%aQRPB5Uxo2gC3zi!`CvAbV0%JD*i7iN#pM4TqT$@mFrT0h#M3YUWPhfN^ zuY=Oe89pQRU$#L2PVxn5zzVuirVELoRGGs5Jk$qlp+8JsjI_Y7RtBCHE)fFIuVV$b zkz3>%UhV)CPm={5fK6H|&j3RN{tP8(&hOxuefNai09lD_rkS0=%ei4zYf)DKGPUO! zpn`h8-B$FubSrFcddzERMgr$Yrg+3L0>J%XOD3{tr)OD1^xkw|1z^U)M%ZhYp*ZC$ zA>3{^>+F@ToiL*_sBRU_9;hBEEljWfXk&mEg#x>bojIBR{WY=@D7%!Nz&J&&#I4(H&E%@-K_h zCf>BUsXNDJ1>9(ho)#TN#aDig%TBe!U2!U(ERVpjS%?LI!@g$Xa^LlNCVleB0yQ2oYb)mH1eLu zWI_MCbv6nTr|`{i-Mj7y+3A>6-1^cLSWl!l0f!;_6W(0iu z$kt5dCxn*ibeA4B6D(D?hhFN3#YlA?7Wt85%i1O$9XicByK+SO1csVyYY)3j841u3 zn5h4q2aOo1fpB8uINrkQr(M_*<-!i=V{?9hcOa(svEzDz6R&MS*$tKc6m(ON8J`Gp zQ2YZSm5GP-d~3yJi2FKz>dvs3-ejcq?$|5o?mjv)9}r`N+i$SYwViFq1V0n1qqleAsH@d@d1ymxGhJBC z2w&L%p?iE2Yo4J`hF}f##!KvHW<5g!BUTR45d7!G;a#IiaQ-HVPt6bjTz&1#lkmf!WYP~~y9ukz1XNfH*qAwZF-!E2XHM&i&%S5dQvHC?RLM|^b3 zi{COLpKU@YQ4;zTBC7b$)WE^-@vP}$-u`qUJ4T}{!*nl3ik%L6rdVI-?SViJ% zp9T2jYMBO3_6d-`SQXptERYSxCmV8+^(I#)#;E5LTa=R1YDl;z1RWk&qj#*J>hlI{ z?|Q*Jo011XJW__*OJy4~lmTGXjGB7sS=3w@vl&_shCD=8P}x`OZyV6o6C<9UK!*`r z(?xAfpv)mKJDKql{@7*b?w>z3Elj2Vcq^}wmoAy20v&((FV5%FI4D7 z2uem(`+GPf82s3m=818#-iOQ1W^pPqBTFJ*WC1Dn0|v9{0~t8(VPP!GRLD1Rph-)k zuh|mFn>6C4BlYeewWgvz-?*)PsTIX15nYg)U)#*| z{J16^-TN;R_8R%X`Ej7<#RP&a>lITHtQT=oqQ)}Cf!GQeU?AkLtyV%Sot*iLwCfJ8 z`H@}>emHP=xviNr>%DX6s%D(;`_=FaX!mm=Bl$otdFeC5SZ&m$8`l+%kQNuz-Dk{S zAYl{S$i)nepzd=Y;bPz9flWSL=L?e2dW)87>%m0Lsk|Q<1rnZ^00yCgGDVw~$}3IK zXDgeq?3p-EvNaT-(pVu1`Sk~W#CbA5Nx#1#91XA1@OwV8?!*(Q2o$Z8+<2+-0VUTb<-8Dh8${U~ffDNEBb;k&%*~ z667ZlLy!=6$6H%4Htm^8~70h_CyFv=RT!;A?w9}J(9mLd+t05&GpM}R8(FEf9_Z!sL zQS!OIWea>qwS~^R3nV}={A&UgIadX0qNMw2AjjsVXFd@;xwKw?-Ht-7@+<|l>O@WZ z+D#HIqP!bq@xKY6{sS-JQAd7ONx1lcs4YPK8~HFQhJRYg8xi)H^(4zI{P<*9Yd&^T*3YD!+!4kzLT{8a#XOYn+{u z54}r1@_8w#5J(jjAH`G35s;JoRoh@NLMpI1B=$jlSfgBhd9uob-sK%g8Oa6zLdykL z0SlF3193ZHnXQBkV4R#51-$T8HLg2IjdfnCgA5`8AyQ4{e@rso6#^XG8?~337qD&i zPi+M$1Lzcp^d0eF7(L*&QtLh+`1EnSBz$Nw21gqY(&*=yj-)*G2bfRUWNV?pEuakY zoxTDCk3x_-7how#YuPo@o9d{yHiU40M+lA!W18&r=6!;hqwB}w&r%9AqDfaE=*la< z#MRJ&kGM?W7YOsfs1T%ZkF5!!N=w2oZSq-}JPx3nI=Qr&JP`8Iff~k(^)wu1goKy`&>_Q%1M;3WP@to*C$X8XEFmN4NHm_Gnf*LRL73}p^gEw_@Wsl zA!IcT%m?F;8GX#8JVdDUiphfb3)5K2W*@q5)~b!v`Z@xSWDPKfX%P!~Bt=}-atJ~z ztY@E$&%@f{Jt1t!^^l)dEN}8t&u)_gNJ@zzRQ|kAfE;C?IP5Y~ttfc2X+?%$(a^r@ zAkkauKr~AKJC#N%&jq+Y28s+4tXlfN?8ZXKNvKdiNCYWf)Du8O$q{7^oORt+)pnX2Pi;M!?|gLlQZr=T^|7i{(~?i+*M) z!Bs0DAIx)oL3(_BC6j7l)&NCr={J8o{y-~${m4L*SxPZA}lD*#YZ@DUp9kB=$snaq^l_QhfHt6OM% z8B9WHTvnK{u^OabmKL;bg;(>ukE1dHS%`fmYKbGuOpZ@N6m2@_ymOw)!DrrYGbnyMm#&|LId?O>|V)C zpF;24WEI{do&f@puA7jgcu{Sq@^~;Ju`F#Nf4QKT^KoMGD{3>Hy~u`U(Dr((mK3Nh zH02nB7OVI{NbuC0SMNt($g>D6$dCNX+xu|J{Ck=z=()2(yeob98(dYz2B|(ir`1Vo zzk-cVl~ww16@C2=A%b9byGXs0(J^-NdDgH2+*KSBIn+vMj=t4O-Fsb0>Kxx1rF;9B zFkIkiQysk!Q%7iWW82^~45$Oha4|T#uFBLxoBP<3G;tc%Briqzea`qO|O8kWq9lOMHs~Fsb(o z$n=sWY7ZTG#{}y?2+G#p1LbF)W|L^L%mjM++XbJ~jsqq&trgVGu<6%!7ZSZ`d~Y8@ zHo3x}qb3~E-+vXp3Ywyvd~Dm4?=JOtg9joL%H}g$ei^7XH1~yZ`Bf_-AxJlED~;6 z)LLO9RK6E_yZA{~NM?M?<)z~e3BfM(g{LvEj}GMV?AzGN&NnghKC!yeqKTiF+?b8h zJbSOsJlBb{_g%n8fJ`wZjJSh1a0K!vY-W!qgxr0|R!0x{P*E%G6ru;wj^CX%>^UBw zFgm278U(>S7tint#y0G52`%W0d=65DoQ1xOKWGbp?h=nt$1s~r-P6Dk4n6#5ZQz!{ zPm+3sHg!K^&BnJtsx6m5B#60tVZ|bJ2R^#-6dL=;CZPp+hdX*FPuApnmcoM(QI?O5 z3uIZy1R;RHQnCr+kLbmnfat40$<`G;5-Ck*)E4r!UT%ke+ej{z7P7dmwDlyf=s9JQ z#-PO@s(iizrGtel;cUvo*0X@sGv|b8K3!nv6+ol5>sf0=;-ZD!s;uq@@Itr?@tpfdbDuzvAN{OXYL z>$Kl(71*7io4z-wiO|){;gg=#HgPn)gh4$``x9Fh-U;@IKjP96x4xo)N)<~ba>W%U zQd5G9dutI32~5yI|07J?0>kDQP~wnj+1U&hC6V4CCmnC{p|H9uf;d48mFk7U`hiGO zlH@WLmiuW8p6}}-Hk(vth2qj$JOcTn6+gK{2pnR+s63E$I-V4oVt@i|g*r}UY&xSg zLIW&FTX8X@!{I&aq*WAT>>2KRB37Vx+gPf&BzMSv2ZH}52MLU1QWPze|U zATKl-DQVJ&v(Xo%<5;PC68)B0I;cMf&CB7cxuUa9-nx+c6FErpLhj1yZ+L58E|`nVXfIA#X->0qiJK?+7L*D6F`i{~ zq#u@FH)F!>b8aAFFiDavjw%gpa05lK zQk4O$h}*8O^U=77X9T8C1xMYrP|&e1IAqTpKB7e$HSP;jx6fxspAL%)iM{X?(ub`M zs(dVXp!GjzbNb{L)gSQHj6@>jP4hW$MFo*(_eK!(Y#|C9mMw@ba7&HQ3C8tA+eb$O530>%W)pT_X2p-z zp4dtxx&d($zhDa>T7EG=oV7vpG(=d5aErc?_523_7l5)Bv7Qq(d$3nCyu1j2koki2 zJS>Uz&q25P+rduv}53R8aq zVk)`HW~JLUwt{x%XY`=Wfb zKj$Bn#|QgyEw{d6g@dk@g2zn%-G_lYnz{oGwJHlIKYb<*^~J3n_?CX$1$94O9DrN| z$DGWoIH%xDL3@FdN6)BjfzPc+UwLGArpn3@!v7>;q*$1|nP1lxK6+oh8|f)fom^#u zxap1|CS*u6D(LlR8=9WUnp zSP@?H|8Vy}BM3i{FT}EFvbGg_`8M8Ew!-d7T=pqc{zR{|L$at&jY@v^Q?x?UR@h2@ zo|r@gSVqEOB-2migpkxif;lJB=%x@yn_pzqPf~`>u2|JLiQP(la>4xj7w`$0SJ{81@si2f}tYmvK3>&dKs~H)( z77f{$WhXfpqZU{iC!9LYX5087;m(B+Kg1|Im@ET*W~%&>gF@M$o;-7+nH*;G6y+BH?I`I3Cd_eRcFq>q#DhZ+Tc`cL3M$TJ6N?iSCDy{^88FPGB}oqM+Q4S~x)4a>(xYg6Jsb@zU@awnX|y-Gb%Yk-Cz5oI`oS4!E#`3O-qgTpUoxI}97A#$X-;7d$*lK1n7DsC#VI4wX zAPxT{L^(~sx51@~aADhjz6iY-;9Gj58)Yhk3W$HO9%?`-Il=I3NN1lh#mFkXeK;_<{W6_>-6YXd z+YDxC>zz%=UF~4AjK&@^!JB=@=78R@!}8b)dY#R}YUBf#gC-crbGVz@ zN&_E)t0Y+781l505G7SMfz5r0&%c8FlRN_E zMJ7FQ(clLv!NZ0CYVMY@S{~9{6|=Bo;z)r5Kd*tA6FvY|vpa5R2RAkfubd{SaENffXokyUP5G(xg~%9~7t zigQd_Ab2xL7|4o}ESHgruc$%dCh(2p8F)T6w9xlvbw69z8ZI4V2TQ2@8%g}jgVlvEQ;uuA|pLU_v}Lkt>cQSr44m7AZ8`8LDO2} zn2p*Bq5Zes3glD0q(*EtjK7?R*bBCToWF$0x@`jtJko{PiQ;OLjvkuCbBG{Ah{I4L zdiO~RYdV18JCOXO@Fy?1TOgfj_yL!Pz7b;a2Lh)mT0;u4ySr|)f&w@c97yXg8`Ktt zZ*o+2;(#rWhj0ed)j=Aa#?JG7kO+|&q^{$S5Lj&zw$*`#5m0bCi^{-ju@0eg)iylc z1vW*BI6x5O=_V}bgkV7xhOSAW#g&M!67d*|bt+X1=5FeF9F4OM)KT(wCGKugjb*idp%?WXZbNTFkx#2h+qvr9`gD#4#mm%V86liPYSoBsVOs}UrcH}R}L z9>WJ7Xu<+ziyBWY+JaPWr`G}P3=~gx3r2yybWZShrDO<8Hc43~Cyh~C6vMP3aKj(A zMrg--)K2Io`z$)Uo|iqtx+))j6fwi%l$)WhD2x>8MMiSUx`}?WM4t?j)T}x< zHwZmS$B?J-3(66g-#(e5-ZYL)xg+?sur6KA90@-Pn`;CUlA;I_B9CAX$SD_0+Sj%Q z$VOOT@qLYwMjke1TrD=WC$uOH98lZIB0)slB?}WxwQV?z+^06j6wf8{e z3KCD`siTu%&!*gM_#Wm4o1bcynu0XAPf*m9dlh>j{}T$+=D}OF_{!DP@P~|c+-o+om_R{4OW>PuP1N#z&I62~i57nC$RufXhh;~V< z6fIjpk=vS@*LCI@FP%CrLf5j1HC5-Bw6FvG^KdKyOhEHTU zmjBPQg3^P^w{2c3Pk{g?<6Tjz+zJKIt7#%2kRWK`QxoXuq(Iu!l3@@)X*+CvpK^|!}Y6kWl| zqZ17@t-Xj+A~}S!aiBCvO)pVqdj*%W3W{bPGRD2k2cG#a1Rl1jb=2}D^ojMLO+iE% z!XS`^^~g_yE-iCS%`}~@N6CRg)n>XpRJo`Y5g$mFP-z10;GOESQym+yXWrPVg{KvO zB{97fk|XX&i(x9gPYWEfkQY=7BXb8kiot3pB0)av?<~O%n`R%B_}A|;bMce{5u(#4 zm(s{AY!TKN#f%FOuav2dgQgr`Qu8JsGVM7`RYsd|osm2Tg?P8%cXHA<&+rQDwoaXa zmc#9h?>Q)Il*5lat>U;X?>@{2%DG;{=JHlOcVTOU_m*?9J@a8~6s^6N=O$=w&RBj> zW#*EPE{CDvIkgl<$AmM_;^$@4%_Dfny&S11YBJLfrq%@Q z0GZZ~?9n$LpvKOvbu{)wZ49skde#i3!Ms>C-E9y^51M`h@I547h&+aD+Ft@el;#pn zGr17w>};|b!LY#(F)muK<;j57D6=+|Ful2i>F^ExYyc(FTjtSdtVsDrsEg!5frt()6A1@Xf9vLT)P*$@@7txNRN$b;^^f^@JKy>RV(z! zC{vVsF*ib3Z4`&!0{vAw7|BMZgUe=fzJu)kE zcx4h7S+s#gYm~zu;W(Y&GXFK2ox__km-t03-_nV*R+b@J7wfS#&B4`;-i*H!M^mVo zI(lO35Bd}uvsT7Aamu_jGZ&w?hffr6;hYY9Glm%Fwn6I;SZRZ5w6lRcHwLjRq5o~clSd(^8Jn^! zKJptlEnY);XGc!FoX098#nCK84?qMnIz+CH6T~jme#YSD0{)kHZ6Siqm!X2CeywgA zdl;hDyWUp;ii#bhu9XG_-TGV0V_f_^8eMV`7OCSEj9_?Sw+ROIbzg)|KgDwhThIB2 zZ^jmm7>YHzj=EatZ*|ba&eb?M^7w0}1fBn@&rJ(9;#dxP)gYOde17`IWPH%gtRnv_ zAuG-Kmx<8y3||Xv#L+52)D&!nJe&C(>ZyxJO6@Qs*@BrPWlYs+LI}#x%S#9L){W$e5jIlbkWE!KXDxXm1`tl*O6N|H?`5qIcKo%dQbT(qnslrhyc;4S2-9p z+}fW}B{fKgIv@9!zcwa0&8M3i1Kg@#cBfgn3C%aJ6HeRJEO_*QD1nke-c>0gf3wuj z?CGqsXYDE$cWd@D70LN+exw+#2e{_q8?~7J!lf_~8aUepsRHsuej1qI$S-`L6PM_> z3{>P^y|*0rPZ{5X`TXNvOhY&JLe>N2n0Kt!NaK41r3tEGJF7lWw7~eMjxSu;>1}Lo z0ND(ZjV*wtk-o!=cnAbS9%T((;xe_BnmHG2oyVE|8P~O%ssDK#nLL|iF$3SSx+pRi z%FIzDxYg9WnmxQ@vnxnV^)@#h`Jl~PeBt@RQi6XMMj1*wkxt3KQ#(~BQ;Rz(k(5r_ zPU)S}bD_2f@u&8TmbU#w%v<`O69_!d|KGbEI^exK|EO+$tU{uQ;1a5=bwnh9M>7*n z!b^riM41MNKvJC~JFY6h$5e%I21!mJWh!asR+**r80jjft|ILdDoFx(ba$EVCLP@= zb}7@Y>Mf_8BApW{4oTxzX%v-(WSCQtjtQ#nil@ir+(7Chq`i}jP%`ci(N3ymtuAGB zfYViVkCR+N+@!stDv>jATlUW?s*P0!h3=C(dQ$9SrnSl>r5%$y;lXifIRoF3Qk9e$ z0ToC3gwrAt?tDMdScpoSo-6BgsaS%)YJemCeIiJyE-CA{>aJM&6$Q_~T*|(n8srX)k-)^Kz$C zDbo{~j?!X(+RL(VDP@+sox8MeEbUFX^Uaj|6YYqSikq^1Q;9_1_KQfcA#su~VRx_| zQseMby=>N{pAYDCH49`-zMP7`1XPAWt8!&?P?aurG1gQnntfFRJ?Sw~Z%xJ5bMc{q zOT?lwCMM((6>dTZK|G9IS4v5VXHQ67oX9vt89)eChFUXzkaQE|f&T1tWmrJf zAm^P*eKe6BFD>zB{4VETN`2hjK2bU{mhrdT?Plt_M0-*uX}Q!Y5tNo-i}B#WNC_dZ z>&jG-)GmscOKaTP9&%|^wS^QE(b}+fm8^Ggg9wLRjuCwWx*$d>qGkO?(jldEw4du( zRXCMyc6TtBjfrtxtGW|;nXoTpEjJ37lIhSftWhzRm59idCfqw2)^%|WPGIt7=-51WBuIjxojh%yxbC`KB z&t8)f?i48lW!4fjtnhzFPH^PyN#O)}X+S?M^+9LW3s(m#8=A$gi)vCq=5ZB>Ax`8f zf@hQOx|IHfyQ?Ghp=j0{S57dMuKFrqbC8Cs8Y%F z*tu1K>`%@Oo1JmPpLc2$MuMbWRiW}u{6AjN60KSONy&So=Fwz!yr9Ip@mDDy+-z*$ zKCW6=^Q0sH{nXXg_CKidj%WNC%fC`H!P7obFfzLFmelQsnkORdlUF-@oAFP$TXGZ_ z;Xjo`IaPm=8(n4AW~7uBacM7!y3sXmZTpn6^BE}}3X0bABGDXFP2e&o739jbPBJK7 z=J09`7TiTQwrIiK*s27{IX4tThR=->QCP)q zTED}>ud`koS)?|+R8%*5mz%#gW!$%3V}ao)-4o=eT^r}{6(2ObN}p`u=Uy8x`^+5* z&#&LB>$vdHggW2AsvaM$-&fIb$)Sl69~kG_`u%ksR~@>i**Cl@eRe}xv#QhlGH2=| zT2*57fmp}KQ|?XpMpg-T&Ob|Xs>m^?dk!Vc4*#-s6^XBwug$+UL>>ym^@6VPwTERuSSs|{H?1q<&B zW}f_iEKKlECNV-JT&;^lpq;fuFX3GX7yQyDrM09BQR7FY=d`rvlc^^f?mL}X(V_QO z)yL~PEed3FsWT__Ueb6%>GXQp^c$ITKkS{)zL>2{zmw_cP`th|EDCLeU8H5yClk+n zGQm4`Qt_6?mn5O7Y({arMFj*B1^gUW5xF`B&S1X~vaqT~=IzzIm0WC?QPR%Yq0e2Z zOO&jS=FbENwk-kd*hV}Mx+#nu*)K(Y6-t8ImH@fYCKL%-B+p!uI#4FZYF~*6&4sg^ z?V7`VBIU1vHx-pu&d`#4ndvz~lCTDPo-WTy3h~0(-p!C$j#00hJAYpYSwsA)6t*>$ zsyRp6bq(~T${UW(KQ+ubz4;BlE?y4t^?UW)OYI(C-Y-#pHrDy?>iciDTlZ@}GDgwr zQfnMJnwsTi?U)9;u3gQ%L7I)fn#D2a{ko1d^QUSyFYj+2^G;0HwPwL8&GujWOJkzi zF5PPu?$+#DKEOWaJ$sklHI=6{PyPz4BH!C(z=B1`Gxkjyxa1v3tf4j5mMzbm8@PJI z2gxo{cPF>?;I9L{V?H$N$ELc9vg+rx-<$riQ-7(!Rgx9#F!;zjmxBD%!;34nK3_HX z?{7}cqaWP3wK4(Vpk_*YVyQ&Zw#0X&yq z$-@)GRaaDoaIb%r!Pbv=iiR?u^s5w}M?P->eC2 zzxiw7rFU;Ty6rsl#A(f6zm7Dg-SKw&ZNb_j-0ews-^lPqx+S}>YuWzKxw~&~{4d#! z6v>=lRVHP6RYMW`sWST08l)7qgJ9GWlHn&pYN{1HliwouaCFvt3*F-9Rb?ewZosfY zYqnpU;i$f$&YWCY?ER%8w==C-sLeWAx+No{Rm}gkM)qq9%f@i(rVfVl>)mq4>axk+ z%ozp6M`|Pf&MBkjdo@oL3_7x*+26H#)caLkl+;R9*Dae={!y!}>=9(m1Okg^t=!(6 znx+sV$#Ad(w&(sL<=xO;JU8lS>4BDlmejnYzgx=aYOl6S;pih?-Hz_nqoL_MATd>u zTvRq}cQmV_aKaIvWk*j8WVGfyMzW<%Yqq7^^NxBUg&+_hM6@JDNoCfmszipOf_`>n z9IsBlBx8QcF>j~W3oD8?J9qSHDF1v^YlUW=uQXrWz-c>N7~A>R!u#o#^&R?87H_ukGhx5kj?gr@w1dJr9h-yQI!PfPGUCm8G*cD>V4O=mg?&jhRP}|Y}$&V znZDkS8Jw!Z+1s`SQiqjMF9{dzU6VEA+JHssKDX#A=l5RWXYU-ps;Tc)!-r-ld z(~p%73+Em#Q*){F;@T}#XesE_U~N`8$_j>!HFxOo_WHVy@Y@DV>hZtzPYv2N z=~t335!hLBhGo|SWvKz%pdCFvUcYZ@#|KwT4ExI586S&J=cwmtRn=7`u^wO0CvK|$ zIXCeQ-;i59eo*aS-*Ndzs&~{wKkV{(>2hWr-t(S3^s|on*Y;Ov_kTDtW*auC=a1{3 zIo0ve-|mUqN_O=8ef@z;9UotDZ^Ab6!=8Vyf0oD@0ZVRKtEFd$l)?x-MLMk5kUFXB zKj)vl)A1&;r)-kC7-@Y#x4Wj=&TlH4Vbs(gwCvtk4f$7MPe~BFljNmLnmKxy&&W6C zPsrIcc~bFv<>!olcR%dhy>))3Wn7E7-N_?|J-fH3OfK7G?PB_^>d5Y#T`MNr$Bmn0 z>RnrZYBy+^z}~=^gVbCmDrUbozRGm=929Q`lm8^B8WhO0Z(dPIWL1e*?0ZDv_2JS3TjD&ipU{Vb{L9*$4CQ?nms;h1$#sO-LD zo9-Lh?q>X$rv1&T`%Z3})|xk~_W4zNZpH6An^~dmJ-_m}f6vMJ)85aVY3seX@o-6*b`^(O~Fr0>Me&AMdz;Mbdz&C{1KI?P3{ig;SHylsiI5g+gc8|99{p$Lg@{@_ex%o=_I${$^l)w9> zUhn+RQ_$~s`RMM>zYiGy{`e6HkCvY~-ucgu<{G6cOGXCCk39KT%KdA`uKBFnZLCMjju5@U(K=@`u z_^OKhj+_hC^UPWAoKw=TBpl)d7?JJUL?6@ylaTmjp{!}M8$HAp&@=Hn^or^OORt>5 z25X&q)c;4*m&Y}6eQ)2%ge;IuLWl^FKmq{)QNt>mI$;Mv!z#E2L_|f4f{4~-!VV&a zMMXsoi;8P;ty*gXqJnEsRNUI&LUE%}u~lpPeGmP8UjE?|!C~g!bI*CsbDnc1)wQzt zoZQOkQf9qOMexZq4L<{3;96?kmRi6rH6J@|-=+L|9-hX!Rx2@)hIPUVx!uzuqRZXg zH;!doZm}A5GA%iJ(+c;Aj4Pd1))td8IGYc;`wUz$)Y~*K$m48ze} zM1i?6k%AprO+#MDG}}M$<^jxm(j_KIr%8~Ydz?G#cUjP9LT|n#&ugN_Ho?i~>&-CdGaa(In*o74TSohiXfmux z`rN$ou%3^-&(g-6s`j~C@+e`<(wt>&F=u*w9+y1M9rNACWxANN=98Y6JgFO#le1hO zb3S&`oBbGMh!XJfKnU<4+))fY(u|N5NQbo*!Ux(&?r72|;Zp@lK8LaX!RlA=rYiz%B!^yU6tLc|k`0|*~LTt)CS2$0< zeB5{R@3BJagapZ_U+M83Q~EsDX3NJFui=G0n}8YvFt@YzVHT%6)N0LgAKti(pF1wFT|v{6h=#C z_DQT-H~-mYm2m4?s^9plFE7~CTjZqQy0HQc8YJ~5u;%%?X1SoES*qORVVIRo1(q=% z^>dCCMkp`|0*eI0@}(HrV}(o;Yvgrcps#@ek#}SjVS`|fw5{(bFgleun@*G4EhlcR zaPkZP{jJTOyE*G_-NyVC;e!cazai&Dbh zWQmX6U3KBs11uml{B3>x@!-5`RS*3FGRIDiC_kXd>m^R41Y{j}mtB|gEbmw1NqNA^ zMML`C=NGIVB7W@-Si9&CqnHVctApdnHN+|lFY8x-yY(9us17%BY&+uf|NBWvDMnJ4 z3iAb9o}~m<9(eD&=PJI&e#?s;fprHyB=5OixW;44z{9|X10VDE+{V`;cv2QkVkW~p z-hm$WH`0MkY-|%$>Ta4CIh>;Cp8b%BRf{_lO5MccO zKCG4?A(e{|{7ainMry(f;#vH<%G>W1Q@X>yxY-Q^BU4f#0ZYTd$E(mO+GL7(^Xiwt zy+L@AcE)fcuaf-w+2WPO)Fy6mzT=TjT5eIGBA%h6)lcyV;-UhUK3EcZKHof3s_)(G zs94_+_UZVP2h6|I?cSYSe|83>Xgs(yqGdBpN#K;ZT2!y58SxXOxXb3ZMS5!Q&Ke-R zq3G~hB1SYfFv@~hHQ$m-^eVDZaeFa|mN6iK9FMJ#UF`Z?J$c^3KFwZ8_-^sOMoxXb z=%2Q|e}4SGClxFjtw%cWM_BgMKbZd_L>qxSBL@Z+1p4rdeteQ!&v+mH?+v@J@f+XX zh9vRJRVffdR8@Bu3CG*!E|6@Ms+JjOQ1MUVo7WUrX|xX^~oXh}u}xW*2e+~jajt4-1rBY(|yYV`Vo56%$Vsv%MQlPZTxiE!Ogs&Zd!#E+NH-G^0GonJlw~ z((xf->B`q_yxC=DtE3Z$i*-sXLGXey&Q_^sZi!wgiVI#^#yu^a^a8O)4heYCK&n{o zaM4t&L4o_ zdaUj9E%IC`lT!{W9nD+5oGLBR@e|6cSva*XD7i2X`IF&9e#n61=E_kK!g5)UtSMw` zmtd}abX~bu58O4lFc@B_5!?y&Q?Lw+EMAqHR`Y#h$9@R8Heg|5svPz{W%@UNs=A|~ zNc5A6c?$Dmhc;yjtDEA|E2f*fMui^A9Cf@Y=|#mnbGM4n6N6YFLJ$@H^MP7PIu-8j zYNbmn6RxH>!lD3;i6Ds36MiI?OgQmprgaA>C!8#^yw}uwX>C?@th>NQ%?{L;GR+YX|X=7s2&Fgf z(P3%s=C)X$J7JH@#;kJqZg}&5e#hH@QO&adJQCcH7Fi*N(sJchRK|=lNKOe>X~n{D zUqSfuGMlXqIk{E(SpT^2H)Z0}%}fKLkq}A#i!tCS!b1H~=+NNBLH6Y1QzQkCC=e!? zITzUX5Npd~%Y}Po;U0@5OY=q;5?e!xBIpMt)-8oanhm;U2=63% zQ57JUp1~x(Oih6l6~v|z>qzgvWkRiw>zO75!R6o%Vbr()qyqeMw)hhm5oj@<$A6)&-Zj}~Qc4BRKM!$o)1^A9IL8NP>(<@nHOI=G%Qq9P& zYQd!tCDsunu8JJr?fA2-URaxcC%P%pyPLRflTOhyDF8oo64+px4$*Z*N@gm#Oj*HJ z|7~o6yxLk~R<90!@2o5^$#l$UF<&<76&{vRF?>9-*&cgQwZw?mAzB0gRqTnZp{_Rf z4)7|IyT|?`(+cZ~?kHEnib`yXAOLkBKxu?Q^ci^@#tVYw6v{Jj3>ZC|u@;#au!>GK zpKZJ}r7SMiBkI_~uQvN46$%x7+&S#lRq@kGlJ6P8jEjnjTI}M!Z~u$BJ%WUasJO+h zv5rj90>CJO33gnr8$p8kGBqX?g|cC5je&s`1(ekhMR03WQe=K-UH*!#M{dQHPwr%l zYb@Sg9bXog^jiEOG(U6S(ax>sYi53pQn|R5?>io{?OIKWsnd2dK7utwCYi=hsOpwr zR@5}l$ni%VulFOUmyMiHMO zpn?Z2!Y2wNFiXp2}84~srb$B&aLvlZ3e8lQ?{3&<4F>cbQ~a6FsaMF9$b zvtZ);eHUMB|5u=j5~VheMXm`e5|#;4@`= z(-!PldA;{sbfx1q)&3hTJA5n_y^h}V%2T~xFWVVrv3MmwYA-gzm3$3?FP;G$E_?^* zPSUIm5<~e+!IJ1&tzV3c?!C`R(74n8#*#Q2;O1UbozU%^Rl9U;Oq+{O_x^_=yOz{0 zJ0Ekl8!(RCIKn{4#UrH^xD=f=0wIA62&}ME;u{d&hH{F7eEC0Vc6l&C4s6!%=4Joa z9ZlzqltI_?iziLy{|axjsQvD1jLyZEeV{+2p`vz$|MV^wKR?7YShm>F2?H@tij0Je zWqbfPjS$cbkd9NJ3NbOP^P-R*NJu;zU0dwueqi85!yb#=is^T{F`0lV0TU6lV)wKt z0biPpRx3~w|HTGXH9qlHfP$+%n;R!{~3fI=#Xx&@t-m1GI_V-r&D|S;(^BdgUt@4IM_iW zv>G8ULa-wv?iTS;gjSL-%F7;WTf8)u-T}!J9;oE6EcKJ4dl8U+k$b$NqC_FKGCICD2ZVHOx*B{3$U;!zE#Rl&Fj3%8`l0?1{Pn!Cqm` ztc_5K<0B~WuA?@7oq=3Qb}JUDHLX+oD_O1z7iXr5YpZKk(ab6o-pQNvjLNu8haw7SZjv0jJ59=47tZeCee<<9~} zMTRkzmT+LYXpuSuQBPyC4&id<1B2)rwu%~irvqzcFm&ih;nZx#ThiYbZ8V7F)Cr}f z5%Jp?0Ttn&ob5g}QwbVDTyRCiC>MuSEh|fD`N*`<;XjCPB>l;_4;Ztv=38}3UGM#r zxadQXeg}^VR>kRS3*usz)eFrmd$+2AeaL;!yD#ksu4(qO5xA*Ic*@Kr%8iPi^nBIRd zaNmI!m-jphT6bv1mxEJHT4`IgqJ*MDO6xZvw3rg@S^9*rTg2lhyb<@v^R;T4<#oaUYYoVX%d(` zEY(QJ09Qd5yfin?)!b7t6vawKBDz61M{BFF?I)J zGuzt1NApxLvt8wQq-50bnn)RlYA#<(wr*aNd!)vE77gwx#qsbdSz|`ciCIZ(-2{Ze zp@uz#=&u8P3)1r$lxr;hL6z80l^83lyf)`O-`yc2!7+IyF^6$-Ns`ULX5Vp(J{{4H zIvFJBiJCRJU~%Zt3sI*}Bt0;ly>Q&J(?`!H{`ev3H`6)A<5qYdvq6}A#L@STJmG(I z`TtRjun;;t69Hv}5YqsEA8-K|U>AY~7pNT(kH~dwELcY(ge<5zTgT0jsH#ut49b!#2 z>s}Nx=3LX1J69j*(Ij2kT(`=t$Gz@fd6q1`zF@tZX4HugOR%2SOA9OAWC(dsv`oa( zGIZM>2c6K(=w4!X>T>#Sx4KVRaoeuVN^v{9@Z6E#X-)|@_v(Wunq^#eJ7RzG$h}wU z@t)UtJ#IS}W-Zxv^Lz?y#fjG~?qc9dH$V$n4 zhiq+-Lq9>5KH|^vcoT6$2+FEkK|x(EJ!M-%-1@Qd63ZUfSz$|Q4TZMZr!+}-;$}_T zwAg$6flsHjNxe0*;>Z2p@%_JJ^&c?~xSJe7RR)OQVBsT2zVY$>eiMVE=u_gUZG;mk zZet7}URI$@1(*!1Z%dQJ3LU$5`ojGOwArcCvNn%Dk$C3D{f9xbc?QA>`Y>@TVi(Ie zZ=;FA>O$dEO~C7*M@^`j<`|7~v~!T!DU(^&uh&-9H;%qoV$Yu%5;^xtsco9&>yDr@ zzIo8=go?4T^ODOy#?D^4Y1!%VKYlu6NP_x6&Zgz}#{cvZ*&@%bQo8uLxfkspQy002wDY9Jkd$nw`~v)3;D?)}k=FMs^k(qKBLU}^RU z93ix9;-e{tjVPJmDu)FwrhUFu6gJ{iSp6(bARGcT6tYJ$r}%odctYpav%&|@(&lWw zzGCtO=rNXc(tTNcLSbf%lPS6Dbj@XRQV}Ur$FATy6?rS|LiS0OlxG`}Ns2#XAl(rn z8i|%5tV`@4GUG*gc(q9v^#3FM#&LZ+nC6Mlr zh=Z&pME@v_M(w6ULzGy8rcx-Gy0h^7^wF=Q<{nzQ>i97zlFS?Zwqh=?*gOKDpAOf| zJ-I3G-h{`iegZupOEGgDLNW;gNeg&KEhbSzouY>1sT_wWOoni|t10n#oSp-o5QD9E zYd?O@W&6u7WSPDCr9?iXQc=eZKznNSp*lrZf>%5M!(9&!!EQF3h5V@o2Og>T0 zLdbDVKE))_3G%(iysKtw94Ed!eW8Bl$CdMLo2@lLkPy*{moOwxg7c|8)h4#YBo2xo z_-unm8)zS4X7KL@R9`%}&-aPKALbP{1}X7(ZCoR=j-W-7Yhxz9PW<`EgHIjv9!~py z*~FoHKVR4`&B6+-Snpx0Z|7sLje!skC0U{ZpG?-aOVSJY2M_;D_TkU-0$V2QSjI%Y zDa~4GL#jkY6W=>Bu8jWTI)C8Jy2c-d_g%a{`tOxo1>J}Q^VkO$Ak?@ZFmwLUoAvEK ze0Kb0VDvvL(I9cnRmL>pNavj|+{h!Qxf-WP3^+vrQOwr50hA>H@iHI*mY@->7t~zA zHSrBhBlUIRFGHjMy*B^r(v9zb`1j>6|BgmxDmZ4ASE1(|7o2A!I&qX2YKctXoADje zSfO@26Vb9L^EO(Bjy z%{_$P{6Qy4rq`-0Dhm?jW_j)MWX4_9m?IDla>x-61CmA6S0xK?(>ycX!{U2Vh0B^Y z*zXCfwtH>w-c)GL<5_;c|27j(oo_OwsIAAoBh1RoKGpF?(QdhLTSr2l>4MbpH;R9j zTUlPBjRZ+BD8K{~)TahaFjay}fMIa9Esj+)!-7`ysq-Wpq~v0X+RlP+#KY7 z9fN}j4o^_*CMX~TA#NyN@E6f<{?ay?(3U)u59D656c&Dn_H`?L)h51jX>ENZ8~GBe zSb{)nOhLTllb}RCYf*+}er~gJpUKkTU8%E;VO~fEj+0b;P9-Zj+QI@oDyZilP7JOr z8|Chh*QrSs#HUTGEdK%k4Wg>IGbCS_*Kv-abET<22}Bz4U!g)H&EnIwl6tk}crGU! z(IiA1$CygdL73Eq7>07iac8H?`>jSDPD^@Qk$T*1|K&4Qf_%hL+0MaNsbm9Dyn12J z;Tf6uYLfd__fkpg(;^wfC%R_T=r?Ke-fmJKmpfg#Vr4yULB`w46r5>9bP^QP&;iOa zB3m`oA{3Cj>ycn094kRDXLuK;htmsNhmq(A&IDx`33|Uwx6KESdtbTosD4b2a`WrW z?ZLT>xu)w;TRW0710>=ucSj>rhIHZbJ2BBb|#pCm?eeE7jLGm6HUY2&9n~N zT5Rpz_mprSABPtUZ{6pSc;;Gi%D9|`KXA5P_DJ!$p7{_TIYIvaP#}YVssMaYA5%Px z8ORKzW@TK;dN}^l!gJBv-+9cte|??xKOMAkMYS_AX`(TC9cBF)i!?B07<48dQa_5I zk*YC8*mr7%4UMi99tg%V@e;%X)`wzJDp4PnidbuPSSD?a!MJ!0g-Z-5QwQ8kb%BE~J*t|x)n25d1(M@b>IjVIM4$8~? zRlbWJAM4C)e{BUe7ePWS52dq6fjvuYiwuN4OY}nCpXFF0G=L+7jP^9oxE0nwxBF+$ ze9PM}9tJiq`gCK@Q_pqVZV&H(+cfEi8kJ0sJb)HK44vpg;f?Ct>??jLu74l-q&YD2 zM3j~Jtg^}9j;N2|JWP@hH1%)1om{OgzMCrh_HZhmiN$ESUIj^d&Lc%|COf9lkAfU; zh!ptZ`6N35mIH?@zLjxL$NWq|a9lzGKb)eKu+Yo%@G1}#X(H{}E$cbR~ptE2V8Q+Tq04ZXS*q{K4xE2)P%kpbxqHS3;UWd+3 zNi*Br={=4IYvaIydfz9PJzyV1WO3Mk!v7YEP)8xZut@fFT`8-E)f#s3nL}s zIGt995M92voK=w}&$GHEX=BF=dj=fR#pP*&k2#a($7cQ%^> zay9jNNpFcLcHEM%cdgRXE&F@7iQ<8*T1-SJCT*Mt8==slvH9m&2jbw2fIP=d)Qx)MKx`FzGV8dlbAhgRWd z3SRwmi%vi@0UF{pCD0R#F{?SaNK1c>03|JdceMTVS*HgBqPd5c=Dj=CfBM4y2mf&e z1d4m>ebEwq-8uQ=(v93U6Q6dc1Cj&?Ap(1toi<+(F^XvBjj(r0ZW|_1F)fcnQzwWNn6^Okn8g{mO8XcdVwbcBj# zs-D$SY~6(C6lvhrY8Heaza+Jyq<}69x`La2B5`!6e921(4H{k5Yhb zq{~RmHWag3)^haJjx!*bh}*Sf_Oc^KPoF#UU;zFPIKxFO1EP?U326qk?0C$Xn?8?{ z9%nsXc4^tUm>=Ky{5s&}6YV3n1J~k(a5&03d~n&tcRyl38l0Xu9)+-b+DvqXV_a-4 z;p)92%}{mb$atov~B4QH`UOG@jnHVnNVnRHeu5BZ`&y@7f?` z;W8CLQGU*50}?D5chnMVyXcbTmv5dGPkOQKN!{a>3zpx!d2TXvKmnTqmde!;QZC## z$uhQdp-2k*hCTF{f3YNXv1Fr8JZIG1>&)w0Rxn)qcK_2eV^+Ue{_DG+)IS=Xe!Vhg&A9If9T*vtg7b^u6e8pWYXV(T zE#{L4ZtiWE6kGV~on32Ze-~5u^S+~-gJ$nhexLK*AKZ(Z%RVRBy?DH?`MXayFFu|0 zZQF0dk2gI3?w^~#{PQC?;Rm+F3vRg-*$~ZERvTf5z<>o6Rsy9rD-hN%aO7zwnu3W@ zvls?i1Lc56pp?0-Sh&HoK@G8ILc7aZli$$|U2_)<=fMIi+%zUPNRat53&$;whKU9aXr=a~T#B`D0Iw=|(%WJlswa|&~^c|=F3FMCqI^PJ+7*`tX| z7-g5u1QA?UHaj&zhDZ&nAt4UXwPGWGs}WM-HG`9$m2bU)p7zWbrWYBcx|T(HFYb^1 z+IvCIvcTv7=gTyJBgX}1mV#40LeSrI zp%mge*H;E28=bct-(rt|HsVWHLBAws0M|*3GBv)_;Ut6-Hks+7#Y!xEk4gYSR^rBiKHYIiMQjj9pe* z9>O+sA@DjfKgUIt+iYr=uADy9tvKgA_T_$?tvQGo*}&^PM6ddpFY|#a0TuK%j@mh6 z>on%emfT9Bp*p@mQCub*)p6};;hn~@+o)hU>rwx;)N^hJUY@bp{$}O8q3h~%^05O~ z8t`l+IO~BhM>>?7ev=s2@R6MkjwRF)Yu=fwOuv!?Ni%jdD>8;|G@b)x%r^bb1v$%Z z-Tc`Pv_3DMGz8Pq4ZP^WBXm|+F-!vRd={%whd0unVGews9~LgEce>tqq9JVX9Og*{ z-Jnd(THy7kmAaQp8IpBf_x1ab;H1FmnkgVjJ|>P&Lm zh&oc-%6Owg$%XzpsMRV|talWq!n_{<342*KaYvCtGT%{ga|)LzEp3VM zV}~EoV1EPAXDG=`HBP4fRjhBT&|KLTF2r)C+ z$HJ_~(La)<>Bq_PloUZe+4&g=JT7}Qas{8l+XCL@=x%k-i zRp*c0edj;#!JBnYf57wFr}uFK(q_J`dBD*VhaRQ=1gfGl;ve7S?QIUL-1a78?KnxSQKkxL0X=}QQMH>Gmxqm{-ihI3H< z^X}$K%c*t78q;+lKn4Qo0q2KR9Df7Mkp3YtQAhiBZw)bC+k*CFg z3j(J@!pQ<_2KP$BlUlc#K{h6&WZI}Bm_NnbNX31_L>lxj+UIPRVt~%%*yG$|3dk%G zV$&&xig5$cplMbscCLzzh2sEPBA{ceD4GP(!H`%Fh@UNoKVS@s?m>be38~eWG~0aJ}WS*(#rE2E0*h5PXF$%IP6yHG5u z=R0FeH}#FivC*Y}XNIg?^!#ScqGx`~&DNf?o-dngQ@-;~lvC&|qh*YQwytWbin&f_ zXUG@de!f2No9@OCv&(GFj^G!Y10&S32445LH5;dQz1SUCxBWxHyhpBNM@w^r1N)BO z%CeiuYs_5uMZ^}5naT66=d78?8@L>}W75aWc{g#innLxMB%7;m&#mD%H{a{KaCybY z>^eu_v*Ur8DX8q*0(SLUS+UM~7!rO0mPd>H%&)z-NDc@)P@b28tKQjM%w&%&N z?{j|`die8CrGI_c^Xud9*ZuIvm!E%Oex}*=nXfC{VjMN)((2Fr`Oo6lZQAnQd&>#M)W=MUUnw`G{H-VinVqtnM21v}fI&Qm%1q z`HQ`6f*Z%JBq7V6Sp+^0P4M&Vi2ZQsuEBYHbMLpR-`X_^zr9|t{^;#bKTqi!{df9r zZ>Q0?Dt|Frmd!K`g6K3TT~D&cCh$+N_sY#)DQ*~7cxX&CIsg@`4Wi15*y?~YYHL6k zI?iXbRE09~YeqGI=*xpLEe@kFU*`JcE?7jJSECwC_>aH8^xZQizM}kKi zL?IJ#9bc$>sk2B&Y?AVa;1)FfB$=fozZLqFncAY96l0JL?jpYt^TDRd`h4cxV-9zs{{vh9IWV946ZsW^B05n^q`(uT+ z9^6BFKmD|!Z{pvJe|dNHA4&9IFK-8k^a zx5i(F5Bz)I?(d}=@mGL>FnCY|D++fFWIx6d1V^zL05@zL|5{xqEL^r^R0Gc#qxi9rh3l&-`n5*xwKK?@V{5T{B!kxU-$m+?~O=~ zOm*02geYj6q){9tj+2c0ikXqx4lQUmQaHv6jrXUaD1mQ{uLu{m$8K4`4Cs9NArjPWo!2?M^?2OBaKr=K%%p2pJ zF2Q@LBoA~;ff3MGX{LvlmeV&N;MJ;HzD1&yctEA{i$}5@^5-mZwKI4j5;{iUtCdAog3>lFU3+LN7&EAy{=e z6PFxlAWUh}VcOa<{|f2c{JP+~GxqZu&8ME_9afFHE3+FeJW^2Le)&wV&e_@IfMnE> zf+VA9TDx1TiI_s*1_-G&Vi12>N^l@v46*4HM{vbJ$By7hf(oB&4)sAH!58nfSBDNXnSFn1 zqvkbo??oZ8`XV>It+SREa}Z61 zBRvt-=n`1mDj#*IBeBbLcH_8Q*gKJjqoUrplh9#SBfioSw?2z!sDjefkh-%-7-m5q zAyC_b7#bu%FyS`;MP*CQl<9oG6+TUi^6Pejv}m5xt+M!p9=s;wKjp16i;!S}rl5!g z`c1a4Qi6QM<6?RMg&%@Qu3FOmf2vgW5uq|0sM>YH^VfEchM)C&Ym54aSl(Kx@I&!0a+7xE z>oc)bsysKTi$-PqsHoa;rxu+M+3(l(Np6>T~QSwwjhCva{b{K{*f;m zdT&p(m>V?!`+=-WF3f2|$0}UjOyU<56cJ~hvkp!l`nyCa|3(FON><&!N`Gk4ue7NO zUYShT>2T0XYb6q@jHJR!=`PR%!>Ke~+-d%#oqiCzN5wVZGT@hVV|y4n3GFpM$6lIU za=we_r?XL-7PZ;&=e>Fu5=iI6G!_+cTk0QO`Z`;D;!@rq@mnLFPrP+A2C^uI9<2?7 zJLQ4;hnjH*LA@IE3tF)kl4yPHb*HE(J6i}Ih@vi)l zU_uK`g1t?L-$7a}m=hgA^TztKyf3L!hfDv*m(Yl7HprHs$v8k@^$`!ObHQ6H(Y^)J z?4ppB3>lqQ#(Y>L=1@>%hlW>YBGIlMz>j`PQOx)9D6EHh7N7E-8MKA8DWe~kh&l_) z_!dn;bIQCVcsqxW-=MH;;(z8GiJBql?+4WE#enW2uuKYT#WtEWDrOqHb^I|+!C8o{ zVxro+3Ynf3RF-0VDLuhD^j;xJ3#lu!Fn^@%ycui0wCH%djg=}ixpR|m(jLu)$3b@X zGukVo)aIT|;%`o(6%H#qs|L-d+DA07rLnTAkeXyc%(KXla+g@gW1ViQk?sKKB_ZMH z!0?fEh~FjdlQ>pZfJ)Jn9D)WX9ml3x7hIq&Z5tHKw~wwY_gLX{r*mhfg_r{GOSIToQS;6cd8NUYU!}yKV&iP+%xq=& z8#p)0_Viadvu3rL6@@WxY;#bYNRJ8}blupxHNtc`tzv)3V;9%r0jGJwhQ81i<@Db2 zfa2?qalh(u>AlHJGoqg*3?Ofl;$ z{sytU=u=j31(9p`KHSC`R^`nf0*pmTb7+KuOI06DR-8>cnJSvwGj2m@o0a9|XUW6g z+fr`ZLQm#f_N2{9*tE2I{FzX=G>63N87zv{T5~&RgIP+}oC;3POM z^cq5f%+>9ZcyUo7KxksAZ1~K`T#N*kjPGe{;*A^^&g%YjJ%HS!46p00Bnrp7?{BCDOrV=a4~i{wTojHhX3K>p(lzs79E_DK*A zfD~0AK~|(98x{A+ZLdJ+G1b8on^bMa=Stfq2FNkH#D9=8>WEcZU#kx5GT|R8rk1{1 zhxiN95-K-UyZeM)Wg(zaLHnAn6}hQ@dms5MYTUW;2VUtXUrF>>QgLVZwe=czZp9vp zx{rqIjL%bPO_%7bUFOz~&(qyf>W+^x6kf};p7=a>v3tF{XBhA1S!=%qi-s%rntPRm z_4tY+7r)LTME9HMxSM za$qJ=Q1u}8Qo8<|UHrCOvd@mj_jT~OU)a;`dae9#&E{A8Xuh>%f57sJu}i#vSm<-- z%A?FN-#IM5vHARpNgu+%yfnmx7*+&Ap*JKNooxq$Zm@YmRE#$6<&c%1v51k9i-Q7n z#s?VrQ-J0bhy@!m$Rg4#XP@*2_3Pl6jSktIs*V-Df~(ImZNwzXMm&Qr4W&}h3Lm|~ zk&&9CvAuF9(MVbK%MTo3$PvxRx`knKru-R)g@3$1qpckndlM<1PI15pkp&;(xqC|) zBaLYj+Z0?CLr(mre$i^P-61Ed>ehR|psRz-#~E)_;!4w8DD{T&${lw^ z(OSmG=gqd9cD>Ddm9#g6wdc6WWOIjXN5}DFG@>Kv*Z99SzAD}n`qIzN=#Y7~n`j*U zuG4>Bcw3qHWOLqI|HstkT6f}qRJ5jjN{PT#-QJivm3AeC9#j5wSSz+&Y_%rSIxTCPNAa$yKjog z$HM>Yvwiyf`=TxHW2f8-{|YU?6bN;u8e#$XD&R?Z&M04%0O>kpPb8j=0P={6WNzzE zZTZW5>OlBEWptaxdJfAM(FDad0=1Q(+1dGDL|4+zHM{ky{}~y4$%1J9SUkK6gLu9H zft+Szgap@v){l`%T1L>UCG3$&6;SV2wBjs-NJcHuAzKpC8zeDKWC&{IqWEe~QfW;F_*2<8{b=-V(|%REl_kk0m# zx}+DM(u@`aXLS8>Kss4h@B*z}5o>TxxpXCg*_ zu}@8}tgH6?fC2jmSQA-CAn-#_!qFj4LF|h0UNskT>9*NVo3^JJEr%rI>rD!kODgHs z2))s=Lp1)zGAr_xPN*w%nYXnm&S6;#tlh8A!k%^69CTPM+w!)0%7^eNfNtpec11nI zT>B-uB6`%xIbps%*<+mSySFSV4(lviqs<~uY|K3Sr$AXCJC!O3S{WgTTzq+iNR?YMekwM+gE{+FeTaVNveTYiyc5^{cO#~UD;DcBO1!Zd6lNv}m z1Yd1sfKFg8iWC!%U_};NS zy|X?ApVqcRMi1-c!xre|LA8 z(7lOcwKcOY_y#+q%f??@>dO!1b83hkZnYU7qMN$C4mv%M?aHbJZM**g~eSm#7aw&;7ak2C9Xb?)0Q+iO;RRL@2>r1Qq$RI{Cf>T?Y?J@mYw_oH~ zZ0_zkMe_@Dy4(WRjD4TJr?>X|ni==I;gXPC0>O^hZVY%I5Mm2_ZCC<8$o7OW+9XwE zRfHih_9%mOrbOCG?+G3qv?Wa^ywvH{FMJ#~`_Il?fzQKq={kWpo7lN!slxU4fn#;0 zkv(Jod9jyXr;bw+Q9&ur+_zZ5PehsK;u1AS4Yq`(hV4^P=DMClAYwb$`i5v zBBpahHp-KTZ76m>DA(G`%@=7!^+dOwuLxPUV%8ARAbCKhBvHUyrvnOEmhIQ2!}VrW zA7X>9MYy<(b=-HPZrg{rv}@6?h_$9K8;vu*QA;%eU8FaKGDa|$2v~GoU>oBBMRQjB zBmWcKfd)*_)G}V(APA&Ni8h-@3iAtvK$N_u=JeE^pigeAi0O6-*mvMtoz^2^N;~n< z%=kcu!&o*7sMv4?;}+$u6%HZ{(Ll0UNA)h2m`cQzRUX;#L-cU|))>j8Nb1}PEBlD$ zG`GogsM)d9{4mE>>DKBrcZ$JdpgeyX8(L%hOZVk0g2!Q-$lswX&5)g9|9&Y(uR+6=ga6suU!&&5GU zRY*i0soQ$8Ch30E>^0+7EIih`6(}7cok`-?I>gzi`56Y@uWel8_24e+K?9_YXV?P$ z81*xP=56Jn6K5h5jOYhvMLcCoyAq~b9Q038^kDZ!v;WFNJ~#I=Sgg*Ig1qA_o!vst!!H9R(2t0OU4e{ zhLeH0Zcf#- zl_?W$DsBjvj)*BrbTmeDC8(DwR5AWVG?imI;yYKZ(w95Yd4ppoKC^hmj^Ebh8Xr-f z((a%ocm2L{LeIkU3ER`h+8>*i_i)0~mp>J4e;+sR*0i-L6W_i3d0qdabO2f~_Kw6p zW6(1jXiC?Z9Kx(2rgex2m+^COn-0Yw7D_YAEfQ-Y)^-(TGFRzr(lH_yUS7notehmH znAF6NFM*)p_SfowhkX{$&B{zx=%74@_XV-J$ zmwHE+evwNvI_v5!YSWUUH?47Z&$!ZCKc;p;UNlpXGKu5Nvc20MhK!BrEN4(2{V|8uaRj>)7Y7qoL&44tMG#iS(i`pWjQHn!vI1Non-J*%EBT`{Gx z1d;}<53@SXx2NRE$R%}> zNr<68Akf@Fyq3cF8_x&Ee9JIWhgQZ^}yF7+oI= zmS)5pJ?DKcA|=mPj#pVN$j8bAs-Jb`P>TX7wcZiF2HQK@($&xVjK{vNPq?Q|hP=&L=jfkzoBF zfkH{Z{s&jas0e$dI!;djCEF6s9^9F-(KZ+_t=gvm>!J|Vrz%1W=WXH>#Q0P>(+pd& z6ovgWUaPwTZ5L0xZm-HY?7J;~^@At2%TA){KurX`L4>~{Om0R4IUa0vBCumG=hhpt z`Zwqp;tRPHMLxNaeZnJDcJITw->mcUA{PVpH}H7!AlqQh?1slsgE8!jj`Wq@S(f< z#0(z-8wq zzO>go@y&`~^Wn*|+Y@u;s$%o(l7}-M%kQ6r)ESfJ+fP6Ia&P&_$)DM^67wBhYnsef zOhx^^TsxbKytXFGnJY^nLmjZ2<829S94{8IEyDq9YQs~yc2m^`|QNIkGP(Lb=e}~$xWn3t`8&Dtc8(s=G|M^z#ex%D zr5lcc(eqO3mMHGL!&S3$iZNv1D$3Y!MM3=nBq~2&z{ZclHvMA}b{pDXep>;K?>wTV z@$|zpihuFC($_ovWzG>wxNh`PyoMSk?wx>uZZET z8|1uuQr_jLM>1qFQ5V=RB=U->)Vl8ttgkvo$-e9aO2y0lmm%-*+4MV3s%uKxbuipq zbUYhFq*P>R1wWU|?B>ASV+otaBaltQObVrzQiMSJjT1Wo(-fu!WFr8=1N#^q%O$mu zY={lk6G5D6nFz&2l=6Z!2}71(U!*u6p-dK=iHO;NAW_coOfEL-TR81pYpA&Us84c< zPoME-7i|n?X-PW32EbSU$PyDPZQXR@-bHpbO~?=C3J=|DRVIdhZ(cH-{VLX7R?$6B zgLrkd+M9xDk-7!0ha1@CmJ0M;@9ASD^Cccl4a#FjLoV;i>{}w^3R&LZYF;i~n8LDf z$7TKUOxQpj<3N@l#&;V@u-lBGEN0mN3z8-wc`;n&r+hhg!doHZ7E0jKVJ5?!LK4px zqN+Nw&pMqFkBXE z>ppTm?XF@3!=gR2WsZ+-se0&7=^d{>(7!Lt$LolP<6&@A3N zb*ogK{LB`s&(znJr;8{_k95sO$#tc|Jf=V!k=Kd^>vR$D{S9_3@ZN+KF>m#hvcSH(@)CmM%VV zXSPDums#d@V9IRMiJtz$%YCEOR~?_SIDTTF|45i`tg);rRv?6w|L*DY3NRHhWx+Si zte3_fXJU=LFHc#$J~5UYo&NZwWK~Oy&6rbdJ}sIwrI6VkbA!9!W=z!wm8786JyWnr zcgnB&yl?8$)nilk1t(|xY99Dz2CaENwXEYLgRNFz16%F#>3;JH>5ZZrom-SucvH z{q%Up^qT*SFnR+aMab&U-OSyBa~ddk5mf%-x{%E9h)TP5$?nVcipkvSz_X4G4F;@q zLH>`}-r}1-cjl~guhY`tp#LW9(hh1c+f`@fSC~oAHg?{WEWh^XYQK^o@5R$D9Sv%0 zkH!1#dFs7vGe`%Pu&4uwIK(}oFm{4P9X`y!2w1;ll0~vML^2FtMGXz)cj9BY{Q_ej zH)D^*rxvEz-Ogj!|269d^WyN(zmod~QU3t6r~!fn&kw^_U`8L{GmzDUP|LyqG8t## zlp&FhDr_I{@!ssY_SB*S$FKSw`r#A4+3Ub5LLE|U;S!-`0_V% zl}Y7 zF-6X{IKsx&snr&><-M4gIw7RApnq4K-Q#FC%>O=V5TmnrlooCd8Bw&DWC}v`r&Yf6$<%a(ykz=NF)HuTePZ8TUdE|@KQVMjUDdB9n z3hcvm1v?RAKGB|edm3LUA{RSrnIND}#ntVinr3NHVFPmYssGqC$AhrBQuwTLPSq zsP3*;T=#ucIVGH_Rqz^)q7k}x?lZ&iQG|ifYW3nc^{3IS@|f7mz=gzGYVNdc-G~O! z`D{9OX}iipZ{KlGhWpu)l#6DAcc#~AFN)ZGc3(=9&tRAOhtro;c?P3P5vk^{r_ z!#BvyvpmNe>^>c6y(sGa*_tnxatC|6R=J$w#M}0kcQK2Hs|F0_iZ01r$-($eFC|7bKQ{cMW~_Tn}$J8W5!JDYP_Xuwk9-&5i23 zJd*^v820GPzSillf|FY}yYmHp+6RtSQ7Z`?`JQ_YMbtFM1LeppH!M|F;OIH>&YylY7)vGgXlf<}p`0rzhnQdmb&8Z`nvmjc}=C zdOOLR+;DG{No_G3hS^;0cRB@)^8S^c!?gQ|;k!Ob{qFOvLF<&0!k5PG9B9-y*p|9Z z?q@hBwn*vXf`jb`*C}Le@IDLI;62aJL7KmWDb)lp#fI}FV09M&_;9i>K)UL7eEBay zX3P>xZnZ@}jf%(K-?=~4=->@nTLMAbRkehBaizX)oypaR@~-a4m z?@Etfv>d$iY?vZ}Uk1O84nVuC!wi54AS&wGk<_qHuNUj)+w(xAP?MLZ2fI`eraMIP zz{+VFkZr_zFf@fT?2PA0)+EI48MtVF@b1@j+CMk)V+Bf0P6s=e0QT zj@_Tq1VaI6nt0I1Q0^qaI_x)Gn+q2NvTP99DD;CcaGpcw(lFuoZvak2N$=cW(B$pk zwK`DXx#`T=1Gk&jS>1ohclOac2oWSwp)lO%u+(mRUdD!%IZaE`orxw~yMF01z!w#_ zX98H?s2~d_X=?ZpGi1;W(oP4Z-cNe+*V|41m{ia&ZAk6j_r&a{A;c*~1C{!}oK0rh zJ)3CtstcFpB})LUtg@lNpQq&G_RHkp#|22r?xyiOVH`w!cpp8b<>vvVhFQt5i4vRX@a>yqlTH{l__520M4igbdBR3V?AQe#! zQ-&FGh-MK)4qO`C80FH^bMumpek4s{01n3USk;nezOr|IKiTui%Z|0)3);zZFP=D@ ziJCL1eSc}k*N23s*rI64;yM>Xt5{vJ_y$vc`CUtm?HO@_PD>h!xdFnjUq`0^y=yK`RKD(!G^I{g9tFOLXe)Un% zQ`q1SF|#ycvi|ajAjQ7rHqnQE6&!j=>!8S}x~gy9`3jtJeJtaZd@;s0?xc%W_PM+U z^))|ZIB^Y1SB@R*KN#ejwb?uF^x7+D4h~!m3i!D>Jnrm)E0?~?df~DdIDyDR;^`91bhq`167wu4(O6 zt)wSrBav@oYZqVMebr~p)78P7gX7Mr`j_-Nj z>~d|&f9!m4>PY<9`nbX*B13lHOtg)^`{jDgB@-L4Y=)IjU${jsMaQQxuSt@~ ziSJZuUT|o9b=|7tDxT->Eo(NketmlM!2P7)^Y^zmn_9m)!r#KPb-$~<4`07Aa+8we zb5MKeKh3}_?agMwk*v>~&-dJJwi#MD9#VaCTSolDFU^bcR5SCr`~6NZ3cokso1Ly_ z2yc2iuG^PhofJVMh1S_87svNm-f&ZyS{Qo#X7b_q$J-%S;tL4UyCejST~5h2)&y`O z_4l%Lg&*Gj(lz2ZWE?q`A86cBS8&5SVEUl>j% zZ+DD&^Xcl23huIJatj+}zRXyTx6yp$PQO{rU-6k>DT*Ify17y1dD&Rgh+X%GCoVT* zhE{;kE5Xs}ub;*_3KB1aw&Q)Pp2Ux&+}x`2;ZA6?ecDv~*p-`UDj(m3-oBakJ^uNZ zn>ll^m4*N*h5-5vdB;ZCaEdGgV#>iShL9|jdtC1Hz-{D|*FnNn3+9)L7UGp+B_^Tu zeW#a_y$R`~SpQbRkVGr2y)s?t5M2w_m9$$7!vYk&9t~s}h83f>6d4$`0hl*~eeCH{i#LiOz)MSH z{2f`2Lcg)QGGm@2VhChK>Usd;EZ|+6qOfDuq2x=QIqbNR(wi{K3rIpu1{U;feza)5 zA&5-?xh>v4vP)jc+3E$hnltdQ-dmN2KBtB~{F%YoI;nK~*rC~jVUL3;zvv5tK~Gd} zm3*P%?W=s~u}tBPT;?1{F5=!Ufsrlnspnsk*suOL!nu8FNPJs);AUpv*0(9QFQ|OI z6ZXVDD`xBaE4OJv$8r)Xg5@-X3S`BalQc8Xs^{Xoj(V}acANoiQ#AHLpjg|cS+*zq zQ&C8<1Ge{?%G{fLTR(oe{g28w^7hInc4s+C`MN84x$)0P>t+!}E!s zTES*d%_3LWaLNmtvfqAc>z6Bk52^f&T>t*&_U4b1LQ1!%HL2~}Owh0sJ80Rb1-hZm z7DbacmbiDTJe&KO`&_bU$5u_I#y>Q(D#7~unFU8zeIIc8k=Na=;_|Gwz=cbH7`ke_NC@vE=u;f4r3rZH}7_3^;u1q_sTKY)M$e={1a~Z%P>+ygae|tpY|2bzZpU zB=h&pobOxz`|{6!DuBX69B^6!VkKg*fnq+Pcg+rPJlffxmXdws^WfIgArV>rDRmK+ zx~0&_g&nArQyT|S?!*v+f+RC|LAOgO9G%*F_G_U+l6$7%+-td;@)e4WjoAxiQV?@7 z`5kO!C+-ok(h0s|NV2e`5lsNlabg0pgz|u+T0zD!$Hu%Gos?fh@*SeHM;W9ksasCG zP%lQ*)(toCWpw0n`Suu`GBMu|MTOMacFh=l+k*GsD!VLlnHAwxlXz%R*}uy*eLrz6P`dOt~MGr_BQKyi{&u+IdA?bOi9BdM-amQ*@+>K z?wZ>M9=Jz5e0k-?RR?yGE>pgvJ&}*+ck3rh7;jpZ4X6L$$$#eTXiP?1IX043O&y2) z;sklCRyS3eLAd^{{KE+fsjX{NW!%CceD73(($&_0VfTDQyBDQG?}qZa{s0w~YcY7h zuNelfrp8Dm$>C@^**RUGb+k}VbAh~$Ky>UnS(!-lL-p7o8&?x6JZa~9Q6bl7FQUvK zhVu?agfG5T(43(1wROF!Y+?9Phn@El)OG+wNQNx-JUH3H*qdm_rbO)jx89(M|EP@+ z`AzoN3yZTmhfFo%+v2~`+g?DHi1jN`Q%%>YRkAWUxi2_Te&^2f~m5>DZ5BMQP;nHSB1Rw2De{DIv3&o zxWmFZ&`SWlju}%_yEg17|8jzXp7W%D{SysZ3TAu5T5&sfFoi7=dERA2$o(rsJVerfUO-aClpDxHKu$!3x=#WK0MvX_ z$a~2(DREosuHSKdSh044UsZ`VKru@B2EPctEKVQf8@EKH8n@l{T6?Qxd&LBbP0Ak> zQLZE&SeH02bJ>TM!=}pZPZ5i1`md_h$8Oi}AADRAns_6-qtQlr#l6X+?;>U(&Bc{r z<>wnhs&=K!{Pm{e_OQxlS`CNu7yf|F+Qf!ES_S3H+4*p`@rif4D)vvl_RQbyFsX(q zV5U76_GRvvdBw0%;o#us&siS+0U|Jtv*kBlLryovU#vBxXAUG>~?@Z$I!Mi^z zwC6VF{Mw5oL7yKz%vOn@2vNmiL{+ID(Ac=+#^sn6xj*l?tB#`L-?&8f(~`gK4uf*7 zho z>8(1Qc~gFR4SfGbbW+D; z*XxU32k$opF25gbyZFrOE8Pc2k^sc915HWsvG&voU7>_}R`)Bny5GrS^iyzZb%O0* z_cxi_ANq3YQ2qUsCx7Ktylly}=nB1aUt4d0mjaLQ<_dh`5o1G?PLT$oqJ~89iG$#9^^fcOch~sB=*>pw&n&Z-r1sEN=42)4!{>i`5Jd8=6G zQSe6RPuV9pS;IZInyr7nc`jR(cPT;ZL3^`}#>A^%hNFCYrd4D(Xdr50oPJkUV!q02 zLYM4{Yhoq=C5plBWK$7HF$23RP=i2LEcE{S6tgh%u z(lC!Icv4mUdE3qheSvmsqNYQt&wWn0^WaG!qKB)Cr6w5zX^v|;S?{~cKCT}OH`ZRL z9UH~$s=j$CP1(Tn!luURXy?v^^`VLG&HDa2!RJ3$w`@ySe)#IJ!=b3p*)@IJGW{RE zJ-qB%)ZDL{7u&K^Are&G1eo+@S3O*qSy`x@5{uJ?FM4TC9qdmT%Rlpegw(z_KR zW&GecO;UG*6D<~iJPk>rh@MNO6EQmp?igs`yC)hbw`$vfD4t_9#ZxD?A5q{zWc)no zyif%C-4J*uM!JnDrpDcT*o&6)lt=i6lN%X&v-u}_m7Y4TkCv^jvz*=erWbyw0$~ea z^9Cf=ehX+2Ps<~BwKi}mWiMBAaat0yyG2fjScr6n`7shhmPl=~mx7_?78B;aMXZtU zRk5^RJth$obtCr+$$dIO&U>R-p+{HE7Q6Nt1-V?91Y9x%5D5`P$TlPt0iy>1lB2nv znii7ObbMI^{~L={@LPI29WEB{Dyxwk6%3fA^9k`}Gz=HU^H# z4VRmfD)eI;FPGNzS=?|Pnbg>QY@09Li@*?`A20S;5UY$r9>}*MHW#dQf3)(5 zhjom>@A|sr@`I0jk9Y>eEYgHW2^d0-8HOSbS^2tg={eJZq{r}Z6EMOzJ(}<@HgGVd zpSL*p;89TK%55=%r^j#49wI*u5As?8C=y5k3lAy-#%BnD35XbgMK&SX2C%v4BmT=? znN8tZY@8=CENQP;_;}M(ui6-k>JtOAM_?XKmh0M;6eG8p?c;?*tl)XRB^zo7LO%c7QF7Abd@&-yPuz;J z(LDKjw(7*=l&7no$2e4<{4!hfKQn>D3V;~~uS3FRO#zz?R7H?j5RQiYhC`->Xv_}A zbWjwes=^EqddV1;=$EH1@ovK)pj0F>!C;{r-6yi_Ww^uJMNsJaLJTN@fu*Gv$?}+C z?a5t)Rrs2@m=(WIA}K=U{=6exmCa7u8{{ov){iWv_@Qh8U}6NW{?apSJ>-QqeFv_l zszfYWz%!foiIR%dV-yRaNd@Y_qc0ReCGP<=`a!HIU4mtZqt3Tarz@OzXXv}?sDJ;i zBi`1V-F`Rdq|_hm-+#m>V49pj`7=}4ljm5j67Ukk?$SGvlo!XkM`6oCK1WrsNN2;e zbN=${sxY>wU}wqdq;b&>j?wuRJ9k2)koJ!DXutM4IQ&J$vdza{uyXe)^D8Hw^;g~S z&6-|AKkam-L2DpQ%m~TbiL<&e)I(MRnFtD+xR4IdQbeeo^bza$gr1%vIX^gX^GLwl=JmhN@KYL<2iuOU zQ+W%!Q{iq5lT$Dt-8xF?mx~XoI_&}%z1`GvcAf||rM{r})>9`gd4A3R*{e{8CQFJV z-=D3uyu4@dQD%_u+s$$3E~IQ}8?*$lq@gDU>Nq?P1U59CL?-Cvu%xufAY#is`wXKC zSDy`zW0I%z)eV=!Zn>uK0Sg#VdghP zVO+hOv_(SMfxoPvY=*d@(w#gNML=3gi4cQX{D`A2+b1QsbL?sGh5fbP&b54D@U1-8 zJTF$ikn3j(s2jO^Q4J(DKIWq3O)fOK(%-AgzL2uMS`Iy^~s%_{{H(d*aZ?ANjqy>6#bL<=?6q zn!OP=@-~Z}>Z14egP|Xp>z&+9TQ1y;5M&d7L(a^5b1yIa2kUafge;!IyWF@&Ijh#y z!!lXn=I?gCZ`8JG-!sh0+OPuXCx8==A@6^h<9Q2hkFv`1Qnw^k>>h#B9524Ozrg1v zmG4O0TN3)D9?m?>*mrKh+dWlD=1K0}M~$kFO`jce+;Y)vu;bqV)!?3%{L*t5t*!2U z7}ol^G4GvVag&?Xy}zEohEzXzG8nF;E1e68?)vlfDKA;dj&6pmLr#leYqJC`b)NOn zhyfHY?E+xLXtgzcVxY0`=)F-j1>fhkmzHgV_dbG7EF zOEu8{UT}*1qhmy+J;#Xu?-Y5wP;<|7&i|&!PY*}5{BMf<|NGlNQ{<=02sW@N@@IxT z1I{Kv#SkGldx*dV6=<`QEka~!Y~pyD8av3C1mAztbUW5GxO?HHo>+_Ep2$mMv9Lpe z2OIzi<1op7R61Xcxw~HOOsk`KaXT7=$nhxo$V%L+4{c|C6ulN|4kJ0h4!`s|)^6m% zol9S0mybLoUna#lj`X@--YpX)LIlcUS}FBmV~B(Hx%}_UmCg$`A%~!V!yA+X!K&)H zcN_<}N^u`6`cg0J#CcRcx_WtO+^WjQUoUgwN&ABhxM;Y3wpbnw%I=RCsptGr&DaVl<$ z1}d-zgk!B10%9yWDbfb8TaE%OC5$R`5}Pa|3Xr`7s|4mSLIDh(ih%JMsCtKStz&~n z-dw#Mmk>O<@LEq?a`0H>wXwK#4Mfi*97E=9B07%8@f^F#6{g~{M*8>5_sC`k)4aEh z1#Pc<{`DFX)U6+q9sC24|LKJX2Hf;N|bIxysb22MSM*Geg#aj)$ zbUjzUaw+oaDsh0byYlv%>&xOjHOBp|d#PoW<2x@uaW`m{Qz&4r+pqE3zd11eNEfBW z`hdK8`|F*}o8pg*yt&hy5??biLB3HCe{^Kh6+*uPF){`eiO~0i76?(ppkoY|4(l>6 zU{a6z)o;^c)7KED{BInNKdCY8|2Bb^E@=9euEogePp{1X3naNpOP$kvuhiIt`7*7o3;$Xl9Q zJA*%+xV3m|ckt)0@OEJ~0E2?E4A3!h1hO|5k@^T87(*nF$=Hj$KUoS)%pLQ&99d0L z?&mxC*-ES1jF$#qUvbLqdy3Y8V$WR`#0JR7wrDe9tK&nBS>@XvTOVtD@xL9obx7mu z38pjiVB2eHB@C8y;J+XTCW$3roUsCz!zm7cA<~q<%gf>j4pgCof=DRkqyYeJM+IUD zV3)fh7y@)tV=;2fk&pm~jEw+0F*?q8Qu+1j?ZmBPm2+Qj^S8dJ{ATrcGn$Mj@RVnn z3hnug%vD&6H@^|V#FCbqQL|wxN z!&m|!L}?hE2fV-=EQ6~z58rq480h*IO!y^FS6a9=h2 zKXyWX6 z@=y^@c(nRd-@F&g8{1bo%T+C86DdP2967C!{CZQ(1kZ<*Lm%}vDa;$?sPPlBxUg?| zYLo8hzgDf5B)t$?RBLsDVTjDh)^iCaA@e3$Zzudw(Kb*}pb9IMVMq@dd?ytmJtR#e zCj`TYEWZ&k>L-~&xZ%oi#nwCM(o5;YUox^PZ9T-dhh*>8^10^o3tZYb?w#@${l(?B zS02nX=Jm|8oIkDn@2?Q6(Qhej&0B0j7$@7_Cpd)2O|<<^z(SY??K+5Su5llO3RZ|T z#f%E1+%Yf#0%@rtH4$W`561$zP~S6Jv<0drNJcK27~QM*u&|U{UZrq>xX`?2Rw1jk z9$(&1ZFG*c$W)}p;B*q{3D-(#nrSGT=o}&+)vlT79>O}=zBtiqKHM=IumV5`elNTN zho>Bkra2M?%IVZ4xk=&d16sy%+vR=pwXV1*s61gi+(Ne_!A15LF`MOov#$o5tx`0Fkksl2kf7~$Wm<%myiiNr4XsmcN;^wkbvk! zM5^~;n-B&yC`|KWtOQC33bCgGBm(&iSUB-A%L7;A!CDGDEby0r0MrDe2xvQN1zLVo zuyRwbR=?u@JIZ%EQWC>PRVa4~5;u&hy4}%1h7BkIt@y=>9 zAGnJ&I%vA=b^dA{&ko)>mAGZT#?YPS#I5t^tK7YpxGe-O2oYG~h`>GqvA{Su(Ln}2 zsDRiHjuDt5I9KGcNE=QtBJM&LU*zh`7a{qLjA0}dXbC{0W<}`(Q?E{Hz0(T5@33Mw zN%LArgIr3LX4>5si5XQ|*Y3_FZm-gwfNMX51t!pcAqP==Q+hVzkds5Bs*SFd+?n1r zTEIzFn5pzQNQBlWEJF!X9_ZAG>?=@miCl6NS@&t12h!H(R&b zG>PlEV4`zbk|0FS;NGgF@(}%~d!b1cqtN;bQ3S9g&=A7j8a7m?(4a^K1(Ax4gN!An z%p*I<1OhdQp%=Q>5fP9aWKv+9$7nzaPzs>cIX!Z=iSY}pbYDoJMu0$!CA=4xR25<{ zac_H)FvQTHYj+a;f3gJmkGXI(`&-OXi~?v9?0HNtNHs(d5#KR1TP8(LUNRqwJ_y%} zly|uZbuP|o#6P+(3spmt0FkyHQaIAo$w#22UCf05K&_1Crg zGfB6rmdxEBlb$XBU5Y_?dAM36>7rdmHz7zPOg7^{fi1@-*XE&h_9lotrY@lW(&iCY z?N@Ce+K8$J&m>59ZZN_`Z*gDM_6J8-dkHf?)4`oG(iDttu{h1p|d3!sT) z3hnEWq810-z>iAiJDFBDuZh=W0IBN8wLL?X;=Akg`T+xdp8%toRBk;{ak0BSF^`Nfa{Za}UPod(B+O5+QQ zi3+AbpkgKZ0dxc^n*66YJh&ws=E1rtcyOnC&lOL@qN38P}us)Qk|KPK?IcaKeJMHJZqHPT5ms`7IjWu1L zBA&+?l2K}2;WrJ_UcI_)d73#0o%YU2*uv52a(!36qDt&VYiRueYRt8jE{6`1R{q}WE}trB}1Lg+!DdE-YtOv_d7|0H# z81|nqxI87Ynv^yhOo0BA)IqQmB|FB7WlKA<1(_zR4)o;o>h`kQ@3<PSf%3vnBQLAdnj z5CH+elMM|hM&?3MBZ;6^EtPqEkHNI_VmcRZ07cPou7w+%A|f+`Q(oIf*u?<?aoKmsGBIu4P+o+^jKJsyRTE1W#( zMODh}znChL`>{Gc*H%`ew8)>cdRTc5CA$tQrRHdtE+`C9OD!C0^W)CS_1)Q7$34el zx+MFe^3%a-g z*=U6t)Zb_5fC;3W;XKKZKTw_GoYFt<;Mk_ZCw=V0)sYi7<5H_aqoOu2m)BH}e0efs zDGc4mdRm-X)fFA3V3P1R^ZA`}KC?cwZw!dwMbTT=kYA_)yTT zm8u=+kq8hr%v?Yf?*M}bXig)fDv8S^0#`@5GWTw(1>IH${6dJ*rHDmSFtpB!O-{oZ zEuH{P#UZ&p8wQ31sn0qf+CmxWNNpO6bsHH-y*d_GI0E+yLrpo+6l0`7x>usS8m?B6 zcEtl_#bB=WS?BmekcIh1XnXFIz+|3Mvb_BJ)LWrjCq{m!ib4|%M(Jto)qj*142q>X zi~-dN`~fzRq20t#08bf-?~)*ifuhG9Jq$(8v=<(ay#ydZ6^TlYmO@x=@qi91k&V0u z3espp5X@_UK`c;U(5UI|vLZZoQud+S=Q8ttMP9y7Uuw7R zy7C>orf7w&3Jov3Z5;WnDS3Y777{F|*Qo)WCpDRdWQ*M&C0g~1`>K=O^gQApYo-K@ z1*Q#YrXCuLNgL5jn+qRMg&u-^KadNLm5oM^kr|(u5)Zgnb{JrT0XQ-^XI9o6_ihSt z(B0-jG7YF;1alvtj6S76_-=iOwRPS{Q1C8!u3+)NSVr1&&2*J##c8iJGXkC+PPV(azX_FABcB)WWjKw1>5@Ed13pE}BAj7SL%zybC1h(U{D)~=I=Izu^d8S-D2{R*i zi??5enI-8rHij#i4P_KQJDxT@mU;Ktm9!6IS(N7;X`jZj-JTDm$>Ej~xETPjxO6`> z4a9Sdl8I@#n!Qe!sb-FHOA!+&4zc`TCM~OV1N5J0;kaib>P~efurVW5TDXXS`Fd&0 zcge_c%nO^Ej5CfGn&)rog888U%}SyPe5vLYq5MfsfM2>)=8(;n zeU>ou?&RJTTc$If!8iYZ%A~x^LA4kF4~^8e(zEt^g5+wo7?DYZbMV5DM)(}o~~B2 z^V*BVbj_N=xfh7^3Sy|!U=-`P-ma5X;#?-A)lSiRyFgTh#CKXl4YJB}{T8h!-CnTz_`;LL;^SKB5x<1wDuhuH_CwCJQLdRKZ{(CMq*?kD?;H|+jj0Fi$$xb^Xs@TNWYyN zQv)sREtTdG?6*_BiqttPF~Wz3)i2GkP2saru-9zk@ZvH;!VXQm-k!k=t1x)8J0l|OaMT+mu-B3GM+Zu+ z9uew2sHE$O^88R?h>flmf30r1i<9ff;WR>BMoi6-Yi}-Q#MM;Jy=lovtf{h|SSD3j zI57gKL2U?4+A#u(8vwZ?PJV*2$*P*ph&BZdAwP7~Wnv)1x~MvB;zh<%- zt89_E=h-pJluPEmXZ3DVYcmhlz+L_G5|E&rV(>x^GAnSj7cRvg8UEu*i{W2Pi;fpg zZOS}S0|op4b{tv^9KLHnBQWTru7kc}f$%S}VucqA_pLxz0G2c_Js`5@!H-)4crF}d zA^|Fb9_0L%6L+UlGHaflq)ZoN9(~r}HZAqs;kQ5#2ZzIiI}QL8E$PAKBv9B$BnHdC z7DO6w;?eaGG7j$)8b(Nb2i-LUps{7#2ks#M@Q zP&YOHXbeJ5B?+qWt5Lv`R4cdJb)Y~P76>u_FO)}u#%@BeTr>#f$!p%14F zKRmlh`Ph;5>Deu}j{{j>pWQC}XvFwl^Y^unGg-g2ASeh*4@_<&a5Mo9b5C9dnXUN% z8FzVJVX)T7kRc$P5$C6?#};4Tc;H)B&JXk#kLKW~&+O^Awo2oc;%>?9Mz*5h`xUd_ zS*x66t!3sf1nWg7SJJXO2SjcXrEEBWzEGl{E%UtfuEa8%Q45#w|BgTv3I$u5qk-3z zt}BTzC$M+OX0C5Hm|2yrxV|H5CNvwW2p+VfBQW(vG-Q;tO$gi#S@M`0mmMxMk?*FH z(yd5)xRAA8q+;~&w|EsVTdnrx!p$L=uslaN^O{Qb9pHGIa5S`oFWMz!pANcvQjn3Y zH1haL`EDO=?M{_X#n}tA?*)81oNb`pCEepcT3H%SA~0dAvWtfC~iERU29@GeYg;0n6#L3RU%%v;M=~VV2?fXNYnzNT^ zcdLB9mu>zWo-Qap@c6+W0Ja}Pr6eIEI8t8x82_gn?DOdcWbu0qq}!<-xUY+l4No$R!2 zE`FZLURL{X?lZETQ`>7jE5F?x5A22N<{)Y+w7~!cw+A|nEO}0Rt9&%t59|fXR5XUK z&ec)e4n)Lo$YM`Nc!*py{G~sJ7=ovKNYnqet9QFhUG(G;()c?UoJ)>4JA8bjR*2oMysYp?5;?#115sZ>x3612 zc=Ai!_K@{Mg)o|gJI00UX(>%^8zR!_4GecHtNypnnc3>?t`8;j4p(uZ|BJ$I6NfxE z(;5?%8^vpz!pluGkCccyGq(FVi9UVdZ?79@R#b>heXx4i;Op+~5$m5seXZUez5eOR zueQKls!L$Bjl(5(knzA^boY+23MyPzMU4lP-dQsfWe2}|PAeKTLt392;O!``NlkRI!q>WM8>1$5&}mJtwU2ftSQe}WBNU(k%gGJ&%Ue40jkA;ld-!RjjXMn^SH76WS$ ziyNS*v8Q*z22Q)li$dZ>aEr?1bYqYTbGlXR_DyNW&gU-*zv=HNdH(Y5H)y|cD2p~g z7OoF!3M`o8N9|17FP)rw&!MvdJwv#EQu&rXH@qw#J}pdV zV+arGpf`V#>L5j=*2qv*N)g$b`maNq^W*^3#veu6LSV>nZH2009V5MUf@f=()71Vc zz`Q}uhw^#omu=2N?OB!I9yyP-zXbdyLHm2`k6>dQE+E2PkrP1G7bTj)jmi~Fb5|y; zJu8<)jPyR|u;>t@s8^m%EOjS_`^BPXa;>Dj&d{+;u;nQ;MGjmtmwC9$D{-wv_GI3d zwBO-5Pintj`<<9GRy#NM`!!=3QGrX&R%+@}_RDn8n{d(6bJTYf*DjYRwy)?s@E`Nv z;+$97-vjQ~CL!GcEVRLLmUNG$mJDV8hXA_NeUpx=<46o6U}YZR!F5%`IBX~> zu)xEEl=)Pc>!QPzbP5ze?tcq#oJ)yC-vH=+^2~_trfdjCTmkfwm;z*4^lM@#c}|9kSk_c_1T|2Od; z3=;uVR8#=d%#94GNnyk6FI3}BB4eJ+bGd;sf%_uk$8VkYCa%2t;6H=^6cvGR`s+;+ z&Mbom;DpjA#~W~nd?-;E9RTb+$YR9iBO9j)37vB$xGWDA-k0M{9?=k4jVlWOND+jg zNaYB=xNs$1TkR9z&NZWSuz*S92mBMRJ8pE^O(6+Xtf#l+fOYONnk_IWw$Qdlsd-bK zlxw68SJ)Xd-fs(=5- z&n(6eV=P&tu``w=$(D{aBu!C?5|V65Dxt;L*EIHBW8aq~SxQ4Hv`H$_?M6sQ(|VV- z-*tT7pPzr`F=Li5jia#z1vtrbvB zB7>wEs71RLJU_!@;sil%JF|ae4ViF{sXO^WpD@gHa1&G$9c6BzQE~|jOkez*y^q$CYTXV<5Je@ ztug2cH;H7pi>dKAL^`>z_2F@gbY?4lF;dobvhdOqmz8lStc2afh`wfzmIm=KtV61j=1ySQH*1h!ETb*AWj{ z3Bs9&2#`~lJbmKtIcAeug;=?kA#RU|;EOpFADGEJ3q?Ev6P0AkIsr5TX-)g!C3^jMsFT@+f4hm*MOeF)pJyBU~@rEfXf{%lpih8q zv-roNZqT%I*DOSJ(Kd{(S&6z$(@_JR>0#>_2u$E?!BGGk=>S5-1dYdxG=xy2@3J?B z3MfPmuyxx7bfX`!H#uXFE>p@Ku7$$s{wQD`{gka|Ah;*`IeT-cpl9@}Ndj9iF#5Io zmU%%V$k4WsDRI%$lLj`F?C7~k*i;i3Y$C+sN#TFVG}Iv$M$fw&RZ|+HNlcMu!JFW? z%GoR~Ux$TYGsTJEjl#_E=IHlqPpa zU{EU`VYe7b59?~-z?gL&+vkNZ#t>0((K_Htz~f=DC)8Ac3hn_(P-={lhpmqYK zVIU?FYgMuvrj;Ua9Vnti^x_C{U>WC`B1|!rSi7k`{bKsD4pWZgwbrqFu=|w67CV;+ zGK@$y3+D3lT1)B(o+hqgDomz+k#UsY>%7(_cE9|-+_iqOuJZdw*M`SZIQz-saj~9L z&Nkvuze2#(0@T423WDQvNtiTb#(Ga3ND!}#^_z0(7jKIVoN^^gm||K&gDpG2DMLvk z2>1(>)E65(bN;xaginNl6;i77!MCJwq?xKcfy@h;RB#Z?viqG2_Bx+lG<@8Qv`Q-%j0+vu9{w4 zA^XU8N%J@e0a2uxus8Lc4&5GBo`4{hap_ZDHd6cIvZo?XNqNSR5CTiGS}-#TLDat^ zUQ7U|fHlQLSWnI6qm-!TT ztK>v3AgiOG_k>m`ri2862fQsGWI%t7gG*=OoCwbm0)t?}50MYH5693TwRM#EK97?= z>*V75J%X#(X~#eGAYtiqD58&oZ9j_B2OJ7{RC4P3I`jCaC8rH!_ryOhITI@D84rt$ zk^qE2pdjKz6<|s;dA#Dsrb7B19d zP`o%(+>)5klVGEeouD$En4nOZK%Y+PS7=Mn_QV0Big1jn&yf2iKYc&6bZ5V;UF^DO zt`2^KLW-o~V8SMaOU{a830o9Wa}^g7KzK20fX5z|5==ZV&nx~(Kuf`ht_n7UT8ZY< zEE^^9M2Lei+zf`{hbk!~+LorbE9oXetc2~qAeu3+WSYpBZUc{toMG-m$c2QhG3Hq4 z;||ABPL|26zXYee*Y{M+?q0*f1%2A0PrMU(w>4~5olklP* z0(8zyp0S=7ln_8TTACNCQkv*nn%}O{l6btd;JZq1BKVmhWD@KQoV*Pw7JNtmv!I1) zs*e*-d+Jo5A4v?EE=o`ZCxR_9m>Z5PEH!2mhLD-W@af`y)o+Oxr>~IJpeGK)4#bEh zHb7^UL`KjU9jI$Zma+}hM3Q1lOG4G~i3y&i)oQEZBDQ95?+833E0m3@86{m-D3?^X zOUft(G+PXjVs2(ZRq{QPF08IY90h+!U?gRgR)ng1Cgqh@wyOsx6_r+fSD&MJqmnxE zBRDc=y$+p=M4+2lJj|q$(rN>GdQwGcO(?xIsiw5HoeuYa)Q!?RlYj=u0dEWmEHo~{ zm_ytUw8?@q_zvnXhy@RlkZf$m?t#duBWv7CYMHLL(Rh*6Hr}{ zu6AwmqC(fGc4zVjg`1Ka{{QU&Nv2`XFkQm{0Vy^m2B0{7w*JH9h%cVEd^SuZfA{RJ z-mskf%k%d927b(NPr|li^vVtR6kOS=CV>B5l@xdpj0qll2IF#>90MJZ6rQr4P#uL7 zzOvqS9o-Zhf`twIkSa5wM77Ey*Gr+ixkKJ)og(t4&t~Jk6!HK2&Q&p&P`oDzcMc1) zDn8f)1j0;&wb3s{M)CgW#_*K&iv5zhNhyko1M~1sFWATbTRRg(xojX*w=_k)Y_MI| z6oIf0D9HpKGXe@VLa_TB-L{lNr4PRA_NHtsduXs}IAwF$Bg`_b-lhOo`MwE%$*gS1Ku_e-B7`Z>c|Otm3a#egek6jW6mi6={w>K}z`f-;$-;CPmXJ7Iz1J43*E27U;3m`lj zFk+KX{xJ@oC0=;R=g3&Ke&eNpBjfY>-Is!nyjI&{gb-2S+~z_)vl+^(mrft~$7jpL zrO+c2)mxS?oj>xgO=h9W#W(-9^Wsu_s4Z7@9v$O|h)o|XJP>)rNZ#P0g9P(v`g$+= z-|YuCZo9cH`pCeWo5HEFWv6k%k(O~sCPEDUoV1Xf&NZN?CM&)fH84uOtT-cSXqTFy zIO}ZalA5D9muu*kTA=uL)G$1Cb&)an8e{@22}gCK;Q3Tj)R-Yyj(fEI3DZ%H^k3xb zv?^zQgI$CQCm%ffh|b=S(F0p{%^N7skT>twzq>`tac3`1)re%#A*7*il%85q_Ab<@ zG_|H|q1~t@wV`bByOAl38a}yh_1 zxSi`~?izX=du5!K_I#?_%K8auf6V7rTHBF_N_YNAZ9h_@Z!nkI`DVHL#mCfJWgos9 zhx>38V>34pFaPN6KJxFoQ z#9GeG>p0oPR-9saTz>UtqH=4L?6~58k~hy>o_O;g*);C*^qcQCrrDS0-uy@~t-LIR zNDTqRBp7Ld!sr-LP7JCwBsOPhM|HH^B28IeYFddV9I_lCKQ-2QZE@YSYekN%vRy8ZLvzs}omEZj_| zDoSAyy>Py0h>OW6E)i8>c}3wnP+iuq>~Eu}5lcvkC}n2H5>?_kVCKS-P$K1-`LSe_ zcwd=?vut1w1ylIPnUpCJ0Yo;Ej!RlPeXyT5%x}h+=0#RFpEmmD;Ep#hab)g#yxBaR zrD4tIYhKJ!^Wv{DZ)9oC+!-9m@81y@LaKgRl<>cPAI z)%KON2ql`74S#yHlKcT1>GXIdg*+R2da{yYP15G{)EPxSTkG`n86{iWed*aV%89n# z>G?A%1GXXQ#Y!8$+D4^I$3#%=M_d9igNWDmBRFDFS=n|b$XqW z#w$DRw8j|?z8&|{TV^zEcf3e%o6$<#F_+#sqdlP{t-W~0y_t=P z_9_{JGr9xz`WcUBHu3FT^==q`2%sWH9Rg1>1nVk9`L1Zf!bJ!&r`-j=BjX5I2AW5z zCgwXp#4sQiM>z~LbtxH2tcFOVkC}Vjl@~0=ONzdl-?6?ply)~mUTE-$%Rt66 zQgGahLzZy7r01C>>b3iCOJg5qbnIH*WKu5lml)};uC{jJ?hbeLp^UHPTf=ruXZ$EP z?b!7x<9GSCAG`3GiT0@B4sxbU%mq%SU}kmZxUhL_1o5buFM}eOnD;)k_4&5$!_QEY ztwOxY=6MWyrsJUb07E~MGHdaw)htuE!qRZ}p3JosR$;q6Go>o5J9Y`awe+r&MUne#2b}e@Q)iFx9k9+$pY^gmurE9NXrG9B zHDTip+K|N(;)`5C{i=C4^`~>4LVeB--&a2yL@O$M!(2+UYbyNSZEMJ`KkEO^r8~R%Xn?xw$9-KVvfGaa z*0|~;rVvcpG02d~x(k}Df6l2!p_CJ`nJL>W`9(A?m89d!<=yW{dK$yfkdN73nRXq2 zII8=Z*(EVID?KOof5Z zWY|H4oPnbvOx0?^oM`i?pVYM{EydFpW2tx2gKOq(&OT5+_3EHePT`@MeM(z%hGx6> z5v+5DkABfPv?oWE)V}wSOU}#LzoF6YIj@vs%MW?mxXy$O916*qm_5tq7MC+U8*1y8 zoijHZmgrWQvoISz;HHb2W;hlUN&)&@+fhiQzV8i?rq}&z|Eud@twI?0MV6FLEdxeKw_fjhvOFyiAtf4!3gvILREm>$v~o zEn|aB%a6*MYvqZ#=;jo$z?e60PuR#_=(Wdf(A+t1rS~ZzlOl@j^f)|`^Zn?>n#0RE zzm7({JNzdH@n)*Ko5BTB-3=#!B&pMEJS0|czB~Q16MuvCe)-)x60$KNdV=qT{Q6qW z_2vl^W4E_={^LbZiIlRl7Ce_2UT*Pm(^taPNN#{vPe!E$Zortw+vS*hR0OX|RGvFM zca2K)D|e$@A(a>@54&8^%GIcx!h|W^5S3$D1Q8-kNOL3+0ffqw>=VdKI>fdZ;mI1< zZ7xs5d-nxzG@+S9^wW0_>nJTmOMSHJTPx-r>+9i`E9o6q;}Mv<&O82{$HiP)B>_+| z+*$LTWc>cZc@2);K*3+7M0YzBc=!m>&H>UZG#LL1bd!i$P{tM zQDO-4XXZV=5%!lH8Dr=(EOq;ra?i0;?;bIgs4NJZDi4*UM{}ml5~(Z5waAYhNBH(M zo%QP@D&u#bmkmEnyh;W&8F7|KR7CS_gEXW{VX zLyV;K4li$;;wNsKPV4Nfw2eeu`{cr(x~j+&2OE!&!!ok)_H&Q+{yk5P*tb1nfUIm^ z>|{OVou3k)dnVf+-@#_co@$ zOD@K^fDle}2(r5R?8n!n&4S~S8@_G|&EtE;d&J;k-oxlEeBP$sITa&E#A5P}-p46; zJK(K{b8W}c@=hLrVLQcnM=kn0HF0=)keDJp6;AAGa9# zo5+*j<m!~YH&+toqmZ9iS=!;Fn}4aY z?1zteep+R@q3@pjtjdZoU(fu!%E}Jk;QXS>svo{l`6ZRrhJNY!6_qt%ex>;}m9>WN z8}jSDOP(7wh^W|{rzQo6?Z^mF0_uk_*4eUzG*s68@axULT3K)CKb(KPvLVcWI=`dx zK#(dMch{OXWABiS(zzF|+U0jGz9~IN<*+zk9BUFMw3gJJ)O* zAYO29?rLIyO2M~`mW}}3f=89tegv2oJgsasJU*5_;th@KZUv*>Z8gUO3toHQcz66_ z!K8QlI{<+=0JuWgoC!30Eqi{eUgA~Bdj50f5en)z$&FUK&6OmTUx0j*#Sj#MQU}Cy z2*iF=WE)e5$s2=P7ujwYm|iej*%204TJWy2vm>yj;C*EmpV9vkTBsc%@b;SpT<@Fe zCmt7k@xJAIVxoY;F{24F2$vHK*>;F{QuMUW;qRiqErm)*rzLHziqk3Xgmq>{Y{4bU zCe)IxIwRIaunh8f&ASD?8Y#!+tBN+~?ovY%i8zJ205cKBZUx*cn3vg|cVeO7r^@YD zCsqpnsz5&;e<4A&r-NQ?QWh(;n-D1-BbzI-hwQ9+Iov6zR4z^+_-K$^A^9yXFR0gZ zM_zA7kR4v&*qwJl%bSH%`=n0V6^d3VSe=|+lW%v|_oQ2)C;bX#RPVn!8D6+v z6|r;LQQymjtK z`fX=$>~Re=J((PP^6u21Li8AP15t`B-$EP+?T1V$tg0P>2ap|#a@IWif-MGk|KNxv z@%1K6yt_YI`%saDb7sW{(Wm>-(<0}|Hs;bEpZmp&qG5ac#fsx7!ne4{+9*Rd1;JZY zL646@k!{s*$7$W7omJ4)VqUbn3XHBE!V7g<*IZ$}yCNK6XF~QJgad6jkM6Iq947@H z#T!R)y$EvVVLhr!!u(K_h01Wp9SR%CIgCQ=}!6V!?F-$*FLL2ZXg1jrSGEr2t~foK;B{G6A3A#p{X zZ%1uIvZ0sZRbohGk>A^~ADHuF5+(`Ggfl>_C#GN=OeXIy0GYs5K=dt+Y$5}Zi_)e2 zWiJo(0dhjxiUQw`^PRm{6#VwJ?b#PaA#eXlJUfB2L(AEMnj`~GEyse(rx#n!kYifd zMv0oY1knFu%Ed(a96KI=KGJcvXd!)~x+7G#_)-LdZ82IDqfeF;>1UDw@yHo24dOTN#0=^(29AldLIwCJ;Wi!1H*NccUjM@pqNi&9F zdy2EFX2Zffi}R}HI>LgBi>lt*lEi=-2aSphemjnSvtSJL8#_e028cTI(e`XZ&8{#7 zvs&COi^W1dheZ|pymamevbTRxygu_yY;oo*f-fsFB;|GQOhrO*M`ljxc3;_xL)Z1f z(~B#r-i3vi7S~iQbcDAQH&iYD2seVBB|$DYI1~d?oe0K|Zc>7XcVhO*$1d5KrX->6 zILDr$1>8APYjLYByLm5(GFW_`5}~4Btl}%v{t=pte;jQjwzkt1K-@`zdgmqebNmOd zslGpOZmjr*>T=$>h2k#N53kOx6yH`QS^CeaBwID{o!523dvVo)uGn|%UV0Y!2>emAoT&}!S{g!vZ@5;F9f3GftU-?({yVS*`D{oYP zK=6soz5S7RvGU5o+m(TfZC94x{^X0ecjeRDU$zl{WWHAY4vUz+@}ufcN5rQqzpMWK zh`_TWa6Z+_ObYab;ry6#Y_boK47AzMYq7vIWmA2K^hgJ`7zFl_Zfr>(Qf*`)dz}yO zLgYm@%?HZLsca=5KEJ49wwe!rZB!#$(+A46-E5ueNF|4&?UQ{Uh|28_oqPmk&5G>~ z-h(rG2gTI;TmSp0C*fr&FlKaU%VfNOQS>l-bG2Z2^fcSBn$j8liM_R2XeAn7GJKRu zkD-)U`Uv~Q$d$}Xh~&r6OLnMQ<2>{1hxjo_(G`KGR2$lhqQznUj1cFz5@g?MdjU`e%@ z#8_;2$>Dh`zPPv&&v{9^xa<<|d8wqh$`ZeM>A|?RlE8T|B0xMx@mxwhMwY;4vq*D> zBKK-4EfWY|<6emW7ik`QfV}G|b)9s)i#K<49qv$n$(4k4Q!zS9BoQxSuac5*uMtD= zHEtWslHgIod2!a+#lI*CnU_t9pDPKUmm7@#R&sHEJ>8Wle8!B31~5$wtR6EQQT5?R z&K+I2(mHgn?G>KV%7X&;E6AnM)d#H;#7nF4<--#cN;OGuHrlC_3MMFYCg_%4s#aV{ zFfUb4KOmfFSDK*)MG=?M95t2vM8DDkHPx}i@X{-4YSKwbr49+_Hx@D1zau=e%p66_ z=6??*9`r7s*Ph*%Sz0--?h;d4T2l=bftJ#SY5?(jORrV~3O`(Wy;>_gdAiij8=&&# z(wl0xhmu!HZ>#A@r|_5EQQPQ}B3*W0O*cP^FpEOSekWr$$}vl55l4Z?AQA)^Ty|nO!)Leb(`vo37JKJsK6kAzeY1RC zy*YpRP}!)Dez>PkS=z{dwWt_vt+$xq2Jdu!A-=E0@3K?NM;X|Mk(q9YV^l#dA;3&j{JYMv7g)iHS3O zzmD*fU$~5}|uQuDcE`F0ETOu!s=;6pHH)Ik$#4R^miK*H> zd{Fsel8~sfQ~6w`Rd||bxl|2cYr*BRH2{u9mCM)I7^SC|AMMe{rdv>Of(SsKBqodm z0I~8= zFAVAZDo1@8(hgH$=IY)0nSnxw2p zX4!F zd8zBJNubu(t%y$9`4z|1UGlSQEBw`AR#Rui3H5{0IkkjwRF$=tJF$&vt*{w6@Q^kdv!z(%X%E%f>Z$&C&Ydpep6)F>JJUerB zD=*a?S;;l8OsnxS%G*WxH(%dYg(_5;-&h$@@9V#i-(A`48$d63T-oY-+^+y?QcN%eR4B`r zp_roL#aWauq9!rYL8?&s1MPKs4Tb^ucbLrKFq1)nCPR1$8k&OyUstyK2G$lV!=OS4 z(*IO)e1qtPl&V#H*$da_3vsnvRlhHU(ArfGeNWMM`0!*#nYr`o5Se!s@p?xIx)#67 zbYfE<*ED=BTn-=dJ)KW$&?NYd$DXsP+Bn~1Smb@~tIJQDqJ32_-knJ*@~-+>7}8l3 zT=kD{*W03tRg=D<^y1X28Q(C!;^L}#-|*Vv#;PS>2r0U&eu#;nh$XQx#y>5~OZg){ z?^+B?c-rAyiO_eu9ZKh=uMAdwR_EGWc~SN4-Gwn-CE2lJ+I7NRQ*maU!C;D{3{DpKh-0~uB=r3RcA`G`Kt-^$Q9(KvB8L&u4aYk z5R3eggg-Bz*0Pr!ZY8X&@5h#_Ci_LLRH#+2p+}FgjjDy{G14V=)uQxRmlBt133}WL zC>q#h2F&FE_ZXvL1h7qq$dg;o!@XlECV9e(?(>7prN03G~v`Y9&8# zTE*2JYDxK}wbdH* z(6)f^KOdBu+HIrRml2jGbdbMeBsHJs@xjldMble8Rd21mZ1iE?cpIG+&iP^PYR($- zcr9_{{pfymQnfK@d_99?d9S%)(dG#Y9)H3w=z8G~yM)#j{JK=l!ZS8nbX;czr?l#kH$_&w4!L3J)> z#A-9MW@bMsT^SN|UWTk%sn0q>&vU8FuQ^7~&#$bl@uwGzRd&`eE}Lb)e(i%fhvync}|>ncpS6da?|G8 z)P*wo5wtd~wtP_JmZJVkoMBCfiwkc>er;B1R&7Oijc09ME!e)Ew9(vI7#6+TR;ax@H+PZtSw`g^8b^Y{{S@ra~2lQ)W^+t71=&jNX zc6HC_*IgR$;Eu`|7_S%=L~viIZ>+jbIkGe(@oef20k>VzbQ(=fm_e1BDf;dCEa|j` z{eimhS)a2Fo^`JlV#*r=>t6dg4mE_={acIR8sqAw7uxL_7kp-GJHi`F>)zFNb~d)u zy|3+BY3!~0=m+4eCJCEF$TP_o2AHYesF?SQpNJXD&pQ34UHHSg_(aE{fa){5g>DTd zzo`4Ra4V_FZfn+|?oR&sx}UYF_nLHhe%Ia}J8bFnm(G!H=C3Dc^td!j*Yj%h<~P&p z*J#`sYc{GE(&$?Nt17$*o($`W0Ba1*b0~2CzawKfo*uwbrEZ{2MmOU%p;(ZYLsK>a*(P4ag4c7 zN6?9UJU+%<0udFn{48%qTWfe(FWtgG=@X$wcv(#;$;`n_oteIe+R<$9;O$XWA!4f__K zCtde$D9m~xU1JpFs_}B{dU!*`VU1Dgwxot5{@ZQavKzb?UnRA@ko2v4QQp?r5a2() z(AM1$eGn0ruL7(`TZ;~OLECXL!f8e{9G!rK)Z6YHis+jSc+Eyl#KjT$d& z%t&|GHD>r1+ji`0%wC*L>hNyNUz{842x%-{e9PY%2NI{lmdzzFnIY`8)h6!z*M_e! zP-mWlY5mo_d*iu8hNT7L%1`}H{#{QWJq%u7D97#Ta&%0QE03F{l7{r|SkF%yvl=Vv z-i3FTHrCWFbau8hHqi^!aYof8;f4R16x$&m|hlQ>`jn+{J@Bt}j%q$ssme7cL876onaG6XX`j{d_EK8#FRW}nfNiqkTyaM(Y_<`?Oi*e0SWFe-XFOEjR>q9>Jat!AzDCPRrq@r_4&+?pi=NXD0z zjUN-_Jj4z*OD~Zg^wjQ<4d{K>bFrBgK-TC@ZB`24^Y1NgRtw;->*YtFlY2Ln1%>h30m4$6V%mS-{xkm`ZYg$dz&}b3mD%SZr)rkc<#=0GoXe; zXf^Q#VrV8`O;{#)M_Om%p6<`OlZ{%3*-+~4h=@HMa=v<}QraXSedNyEam}cOr%R&> zBg59>`$MH|t@f7kpWov~K7Y#D_q^#+$IL+!iJs>|Yx+o6&6lV<`oynVF9|32sa&;N z5?O>fCjtlo8&@&PG^AcKpc-?GSUX2~#PD;B{rzM^B%JwfQar(a7yHe|t2^sOfA$;- zX@60$;$U+1{ISMa;a6wRJ8vZ3wZ6KiJ`??5f7NN}$=Z&O*emDH; zVNFSydr4O>M(NA{>J#5?bu@i1hnSA%DRH6^ZSZG4vvjV$v+TP5Ve-NeO)1xV#Wmgm zA#}9(s<*iGgMIBME_1vT_jAbXgxfghc15ei_EW<;5@#&_vN^Xree0#W?zLP!UN7_W zUhmbD_3Mo94_`e~FKb*raWynRuI~Qw)$;-C7w`YM$_$`s^ix{Er_g}iM26f_P!EBo zLLH%bsvqE|cI7Zb2plg)>_>F!e5_y_-7}qJ5hm=I7ZMX7@82)ik`SO!*RS0&5e3?8 zPuOnj!j{GQ0D)hIQKTWogl8Ne)6#H2>|RxP?Bm#IDNs3RqCsK$E)huyP+aUcZD9o{ zX$&~DWCkev54g4D2AE-$L9hwfJiK1gJmP%XDr0wm*)z6~T;w~pstK`W5GJikn*0a0 zlF%V*zw0LLm6OVLb0PLxJ)$oT&MEnY5a1MXp@Rf5bCtS*z?Q-Q)y08}E$jd_jltBG z@&NTkOw*bB*fvz!m1tuY@br0slSE<@sw}pZtaZmFL4^;pV)!z5xE4UCu{4I2P9;}4ClJ<-&Yd1QC(ndWBKM=sZ1){n6rs50466<}|6W?dS*X4fv^>(HA?inJOH zxFc4VzOBknUnbA@+JKZQbK*eec))*mADKH3J=Q;iui1V>e3&igYqy)Oclxj-ZIguK zJvjs0e;qE2Jqo|}ucm>_f8o1hcjw?*K%#TqlCRv|4*nWuKGqFPq2PhDCiw5$uB`nAe5K=Tw0;fsiijUAKqG zZ_>UV<5q{;x%<=HG`DWrZ&x?m*s6Ja$Kr5ztIlzIjc1Qr^^WiS2}S45Vkw-79?=J} zV}khC_7O|q1fFMziiMz(NK(u`=#uB*0VRPyaA6pjM`7+f_iVb=u)(40*{9a64ZD6m z!(Rsvy}3NMGNswWnZ&etn0Q zPmhg=~VJgena@N(h$IjzIvFITQdXt~Rb^0!56z3I6v(iYp`0Syf4 z3CBI_Mzz~gjvrYZHEm-Z_tJRf(3W}psQ)Xsw%p_18bJ7>B1=SJR3T!!)pmI}SxcYi z8PQrt!a4S~FqxrmQvbQ~Rk*^8?XNQBFP37n=^d}k?F)||dk_@fc16p_H9+30q~W&8 zSZdqL8jVDSw6=-{-*aQ7Z8Z&kU1Ke64GsQ3$9mhYHUt=t54Q<$2yDcFxDI!nNm3%g zAluy%9P+s+4YOxDN-_7KrJboTl^Xmsp9h7kk0UQ?)wVlrA$`WwTkGSSvr zxKA_W17wTXCFa@#H!JTaYMYYQ}CKykrw<|X$o}2c=w<{(UOp~Y+8A)B!E$v#3 z$v>wb3+e=>XuNscuBSci{AR3ui*{C$&eb(m_T!%cG{xO(<2%?()?#Uv$kue7tC~TwOdYqFr(k`BQ@jajCsfI z#(f&I4joQ`S^l$b9nOK-b+dsT2Lp2!XD@cR2j*(brFM7)=K0SRci^$e9uP=#2oQcD zd>o-6DwQS{)5%d~<03??(v^BkI&P|TW1_y;CEm=h^D-dON+uD7G?_|%)(@^-l6Ok>fxx6>VAjm2GWKXqJayz=uczB96MHO_#_#}Ky1 zh`75W4Yvr))&Vt<&?u<0W9^xmJ)3^XFW(86+QktN6IPr~NKrj%c1V7o*Y^J1ZvR#C zcSdWMxXw#=#%q@r%+ouQwadomjXE!Dm&?4f>&yrg4>C02-*`uWC9=*WGLFPih4Xix z{6;oF?+!;|3N=778+Wk8XZR|kwG=LlB6>U&c2Nm=?{<>>vL)h!R`|bj>&y+Tta}&O zxvGvB=?e*hmOqF%FpDi{W`QC>okh#=EVT2AcD2kxQYVm&bQaP(D;hy+S4Ei%!Ut@4 z2CqBe0CP3sdVww@NDR#4#^%}(A`pnNl$6#C*uGH+^(yWcbYCd$tPZTLTWIX853KvC z=0xBSsoe8UFgBv9=T15$0)8DmNYIMv&%!#Cd+eX1<-)Cfzuzo$cQ!A_MITBE8rxH^ zvG}-CM7zOtajf%3V_Nd!TxaKU;{%w`-@V+lW{K1#8Ur0>lekYkA6OJ*C#mNx^&$h! zE1YJ^m7F{rmBci@Xa7)HP<4sY)u&DPVZNu9>~+G&$O?*zIW+*sohpUniLAL7~%c2#CX-%CQ}sH^+oE&1HX{2iNLaz_jrNH!1m;( z#I85m9j?pyU8(mwl9%_iziaGt&1~pe3hY{3?(X6S-qiT;xa&*cE&mS_UEc${>pm=Z z{R+Ij_`wub9=bbcD3^QddsR(<)C9BzOGL~3p*zLNkhdo}XzzKEhl3>UW-mG=M%tZu z)3}oNH&@JFLd)^uw;rb0s|>3jAMiITY&jZShYrGq9+_zIo1_mt$y}A2{2zKBaP@Ce zKHORJ(fTIP->8?s27%cC;|x6}7}MH@343XR%%d)}kK)AUXMGP40bqwLb9sk=R(99* zqsvW+4fhHlotD{ffBa+kO(H_Y#@alCX%r+Xjbq8PJCo(7CZw3DbJt;mP57i)Sl$Dt z!R-w8n)M%Qg#XZv(N6UHa}sYVZWwU=B%Kl=#S{Vnng>OVx#&9O&3C#Svovx1dn+?k znG`a|eA2E@ICDXfx;@uS%r&CaluJDWk%rKaSWmRVRY|gpcF#Ljfe-KHUSk@J5Cn?c z5Ip#xHXeflUj7jFRN$H$|Z2k{yDmN!w1^_Amnfw`tC$7?=tg|#@!d>EhjP(b7slC>7!XY zKkhU*@wo2u@=cQyPZmG_xrv?_()dETW!WSHw*7{v(AB1@;Onx3BfqHxQ$iNK&4AfL+#Trn@4-G_h8!A2nN$Us z4TZy$5MI?%QLf(ac*UdWLRuUr9RIksV};9Ko2{|)2g-#TyMF$W5VDWS`gK)$p# zhq}H!Va)7kdYcaNj44Eeg@o}fLoiAou58t4F`>-_@Wh_=Fdo`myJwkWp^5BG)fz@E z`AJwH>xFPp0uw&xh1Dft#4l#WA%f+MuleuZt>6;?M;bsM7~CWg!J|+A-@u*MJN|od zE9ApJKVixK7vz9b<|2~F0R%GoT--|zkqzy}a~31Q@D5Np=6`dy!kd7s14$|{`W=U` z<6MT|9_E+?ojN@vyLaNje|Fjzn*ROy-wPZ+44vT}IuAOEC4VqUiV4}`bC{JtBf{}9 z`Xzu=NA&BT+}%eg-Tr8jQiu}+T!`16x|Jz~d?z6wrjS=sB6gsJp!HvmA z4+dELU`}^^*X_R4^ycSx^X{~!8RH*&y0e;Q{gucv#G$TJ7CZSWUi<82u=hM5C2~bF zaTU?}s9@-twY{^+aJ~m{RJpLc(8C0yc93^~e1bcM${!83#RFL;kPC$=h%sBq$x_sk z=+0kwcH`ZENTpDPugphfroYyw_KQ1Z>fr5do}2CP>AorAcH>8IcTv;ZpFg6yOPc15 zSJJyHn%R;fHce z9bZOT81|XRuHc($nil-eH+I*bSk$mGscrnQxaMcl)=mCP$$JL7uWfkm`g5%N#)jpB zp9|ex8$OKxT~Wtj}Z%3P1qhK#f1Y^=20A1ZHTv$boYf^v#eTA440RN*mCq3a1VH_3XdRsPF!#$iDJSscpVHgfUMn)EYHu$# zogVnJ@A|O?+>1Y^S1YQ2{`}K>Tlo301Eu$F7iRzJ^3_^*Zek=uSKTS%w3$NL+FP>Y zqrZ0ieR2EShu_J6=Wefj`19cJx7&X{{9OY}c-h>rN0^L|nEz)NG4+6<2N>Z1{F*zQ z_+g8}JS!s5wvlzn8V*4RcMy@`@ao_T5e*K=_aqo7ur~;dzc1*YeAU<6zJ{xQAGvc% zu$k}+vET?d6HRcAoVCq7=W$0kQq8L$5JbzV>L&c47aTh;`g0W2k4(5VG@l0c4U8p| z0NvJ{w?rBYS3xb<`dkQ^8iv z!sm&KJ+{pvH;J2iCVK0qVd($~WDCvXB%X-(2ol-G76C}OpOP#%FA4T>ke#{n$reC9n-aZjdzcjJ}Si#5(MUuss58Mp8K78s0w+iw|GVO3kb@$APS&3^3W|kX3 z&A0>~qz66v39!_Uh-4)16|)YXR2J`Ik2}7ynfG(gh356YcnQ6c%`_9TXm9NQ6C$3T z%~W+nl+|kzgzG09WmXAqno$Y1+Gqa%k@enDO=aI7=($NqLJOgaG((XthTic~ML~$Y z02&b$l@dAvj+drb!8YnpjAO%&NEOu3I|Kni1q@b{BF#4H%-iw%dw;z3;#xq2+O!^{uuoJG4GR|O@1;xEEZ`aBVfW-aaq4O8B9)DuP=W<7 z*-8!dtW(?^E4i(AupD6LYLyBDWf7{hPg_t zl2|GGhEZ4q?jZO=f(1p6gOZoY%Y|8No$E#SLnI4pE&7eyrOIpXOqs|?H`NwTnfgli z*OpB!I%+SJ_$+|QTA0qYWu0t?aR$*qi3&AD{or%c*3dtq0_Gp0+DbN<;ByjQ4V2ik z*GZ3sp0UH|xJ&z(-i3T0*YvT=()VR@KAM?U%+z{gQoT?mdCa4vJto!F6wNb|k*llc znTN^v|JB5{$dfUtYhzmuLItIZZKWaWQ`f`WB$V$JM}thxM;R~4%pz4f*&b~Y!YG&< z6zf3QC1O=0mI=uAi{WPyh~G(ha1{vz-b9wpO1*JZdFY>oI92zy$UcP;skjW8TwD|C`I>Tq(zVt` zJ$v)%>xmSPLkDvJ`g@MZU}9_NV9Z!@8emER;Y>sATHRZgL#V|5!IFDR(B(IP`V@P} zKtkaJ+xHEV?f#3;Ikb8==f;V5^-CP&jYRn?yo~4$c~Es4V>=Eqs_H(moiyay>So!_ zaCQm$84ErO{B$i@|L<+PZI6wt-C}r#TZwB z444QF)O}^U)S)l)#fQgPy_loQ2Cv}n$) z!&6#8Zzx2zX>%}hsrUYtNu4-mu4?X|)dyfUm-k_}YNlnq>^=9NOhpN16r{xc>y@HB z!{oQrt44Xx+A&gy(SePYF%0VTXFoJ*w^EifUy=qLN>LZ$*b9OVAX-?m{=2Lms zJz{c1KEPvv`QvpD%kH!8m8mNnsn<1M7O0S0Z(zPWPvK_0iMh|9LRI}@b6*X`wt8S5 z7Vs1tCeA^8vb5MGT0@svHkGpiVA<*y{Oz|4Pi~%zqN##*xWoYyxr}hlv2Wi00hhbi zlW%HiZjCGU*IVJ2-Hq5Ne)%L<&khx&uNd?jthbBuyQTQ4-YLp|T=BnpJc?tgB-a4r z@}_`&V0If0Ph=$k>%fPk^~yk{$olyLO@hKiifI&A@gM^ns8zR= z7B~1ttsWO!6*MZatdLvU5_@vRQI!dzH+2?zY;gslKU*)!^}2T08mS`! z!c~Rt^$Nuv$vF0g;Vf7H9x6=uJt4{}A)l`+5NhQyy6G!)3r^45JiT5<CNr)zBc?Zy+uZq z)|fWUJxcMV@Bcv9Pmx&=^}?WrB00GllZyuR3dR`Q989LX2P{+r4ZF!QVNDrPTfIuDYZ#Co05rzJKHCsO@3%w=|xM+Hq@sWMf{`&hh#C8~IV8 zrfS)Zm!o!#!xa(Xl(QlO>X}8UEq0V?0VE+#OHgqY4qAh*9hyo%gEMy_2QGkQ-pQPw zqiTgVWa{v}3$fE_4g!dX_X{*}BQEs(18V`y5&^uYK-U$)t8tAM4kYprpo0?!QDZ zRz$v$v5~LPPL{?Z^3=x~tIQ(@q3}&5FhGAp+c6ePW>8Xrq?WTWX%6!Si98uWC z6?}^S;I8G(xQ^Gd6yC-}mlattyLtaMCSHG7cl7|K@Ta@P=U*z@-iCPi(A~8>=d+Db zQ_Ve|lZIkb!@Z~!4Fd>-;QC7cQ}89^kL2h)4U?ue^O!-Xw?hyh1g%ekbQb)H0H<;x z-P09C6(=hwxQckPAQf|98=Io|RGqD|&E%($4uJ`w*`y0Ouusq#uf2XMRhbm4q3P4q zV;&c%8PL>k9-pVVr|E@xLJG42eEiD-K*@VUNj6_?Z~jc{uYS$srkD4$B(x4Ty)vIP z*E-eo_TJtUEk~KrsH9t3cbmqek^{XTG<`Bp(OA&dG;6*uaKVeFujYT`K_|cu^ZkPh zel-1OPH3>Co5>cbfh_fAnnl_;!*I8gK$E-1cY(d9Gb?NWgP~^(WA@Z4*)#SR>3Iwz z*9VY+Sy+4`!REY?+jrAVCs}I{_L!dtyv1W{4k_y*%;1r}^Oy*EEkb%YFJe?&{A&fNk z)aG$UWKRwGT*bEio8KPXdhZJPPKG_9Vv4L0SXDiBV~g8$N&{O>ERGE7R5dTQII5xB z*8Fn%sIP8+v(3!0qcD)qVdi+d?$>6QnQR$7T8rCEj<230@+>|v4rv=nMv4>)VFd3$ zLWb#{ITDF*M84ty5^JG-g(;h1opT1!wMnH`D@Pq2hWD`#KgWFW^*;|~Eui337AWPN zslhpVVLIPa4TAsDXz`9dc}s6`i*NL)alIuioaoc03;kOZYHcO!IW22vs&*{gmOXpE z__KCUi<9b~fyu1;jm5{mEDUW4usA!oFu7%m#W@ZABQ4u3&Ijt}wnzYAry~ajW4f`| zPsxmuSGW_SlBu|^!V($9C*FP2DfOD&G*)e$jmgep>9F2cCA6EXz_O* zbWzU#!DMs5`&lg{&gk&lugD)+-i$yglbzl@&qZY~Co0 z9CWIPz7uA3Ze92FJJlw$t-;q5b=J?dKAO2JV@hkQohkA)o!8blb8j59KEh=QQ-ikF zXmG|Da?(=)fP*4VKHBiXjzX@i$kei}qxk+$Q}?#+;u5DtG>Cy9_hE=Z)c{O1B!gZ} zk)I)VvBhg83;1+8`FTybjM>4qS2Gp9W@p>p%~T#WyVeHHG~yGZ z8)0%mtg7TmQutOck)&PSi_0#YuydI|Ma6|}G20bVRoFUX7FC00Rc)Uvsx=n3war>Q z3|uS?oeMCvfdykB!DSU6!4JHcFAtLBQxtgHcfymZy(N^!NPU>H_;uU&;z!ksXWRDw zDt`QPF}Yp(5JQa34C6$(R6T%F16U|FI2vRoTe_WWSrf=sZ{JqNRhU`TBO1*@mO$JKNP}8{1+0qSk$A zXXB6$Vd7)@D*ny3CGi7ty(>O`IkIrI-;Rr)&C}bp?>9SH$d&5Fh&EW{wi{Ts=2_fq zH?eFRw5V!de4oq+^Hlh5MR!6w7!D2q+{Qrd$ATdkR7E7b-PE$H9TfBwnK5QH_d)`k zL?r|eUsC|hAe~BOJFT(bosIzNzuo$NM~da^cKiFC)t0mE&iA_pnT8Z!?=U^`Bh%Z0 z=D$}K&AZ}-J+b_zc-8j;v9?`d%2gxE`npW_klhItUxOuz8BPn*eormtfs&@RQ=z9t>Gp3#12<522 zz!vn{3DZ+xxV|2QQ9?}DE|J}m&YYMxruP1wr(@oR*>3^tvw{hd2Dbn@>C36II_ zaVN)~&eHo6DUPo@EALNMJI;1G;d8;QzRa+tl-M+`)bufZyns7TP5zkGSUu&wpEIs| z-l^oNwB0%w$?M)Fbo|lz*m6q4NxG}fayrmSy{pMmua?Z}I-}{Wzogk~Rnzen3s0}l z=c|Qbr|Dgp-xPy9&a}iBUvpaA)oywD^@%>$j{CDeo!q3Tl^!@%Gj5FHx!}7nuB|p0UvqYM>w2*9t zg>x0Qj$*hmS>?Dy3APXa;ZL92G(y)CO3jfbe9VQiCFEbYWf{!0T;%E_t7s(=1T9$e ztf={}dxYv%v?14I;jLP04%LwH5wW+bywSHyH~8#&jWXqVwe;DDC(BA;Qq^j!X-=O? z;@fXLv|YjNh)~x`G6*`j46LN`-EIm^tiT%;7Y-eu(u`G-0mc2Ygbcospdu^@U@^d{ zq9W-bw<_UcD;Z7q*OH{>lQfADNh&VOW$G!sBR1whV*IKvW2;xSpT$ubXZIeVb&2dE zsiTUvR*Zc2F`=WC+>rYZ;SwvRriUYVzZeb<9+c)-V!HszLIlv5xPy?vgrRJ592GsN zUd~4t;6mcAEDyPEk68I|j|JV{u?n|67I*tvc}(pafXXJEfJCUCs^62uTm7LS*j(Pa z+crxv-;!`z^>Xpy*Dac|u9PVc_wJP?O3t3EyVsT|@AKT&y|IKWmN`nwFDA-kaa_t6#+dg-V1CS z?p<^lK-){^@AJCUy{km+q1XNH@DlZ3UfC-9#bIkZ#N*aTE(B8|isa=gRAMr}6J9d( zL+2j{k7}%Y;}MQ6ZR(Dm(^vr`MdRl*k1c)Qon*DE)Ujxble~H9(%J5BI=oFV60SSp zeTqRR3WSm4`sSHW-1n@#6*8_nvBc0pLtbxa*9h-KiJtSa)lbfpEDTy(Ogd|&pTBI+ zlUyr!Jt>J@6z=o#Nky#LZJ$q1s!Pa7#z{e- z1ZQ9=*BF^;`sT`A;I$=mMs3|L++`u($Mym>#2`55BFWr(;RDY z+jntKyOn~_*RjXG+fsIg|F!NCs}=KndwOH7e^nBWJihh572A5A&BnEVxy zJ%h2f6D#)jh+^#)`DORKiQN$*e?mlkgx}+ysgn7kMS$oAik!xTYA6$$x)g|78_vBF z`5jmQ91(-IJ~gI)ThFYObCCawp08Fe`Tk=)KVm1@#@`Tt*6-C#h|3w!nkazumKC7L0jM<; z)6o?!)b**Zqe9#edJM<{#O{?Xb^pbIvTUh`^UBq|%B7ya$Zwdo_zAW)M_Rtt?TLFc zotiz#^i}rWF^}FOJ+kTH$^Vw8^Xjj+q+pqWy{d6uw^v5?YQ!y_Sh>HK73ZBV@jC^; zQ3<8tihD`Pg>wE^Dps#IoEIZur@iV_gKnJ4Kp??TCM^qsjzt6O<@u{__L^Ax46Ul_ zm4M|cJX&!MV5EByi`$8mnWAG+f9 z*%!IV^m)Xs3}3UL&pU3_?KO-0eB)OC0%VBD1X4i}^!SIyZMwbgZeLhjz{I-8 zeLU+=T-d-19?5LK7V;fRw95JgTL%vWIq%FF_2&HbV|~fi zTZY#E=-Y42)!ZQcG~Ie@&<6FV2d#tiH<&yiO7bO^;#Q$@umu0kCo2n zE-Bm{;5o^qegg%&?binPrzc87oHwq1dZu*yzKz?SVo;ITxaVnZDP&P$h#h2TAT42y zf&mXz;&iPOTP}3xt))4w8xx)ueBLQL#wg{-g)Z8Z{q%C&uJBD4o)*UKzP%}TsT~2? zms?M7#qF8cwCCwv>oCoLmoC3kGPk6z=Nk2p1xo^;$VazA#h=4g1oT4(s)K+GgEFj( zyAOHn@FPd$2L#}}gCUm#jvO~_{mYj(@l@Ghb4S3}r;n_&{s~y`C5YoK3Y6=wkBbTq zT+rVf7kxX>-$p=@<*ng_EvGOIn`kx?Z*Tm2cL=c8-iyQC~#2pLT+27en89{+$NkL%_!~hb41zcIk_E9#m z7cD>hJ|G%I2%W`Q0q%Xt@?z{o&msCw)Wn3_yU;wx^BC~z-pl8pTt;-r9 z(4RkZO2{&h>15~)NPS7`;Mxu_zNE`;T{@ufCBxa@WtqB0X1-!7$zgM5_|`20%1F7s zm7*+crI;!UDoDyqWvVh&LzNCRa4~3k@A~^EH2KH&8WjZiRsX;Ll@~XO{C$Nqckv`R z5C|@T$?aFQ`4gKotn;euE(#y83)^vzk$Z5Wjv73x^Q({Bnq(rS7F@|{(A#BJ_qvTDgj428omUl-)k5M z3A40O3pm!%_zpe`5DjQMX<=?<+Uh56H}42>EY^N@GHiL-!dw$fk()&5vY)vaG&4p?A2U6p zj?LV%ekN46(K2{(O14O1`;p>h&#s28DKpMJGtqirdt33YXJui5WoEf&C)%hxr0*Yk z))?kUI0%-erU6RSuQw}q%Nr|Nym;d^n>jDbRp8qiW_G#Z*!hX}13QupuNdN*?kAb< zf34^!+p+C_>9fJGNE^F=ycL}`JKG>zvqqAN90H1Ob-qKPKpGZ+ey?-27Ien%+(RqG ziX|nohOklAcJ15e6vhkf&;jb=Qysb+W^$VMg(&@Foml1+pzNb{scKpF=(8_jDP=CX z7bd!>q0%Li&#B=VWobAj!UPmf6-6;vmp}^$jG(f@0EwGYgc)M%QqO)^?poQRp|P-7 za*}Y%y*ME}5b9H6^jszUXqi{;rHSr$Xh4%i)j__nzfcy3zH1Uf8zi6!8({*BpfOK2 zvtxB?)xFg*dhp+p=^IOEI^ieFmZ@L4{ba|ks*!q z@LFSTK+%c;n=sunT0jkeuEx`l6A@?rqLxlt_{}Yo|Lk2@ za+&Lkzr&xD?NTqj{d`Awu8R`76FyKDmRlD7qA`4|Z10Ol;i58LfIE^TXm(^ixs`+? z@%RfGf?DMOil;hf&=E^OW66jVmDGf!S@a|okiJg6Y1w1)40R~DoGVA0SQ)J!UT z;jwGX#tK#49(osXgyjUHn1E=wf&g)WI)>0_KqY7djIZZHcXuIKh%pH^zDZ!pH1eid zQQAogq|Y@=wsNthg%L+p*2oD?C8$>~8rF}@E$@EuG5kwevihS%FI58U7B@r5YZ>fz zAs&S&6;xkxJZ)LpK|xC}npR5OhzC8Imj%_pN8v9UBge|WzxX#Cl@qywaFG`;1~SGZ zG(t%y-s0h0WGKzYrXZ%kh&`_U`0B#t6?AW!gl+nZ1tQS_o==6*ph|>H`GMTJi4khl zkqT=x38h>|fenthR2EF1RfFv(;g<;#Uz4psM-S*UI46Yo7%M8bV&$N5gi84l^~Oc7 zuSUJ7h#K4tRTC=lO}mV}G!eoZ3#4hA{h~?s&AI^TN=fK>(X>7BqWRbxFQaoz4=I3x zAtZ>6$c?Y8s@*R0r)3vK-8+bH#)-D9%pc@L7}?Tbzu%Tc$AE}xAp~5gfF!3t(+*;R zlAdWd-I4)lY1=BZQN~sE8s_=7dv%`p5`lw|wIO1!yqtSm$J;N_>6HzGArVd)q$lmi z-mQzdUpX|$i?FxNf6;mD{nMCSY96as`YKtAMB$Qn4*U~_k_RNUNS8DP*%Eq6!aIGJ@lQTNgqllH1Q8*vD+S459LMp+ZF~uTFNHw(t|5x zUrY+E#QVZm^hIx@T*e$|i&OWf$%?3aGhM5n$z@XS6>h$mX#V%aN`fwuxf8LW{8sK$ zv0)f^@PSql!B<+*r2ER0`H-MY$x);vm~?eyB4dw7ewu`64uRC}%-o8=|BiNOWayB^6)aKuIZh8WCp8RoA>W zq5qTXQ86?e!7H!G9SooJO1N3|Y-lnf(UwMlYYufv@a|?JlFA>xAPZnsp=fI8p9o`H zJ=~SgVmh%5SduVcDT72{f*vMzU7B#uL4TA#Ru?Ur(oa;cmLHaiJYZ{y2aD9WRFU>K zNghfhVF-8*Hv)ynC?Q{<3uB`s>@%?-G-%U59ldA!Zi>SAukIzoqOB~tGN{1r zS}YlXA%ET)k|f%LBLSRP#*q~zk#_knQtA~EgK0ES9X0F_Sy0}kKDua5KS}-JiQ(mu zBtizaMw%S$4a#fmeIu{g_6B@h@wqH%+r!e~z{tC{0|Db57@MLB`db6?Ni<^o_G_Eu zOAq^o!y?OV2LmQod@W0sMpMH{k&nt>=K9gUsiY`Al6^@*_2sW}r^D&Ils3eAc`_0- zKQR;jy)k9aBWIKs*=0K#Fn9Zz{=T}izAsP9_m+Rm{XFr{fqh3FTE8sNd1m`A_e=PX z#(iUt_P%@+DJq}J{Wih2_(S)xJuKsGIeySx@N*sD0EM8=$kFmSb%g(lr!_;DtoSyc z)qmXn_3n@4$2Bi+MNZp(&qdsSz4qUH{OsjqunE zL?;CP1KCE!xeqsZiH=^kyZI z-d6KL6wh<2(8`mWq|q{xA4-g5@JNJqAg~TUMYmRYj{MDARbix|d`D_$=4(OFNJ=EYl?D#WN)nlEwa-dQcmZ~1gP%I6{h2;B z7^>!dKM7f4Bq>gi+kyU)BVzCm0)+Q))aPWrQ5-VPc|PEtV>uAsJWo9x+IjMk8(umy znYppV$nHg3?aT*NkISq-U|E+xBINC|vmR7CF57<~rVc}15;CwnSyV*0h!j1flt`he zOOO*wm7}%6R8`VNQi7x@m>bzac-kk*D1MYuAuhX{jL6rxC)U-Byy8Vy*lTFs0h1tp zX^D9f773l1p`fpe#Rrmb=ue$8Uy}tgJSvy=ZRB4bQGw^NBA83FOzP*q zVnn$R2;YPQqJ9OSiE5$!Qb-Dcd_#elq^DpO z@l3C!$B*M8wH6#Zz3C}P^GnBpzT{pD{vJkh%OemkjG(;zn1cHV^A_+vpKM-qkD21$Vk}1?But+L@0`C#bk6q0T zx?LfcZsK5$ZAG zW2?(k<@gMyYqLhqJVS|f3>t1N09{}R>I@<#M8@6u;O8YO^&&$F8t|w+S7YgMlcw{p zJEKM`V)Gm#G@Fj+f`|3D{3%(K>K438cs!=*;cHQpV?|<~Q-s#i?3+!`UQb4StDxZ| zt|k}m=>#k*N6>KagT%)qoTR)YGO3zrY!MBLS+q6e6!bfD%*UW5RLMz73V9<7!k$kR zQ25xJ*K<)n?EVN`GRfe{ibFF5ft`im;#Nd#G}O@c_GL|C+?FJ)<4M)C&J^abdiw#D zniV7A#aaW>DSKvY|E6ZP3Tqa8%_cWXyrD#s?b8BXJ6Q=i?#&C|C`F5H44DO$J&uN0 zyfK6k@d6FDwxKkg%plbenHuhQwBP3>H@m*kiB_mQq~Uo-=PQui4i*7~1jA0elg9xhIM*NuO#(UwuZNvp211=mJ@H5N9$Lf z(pYY`@Y>0M76~8+B9>x^MdpIPE#_}<`~+lTVgJdPmWOY+(XwzOSf>aUeN;*d{@xM? z#^Nw>(jee2KN<_%8b^hBsyu8#);+u0&Gkk@F zEV>-H%Fn3$^tM*(w|UY2_Jw({DmEpnb=lkB@+<(4oI~3{(-7BsksdB9kYNK;0-h1} z6a?5>KogNwm3`k9Mz6KMIk=W#a`sG5YxvuW=pg&wmO<>=A?y|gE*83i=scQu&7fdG zkRZ(AQ+RX@3KJ;48*U^cI`gA7^=)l*aOFLXjdx6U{^{6u@$Hl7-T&{U#Gj3)B@io9 z5nm04bxCuiQpC;X@OTU!Efn}niqr?8SRt+{R+QfKUhFU`#pFaWMSpH!+ffeaha zCcm22=;m8fh8AzoKq@NaOX*8Jf;!C-&epZPeLEMOZ2u^5OXuRRXUXjn?-a-(=pa%g zw2K%6R1vltEg{^YUEhsRWy6{oB-zv$f*ZkJdd{SM{yRoYR;3=UiI`kw5p|8e7#6#g zB0lxN%pvS_eCZo#M@TK>ygAcl?bFLy5|<>1G=&kXX*%vq(V;TC4k!4Ua4!=y-K`#u zN-K2(<_9@Uwgmq_GlfDEJR}i8*!+Sq;IAWIY1$SvcZooRh0XOAtkXxHRbdrgF%p zw2!DE)tV)l1EdmWA57jHU(3^lURoE zEFiH05U@~K^dy{LB!LiOTyW*}us={y76PkfJaCK!a_PqoYUgEA&f0usNg`7Cz1rgsmks>oOwl3fuuwd$-}g!kmc$<@0*Mk z$&akIY+Z1f@F3?rlRg>qt@3By9}!EME{t`3fB$a`dVunY2wW`BEHR-7XyoK$1ce7E zN>nsXwx+$qy^0)p3n^q%MS0Q&QWwjO@7OHYt87Nwj`WG6V&bxd$}kO?=0FKb>jX=M zelPMj+2MD;`N{&A!IJRRHj)2hw3$O^1FFi7hWoD`j6~wn9&{DjONK=LWxfu{uW-4y zO`x>212rhU)AcJqUFbQg7pv$X6_nZOmT)oo_mzR;L5;$d>G1D=N*07L2NMXbLFyR5 z9~d6RT%85_Q#>KfQv5_hSe5w12#HvUk&vbUG*>Tp@`;2@{(%Vhri)|3y`wI%tOv~e ztO$>#f17k;SSZ?WMGV#y;xv4-5Np;vtl&;ls!!sRg0Bf2IJbRc6-yK~5Bp8Mt=_9Y zt{*JL$?>7J1V`~V+a=~%Y?d=7aqz=tDwc`%S=UF`#hN})$v-mbNxO8UyJd7otknax z{9}_|2O%gs2VzEr#cA;w;4~stNU_+aYt_ydfi+8{=}|0{cM)f6{u{Z$a$;>9PP52Xa!|=F8z9m{6ykIMy$JoPCk%>O=%`MAuv!x8iDv=QbpQ@ zvO7>pnyBV7-;DXN0y{k~OsYa+qi02(QqF^A=afDija}-X7j)8ZS^4E{Ppm)W#riuK z2A!US9R;2R+Vvq&I${eP3Lx=UF-b(hWkqnpR6zcT8A|jKdIS(ztnGTSNkk=Na9146 zCQizmM?s&6Wi=TBP1cp%Co4bPh+X%u(ZOnX<7~M&QrszwTQ^jzC)+*g@y~d~L7l_MG|9 z9=p@QD(El273Ei@p{A~Z?ow=maywUiy_(+B@Zn8tjDtf^ey3l;wYnZ{Y$i78fwSfX z21H+CP0@}<2@$r=_5Ic}Ea$o9e9fH&Kbs?T|-Gia!0B+=FU+R+AzMh!z=knus#pG{$(6M0M|zii)Q>y;V0r$P$yEohxAnp)1@QCJ;8MR82ONS! z7-5Pq5e>XEP@_5Eorw>OX!5VW=#Bd55LfWPU$f9`jlm7|z7rpp$6a;!Z6`!oqw~iIZJ%13cS$-$r{p}x5Q^#uKUOk8k!ua4M8$wl5184)Q z<6{E!4Ni;_AXm{rm7ReJcij80jP=HiIm8E5b;6$gUz~$r8xUd}t19=R-RM%i3!~#ebMzh@EcgTb-FF5-H;xE_D~B zG0m+(iOZV5s6>VtFX@;$RC|1De^JbU^EfMB-to{-{qf+lj!-}Vr2`y}y8=_na!9I@ z(NfBeM}`_0+s@wWfpn`~yryIJP!lA;C|OEEbd<6T?ID0xIiTnV!6sk`=2GxsXPUwE z8KO%hNNED;Fhii@6m%)$xJ@dCli74OmW1T7oSdI$hHva|wBf(9=l^xBtB&^k+4Oi)yi3&u zO`%z+L5ccv`H92vUR9U!fv=|EiU0Sa2`&j_*v8GI9IOaplijd&(k#~;qbcSvI5u38 z2lSpeY(S>ys$v$FDahw4_blMMX-M*Abx!+Ho|x^rRub^seB!Tozp87Ry=J=&N^_q( z1GfWDiXVaX`!0p?YaMS6^)dE*MFK^poGESpFNz)kQLhMoJ)k56Zkn$DT9ZnA5b}DJ z{*`->d#hd?GFhyqeM2c|oY1Mc!SWZToO5xaY>?POPRNkZUP5ece!gp>EIzR6PJaL7 z9$K07i$fEQ@gY^kL-2$gco4BWo}Cs?IEtWM6el56Lat2r#)A2=ENwf@4U8hxeI$&e zhGMP#jK+>nM&mmCs_AUwY9uF&>}bsE0;HG$eP9 zH7C<5d6g`5?G$LE4OvRf%2V-s9Ul%2ACK%WpMCLb0wqA{kANovP6fwainI~IjaWQ` z3iUzxNvVYY%Ox_wiW*Y%C`%8C^KdM-G1K2}feMVQ+D&K@YDJ85esjnWMQ1L-ZM4l< z+JzXLXiqrkSReGtFRHv^+o1KNMnbk@bI=>VXmKR-f1W%JK84s32n0p?JIO(SA+V!g zmRKWcky+w-)h)MZjnEDE<}BWv)dx@?-w7&jAwbok9MT+4(Jn*2LgP1)r)85=xo0e2 zU$2W_cFuRwFyV}2+t6D^%-PBwsA||H%%<4;_C87n$Mx@Dy#2X^Xkfc+)Qr}O;&>lz+9fAVM<*Fz7A0}fDKJXd3 zJ}LH@|8I{H!RSFYLHw4lDUK2TXMtq|TernEJ&1v~IS3=bxZz0bk07Y?*TSa#jv#Ov zhpa(TBxMogi{IJnxuhvngkmzeco4cTd=NAAaFUyF&k+Roc>MaR`$I#MyoAcC1-La_ zjzWj@rUqDVjIbf7{Hium2)Y62B)bI*M4CAa4!l*OZA9^c$>RzARkK6R2r~8vBnMVN z&oL^LT|-hMS~ISXBz*m})xM_Sjrvn5E)mS9BKc-gFLqSn{9#gtuG>F3XNdWsc8#ls zEr)6y^>?9a>0!xF2NLS5Ugb|uCLXNz88-U#XF_|GuIp^)-mlf^!=9fmC-gXe4Eo%e zl<=@_c>5;{^xP4M!-5v0W}sDB!eG^8{#OPh(#75iSnbkA%l{FW-Ke6AJ?ZlgozcyArr|G6c*c;_h#HJofVYr+*VrH5vwn z2GWX6qnI1u>M~rKAq+}_`9vs;h!fe zBoJdWtt^dLcXQ;~R1)1W{afvdH~UM!*pJ=vjYzzBdHP^8VgH3hPS38zW=^SNt(X#mM(}!KhPPa~R-zyAml9O|PRrg~An@&q~tJc<% zznitQ-tm?8^vT5K)eE&0?;d(zFAe81#Mu;}1|h@5iZpx;iqUBjm*mLbz7#uWavF;U z`E1S*M-2^z*;?VWy<7(&pHY8S+l;#7-R zo@oeF1N@9MC~7E#*i9(#A#cf73M3O)55X=_jXb)v@jh9ITBYMt*J3uf^uqbwSt1W9 zO`Ggvq@|4&JzdNq`e}i+n{iRvRq{2`q^dzXE6>(1{jOWVE337ezOP&>*_wF9cy$LQ z+&#F_@%6>&CyBeOt+mwe9(&)I{JLiPRbq6tqd+73_wErL{QwTGNZy)6@SX{!zU|i?ukXoXnQ~hUm=4 z>EB2zb%Ho7p$6f&%0)jXRbjP9&ib(dc9A@FZ$`CSf%d1IgUvo~jAm5!9Fsaq|-0U zN+~kE)J7CnvZB_RN~#*3S6;UHzuj&3tIoe!Ib*!{&uSkn{l%xQwY+!}HRG_ipxS@9 zkk1lXa@3D99?+HL&!_IHjX?V6{^2Xy(DTy`Q$^d)FpuGKr)h^NQVQ zp(>K+D@cZmPaCwVzdbRteDBrj)mp}j&s=K_czbWA1X7ER7aNb^$< z3d}_Kl%k$;3T+D|Cha>b36mjQ2%eBZSXume(}eT1HRkQZ8SdVDP6lU9BmZ35cJuAC znTWj=)qw?Ok!PFQwm~LYgFb^KUEM_bZeat4;}U$|cE*-d&$cG^wE3jwSwt_mb&yB; zSkuyLx^@2P-3-m-!-=W0@8;dlC{pq^b&-Emy+wzj*d;JM;?MNsNG3|JAr)n=b(0_#3o;0njM@|FF3OOs zxrfOUDRyL_(klJ^BxA}?JY&kx_1)f~+T|@yKbnN1KZ`9`i#{Y)Fk7p)Ygyhs|Gqu> zo$Ku1d!JPADga-O_uFiWeHmaR!EZasnZ2?1Y4sj0o5i`dvOGFK*P$_p5kk_@MdfoQ zGK#V21Njn#<{Evet0u{smW&dH*$8gB)Z#y;|AsjoP;&a#qE3FJH-~w3KqH^?>7Iy_wE{)DB0{Ubpnbf^U}+N!w4p@0cCk``IaZ*jetv*{+`V6SLJW z<)<|d_r4`5EKQ^|vy#@_p&fJc$k>8O*;!A`-U{(8i(IwD-$GG+=6!eK@|8a&CTgC( zxj++2k4nx_lPC|b^cLOV?-b^iYs@i|9+YJixJ6#v3GMaPa~er<&RLs1{QtJ?zBIaa z&NOMB^U=*-{+F(8v(SoN7GYGHb*LdK z=SqcTcQ5aJ;`rg>+^Qtwhi9~W?p}HSB>6+lTyT=b!}G&ij$B>ebN|E8952bRKioghovO@o+sbO8Xz9}CAK##o7Ob7gv=Y*u)B9x8 zmmY9`g!+zrT=w~D(wc`i3f6wQaj>uL<5qGnlwX%)S41*wZO}oG_x4zLa%&fM`(C^T#YKD<+~ezDotKJr*M)CpyfzQD$nEXw+( zcg{jpzF1;aojs-`&$3f9G^$N9a(JG;A@Ww!kM2WRq`zIhs~2ni8T|YbKtWq;yC9RS zIbxc1!d!N%{5f!HLLZhCY>K?y^mNZy<>%p~4Bb5q2QPXTtq>`qpcGr4^I80At?o(p z>Gb-~+@uQK%7TBS&sy|vOKk`mO_I!eP!N>u9@k$t_V)8!Qu4z~sPf3&ojgm{=g&Wr z_B#tUb3f6v2h_)9Ptub!o$H3T%H2CVuzGya7uDor&P|)K|K;SZpkVX6UL^n{BX*+T zMNo10Dgr@LLaG4KW`WDH;G~%NSK^8~{2;dcY;p+1&mjclESex}amI zT(!y$#7JES>MW5UhteSbEtnwxqG+yd1j~6IYf|lX%*L9-CjcT)}A=? zrP}A}!=8dOvZZIAub#O5Wkd39=lrccM0shzC* zf60X3U7NWGJJk0jEV&;PaTKsM)q*~%RA&&4a%9?32^c(?BT$d9Sa zRd|ZFi~P&1?E3YuET{9oaZ-$2lwTgsZs>m%GyU)zH^tm#{>!7;jq6|EpC0!=j= z*F@++i}Y_<*j9plmgs(ZUan(a%JSJOmAxr@Tx_=Fc6EGxmpB*0W@S4rneDb)Q+YsCG&3|SE2nVDv28M^ zDJ!Qzv%%NVT$W-CvHC<_&Oy2BHB`OA@T8L zkDR8#W;~qmfZ=L+LpPA=zi!_>XCqBwnM|}x`dXZ^dtGD5jri*u>n0t(V*dP@K<4wo zZFb$H`~G3uo?S!JURdqUNh3lp~Jh=VCd$p7wnG3~?gFDYA& zPn!AosO25Im(yUKzaE@aLSxK4mcUi_n~u`UAhT~@>=*9mCLp=i4nxcVQfA)yC+m8H zf*Y#1POPZ>>b&P%jOi+Q*tp^xy#y5HUw2<;JYM$U#+R%ue@>e7__*bNdtTm#tT;aD zK5V`sF*kjrF{mmioKRmfU9q^$DsfjfE7(F$ja9^7`YhXz1*ubxImC^#k%%v8C-os_V%U-4h_fhr(jlT)r5O)D+4RG~g9@gs{-4 zwjum3tJ2qvLAO|KkNM_lCHmcc}r)| z>IG;2d9dM4P!!zVP{kK9asQEA>lb zTsBPuJFqr#9!|h$n&3uI0lD$r_y9U1ZAcrF-e5?6w8eNK=U~gqM=@`Ye!Bbh&6eRw zLyC}8IAg2?RY(T?5n+iCP2D1}lzBF=Hj@ML&9pQElNAW8a~Li3cSKyYo$Kws#vww_ z4ySy+@Z+*QY+4@V@r*zaz`GPKc;laC7SOD`1#6 zOw$t&=D8!B>WON1)$~`ES?D2<_vq#hFcfC*y>=-Ud~NSeih(+&mvF?;DqV{p;n2T4urOrBTxrGgIET%rce(?nM z#q(R~ytuy)x%w0jcq^BD3Hf$lt8r|@g087ACVZ&0kf+_F(JEh~@TAK-Sqcgu8*gV!h9;1 z^_$l*_K+9__YQTON^Zm({JwC>s=l~OHE+)Z1Y7D{){oYfe-+u*Jd*z~ewB0ltuiSw zSFU!vSWg)Q4Qb!E;(u!o8de%(hDVLqe`n;X{%${r$dXNELLFQXFdommyt=hs8z-S^ z5H=wmFVzxo2aNm!Y_^P|8J;sT_PaxF>EBme`^LQU z{=9$0L}-QGrk04mJM*t&JkPPt`BtfO@oSx-qU!KSRG43G)}+P1e(irZvs+l1`aK|b z-`_V}pRYXf@8|a;TfSqt)e)VK`*#e@{1W)>*YDEY!x3)Dg=6m4eVOy^#H#zDUz~pH@;`(=KdLR|M6?fPkX-J{`UHNPVQe3j~_3sUXwlDU}dB=(T))&3A@}D z8OLdz8qm3fr|84Bw=4ag#@dI0A9dEP5k0O&?x)=SdS;#?NYRTsAKx(U7@j#2_+37x zG*|a`-@$h)KVKPH`aR^wfn5FH{Rf9ueu?>Z^!uzI?vOlq0CB+)EFyU0+G!2sn+1oi zeE6qY`R&^G#Xnvxx*zdo!KZ(|e)>lIk^iGT_esRN1)u*J+3-E`$Km(&(*`0wJpQud z+kfBJ{P^pKA$Kt1^W%{n-)H{#l-wuWwoN;zAb;J$#a?IbM2*)$z?pprb zDbHd@=Ls)flbNwS8tk)(Z_qA6KJK7(#yM)Hgx(EjkcEJR?ZPd(e+>TklKcJdAFel7K_Get&ml_yBfV!)0S`- zLv2K%TM@ntA1$5GOs^*{iV?}&xZC-#a)tPs7S#~4VQsk#gaRMZcXSix=QfEsvwL9Z z{X71B`!Yq>q2$QKhGh*gNtC+6MQu*Y$a$lZ})k&zTa#2He`|&m+ zlfZ%PVFK{MZ7?$fiAl_%nC3T5Cg2T@Nky6|TC3|eQUV2cz(_rb2BL((1vmn5G4!W` zHM0&5Cnn&hLm;nA4^c-HDFF6>222DgW;WRV5})!6#{5xl94Ie=!uvyQGkwE2;Pk?hJY8@TD9Zj@Lu<%at{; zr+8>`$wp`1#(BkVTvnre8d~+Sf%}T9-T!#|Y08w{-`PLxksY`M+c}>tr8PXAO$b2t z;|W@CuC;*9Csh%Wki4XER&AaC{YKZV4m;g=_(jrWFXA2>sZTbko$%eW37^RuZLnoF zUm?9BY(oCVWmcC9SA56u<5<5L?6|%F6;<<9;!mO^gK*m#w>W? zbB8*&j8#y?)vWEWR5^vU`y6gud1I$xw_={=M>b*lxY64(?if^Naz#J7i4Y;zXr&r{ zwzY)rN7_gDY_pB@Ngh;_iDmUWH9DW7RhHI>#EYeNHTpkEQwGMF73sQ)DQXD>8GumjY zGP_QC0U7@-+WDF>(zWU!^`vE^HC!JAL&a`-?wfw`2;rhM?AO(FA7B2Zd}_UfMxEqs z21!r77Ni)iZ=Eols@47yFOYJA&99FziQD9twdvddfqjGdTyg+$zg$eh+Ghw|-Un>- z(s3IX-_$PB_|qLY7Rx?Kh-c^B5uD!EElg(ft*VzTs+V_ZmuSWr9aI*ZhsT|5lHb!V z=T2yJ?6(*pD~K26z1mgWkVdC0MmVL0m`=NoMqWI5F-N-fZsam+u7`_#ebK!`zCEDd zjZbERXSfW6%0f@7F=0cDAaDR%X9#8fQyX+msFtS9Bh=+pD*E1b3gjx}e%F{+*!-OZ zb(>uF>4^g&kP7KoI*LF##Ri%EoK!xZ(B?slYQ!QD*uDt?+s^*j3#s)o))R= zYWm&tD|X1XEB#SV)5TKV&SCkVs;!y`qbrqZPNkz11=_062nC|XFbobmI3QY)r#YT} zp#40pexWr}K@-}fC|{1M`6Ey@?ufPGlOkW{Q|u-&685srIw%;eh1@kHcMhw9nt=K! zaxZQ#)oK}NQQ~0*-;!f84 zYrPFteY7-MrjkrJpph6ux}ACG8`MIc1Cv`fhDf1<;c9vu9;*G-kf3H8?G3cqin|_m z!ZgZ!>T=On(ATX(`v!PdT6NLhpc@qvg$E5&nS745 zlBu)yvyu=bu-tK4jnGn!D@su&Q_{XXbwHjH+j$5{w*6c&KQ^jvD))d)TxA*O;Js~+ z5Ft!621q{hC$`YYyXWoPCE|044)oo>gpU@t)@Txqe3f-P-IugS5#L(RC2HWXS_TPF zOF)HU8NR5dcTlL8Wl4jA9e5VI$y4%v6L!g#NXIohWLTUg zdr$ej^*`=1!Fax7eE$vd;=DhF_YKRL6Dl3MEZ&ee=KUpnY=FbO|Cde0z+G_@yPJbS z5DiwRxCu)`VBPC#u&zfCoF=k2Y*rgN*a%sk*DCBWWUGTyoProGl(Ibds9*3_-Rrb7Z5k@_R{Ad}cFR{cISn2Ayst9vhVZ#z4KtMET)`*@^?6;b zFEs0np(^K~gBg@R^X?1bFjyZp?2K9#P%h=kS_ios8^g0)!YykkxAR`Ke&GJnII-Vl zvt=9QNnVa3MG%ID>ReHr+ zb&&PEgQBM39GG`_xf!L~RITZH!*@frj$-HgUid|}ML#LWwcYX=PEtO>^RM=#-C%MTHK*W?&)`m7a1ol?#b`KRvD zPagI}tqN$Dl<95IZA6P`nS6G)RAte~o~;;my8!TRH*RE|0Cm*@R$=@!D>8WKVaeOMQ6X-tqyF`X*Np>A5OWJ;J#3HctwdzyCsblqguW2Bc3wo2B&2CO>WG%QQ+>$Nana~dRYE} zwyACnf@Hq0lTA5&a(;c=w4NZYn|_l)%yWE4@h~gx9))CyA}U9BrN2X-ZU3F^gGJ-M z8JW^$@%9t(yrd)QG-4aai-%&ACAcSGaLd#jDU>VD%0Die*>jXRgEOka<|chH$c@F{ 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 LA`mRd-SoczYWa@5 literal 913395 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%0AU5VJ0>I-O6F-u5ImT7 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 S^sgIS+IigLpmF)dP_`~YtYZK;oZ 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≠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

TV6U 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 AEdT%j literal 0 HcmV?d00001 diff --git a/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.json b/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.json new file mode 100644 index 0000000..c45d9bd --- /dev/null +++ b/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.json @@ -0,0 +1,5834 @@ +{ + "format_version": 1, + "name": "operation-resume", + "description": "Resuming a long build another process started reads its operation by id, and the operation is pending or running. Waiting polls it at the server's pacing until done; the client holds no spec, so it takes the sentence from Search by posting the built identity with variable_text \"dataset\", then downloads the file. A resumed build holds no request, so a failed operation is not posted again.", + "origin": { + "kind": "recorded", + "base_url": "http://127.0.0.1:19493/api", + "dfo_commit": "635943e03a297f686ca5af32f6d027181d1971d4", + "recorded_at": "2026-10-21T08:58:26Z" + }, + "call": [ + { + "op": "operation", + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + }, + { + "op": "result" + } + ], + "exchanges": [ + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "status": "pending", + "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 123015 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "status": "running", + "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 123015 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "status": "running", + "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 123015 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "status": "running", + "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "retry_after_ms": 1500, + "progress": { + "rows_written": 0, + "estimate_rows": 123015 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "status": "running", + "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "retry_after_ms": 1518, + "progress": { + "rows_written": 2135, + "estimate_rows": 123015 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "2" + }, + "json": { + "operation": { + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "status": "running", + "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "retry_after_ms": 1901, + "progress": { + "rows_written": 18167, + "estimate_rows": 123015 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "3" + }, + "json": { + "operation": { + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "status": "running", + "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "retry_after_ms": 2379, + "progress": { + "rows_written": 50948, + "estimate_rows": 123015 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "3" + }, + "json": { + "operation": { + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "status": "running", + "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "retry_after_ms": 2977, + "progress": { + "rows_written": 103172, + "estimate_rows": 123015 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "retry-after": "4" + }, + "json": { + "operation": { + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "status": "running", + "poll": "/api/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "retry_after_ms": 3739, + "progress": { + "rows_written": 123015, + "estimate_rows": 123015 + } + } + } + } + }, + { + "request": { + "method": "GET", + "path": "/datasets/operations/op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "operation": { + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "status": "done" + }, + "manifest": { + "schema_version": 1, + "definition": { + "schema_version": 1, + "spec_id": "spec_8a4676c4abdf43d105aeff9d4ba9299b", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "ref": "DAC2aAidType206", + "state": "value" + }, + "property": "dac2aAidType" + }, + { + "binding": { + "state": "unbound" + }, + "property": "dacTypeOfFinance" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "facets": { + "provenance": { + "ref": "provenance/OECDDAC2A", + "state": "value" + } + }, + "entities": {}, + "open_roles": [ + "destination" + ], + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2024, + "start_year": 2017 + } + } + }, + "content_version": "cv_50e17ab9c2e732f13c48cf2028ac5928", + "prepared_at": "2026-10-21T08:58:45Z", + "coverage": { + "rows": 123015, + "dimensions": [ + { + "label": "financingProvider", + "count": 172, + "axis": "origin", + "noun": { + "singular": "provider", + "plural": "providers" + } + }, + { + "label": "financingRecipient", + "count": 241, + "axis": "destination", + "noun": { + "singular": "recipient", + "plural": "recipients" + } + }, + { + "label": "years", + "count": 8 + } + ], + "window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 2017 + } + }, + "citation": { + "text": "OECD DAC2A (2026), via the Development Finance Observatory", + "sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "license": "OECD Terms and Conditions", + "license_type": "OECDTermsAndConditions", + "license_url": "https://www.oecd.org/en/about/terms-conditions.html", + "url": "https://data-explorer.oecd.org/vis?tm=dac2a&pg=0&snb=1&df[ds]=dsDisseminateFinalDMZ&df[id]=DSD_DAC2%40DF_DAC2A&df[ag]=OECD.DCD.FSD&df[vs]=1.6&dq=.DPGC.206.USD.Q&lom=LASTNPERIODS&lo=5&to[TIME_PERIOD]=false&isAvailabilityDisabled=false&page=0", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": { + "publisher": "Organisation for Economic Co-operation and Development (OECD)", + "description": "DAC2A is the OECD Development Assistance Committee's table of ODA disbursements by donor and recipient country or region. It covers bilateral donors and multilateral agencies reporting their own outflows, and includes the OECD's estimate of each donor's core multilateral contributions attributed to recipients.", + "source_data_url": "https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip", + "attribution": "OECD (2026), OECD DAC2A, OECD Data Explorer, https://webfs-dcd.oecd.org/files/dotStat/DSD_DAC2/Table2a_Data.zip (accessed on 2026-10-12)", + "update_cadence": "Quarterly", + "last_update": "2026-10-15", + "years_covered": "1960-2024", + "granularity": "Annual, by provider and recipient", + "currencies": [ + "USD" + ], + "transformation_log": [ + { + "transformation": "Download the source data", + "description": "The OECD publishes DAC2A in April, June, September and December. The complete table is downloaded from the OECD each time it is republished, and replaces the previous copy, so the data reflects the OECD's latest release." + }, + { + "transformation": "Exclude the partial preliminary year", + "description": "Before each full release, the OECD publishes preliminary data for the year that release covers, as reporters submit it. Until then, that year is partial, so the pipeline excludes it. Support for partial years is in development. Partial years will be marked incomplete, so they don't lead to incorrect or confusing analyses." + }, + { + "transformation": "Standardise providers and recipients", + "description": "Provider and recipient codes are standardised to Data Commons IDs used across the platform, so data can be compared across datasets. The totals DAC2A reports for groups of providers, such as all DAC countries, and for groups of recipients, such as regions and income groups, are included as providers and recipients of their own. Where two provider codes name the same organisation and report the same figures, the figures are counted once. Where two recipient codes name the same organisation, such as IDA and IDA's Multilateral Debt Relief Initiative, their flows are added." + }, + { + "transformation": "Select figures", + "description": "Only figures in current US dollars are included, not constant US dollars. Only flows to recipients on Part I of the DAC List are included: the developing countries, and the multilateral organisations DAC2A reports as recipients, such as development banks and UN agencies. Flows to Part II recipients, the countries in transition, are excluded." + }, + { + "transformation": "Convert to whole units", + "description": "DAC2A reports amounts in millions, which are converted to whole units. ODA per person and ODA as a share of GNI are kept as reported." + }, + { + "transformation": "Select dimensions", + "description": "Each figure is reported by year, provider, recipient and type of aid, such as grants, repayments, interest received, or debt forgiven or rescheduled. DAC2A is a table of disbursements, so every figure, repayments and interest included, is recorded as a disbursement. Figures are marked as gross or net, except where DAC2A does not say which, and as grants or non-grants where the type of aid is wholly one or the other. Imputed multilateral ODA, the OECD's estimate of each provider's share of multilateral organisations' ODA, is marked as modelled. ODA as a share of GNI records the recipient's GNI as its denominator, and ODA per person records the recipient's population." + } + ], + "version_history": [ + { + "date": "2026-10-15", + "title": "Partial preliminary year excluded", + "changes": [ + { + "kind": "changed", + "note": "The partial preliminary year published ahead of the next full release is excluded." + } + ] + }, + { + "date": "2026-10-14", + "title": "First release", + "changes": [ + { + "kind": "added", + "note": "ODA disbursements by donor and recipient country or region, including the OECD's imputed multilateral contributions, and ODA per person and as a share of recipient GNI." + } + ] + } + ] + } + } + ] + }, + "trace": { + "facets": [ + { + "ref": "provenance/OECDDAC2A", + "axis": "provenance", + "basis": "bound", + "default_policy": null, + "selection_reason": null, + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": null + }, + { + "ref": null, + "axis": "measurementMethod", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "absent_on_selected_facet", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + }, + { + "ref": "CurrencyUSD", + "axis": "unit", + "basis": "deployment_fallback", + "default_policy": "dfo/facet-policy/most-observations", + "selection_reason": "sole_candidate", + "dispatch_facet_id": "1962969911839422253", + "default_policy_version": "1" + } + ], + "applied_window": { + "kind": "range", + "origin": "query", + "end_year": 2024, + "start_year": 2017 + }, + "graph_revision": null, + "normalisations": [], + "code_index_stamp": { + "exported_at": "2026-10-20T19:50:14Z", + "content_hash": "602c7022fc21c17540a6873d93196ad6b967eaae3e71f9dce6dec178a735daf4", + "graph_endpoint": "graph_release" + }, + "source_revisions": [ + { + "source": "provenance/OECDDAC2A", + "revision": "2026-10-15" + } + ], + "capability_version": "dset_88fecfec3c5b89d1", + "materialiser_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "resolved_stat_vars": [ + { + "ref": "dcid:Amount_FinancialFlow_Gross_Disbursement_DAC2aAidType206_Nominal", + "roles": [ + "financingProvider", + "financingRecipient" + ], + "observation_count": 123015 + } + ], + "family_member_count": 1, + "family_member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "frame_grammar_version": "1.1.0", + "origin_catalogue_build_id": "20261021T070020Z-7262111e", + "served_from": "materialise", + "confirmed_at": "2026-10-21T08:58:45.913023+00:00" + }, + "warnings": [], + "diagnostics": [ + { + "code": "processing_level_undeclared", + "severity": "info", + "message": "A source StatVar lacks a processing-level declaration; the citation credits the source and omits the processing qualifier." + } + ], + "artifacts": [ + { + "artifact_digest": "sha256:cf2a4a97cc0fdfeb74ce021502e58c70d87ae4d67dc061a46fa62bb4f106a192", + "rendering": { + "bundle": false, + "format": "parquet", + "layout": 3 + }, + "bytes": 1031059, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:58:45.884058+00:00", + "tier": "working", + "url": "/api/datasets/spec_8a4676c4abdf43d105aeff9d4ba9299b/cv_50e17ab9c2e732f13c48cf2028ac5928/files/sha256:cf2a4a97cc0fdfeb74ce021502e58c70d87ae4d67dc061a46fa62bb4f106a192" + }, + { + "artifact_digest": "sha256:1a9852b1499a841264af878b70b999a25b104804e6ae1825dcfaabd5eab989bd", + "rendering": { + "statistics": "series" + }, + "bytes": 984263, + "media_type": "application/vnd.apache.parquet", + "created_at": "2026-10-21T08:58:45.884058+00:00", + "tier": "working", + "url": "/api/datasets/spec_8a4676c4abdf43d105aeff9d4ba9299b/cv_50e17ab9c2e732f13c48cf2028ac5928/files/sha256:1a9852b1499a841264af878b70b999a25b104804e6ae1825dcfaabd5eab989bd" + } + ], + "series_count": 21438, + "output_options": { + "capability_version": "dset_88fecfec3c5b89d1", + "columns": [ + { + "name": "stat_var", + "kind": "grain", + "droppable": false, + "distinct": 1 + }, + { + "name": "financingProvider", + "kind": "role", + "droppable": false, + "distinct": 172 + }, + { + "name": "financingRecipient", + "kind": "role", + "droppable": false, + "distinct": 241 + }, + { + "name": "time_period", + "kind": "grain", + "droppable": false, + "distinct": 8 + }, + { + "name": "value", + "kind": "value", + "droppable": true + }, + { + "name": "unit", + "kind": "unit", + "droppable": false, + "distinct": 1 + }, + { + "name": "measurementMethod", + "kind": "facet", + "droppable": true, + "distinct": 1 + }, + { + "name": "provenance", + "kind": "facet", + "droppable": false, + "distinct": 1 + }, + { + "name": "status", + "kind": "status", + "droppable": true + } + ], + "formats": [ + { + "name": "csv", + "state": "available" + }, + { + "name": "xlsx", + "state": "available" + }, + { + "name": "parquet", + "state": "available" + } + ], + "bundle": { + "state": "available" + }, + "enrichments": [ + { + "column": "financingProvider", + "field": "iso3", + "token": "financingProvider_iso3", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 172, + "covered": 50 + }, + "missing": [ + { + "ref": "AdaptationFund", + "label": "Adaptation Fund" + }, + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentBankGroup", + "label": "African Development Bank Group" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AndrewCarnegieFoundation", + "label": "Andrew Carnegie Foundation" + }, + { + "ref": "ArabFundForEconomicAndSocialDevelopment", + "label": "Arab Fund for Economic and Social Development" + }, + { + "ref": "Arcadia", + "label": "Arcadia" + }, + { + "ref": "ArcusFoundation", + "label": "Arcus Foundation" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianInfrastructureInvestmentBank", + "label": "Asian Infrastructure Investment Bank" + } + ], + "truncated": true + }, + { + "column": "financingProvider", + "field": "iso2", + "token": "financingProvider_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 172, + "covered": 50 + }, + "missing": [ + { + "ref": "AdaptationFund", + "label": "Adaptation Fund" + }, + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentBankGroup", + "label": "African Development Bank Group" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AndrewCarnegieFoundation", + "label": "Andrew Carnegie Foundation" + }, + { + "ref": "ArabFundForEconomicAndSocialDevelopment", + "label": "Arab Fund for Economic and Social Development" + }, + { + "ref": "Arcadia", + "label": "Arcadia" + }, + { + "ref": "ArcusFoundation", + "label": "Arcus Foundation" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianInfrastructureInvestmentBank", + "label": "Asian Infrastructure Investment Bank" + } + ], + "truncated": true + }, + { + "column": "financingProvider", + "field": "label", + "token": "financingProvider_label", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "type", + "token": "financingProvider_type", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingProvider", + "field": "party_kind", + "token": "financingProvider_party_kind", + "state": "available", + "coverage": { + "entities": 172, + "covered": 172 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "iso3", + "token": "financingRecipient_iso3", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 241, + "covered": 146 + }, + "missing": [ + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianDevelopmentBankSpecialFunds", + "label": "Asian Development Bank Special Funds" + }, + { + "ref": "CaribbeanDevelopmentBank", + "label": "Caribbean Development Bank" + }, + { + "ref": "CentralAmericanBankForEconomicIntegration", + "label": "Central American Bank for Economic Integration" + }, + { + "ref": "DACACPCountries", + "label": "ACP countries (DAC)" + }, + { + "ref": "DACAfrica", + "label": "Africa (DAC)" + }, + { + "ref": "DACAfricaUnallocated", + "label": "Africa, unallocated by country (DAC)" + }, + { + "ref": "DACAllMultilateralRecipients", + "label": "all multilateral recipients (DAC)" + } + ], + "truncated": true + }, + { + "column": "financingRecipient", + "field": "iso2", + "token": "financingRecipient_iso2", + "state": "partial", + "reason": "enrichment_unavailable", + "coverage": { + "entities": 241, + "covered": 144 + }, + "missing": [ + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank" + }, + { + "ref": "AsianDevelopmentBankSpecialFunds", + "label": "Asian Development Bank Special Funds" + }, + { + "ref": "CaribbeanDevelopmentBank", + "label": "Caribbean Development Bank" + }, + { + "ref": "CentralAmericanBankForEconomicIntegration", + "label": "Central American Bank for Economic Integration" + }, + { + "ref": "DACACPCountries", + "label": "ACP countries (DAC)" + }, + { + "ref": "DACAfrica", + "label": "Africa (DAC)" + }, + { + "ref": "DACAfricaUnallocated", + "label": "Africa, unallocated by country (DAC)" + }, + { + "ref": "DACAllMultilateralRecipients", + "label": "all multilateral recipients (DAC)" + } + ], + "truncated": true + }, + { + "column": "financingRecipient", + "field": "label", + "token": "financingRecipient_label", + "state": "available", + "coverage": { + "entities": 241, + "covered": 241 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "type", + "token": "financingRecipient_type", + "state": "available", + "coverage": { + "entities": 241, + "covered": 241 + }, + "missing": [], + "truncated": false + }, + { + "column": "financingRecipient", + "field": "party_kind", + "token": "financingRecipient_party_kind", + "state": "available", + "coverage": { + "entities": 241, + "covered": 241 + }, + "missing": [], + "truncated": false + } + ], + "long_layout_defaults": [ + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient_label", + "financingRecipient_party_kind" + ], + "long_layout_totals": [ + "financingRecipient" + ], + "pivots": [ + { + "index": "financingProvider", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 8 + } + ] + }, + { + "index": "financingProvider", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 241 + } + ] + }, + { + "index": "financingRecipient", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "time_period", + "distinct": 8 + } + ] + }, + { + "index": "financingRecipient", + "columns": "time_period", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 172 + } + ] + }, + { + "index": "time_period", + "columns": "financingProvider", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingRecipient", + "distinct": 241 + } + ] + }, + { + "index": "time_period", + "columns": "financingRecipient", + "state": "unavailable", + "reason": "pivot_not_unique", + "varying": [ + { + "column": "financingProvider", + "distinct": 172 + } + ] + } + ], + "groupby": { + "state": "available", + "axes": [ + { + "name": "crsCooperationModality" + }, + { + "name": "crsPurpose" + }, + { + "name": "crsTypeOfFinance" + }, + { + "name": "crsTypeOfFlow" + } + ] + } + }, + "series_coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "retention": { + "pinned": false, + "held_until": "2026-11-20T08:58:45.884491Z" + } + } + } + } + }, + { + "request": { + "method": "POST", + "path": "/search/resolve", + "json": { + "schema_version": 1, + "input": { + "kind": "dataset_resubmit", + "entries": [ + { + "entry_kind": "identity", + "variable_text": "dataset", + "identity": { + "shape": { + "kind": "statvar_schema", + "stat_type": "measuredValue", + "population_type": "FinancialFlow", + "measured_property": "amount", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "binding": { + "ref": "DAC2aAidType206", + "state": "value" + }, + "property": "dac2aAidType" + }, + { + "binding": { + "state": "unbound" + }, + "property": "dacTypeOfFinance" + }, + { + "binding": { + "ref": "Disbursement", + "state": "value" + }, + "property": "financialFlowType" + }, + { + "binding": { + "ref": "Gross", + "state": "value" + }, + "property": "nettingBasis" + } + ], + "facets": { + "provenance": { + "ref": "provenance/OECDDAC2A", + "state": "value" + } + }, + "entities": {}, + "open_roles": [ + "destination" + ], + "identity_version": "spec1", + "requested_window": { + "kind": "range", + "end_year": 2024, + "start_year": 2017 + } + } + } + ] + } + } + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json" + }, + "json": { + "schema_version": 1, + "query_echo": { + "entry_path": "dataset_resubmit", + "extract_skipped": true + }, + "diagnostics": { + "engine_build": "635943e03a297f686ca5af32f6d027181d1971d4", + "trace_id": "66862f73d51a4f6db9b08fca2b8a83cc", + "warnings": [], + "timing_ms": { + "total": 2543, + "by_step": { + "coverage": 0 + } + }, + "timed_out": false + }, + "kind": "resolution", + "parts": [ + { + "variable_text": "dataset", + "warnings": [ + { + "code": "role_scope_defaulted", + "severity": "warn", + "message": "no recipient was named; the answer was resolved across the 241 recipients with data." + }, + { + "code": "role_scope_defaulted", + "severity": "warn", + "message": "no provider was named; the answer was resolved across every provider with data." + } + ], + "timing_ms": { + "total": 2118, + "by_step": { + "validate": 1, + "walk": 4, + "reread_arcs": 0, + "detect_edits": 0, + "resolve_survivors": 0, + "shape": 1921, + "bind": 0, + "where_places": 0, + "materialise": 174, + "answer": 4, + "options": 14 + } + }, + "operations": [], + "departures": [], + "assumptions": [ + { + "kind": "open_role", + "binding_ref": "origin:", + "text": "every provider", + "refs": [] + } + ], + "status": "definite", + "spec": { + "spec_id": "spec_8a4676c4abdf43d105aeff9d4ba9299b", + "definition": { + "schema_version": 1, + "spec_id": "spec_8a4676c4abdf43d105aeff9d4ba9299b", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Gross" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2017, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + }, + "open_roles": [ + "destination" + ] + } + }, + "resolved": { + "shape": { + "shape_id": "financialflow_amount_measuredvalue_nominal_family_f096b1ba", + "label": "gross disbursements (official development assistance)", + "population_type": { + "ref": "FinancialFlow", + "label": "financial flow" + }, + "measured_property": { + "ref": "amount", + "label": "amount" + }, + "stat_type": { + "ref": "measuredValue", + "label": "measuredValue" + }, + "measurement_qualifier": { + "ref": "Nominal", + "label": "Nominal" + }, + "measurement_denominator_unresolved": false, + "slot_keys": [ + { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + { + "axis": "where", + "label": "place" + }, + { + "axis": "when", + "label": "time window" + }, + { + "axis": "source", + "label": "data source" + } + ], + "member_count": 1, + "member_digest": "1a36e1a7292b1bfff95a5415de0be74cac7bb033217ed50e79faa8ce51a224c0", + "refine_supported": true, + "data_commons": [ + { + "id": "dfo", + "label": "Development Finance Observatory" + } + ] + }, + "slots": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "DAC2aAidType206", + "label": "official development assistance" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Disbursement", + "label": "disbursement" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "Gross", + "label": "gross" + }, + "value_kind": "enum_value" + } + }, + "summable": false + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding": { + "kind": "unbound" + }, + "summable": false + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding": { + "kind": "value", + "value": { + "value_kind": "time_window", + "time_window": { + "start_year": 2017, + "end_year": 2024 + } + } + }, + "summable": false + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding": { + "kind": "value", + "value": { + "ref": { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A" + }, + "value_kind": "source" + } + }, + "summable": false + } + ], + "inapplicable_slots": [ + "dacTypeOfFinance" + ], + "unresolved_slots": [], + "stat_vars": { + "member_count": 1, + "member_count_exact": true, + "served_count": 1, + "data_date_range": { + "start": "2017", + "end": "2024" + } + }, + "entities": [], + "coverage": { + "kind": "breadth", + "has_data": true, + "dimensions": [ + { + "label": "recipients", + "count": 241 + }, + { + "label": "sources", + "count": 1 + }, + { + "label": "variables", + "count": 1 + } + ], + "window": { + "start_year": 2017, + "end_year": 2024 + } + }, + "headline": { + "year": 2024, + "year_named": true, + "named_window": { + "start_year": 2017, + "end_year": 2024 + }, + "observations": 15402, + "series": 15402, + "role_counts": { + "financingProvider": 148, + "financingRecipient": 234 + }, + "recent_years": [ + { + "year": 2024, + "observations": 15402, + "series": 15402, + "role_counts": { + "financingProvider": 148, + "financingRecipient": 234 + } + }, + { + "year": 2023, + "observations": 15579, + "series": 15579, + "role_counts": { + "financingProvider": 156, + "financingRecipient": 234 + } + }, + { + "year": 2022, + "observations": 16403, + "series": 16403, + "role_counts": { + "financingProvider": 162, + "financingRecipient": 235 + } + } + ] + }, + "download": { + "rows": 123015, + "rows_exact": true, + "series": 21438, + "window": { + "start_year": 2017, + "end_year": 2024 + }, + "licence": { + "label": "OECD Terms and Conditions" + } + }, + "coverage_stamp": "5a4dd8009d09f5328e1439a71fc02ff8e2385aaed6310928fc34efb3a592fac4", + "scope": { + "axis": "destination", + "members": [ + { + "ref": "AfricanDevelopmentBank", + "label": "African Development Bank", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "AfricanDevelopmentFund", + "label": "African Development Fund", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "AsianDevelopmentBank", + "label": "Asian Development Bank", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "AsianDevelopmentBankSpecialFunds", + "label": "Asian Development Bank Special Funds", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "CaribbeanDevelopmentBank", + "label": "Caribbean Development Bank", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "CentralAmericanBankForEconomicIntegration", + "label": "Central American Bank for Economic Integration", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "DACACPCountries", + "label": "ACP countries (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACAfrica", + "label": "Africa (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACAfricaUnallocated", + "label": "Africa, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACAllMultilateralRecipients", + "label": "all multilateral recipients (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACAllRecipients", + "label": "all recipients (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACAmerica", + "label": "America (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACAmericaUnallocated", + "label": "America, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACAsia", + "label": "Asia (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACAsiaUnallocated", + "label": "Asia, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACBilateralUnallocated", + "label": "Bilateral, unallocated (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACCaribbean", + "label": "Caribbean (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACCaribbeanAndCentralAmerica", + "label": "Caribbean and Central America (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACCaribbeanAndCentralAmericaUnallocated", + "label": "Caribbean and Central America, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACCaribbeanUnallocated", + "label": "Caribbean, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACCentralAmerica", + "label": "Central America (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACCentralAmericaUnallocated", + "label": "Central America, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACCentralAndEasternEuropeanCountries", + "label": "Central and Eastern European countries (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACCentralAsiaUnallocated", + "label": "Central Asia, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACClubDuSahelCountries", + "label": "Club du Sahel countries (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACDevelopingCountries", + "label": "developing countries (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACEasternAfrica", + "label": "Eastern Africa (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACEasternAfricaUnallocated", + "label": "Eastern Africa, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACEurope", + "label": "Europe (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACEuropeUnallocated", + "label": "Europe, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACExYugoslaviaUnallocated", + "label": "States of the former Yugoslavia, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACFarEastAsia", + "label": "Far East Asia (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACFarEastAsiaUnallocated", + "label": "Far East Asia, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACFragileStates", + "label": "fragile states (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACLowerMiddleIncomeCountries", + "label": "lower middle-income countries (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACMelanesia", + "label": "Melanesia (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACMelanesiaUnallocated", + "label": "Melanesia, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACMicronesia", + "label": "Micronesia (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACMicronesiaUnallocated", + "label": "Micronesia, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACMiddleAfrica", + "label": "Middle Africa (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACMiddleAfricaUnallocated", + "label": "Middle Africa, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACMiddleEast", + "label": "Middle East (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACMiddleEastUnallocated", + "label": "Middle East, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACMoreAdvancedDevelopingCountriesAndTerritories", + "label": "more advanced developing countries and territories (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACNewIndependentStates", + "label": "New Independent States of the former Soviet Union (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACNorthOfSahara", + "label": "North of Sahara (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACNorthOfSaharaUnallocated", + "label": "North of Sahara, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACOceania", + "label": "Oceania (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACOceaniaUnallocated", + "label": "Oceania, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACOtherEUInstitutions", + "label": "other EU institutions (DAC)", + "entity_type": "DACUnspecifiedParty", + "role": "destination" + }, + { + "ref": "DACOtherLowIncomeCountries", + "label": "other low-income countries (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACOtherMultilateralRecipient", + "label": "other multilateral recipient (DAC)", + "entity_type": "DACUnspecifiedParty", + "role": "destination" + }, + { + "ref": "DACOtherRegionalDevelopmentBanks", + "label": "other regional development banks (DAC)", + "entity_type": "DACUnspecifiedParty", + "role": "destination" + }, + { + "ref": "DACOtherUnitedNations", + "label": "other United Nations entities (DAC)", + "entity_type": "DACUnspecifiedParty", + "role": "destination" + }, + { + "ref": "DACOtherWorldBank", + "label": "other World Bank (DAC)", + "entity_type": "DACUnspecifiedParty", + "role": "destination" + }, + { + "ref": "DACPolynesia", + "label": "Polynesia (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACPolynesiaUnallocated", + "label": "Polynesia, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACSmallIslandStates", + "label": "small island states (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACSouthAmerica", + "label": "South America (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACSouthAmericaUnallocated", + "label": "South America, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACSouthAndCentralAsia", + "label": "South and Central Asia (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACSouthAndCentralAsiaUnallocated", + "label": "South and Central Asia, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACSouthAsiaUnallocated", + "label": "South Asia, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACSouthOfSahara", + "label": "South of Sahara (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACSouthOfSaharaUnallocated", + "label": "South of Sahara, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACSouthernAfrica", + "label": "Southern Africa (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACSouthernAfricaUnallocated", + "label": "Southern Africa, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "DACUnallocatedByIncome", + "label": "unallocated by income (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACUpperMiddleIncomeCountries", + "label": "upper middle-income countries (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACWesternAfrica", + "label": "Western Africa (DAC)", + "entity_type": "DACGroup", + "role": "destination" + }, + { + "ref": "DACWesternAfricaUnallocated", + "label": "Western Africa, unallocated by country (DAC)", + "entity_type": "DACRecipientUnallocatedByCountry", + "role": "destination" + }, + { + "ref": "EuropeanCommission", + "label": "European Commission", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "EuropeanInvestmentBank", + "label": "European Investment Bank", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "EuropeanUnionInstitutions", + "label": "European Union institutions", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "HeavilyIndebtedPoorCountries", + "label": "heavily indebted poor countries (IMF and World Bank)", + "entity_type": "Grouping", + "role": "destination" + }, + { + "ref": "InterAmericanDevelopmentBank", + "label": "Inter-American Development Bank", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "InterAmericanDevelopmentBankFundForSpecialOperations", + "label": "Inter-American Development Bank Fund for Special Operations", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "InternationalBankForReconstructionAndDevelopment", + "label": "International Bank for Reconstruction and Development", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "InternationalDevelopmentAssociation", + "label": "International Development Association", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "InternationalFinanceCorporation", + "label": "International Finance Corporation", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "InternationalFundForAgriculturalDevelopment", + "label": "International Fund for Agricultural Development", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "InternationalMonetaryFund", + "label": "International Monetary Fund", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "UNLandlockedDevelopingCountries", + "label": "landlocked developing countries (UN)", + "entity_type": "UNCountryDevelopmentGroup", + "role": "destination" + }, + { + "ref": "UNLeastDevelopedCountries", + "label": "least developed countries (UN)", + "entity_type": "UNCountryDevelopmentGroup", + "role": "destination" + }, + { + "ref": "UNRWA", + "label": "United Nations Relief and Works Agency for Palestine Refugees in the Near East", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "UnitedNationsChildrensFund", + "label": "United Nations Children's Fund", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "UnitedNationsDevelopmentProgramme", + "label": "United Nations Development Programme", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "UnitedNationsHighCommissionerForRefugees", + "label": "Office of the United Nations High Commissioner for Refugees", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "UnitedNationsPopulationFund", + "label": "United Nations Population Fund", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "WorldBankHighIncome", + "label": "high income (World Bank)", + "entity_type": "WorldBankIncomeGroup", + "role": "destination" + }, + { + "ref": "WorldBankLowIncome", + "label": "low income (World Bank)", + "entity_type": "WorldBankIncomeGroup", + "role": "destination" + }, + { + "ref": "WorldBankLowerMiddleIncome", + "label": "lower middle income (World Bank)", + "entity_type": "WorldBankIncomeGroup", + "role": "destination" + }, + { + "ref": "WorldBankNotClassifiedByIncome", + "label": "not classified by income (World Bank)", + "entity_type": "WorldBankIncomeGroup", + "role": "destination" + }, + { + "ref": "WorldBankUpperMiddleIncome", + "label": "upper middle income (World Bank)", + "entity_type": "WorldBankIncomeGroup", + "role": "destination" + }, + { + "ref": "WorldFoodProgramme", + "label": "World Food Programme", + "entity_type": "Organization", + "role": "destination" + }, + { + "ref": "country/AFG", + "label": "Afghanistan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/AGO", + "label": "Angola", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ALB", + "label": "Albania", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ARG", + "label": "Argentina", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ARM", + "label": "Armenia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ATG", + "label": "Antigua and Barbuda", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/AZE", + "label": "Azerbaijan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BDI", + "label": "Burundi", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BEN", + "label": "Benin", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BFA", + "label": "Burkina Faso", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BGD", + "label": "Bangladesh", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BIH", + "label": "Bosnia and Herzegovina", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BLR", + "label": "Belarus", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BLZ", + "label": "Belize", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BOL", + "label": "Bolivia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BRA", + "label": "Brazil", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BTN", + "label": "Bhutan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/BWA", + "label": "Botswana", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CAF", + "label": "Central African Republic", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CHL", + "label": "Chile", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CHN", + "label": "People's Republic of China", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CIV", + "label": "Ivory Coast", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CMR", + "label": "Cameroon", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COD", + "label": "Democratic Republic of the Congo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COG", + "label": "Republic of the Congo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COK", + "label": "Cook Islands", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COL", + "label": "Colombia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/COM", + "label": "Comoros", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CPV", + "label": "Cape Verde", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CRI", + "label": "Costa Rica", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/CUB", + "label": "Cuba", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DJI", + "label": "Djibouti", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DMA", + "label": "Dominica", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DOM", + "label": "Dominican Republic", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/DZA", + "label": "Algeria", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ECU", + "label": "Ecuador", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/EGY", + "label": "Egypt", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ERI", + "label": "Eritrea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ETH", + "label": "Ethiopia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/FJI", + "label": "Fiji", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/FSM", + "label": "Micronesia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GAB", + "label": "Gabon", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GEO", + "label": "Georgia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GHA", + "label": "Ghana", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GIN", + "label": "Guinea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GMB", + "label": "The Gambia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GNB", + "label": "Guinea-Bissau", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GNQ", + "label": "Equatorial Guinea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GRD", + "label": "Grenada", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GTM", + "label": "Guatemala", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/GUY", + "label": "Guyana", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/HND", + "label": "Honduras", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/HTI", + "label": "Haiti", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/IDN", + "label": "Indonesia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/IND", + "label": "India", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/IRN", + "label": "Iran", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/IRQ", + "label": "Iraq", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/JAM", + "label": "Jamaica", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/JOR", + "label": "Jordan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/KAZ", + "label": "Kazakhstan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/KEN", + "label": "Kenya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/KGZ", + "label": "Kyrgyzstan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/KHM", + "label": "Cambodia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/KIR", + "label": "Kiribati", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LAO", + "label": "Laos", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LBN", + "label": "Lebanon", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LBR", + "label": "Liberia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LBY", + "label": "Libya", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LCA", + "label": "Saint Lucia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LKA", + "label": "Sri Lanka", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/LSO", + "label": "Lesotho", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MAR", + "label": "Morocco", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MDA", + "label": "Moldova", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MDG", + "label": "Madagascar", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MDV", + "label": "Maldives", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MEX", + "label": "Mexico", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MHL", + "label": "Marshall Islands", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MKD", + "label": "North Macedonia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MLI", + "label": "Mali", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MMR", + "label": "Myanmar [Burma]", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MNE", + "label": "Montenegro", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MNG", + "label": "Mongolia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MOZ", + "label": "Mozambique", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MRT", + "label": "Mauritania", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MSR", + "label": "Montserrat", + "entity_type": "AdministrativeArea1", + "role": "destination" + }, + { + "ref": "country/MUS", + "label": "Mauritius", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MWI", + "label": "Malawi", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/MYS", + "label": "Malaysia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NAM", + "label": "Namibia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NER", + "label": "Niger", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NGA", + "label": "Nigeria", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NIC", + "label": "Nicaragua", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NIU", + "label": "Niue", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NPL", + "label": "Nepal", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/NRU", + "label": "Nauru", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/PAK", + "label": "Pakistan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/PAN", + "label": "Panama", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/PER", + "label": "Peru", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/PHL", + "label": "Philippines", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/PLW", + "label": "Palau", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/PNG", + "label": "Papua New Guinea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/PRK", + "label": "North Korea", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/PRY", + "label": "Paraguay", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/PSE", + "label": "State of Palestine", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/RWA", + "label": "Rwanda", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SDN", + "label": "Sudan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SEN", + "label": "Senegal", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SHN", + "label": "Saint Helena, Ascension and Tristan da Cunha", + "entity_type": "AdministrativeArea1", + "role": "destination" + }, + { + "ref": "country/SLB", + "label": "Solomon Islands", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SLE", + "label": "Sierra Leone", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SLV", + "label": "El Salvador", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SOM", + "label": "Somalia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SRB", + "label": "Serbia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SSD", + "label": "South Sudan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/STP", + "label": "São Tomé and Príncipe", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SUR", + "label": "Suriname", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SWZ", + "label": "Swaziland", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SYC", + "label": "Seychelles", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/SYR", + "label": "Syria", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TCD", + "label": "Chad", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TGO", + "label": "Togo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/THA", + "label": "Thailand", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TJK", + "label": "Tajikistan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TKL", + "label": "Tokelau", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TKM", + "label": "Turkmenistan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TLS", + "label": "Timor-Leste", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TON", + "label": "Tonga", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TUN", + "label": "Tunisia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TUR", + "label": "Turkey", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TUV", + "label": "Tuvalu", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/TZA", + "label": "Tanzania", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/UGA", + "label": "Uganda", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/UKR", + "label": "Ukraine", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/URY", + "label": "Uruguay", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/UZB", + "label": "Uzbekistan", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/VCT", + "label": "Saint Vincent and the Grenadines", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/VEN", + "label": "Venezuela", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/VNM", + "label": "Vietnam", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/VUT", + "label": "Vanuatu", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/WLF", + "label": "Wallis and Futuna", + "entity_type": "AdministrativeArea", + "role": "destination" + }, + { + "ref": "country/WSM", + "label": "Samoa", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/XKS", + "label": "Kosovo", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/YEM", + "label": "Yemen", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ZAF", + "label": "South Africa", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ZMB", + "label": "Zambia", + "entity_type": "Country", + "role": "destination" + }, + { + "ref": "country/ZWE", + "label": "Zimbabwe", + "entity_type": "Country", + "role": "destination" + } + ] + }, + "facets": { + "provenance": { + "basis": "bound", + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A", + "account": "provider" + }, + "unit": { + "basis": "fallback", + "ref": "CurrencyUSD", + "label": "US Dollar", + "currency": "USD" + } + }, + "slot_options": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "options": [ + { + "value": { + "ref": { + "ref": "DAC2aAidType218", + "label": "ODA loans and other long-term capital" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 2, + "served_rows": 26525, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType201", + "label": "ODA grant" + }, + "value_kind": "enum_value" + }, + "relation": "child", + "parent": "DAC2aAidType206", + "member_count": 1, + "served_rows": 119269, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType207", + "label": "free-standing technical co-operation" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 52151, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType213", + "label": "developmental food aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 15005, + "served_rows_exact": false + }, + { + "value": { + "ref": { + "ref": "DAC2aAidType216", + "label": "humanitarian aid" + }, + "value_kind": "enum_value" + }, + "relation": "root", + "member_count": 1, + "served_rows": 50159, + "served_rows_exact": false + } + ], + "truncated": false, + "source": "observed" + } + ], + "entity_options": [ + { + "role": "destination", + "options": [], + "truncated": true, + "source": "observed" + }, + { + "role": "origin", + "options": [], + "truncated": true, + "source": "observed" + } + ], + "facet_options": [ + { + "axis": "provenance", + "options": [ + { + "value": { + "ref": { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A" + }, + "value_kind": "source" + } + } + ], + "truncated": false, + "source": "observed" + }, + { + "axis": "unit", + "options": [ + { + "value": { + "ref": { + "ref": "CurrencyUSD", + "label": "US Dollar" + }, + "value_kind": "enum_value" + } + } + ], + "truncated": false, + "source": "observed" + } + ], + "rendered_sentence": "Gross disbursements to 241 recipients from 172 providers for official development assistance, 2017 to 2024. Current US dollars · OECD DAC2A.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ] + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "241 recipients", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ] + }, + { + "kind": "text", + "text": " from ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "172 providers", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [], + "states": [ + "origin:" + ] + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2017 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC2A", + "axis": "source", + "segment": "byline", + "binding_ref": "source:", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + } + ], + "trace": { + "resolved_entities": [], + "resolved_sources": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2a", + "source": { + "ref": "dc/s/OrganisationForEconomicCo-operationAndDevelopmentOecd", + "label": "Organisation for Economic Co-operation and Development (OECD)" + }, + "data_commons": { + "id": "dfo", + "label": "Development Finance Observatory" + }, + "documentation": "/api/graph/documentation/provenance/OECDDAC2A" + } + ], + "slot_filters": [ + { + "key": { + "axis": "how", + "property": { + "ref": "dac2aAidType", + "label": "DAC 2a aid type" + }, + "label": "aid type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "DAC2aAidType206", + "label": "official development assistance" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "financialFlowType", + "label": "financial flow type" + }, + "label": "financial flow type" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Disbursement", + "label": "disbursement" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "nettingBasis", + "label": "netting basis" + }, + "label": "netting basis" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "Gross", + "label": "gross" + } + ], + "provenance": "binder" + }, + { + "key": { + "axis": "how", + "property": { + "ref": "dacTypeOfFinance", + "label": "DAC type of finance" + }, + "label": "DAC type of finance" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "where", + "label": "place" + }, + "binding_kind": "unbound", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "when", + "label": "time window" + }, + "binding_kind": "value", + "refs": [], + "provenance": "binder" + }, + { + "key": { + "axis": "source", + "label": "data source" + }, + "binding_kind": "value", + "refs": [ + { + "ref": "provenance/OECDDAC2A", + "label": "OECD DAC2A" + } + ], + "provenance": "binder" + } + ], + "query_qualifiers": [], + "requested_window": { + "start_year": 2017, + "end_year": 2024 + }, + "capability_version": "cap_347a470e04c97eec" + }, + "confidence": "high", + "alternative_measures": [ + { + "definition": { + "schema_version": 1, + "spec_id": "spec_de034b2632a047bf6b7f6c8fdf1b172e", + "identity": { + "identity_version": "spec1", + "shape": { + "kind": "statvar_schema", + "population_type": "FinancialFlow", + "measured_property": "amount", + "stat_type": "measuredValue", + "measurement_qualifier": "Nominal" + }, + "slots": [ + { + "property": "dac2aAidType", + "binding": { + "state": "value", + "ref": "DAC2aAidType206" + } + }, + { + "property": "dacTypeOfFinance", + "binding": { + "state": "unbound" + } + }, + { + "property": "financialFlowType", + "binding": { + "state": "value", + "ref": "Disbursement" + } + }, + { + "property": "nettingBasis", + "binding": { + "state": "value", + "ref": "Net" + } + } + ], + "entities": {}, + "requested_window": { + "kind": "range", + "start_year": 2017, + "end_year": 2024 + }, + "facets": { + "provenance": { + "state": "value", + "ref": "provenance/OECDDAC2A" + } + } + } + }, + "label": "net disbursements", + "axis": "what", + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Net", + "label": "net" + } + } + ], + "served_rows": 125252, + "served_rows_exact": false + } + ], + "measure_label": "gross disbursements", + "measure_label_axes": [ + "populationType", + "measuredProperty", + "measurementQualifier", + "financialFlowType", + "nettingBasis" + ], + "measure_axis_values": [ + { + "axis": "populationType", + "value": { + "ref": "FinancialFlow", + "label": "financial flow" + } + }, + { + "axis": "measuredProperty", + "value": { + "ref": "amount", + "label": "amount" + } + }, + { + "axis": "measurementQualifier", + "value": { + "ref": "Nominal", + "label": "nominal" + } + }, + { + "axis": "financialFlowType", + "value": { + "ref": "Disbursement", + "label": "disbursement" + } + }, + { + "axis": "nettingBasis", + "value": { + "ref": "Gross", + "label": "gross" + } + } + ], + "role_axis_facts": [ + { + "role": "destination", + "member_count": 241, + "members_available": true + }, + { + "role": "origin", + "member_count": 172, + "members_available": true + } + ], + "unit_conversion": { + "currencies": [ + { + "code": "AED", + "noun": "UAE dirhams", + "current_years": { + "start_year": 2017, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "AFN", + "noun": "Afghan afghanis", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 2002, + "base_year_max": 2025 + }, + { + "code": "ALL", + "noun": "Albanian leks", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AMD", + "noun": "Armenian drams", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "AOA", + "noun": "Angolan kwanzas", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "ARS", + "noun": "Argentine pesos", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "AUD", + "noun": "Australian dollars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "AWG", + "noun": "Aruban florins", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2025 + }, + { + "code": "AZN", + "noun": "Azerbaijani manats", + "current_years": { + "start_year": 2017, + "end_year": 2019 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "BAM", + "noun": "Bosnia-Herzegovina convertible marks", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1996, + "base_year_max": 2025 + }, + { + "code": "BBD", + "noun": "Barbadian dollars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BDT", + "noun": "Bangladeshi taka", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BHD", + "noun": "Bahraini dinars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BIF", + "noun": "Burundian francs", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BND", + "noun": "Brunei dollars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1985, + "base_year_max": 2025 + }, + { + "code": "BOB", + "noun": "Bolivian bolivianos", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BRL", + "noun": "Brazilian reais", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "BSD", + "noun": "Bahamian dollars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BTN", + "noun": "Bhutanese ngultrums", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BWP", + "noun": "Botswana pula", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "BYN", + "noun": "Belarusian rubles", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "BZD", + "noun": "Belize dollars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CAD", + "noun": "Canadian dollars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CDF", + "noun": "Congolese francs", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "CHF", + "noun": "Swiss francs", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "CLP", + "noun": "Chilean pesos", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CNY", + "noun": "Chinese yuan", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "COP", + "noun": "Colombian pesos", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CRC", + "noun": "Costa Rican colones", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CVE", + "noun": "Cape Verdean escudos", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "CZK", + "noun": "Czech korunas", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "DJF", + "noun": "Djiboutian francs", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "DKK", + "noun": "Danish kroner", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "DOP", + "noun": "Dominican pesos", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "DZD", + "noun": "Algerian dinars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EGP", + "noun": "Egyptian pounds", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ERN", + "noun": "Eritrean nakfas", + "current_years": { + "start_year": 2017, + "end_year": 2019 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2019 + }, + { + "code": "ETB", + "noun": "Ethiopian birr", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "EUR", + "noun": "euros", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1973, + "base_year_max": 2025 + }, + { + "code": "FJD", + "noun": "Fijian dollars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GBP", + "noun": "British pounds", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "GEL", + "noun": "Georgian lari", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1994, + "base_year_max": 2025 + }, + { + "code": "GHS", + "noun": "Ghanaian cedis", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GMD", + "noun": "Gambian dalasis", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GNF", + "noun": "Guinean francs", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GTQ", + "noun": "Guatemalan quetzales", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "GYD", + "noun": "Guyanese dollars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HKD", + "noun": "Hong Kong dollars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HNL", + "noun": "Honduran lempiras", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HTG", + "noun": "Haitian gourdes", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "HUF", + "noun": "Hungarian forints", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 2003, + "base_year_max": 2025 + }, + { + "code": "IDR", + "noun": "Indonesian rupiahs", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ILS", + "noun": "Israeli new shekels", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "INR", + "noun": "Indian rupees", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "IQD", + "noun": "Iraqi dinars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2025 + }, + { + "code": "IRR", + "noun": "Iranian rials", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ISK", + "noun": "Icelandic krónur", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "JMD", + "noun": "Jamaican dollars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JOD", + "noun": "Jordanian dinars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "JPY", + "noun": "Japanese yen", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "KES", + "noun": "Kenyan shillings", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KGS", + "noun": "Kyrgyz soms", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "KHR", + "noun": "Cambodian riels", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1986, + "base_year_max": 2025 + }, + { + "code": "KMF", + "noun": "Comorian francs", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "KRW", + "noun": "South Korean won", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "KWD", + "noun": "Kuwaiti dinars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1995, + "base_year_max": 2024 + }, + { + "code": "KZT", + "noun": "Kazakh tenge", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2024 + }, + { + "code": "LAK", + "noun": "Lao kip", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LBP", + "noun": "Lebanese pounds", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LKR", + "noun": "Sri Lankan rupees", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2024 + }, + { + "code": "LSL", + "noun": "Lesotho maloti", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "LYD", + "noun": "Libyan dinars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MAD", + "noun": "Moroccan dirhams", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MDL", + "noun": "Moldovan lei", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MGA", + "noun": "Malagasy ariary", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MKD", + "noun": "Macedonian denars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "MMK", + "noun": "Myanmar kyats", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "MNT", + "noun": "Mongolian tugriks", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MOP", + "noun": "Macanese patacas", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 2001, + "base_year_max": 2025 + }, + { + "code": "MRU", + "noun": "Mauritanian ouguiyas", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "MUR", + "noun": "Mauritian rupees", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MVR", + "noun": "Maldivian rufiyaa", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MWK", + "noun": "Malawian kwachas", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MXN", + "noun": "Mexican pesos", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MYR", + "noun": "Malaysian ringgits", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "MZN", + "noun": "Mozambican meticais", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NAD", + "noun": "Namibian dollars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1989, + "base_year_max": 2025 + }, + { + "code": "NGN", + "noun": "Nigerian naira", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "NIO", + "noun": "Nicaraguan córdobas", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1987, + "base_year_max": 2025 + }, + { + "code": "NOK", + "noun": "Norwegian kroner", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "NPR", + "noun": "Nepalese rupees", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "NZD", + "noun": "New Zealand dollars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1961, + "base_year_max": 2025 + }, + { + "code": "OMR", + "noun": "Omani rials", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PEN", + "noun": "Peruvian soles", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PGK", + "noun": "Papua New Guinean kina", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PHP", + "noun": "Philippine pesos", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PKR", + "noun": "Pakistani rupees", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "PLN", + "noun": "Polish zlotys", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1998, + "base_year_max": 2025 + }, + { + "code": "PYG", + "noun": "Paraguayan guaranís", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "QAR", + "noun": "Qatari riyals", + "current_years": { + "start_year": 2023, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2023 + }, + { + "code": "RON", + "noun": "Romanian lei", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 2013, + "base_year_max": 2025 + }, + { + "code": "RSD", + "noun": "Serbian dinars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1997, + "base_year_max": 2025 + }, + { + "code": "RUB", + "noun": "Russian rubles", + "current_years": { + "start_year": 2017, + "end_year": 2020 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 2010, + "base_year_max": 2020 + }, + { + "code": "RWF", + "noun": "Rwandan francs", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SAR", + "noun": "Saudi riyals", + "current_years": { + "start_year": 2017, + "end_year": 2023 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 2000, + "base_year_max": 2023 + }, + { + "code": "SBD", + "noun": "Solomon Islands dollars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SCR", + "noun": "Seychellois rupees", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SDG", + "noun": "Sudanese pounds", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SEK", + "noun": "Swedish kronor", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "SGD", + "noun": "Singapore dollars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SLE", + "noun": "Sierra Leonean leones", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SRD", + "noun": "Surinamese dollars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SSP", + "noun": "South Sudanese pounds", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 2011, + "base_year_max": 2025 + }, + { + "code": "STN", + "noun": "São Tomé and Príncipe dobras", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "SYP", + "noun": "Syrian pounds", + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2010, + "current_years": null + }, + { + "code": "SZL", + "noun": "Swazi emalangeni", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "THB", + "noun": "Thai baht", + "current_years": { + "start_year": 2018, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 2018, + "base_year_max": 2024 + }, + { + "code": "TJS", + "noun": "Tajikistani somonis", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TMT", + "noun": "Turkmenistani manat", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "TND", + "noun": "Tunisian dinars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TOP", + "noun": "Tongan paʻanga", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TRY", + "noun": "Turkish lira", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1990, + "base_year_max": 2025 + }, + { + "code": "TTD", + "noun": "Trinidad and Tobago dollars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "TWD", + "noun": "New Taiwan dollars", + "current_years": { + "start_year": 2018, + "end_year": 2021 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 2023, + "base_year_max": 2025 + }, + { + "code": "TZS", + "noun": "Tanzanian shillings", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UAH", + "noun": "Ukrainian hryvnias", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1991, + "base_year_max": 2025 + }, + { + "code": "UGX", + "noun": "Ugandan shillings", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "USD", + "noun": "US dollars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1960, + "base_year_max": 2025 + }, + { + "code": "UYU", + "noun": "Uruguayan pesos", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "UZS", + "noun": "Uzbekistani soms", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1992, + "base_year_max": 2025 + }, + { + "code": "VES", + "noun": "Venezuelan bolívares", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 2017, + "base_year_max": 2025 + }, + { + "code": "VND", + "noun": "Vietnamese dong", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "VUV", + "noun": "Vanuatu vatu", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "WST", + "noun": "Samoan tala", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XAF", + "noun": "Central African CFA francs", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XCD", + "noun": "East Caribbean dollars", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "XOF", + "noun": "West African CFA francs", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "YER", + "noun": "Yemeni rials", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 2014, + "base_year_max": 2025 + }, + { + "code": "ZAR", + "noun": "South African rand", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + }, + { + "code": "ZMW", + "noun": "Zambian kwachas", + "current_years": { + "start_year": 2017, + "end_year": 2024 + }, + "constant_years": { + "start_year": 2017, + "end_year": 2024 + }, + "base_year_min": 1980, + "base_year_max": 2025 + } + ], + "default_base_year": 2024, + "role_currencies": {} + } + } + } + } + ], + "rendered_sentence": "Gross disbursements to 241 recipients from 172 providers for official development assistance, 2017 to 2024. Current US dollars · OECD DAC2A. Assumed: every provider.", + "sentence_plan": [ + { + "kind": "slot", + "text": "Gross disbursements", + "axis": "what", + "segment": "heading", + "entity_refs": [], + "states": [ + "how:financialFlowType", + "how:nettingBasis", + "axis:populationType", + "axis:measuredProperty" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " to ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "241 recipients", + "axis": "where", + "segment": "heading", + "role": "destination", + "binding_ref": "where:", + "entity_refs": [], + "states": [ + "where:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " from ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "172 providers", + "segment": "heading", + "role": "origin", + "binding_ref": "origin:", + "entity_refs": [], + "states": [ + "origin:" + ], + "part_index": 0 + }, + { + "kind": "text", + "text": " for ", + "segment": "heading", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "official development assistance", + "axis": "how", + "segment": "heading", + "property_dcid": "dac2aAidType", + "binding_ref": "how:dac2aAidType", + "entity_refs": [], + "states": [ + "how:dac2aAidType" + ], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "dacTypeOfFinance", + "binding_ref": "how:dacTypeOfFinance", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "financialFlowType", + "binding_ref": "how:financialFlowType", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "slot", + "text": "", + "axis": "how", + "segment": "heading", + "property_dcid": "nettingBasis", + "binding_ref": "how:nettingBasis", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ", ", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "2017 to 2024", + "axis": "when", + "segment": "heading", + "binding_ref": "when:", + "entity_refs": [], + "states": [ + "when:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "heading", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "Current US dollars", + "axis": "unit", + "segment": "byline", + "binding_ref": "unit:", + "entity_refs": [], + "states": [ + "unit:", + "axis:measurementQualifier" + ] + }, + { + "kind": "text", + "text": " · ", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "slot", + "text": "OECD DAC2A", + "axis": "source", + "segment": "byline", + "binding_ref": "source:", + "entity_refs": [], + "states": [ + "source:" + ] + }, + { + "kind": "text", + "text": ".", + "segment": "byline", + "entity_refs": [], + "states": [] + }, + { + "kind": "text", + "text": " ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "Assumed: ", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": "every provider", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + }, + { + "kind": "text", + "text": ".", + "segment": "assumption", + "entity_refs": [], + "states": [], + "part_index": 0 + } + ], + "status": "definite" + } + } + }, + { + "request": { + "method": "GET", + "origin_path": "/api/datasets/spec_8a4676c4abdf43d105aeff9d4ba9299b/cv_50e17ab9c2e732f13c48cf2028ac5928/files/sha256:cf2a4a97cc0fdfeb74ce021502e58c70d87ae4d67dc061a46fa62bb4f106a192" + }, + "response": { + "status": 302, + "headers": { + "location": "https://storage.googleapis.com/e2e-working/sha256%3Acf2a4a97cc0fdfeb74ce021502e58c70d87ae4d67dc061a46fa62bb4f106a192?X-Goog-Signature=redacted" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://storage.googleapis.com/e2e-working/sha256%3Acf2a4a97cc0fdfeb74ce021502e58c70d87ae4d67dc061a46fa62bb4f106a192?X-Goog-Signature=redacted" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/vnd.apache.parquet" + }, + "body_file": "operation-resume.parquet" + } + } + ], + "expect": [ + { + "operation": { + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "status": "pending" + } + }, + { + "dataset": { + "rows": 123015, + "columns": [ + "stat_var", + "financingProvider", + "financingProvider_label", + "financingProvider_party_kind", + "financingRecipient", + "financingRecipient_label", + "financingRecipient_party_kind", + "dac2aAidType", + "dac2aAidType_label", + "time_period", + "value", + "unit", + "unit_label", + "currency", + "price_basis", + "base_year", + "measurementMethod", + "measurementMethod_label", + "provenance", + "provenance_label" + ], + "complete": true, + "members": [ + { + "parts": [], + "spec_id": "spec_8a4676c4abdf43d105aeff9d4ba9299b", + "content_version": "cv_50e17ab9c2e732f13c48cf2028ac5928", + "sentence": "Gross disbursements to 241 recipients from 172 providers for official development assistance, 2017 to 2024. Current US dollars · OECD DAC2A." + } + ], + "missing": [], + "long_builds": [ + { + "operation_id": "op_33dee3c9711dcc7f5f4f12d8b76c44f96c6be64f38521f5d5724e844495a5445", + "poll_waits": [ + 1.5, + 1.5, + 1.5, + 1.5, + 1.518, + 1.901, + 2.379, + 2.977, + 3.739 + ], + "resubmissions": 0 + } + ] + } + } + ] +} diff --git a/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.parquet b/python/client-contract/src/dfo_client_contract/scenarios/operation-resume.parquet new file mode 100644 index 0000000000000000000000000000000000000000..c7a5f317990a3f6ab81e56c418d9144c6288faf5 GIT binary patch literal 1031059 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�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